]> git.webhop.me Git - input.git/commitdiff
* initial commit
authorsvenhoefer <svenhoefer@svenhoefer.com>
Tue, 14 Aug 2012 20:09:49 +0000 (22:09 +0200)
committersvenhoefer <svenhoefer@svenhoefer.com>
Tue, 14 Aug 2012 20:09:49 +0000 (22:09 +0200)
gfx.c [new file with mode: 0644]
gfx.h [new file with mode: 0644]
input.c [new file with mode: 0644]
input.h [new file with mode: 0644]
inputd.c [new file with mode: 0644]
inputd.h [new file with mode: 0644]
io.c [new file with mode: 0644]
io.h [new file with mode: 0644]
text.c [new file with mode: 0644]
text.h [new file with mode: 0644]

diff --git a/gfx.c b/gfx.c
new file mode 100644 (file)
index 0000000..23c826b
--- /dev/null
+++ b/gfx.c
@@ -0,0 +1,128 @@
+#include "input.h"
+
+char circle[] =
+{
+       0,0,0,0,0,1,1,0,0,0,0,0,
+       0,0,0,1,1,1,1,1,1,0,0,0,
+       0,0,1,1,1,1,1,1,1,1,0,0,
+       0,1,1,1,1,1,1,1,1,1,1,0,
+       0,1,1,1,1,1,1,1,1,1,1,0,
+       1,1,1,1,1,1,1,1,1,1,1,1,
+       1,1,1,1,1,1,1,1,1,1,1,1,
+       0,1,1,1,1,1,1,1,1,1,1,0,
+       0,1,1,1,1,1,1,1,1,1,1,0,
+       0,0,1,1,1,1,1,1,1,1,0,0,
+       0,0,0,1,1,1,1,1,1,0,0,0,
+       0,0,0,0,0,1,1,0,0,0,0,0
+};
+
+void RenderBox(int sx, int sy, int ex, int ey, int rad, int col)
+{
+       int F,R=rad,ssx=startx+sx,ssy=starty+sy,dxx=ex-sx,dyy=ey-sy,rx,ry,wx,wy,count;
+
+       unsigned char *pos=(lbb+(ssx<<2)+fix_screeninfo.line_length*ssy);
+       unsigned char *pos0, *pos1, *pos2, *pos3, *i;
+       unsigned char pix[4]={bl[col],gn[col],rd[col],tr[col]};
+               
+       if (dxx<0) 
+       {
+               printf("[input] RenderBox called with dx < 0 (%d)\n", dxx);
+               dxx=0;
+       }
+
+       if(R)
+       {
+               if(--dyy<=0)
+               {
+                       dyy=1;
+               }
+
+               if(R==1 || R>(dxx/2) || R>(dyy/2))
+               {
+                       R=dxx/10;
+                       F=dyy/10;       
+                       if(R>F)
+                       {
+                               if(R>(dyy/3))
+                               {
+                                       R=dyy/3;
+                               }
+                       }
+                       else
+                       {
+                               R=F;
+                               if(R>(dxx/3))
+                               {
+                                       R=dxx/3;
+                               }
+                       }
+               }
+               ssx=0;
+               ssy=R;
+               F=1-R;
+
+               rx=R-ssx;
+               ry=R-ssy;
+
+               pos0=pos+((dyy-ry)*fix_screeninfo.line_length);
+               pos1=pos+(ry*fix_screeninfo.line_length);
+               pos2=pos+(rx*fix_screeninfo.line_length);
+               pos3=pos+((dyy-rx)*fix_screeninfo.line_length);
+               while (ssx <= ssy)
+               {
+                       rx=R-ssx;
+                       ry=R-ssy;
+                       wx=rx<<1;
+                       wy=ry<<1;
+
+                       for(i=pos0+(rx<<2); i<pos0+((rx+dxx-wx)<<2);i+=4)
+                               memcpy(i, pix, 4);
+                       for(i=pos1+(rx<<2); i<pos1+((rx+dxx-wx)<<2);i+=4)
+                               memcpy(i, pix, 4);
+                       for(i=pos2+(ry<<2); i<pos2+((ry+dxx-wy)<<2);i+=4)
+                               memcpy(i, pix, 4);
+                       for(i=pos3+(ry<<2); i<pos3+((ry+dxx-wy)<<2);i+=4)
+                               memcpy(i, pix, 4);
+
+                       ssx++;
+                       pos2-=fix_screeninfo.line_length;
+                       pos3+=fix_screeninfo.line_length;
+                       if (F<0)
+                       {
+                               F+=(ssx<<1)-1;
+                       }
+                       else   
+                       { 
+                               F+=((ssx-ssy)<<1);
+                               ssy--;
+                               pos0-=fix_screeninfo.line_length;
+                               pos1+=fix_screeninfo.line_length;
+                       }
+               }
+               pos+=R*fix_screeninfo.line_length;
+       }
+
+       for (count=R; count<(dyy-R); count++)
+       {
+               for(i=pos; i<pos+(dxx<<2);i+=4)
+                       memcpy(i, pix, 4);
+               pos+=fix_screeninfo.line_length;
+       }
+}
+
+/******************************************************************************
+ * RenderCircle
+ ******************************************************************************/
+
+void RenderCircle(int sx, int sy, char col)
+{
+       int x, y;
+       unsigned char pix[4]={bl[col],gn[col],rd[col],tr[col]};
+       //render
+
+               for(y = 0; y < 12; y++)
+               {
+                       for(x = 0; x < 12; x++) if(circle[x + y*12]) memcpy(lbb + (startx + sx + x)*4 + fix_screeninfo.line_length*(starty + sy + y), pix, 4);
+               }
+}
+
diff --git a/gfx.h b/gfx.h
new file mode 100644 (file)
index 0000000..f3a9466
--- /dev/null
+++ b/gfx.h
@@ -0,0 +1,8 @@
+#ifndef __GFX_H__
+
+#define __GFX_H__
+
+void RenderBox(int sx, int sy, int ex, int ey, int mode, int color);
+void RenderCircle(int sx, int sy, char col);
+
+#endif
diff --git a/input.c b/input.c
new file mode 100644 (file)
index 0000000..54920f1
--- /dev/null
+++ b/input.c
@@ -0,0 +1,504 @@
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+#include <signal.h>
+#include "input.h"
+#include "text.h"
+#include "io.h"
+#include "gfx.h"
+#include "inputd.h"
+
+#define NCF_FILE       "/var/tuxbox/config/neutrino.conf"
+#define BUFSIZE        1024
+#define I_VERSION      1.08
+
+//#define FONT "/usr/share/fonts/md_khmurabi_10.ttf"
+#define FONT2 "/share/fonts/pakenham.ttf"
+// if font is not in usual place, we look here:
+#define FONT "/share/fonts/neutrino.ttf"
+
+//                                        CMCST,   CMCS,  CMCT,    CMC,    CMCIT,  CMCI,   CMHT,   CMH
+//                                        WHITE,   BLUE0, TRANSP,  CMS,    ORANGE, GREEN,  YELLOW, RED
+
+unsigned char bl[] = { 0x00,   0x00,   0xFF,   0x80,   0xFF,   0x80,   0x00,   0x80,
+                                           0xFF,       0xFF,   0x00,   0xFF,   0x00,   0x00,   0x00,   0x00};
+unsigned char gn[] = { 0x00,   0x00,   0xFF,   0x00,   0xFF,   0x00,   0xC0,   0x00,
+                                           0xFF,       0x80,   0x00,   0x80,   0xC0,   0xFF,   0xFF,   0x00};
+unsigned char rd[] = { 0x00,   0x00,   0xFF,   0x00,   0xFF,   0x00,   0xFF,   0x00,
+                                           0xFF,       0x00,   0x00,   0x00,   0xFF,   0x00,   0xFF,   0xFF};
+unsigned char tr[] = { 0xFF,   0xFF,   0xFF,   0xA0,   0xFF,   0xA0,   0xFF,   0xFF,
+                                               0xFF,   0xFF,   0x00,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF};
+
+void TrimString(char *strg);
+
+// OSD stuff
+static char menucoltxt[][25]={"Content_Selected_Text","Content_Selected","Content_Text","Content","Content_inactive_Text","Content_inactive","Head_Text","Head"};
+static char spres[][5]={"","_crt","_lcd"};
+
+char *buffer=NULL;
+
+//static void ShowInfo(void);
+
+// Misc
+char NOMEM[]="input <Out of memory>\n";
+char TMP_FILE[]="/tmp/input.tmp";
+unsigned char *lfb = 0, *lbb = 0, *obb = 0;
+unsigned char nstr[512]="",rstr[512]="";
+unsigned char *trstr;
+unsigned char rc,sc[8]={'a','o','u','A','O','U','z','d'}, tc[8]={0xE4,0xF6,0xFC,0xC4,0xD6,0xDC,0xDF,0xB0};
+int radius=10;
+
+static void quit_signal(int sig)
+{
+       put_instance(get_instance()-1);
+       printf("input Version %.2f killed\n",I_VERSION);
+       exit(1);
+}
+
+int Read_Neutrino_Cfg(char *entry)
+{
+FILE *nfh;
+char tstr [512], *cfptr=NULL;
+int rv=-1;
+
+       if((nfh=fopen(NCF_FILE,"r"))!=NULL)
+       {
+               tstr[0]=0;
+
+               while((!feof(nfh)) && ((strstr(tstr,entry)==NULL) || ((cfptr=strchr(tstr,'='))==NULL)))
+               {
+                       fgets(tstr,500,nfh);
+               }
+               if(!feof(nfh) && cfptr)
+               {
+                       ++cfptr;
+                       if(sscanf(cfptr,"%d",&rv)!=1)
+                       {
+                               if(strstr(cfptr,"true")!=NULL)
+                               {
+                                       rv=1;
+                               }
+                               else
+                               {
+                                       if(strstr(cfptr,"false")!=NULL)
+                                       {
+                                               rv=0;
+                                       }
+                                       else
+                                       {
+                                               rv=-1;
+                                       }
+                               }
+                       }
+//                     printf("%s\n%s=%s -> %d\n",tstr,entry,cfptr,rv);
+               }
+               fclose(nfh);
+       }
+       return rv;
+}
+
+void TrimString(char *strg)
+{
+char *pt1=strg, *pt2=strg;
+
+       while(*pt2 && *pt2<=' ')
+       {
+               ++pt2;
+       }
+       if(pt1 != pt2)
+       {
+               do
+               {
+                       *pt1=*pt2;
+                       ++pt1;
+                       ++pt2;
+               }
+               while(*pt2);
+               *pt1=0;
+       }
+       while(strlen(strg) && strg[strlen(strg)-1]<=' ')
+       {
+               strg[strlen(strg)-1]=0;
+       }
+}
+
+int Transform_Msg(char *msg)
+{
+int found=0,i;
+char *sptr=msg, *tptr=msg;
+
+       while(*sptr)
+       {
+               if(*sptr!='~')
+               {
+                       *tptr=*sptr;
+               }
+               else
+               {
+                       rc=*(sptr+1);
+                       found=0;
+                       for(i=0; i<sizeof(sc) && !found; i++)
+                       {
+                               if(rc==sc[i])
+                               {
+                                       rc=tc[i];
+                                       found=1;
+                               }
+                       }
+                       if(found)
+                       {
+                               *tptr=rc;
+                               ++sptr;
+                       }
+                       else
+                       {
+                               *tptr=*sptr;
+                       }
+               }
+               ++sptr;
+               ++tptr;
+       }
+       *tptr=0;
+       return strlen(msg);
+}
+
+void ShowUsage(void)
+{
+       printf("\ninput Version %.2f Syntax:\n", I_VERSION);
+       printf("    input l=\"layout\" [Options]\n\n");
+       printf("    layout                : format-string\n");
+       printf("                            #=numeric @=alphanumeric\n");
+       printf("Options:\n");
+       printf("    t=\"Window-Title\"      : specify title of window [default \"Eingabe\"]\n");
+       printf("    d=\"Defaults\"          : default values\n");
+       printf("    k=1/0                 : show the keyboard layout [default 0]\n");
+       printf("    f=1/0                 : show frame around edit fields [default 1]\n");
+       printf("    m=1/0                 : mask numeric inputs (for PIN entrys) [default 0]\n");
+       printf("    h=1/0                 : return on help key (for PIN changes) [default 0]\n");
+       printf("    c=n                   : colums per line, n=1..25 [default 25]\n");
+       printf("    o=n                   : menu timeout (0=no timeout) [default 0]\n");
+
+}
+/******************************************************************************
+ * input Main
+ ******************************************************************************/
+
+int main (int argc, char **argv)
+{
+int tv,cols=25,debounce=25,tmo=0,index, spr;
+char ttl[]="Eingabe";
+int dloop=1,keys=0,frame=1,mask=0,bhelp=0;
+char *title=NULL, *format=NULL, *defstr=NULL, *aptr, *rptr; 
+unsigned int alpha;
+//FILE *fh;
+
+               if(argc==1)
+               {
+                       ShowUsage();
+                       return 0;
+               }
+
+               dloop=0;
+               for(tv=1; !dloop && tv<argc; tv++)
+               {
+                       aptr=argv[tv];
+                       if((rptr=strchr(aptr,'='))!=NULL)
+                       {
+                               rptr++;
+                               if(strstr(aptr,"l=")!=NULL)
+                               {
+                                       format=rptr;
+                                       dloop=Transform_Msg(format)==0;
+                               }
+                               else
+                               {
+                                       if(strstr(aptr,"t=")!=NULL)
+                                       {
+                                               title=rptr;
+                                               dloop=Transform_Msg(title)==0;
+                                       }
+                                       else
+                                       {
+                                               if(strstr(aptr,"d=")!=NULL)
+                                               {
+                                                       defstr=rptr;
+                                                       dloop=Transform_Msg(defstr)==0;
+                                               }
+                                               else
+                                               {
+                                                       if(strstr(aptr,"m=")!=NULL)
+                                                       {
+                                                               if(sscanf(rptr,"%d",&mask)!=1)
+                                                               {
+                                                                       dloop=1;
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               if(strstr(aptr,"f=")!=NULL)
+                                                               {
+                                                                       if(sscanf(rptr,"%d",&frame)!=1)
+                                                                       {
+                                                                               dloop=1;
+                                                                       }
+                                                               }
+                                                               else
+                                                               {
+                                                                       if(strstr(aptr,"k=")!=NULL)
+                                                                       {
+                                                                               if(sscanf(rptr,"%d",&keys)!=1)
+                                                                               {
+                                                                                       dloop=1;
+                                                                               }
+                                                                       }
+                                                                       else
+                                                                       {
+                                                                               if(strstr(aptr,"h=")!=NULL)
+                                                                               {
+                                                                                       if(sscanf(rptr,"%d",&bhelp)!=1)
+                                                                                       {
+                                                                                               dloop=1;
+                                                                                       }
+                                                                               }
+                                                                               else
+                                                                               {
+                                                                                       if(strstr(aptr,"c=")!=NULL)
+                                                                                       {
+                                                                                               if(sscanf(rptr,"%d",&cols)!=1)
+                                                                                               {
+                                                                                                       dloop=1;
+                                                                                               }
+                                                                                       }
+                                                                                       else
+                                                                                       {
+                                                                                               if(strstr(aptr,"o=")!=NULL)
+                                                                                               {
+                                                                                                       if(sscanf(rptr,"%d",&tmo)!=1)
+                                                                                                       {
+                                                                                                               dloop=1;
+                                                                                                       }
+                                                                                               }
+                                                                                               else
+                                                                                               {
+                                                                                                       dloop=2;
+                                                                                               }
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       switch (dloop)
+                       {
+                               case 1:
+                                       printf("input <param error: %s>\n",aptr);
+                                       return 0;
+                                       break;
+                               
+                               case 2:
+                                       printf("input <unknown command: %s>\n\n",aptr);
+                                       ShowUsage();
+                                       return 0;
+                                       break;
+                       }
+               }
+               if(!format)
+               {
+                       printf("input <missing format string>\n");
+                       return 0;
+       }
+               if(!title)
+               {
+                       title=ttl;
+               }
+
+               if((buffer=calloc(BUFSIZE+1, sizeof(char)))==NULL)
+               {
+                       printf(NOMEM);
+                       return 0;
+               }
+
+               spr=Read_Neutrino_Cfg("screen_preset")+1;
+               sprintf(buffer,"screen_StartX%s",spres[spr]);
+               if((sx=Read_Neutrino_Cfg(buffer))<0)
+                       sx=100;
+
+               sprintf(buffer,"screen_EndX%s",spres[spr]);
+               if((ex=Read_Neutrino_Cfg(buffer))<0)
+                       ex=1180;
+
+               sprintf(buffer,"screen_StartY%s",spres[spr]);
+               if((sy=Read_Neutrino_Cfg(buffer))<0)
+                       sy=100;
+
+               sprintf(buffer,"screen_EndY%s",spres[spr]);
+               if((ey=Read_Neutrino_Cfg(buffer))<0)
+                       ey=620;
+
+               for(index=CMCST; index<=CMH; index++)
+               {
+                       sprintf(rstr,"menu_%s_alpha",menucoltxt[index]);
+                       if((tv=Read_Neutrino_Cfg(rstr))>=0)
+                               tr[index]=255-(float)tv*2.55;
+
+                       sprintf(rstr,"menu_%s_blue",menucoltxt[index]);
+                       if((tv=Read_Neutrino_Cfg(rstr))>=0)
+                               bl[index]=(float)tv*2.55;
+
+                       sprintf(rstr,"menu_%s_green",menucoltxt[index]);
+                       if((tv=Read_Neutrino_Cfg(rstr))>=0)
+                               gn[index]=(float)tv*2.55;
+
+                       sprintf(rstr,"menu_%s_red",menucoltxt[index]);
+                       if((tv=Read_Neutrino_Cfg(rstr))>=0)
+                               rd[index]=(float)tv*2.55;
+               }
+
+               if(Read_Neutrino_Cfg("rounded_corners")>0)
+                       radius=10;
+               else
+                       radius=0;
+
+               fb = open(FB_DEVICE, O_RDWR);
+               if(fb == -1)
+               {
+                       perror("input <open framebuffer device>");
+                       exit(1);
+               }
+
+               InitRC();
+
+               if((trstr=malloc(BUFSIZE))==NULL)
+               {
+                       printf(NOMEM);
+                       return -1;
+               }
+
+       //init framebuffer
+
+               if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1)
+               {
+                       perror("input <FBIOGET_FSCREENINFO>\n");
+                       return -1;
+               }
+               if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1)
+               {
+                       perror("input <FBIOGET_VSCREENINFO>\n");
+                       return -1;
+               }
+               if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0)))
+               {
+                       perror("input <mapping of Framebuffer>\n");
+                       return -1;
+               }
+
+       //init fontlibrary
+
+               if((error = FT_Init_FreeType(&library)))
+               {
+                       printf("input <FT_Init_FreeType failed with Errorcode 0x%.2X>", error);
+                       munmap(lfb, fix_screeninfo.smem_len);
+                       return -1;
+               }
+
+               if((error = FTC_Manager_New(library, 1, 2, 0, &MyFaceRequester, NULL, &manager)))
+               {
+                       printf("input <FTC_Manager_New failed with Errorcode 0x%.2X>\n", error);
+                       FT_Done_FreeType(library);
+                       munmap(lfb, fix_screeninfo.smem_len);
+                       return -1;
+               }
+
+               if((error = FTC_SBitCache_New(manager, &cache)))
+               {
+                       printf("input <FTC_SBitCache_New failed with Errorcode 0x%.2X>\n", error);
+                       FTC_Manager_Done(manager);
+                       FT_Done_FreeType(library);
+                       munmap(lfb, fix_screeninfo.smem_len);
+                       return -1;
+               }
+
+               if((error = FTC_Manager_LookupFace(manager, FONT, &face)))
+               {
+                       if((error = FTC_Manager_LookupFace(manager, FONT2, &face)))
+                       {
+                               printf("input <FTC_Manager_LookupFace failed with Errorcode 0x%.2X>\n", error);
+                               FTC_Manager_Done(manager);
+                               FT_Done_FreeType(library);
+                               munmap(lfb, fix_screeninfo.smem_len);
+                               return 2;
+                       }
+                       else
+                               desc.face_id = FONT2;
+               }
+               else
+                       desc.face_id = FONT;
+
+               use_kerning = FT_HAS_KERNING(face);
+
+               desc.flags = FT_LOAD_MONOCHROME;
+
+       //init backbuffer
+
+               if(!(lbb = malloc(fix_screeninfo.line_length*var_screeninfo.yres)))
+               {
+                       perror("input <allocating of Backbuffer>\n");
+                       FTC_Manager_Done(manager);
+                       FT_Done_FreeType(library);
+                       munmap(lfb, fix_screeninfo.smem_len);
+                       return -1;
+               }
+               if(!(obb = malloc(fix_screeninfo.line_length*var_screeninfo.yres)))
+               {
+                       perror("input <allocating of Backbuffer>\n");
+                       FTC_Manager_Done(manager);
+                       FT_Done_FreeType(library);
+                       free(lbb);
+                       munmap(lfb, fix_screeninfo.smem_len);
+                       return 0;
+               }
+
+               memcpy(lbb, lfb, fix_screeninfo.line_length*var_screeninfo.yres);
+               memcpy(obb, lfb, fix_screeninfo.line_length*var_screeninfo.yres);
+
+               startx = sx /*+ (((ex-sx) - 620)/2)*/;
+               starty = sy /* + (((ey-sy) - 505)/2)*/;
+
+
+
+       signal(SIGINT, quit_signal);
+       signal(SIGTERM, quit_signal);
+       signal(SIGQUIT, quit_signal);
+
+       //main loop
+       put_instance(instance=get_instance()+1);
+       printf("%s\n",inputd(format, title, defstr, keys, frame, mask, bhelp, cols, tmo, debounce));
+       put_instance(get_instance()-1);
+       
+       //cleanup
+
+       // clear Display
+//     memset(lbb, 0, var_screeninfo.xres*var_screeninfo.yres);
+//     memcpy(lfb, lbb, var_screeninfo.xres*var_screeninfo.yres);
+       
+       memcpy(lfb, obb, fix_screeninfo.line_length*var_screeninfo.yres);
+
+       free(buffer);
+
+       FTC_Manager_Done(manager);
+       FT_Done_FreeType(library);
+
+       free(lbb);
+       free(obb);
+       munmap(lfb, fix_screeninfo.smem_len);
+
+       close(fb);
+       CloseRC();
+
+
+       return 1;
+}
+
diff --git a/input.h b/input.h
new file mode 100644 (file)
index 0000000..d53dcc0
--- /dev/null
+++ b/input.h
@@ -0,0 +1,125 @@
+#ifndef __INPUT_H__
+
+#define __INPUT_H__
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <linux/fb.h>
+#include <linux/input.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/un.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_CACHE_H
+#include FT_CACHE_SMALL_BITMAPS_H
+
+//freetype stuff
+
+enum {LEFT, CENTER, RIGHT};
+enum {SMALL, MED, BIG};
+
+FT_Error               error;
+FT_Library             library;
+FTC_Manager            manager;
+FTC_SBitCache          cache;
+FTC_SBit               sbit;
+#if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0
+FTC_Image_Desc         desc;
+#else
+FTC_ImageTypeRec       desc;
+#endif
+FT_Face                        face;
+FT_UInt                        prev_glyphindex;
+FT_Bool                        use_kerning;
+
+// rc codes
+
+#undef KEY_EPG
+#undef KEY_SAT
+#undef KEY_STOP
+#undef KEY_PLAY
+
+#define KEY_1                                  2
+#define KEY_2                                  3
+#define KEY_3                                  4
+#define KEY_4                                  5
+#define KEY_5                                  6
+#define KEY_6                                  7
+#define KEY_7                                  8
+#define KEY_8                                  9
+#define KEY_9                                  10
+#define KEY_BACKSPACE           14
+#define KEY_UP                  103
+#define KEY_LEFT                105
+#define KEY_RIGHT               106
+#define KEY_DOWN                108
+#define KEY_MUTE                113
+#define KEY_VOLUMEDOWN          114
+#define KEY_VOLUMEUP            115
+#define KEY_POWER               116
+#define KEY_HELP                138
+#define KEY_HOME                102
+#define KEY_EXIT                               174
+#define KEY_SETUP               141
+#define KEY_PAGEUP              104
+#define KEY_PAGEDOWN            109
+#define KEY_OK                         0x160
+#define KEY_RED                        0x18e
+#define KEY_GREEN                      0x18f
+#define KEY_YELLOW                     0x190
+#define KEY_BLUE                       0x191
+
+#define KEY_TVR                                        0x179
+#define KEY_TTX                                        0x184
+#define KEY_COOL                               0x1A1
+#define KEY_FAV                                        0x16C
+#define KEY_EPG                                        0x16D
+#define KEY_VF                                 0x175
+
+#define KEY_SAT                                        0x17D
+#define KEY_SKIPP                              0x197
+#define KEY_SKIPM                              0x19C
+#define KEY_TS                                 0x167
+#define KEY_AUDIO                              0x188
+#define KEY_REW                                        0x0A8
+#define KEY_FWD                                        0x09F
+#define KEY_HOLD                               0x077
+#define KEY_REC                                        0x0A7
+#define KEY_STOP                               0x080
+#define KEY_PLAY                               0x0CF
+
+//devs
+
+int fb;
+
+//framebuffer stuff
+
+enum {FILL, GRID};
+
+enum {CMCST, CMCS, CMCT, CMC, CMCIT, CMCI, CMHT, CMH, WHITE, BLUE1, GTRANSP, CMS, ORANGE, GREEN, YELLOW, RED};
+#define TRANSP 0
+
+extern unsigned char *lfb, *lbb, *obb;
+extern unsigned char rd[], gn[], bl[], tr[];
+
+struct fb_fix_screeninfo fix_screeninfo;
+struct fb_var_screeninfo var_screeninfo;
+
+int startx, starty, sx, ex, sy, ey;
+extern unsigned char sc[8], tc[8];
+extern char *butmsg[3];
+extern int buttons,selection;
+
+#define FB_DEVICE      "/dev/fb/0"
+
+#define BUFSIZE 1024
+
+#endif
+
diff --git a/inputd.c b/inputd.c
new file mode 100644 (file)
index 0000000..5a5524a
--- /dev/null
+++ b/inputd.c
@@ -0,0 +1,623 @@
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+#include "input.h"
+#include "text.h"
+#include "io.h"
+#include "gfx.h"
+
+#define xbrd   25
+#define ybrd   25
+#define exsz   23
+#define eysz   38
+#define bxsz   60
+#define bysz   60
+#define hsz            50
+#define tys            30
+#define NUM            '#'
+#define ANUM   '@'
+#define HEX            '^'
+#define ndelay 3
+
+char rstr[512],tstr[512], *format, *estr;
+int epos=-1,cpos=0,kpos=0,cnt,first=1,hex=0;
+char kcod[10][13]={"0 _.:,;$@()#","1-+*/", "2abcä", "3def", "4ghi", "5jkl", "6mnoö", "7pqrsß", "8tuvü", "9wxyz"};
+char hcod[10][13]={"0","1", "2abc", "3def", "4", "5", "6", "7", "8", "9"};
+unsigned rc;
+extern int radius;
+char INST_FILE[]="/tmp/rc.locked";
+int instance=0;
+
+int get_instance(void)
+{
+FILE *fh;
+int rval=0;
+
+       if((fh=fopen(INST_FILE,"r"))!=NULL)
+       {
+               rval=fgetc(fh);
+               fclose(fh);
+       }
+       return rval;
+}
+
+void put_instance(int pval)
+{
+FILE *fh;
+
+       if(pval)
+       {
+               if((fh=fopen(INST_FILE,"w"))!=NULL)
+               {
+                       fputc(pval,fh);
+                       fclose(fh);
+               }
+       }
+       else
+       {
+               remove(INST_FILE);
+       }
+}
+
+int IsAlpha(char ch)
+{
+       char uml[]="AÖÜaöü";
+       return (((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z')) || strchr(uml,ch));
+}
+
+int IsNum(char ch)
+{
+       return ((ch>='0')&&(ch<='9'));
+}
+
+int IsInput(char ch)
+{
+
+       if((ch==NUM) || (ch==ANUM))
+       {
+               hex=0;
+               return 1;
+       }
+       if (ch==HEX)
+       {
+               hex=1;
+               return 1;
+       }
+       return 0;
+}
+
+void FindCode(char ch)
+{
+
+       if(!hex)
+       {
+               for(cpos=0; cpos<10; cpos++)
+               {
+                       for(kpos=0; kpos<strlen(kcod[cpos]); kpos++)
+                       {
+                               if(ch==kcod[cpos][kpos])
+                               {
+                                       return;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               for(cpos=0; cpos<10; cpos++)
+               {
+                       for(kpos=0; kpos<strlen(hcod[cpos]); kpos++)
+                       {
+                               if(ch==hcod[cpos][kpos])
+                               {
+                                       return;
+                               }
+                       }
+               }
+       }
+}
+               
+void NextPos(void)
+{
+       do
+       {
+               epos++;
+               if(epos>=cnt)
+               {
+                       epos=0;
+               }
+       }
+       while(!IsInput(format[epos]));
+       FindCode(estr[epos]);
+       first=1;
+}
+
+void PrevPos(void)
+{
+       do
+       {
+               epos--;
+               if(epos<0)
+               {
+                       epos=cnt-1;
+               }
+       }
+       while(!IsInput(format[epos]));
+       FindCode(estr[epos]);
+       first=1;
+}
+
+void SetCode(int code)
+{
+       if(format[epos]==NUM)
+       {
+               hex=0;
+               cpos=code;
+               kpos=0;
+               estr[epos]=kcod[cpos][kpos];
+               NextPos();
+       }
+       else
+       {
+               if(format[epos]==HEX)
+               {
+                       hex=1;
+                       if(strlen(hcod[code])>1)
+                       {
+                               if(!first)
+                               {
+                                       if(cpos==code)
+                                       {
+                                               if(++kpos>=strlen(hcod[cpos]))
+                                               {
+                                                       kpos=0;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               NextPos();
+                                               cpos=code;
+                                               kpos=0;
+                                               first=0;
+                                       }
+                                       estr[epos]=hcod[cpos][kpos];
+                               }
+                               else
+                               {
+                                       cpos=code;
+                                       kpos=0;
+                                       estr[epos]=hcod[cpos][kpos];
+                                       first=0;
+                               }
+                       }
+                       else
+                       {
+                               cpos=code;
+                               kpos=0;
+                               estr[epos]=hcod[cpos][kpos];
+                               NextPos();
+                       }
+               }
+               else
+               {
+                       hex=0;
+                       if(!first)
+                       {
+                               if(cpos==code)
+                               {
+                                       if(++kpos>=strlen(kcod[cpos]))
+                                       {
+                                               kpos=0;
+                                       }
+                               }
+                               else
+                               {
+                                       NextPos();
+                                       cpos=code;
+                                       kpos=1;
+                                       first=0;
+                               }
+                               estr[epos]=kcod[cpos][kpos];
+                       }
+                       else
+                       {
+                               cpos=code;
+                               kpos=1;
+                               estr[epos]=kcod[cpos][kpos];
+                               first=0;
+                       }
+               }
+       }
+}
+
+int ReTransform_Msg(char *msg)
+{
+int found=0,i;
+char *sptr=msg, *tptr=tstr;
+
+       *tptr=0;
+       while(*sptr)
+       {
+               found=0;
+               for(i=0; i<sizeof(tc) && !found; i++)
+               {
+                       rc=*sptr;
+                       if(rc==tc[i])
+                       {
+                               rc=sc[i];
+                               *(tptr++)='~';
+                               found=1;
+                       }
+               }
+               *tptr=rc;
+               ++sptr;
+               ++tptr;
+       }
+       *tptr=0;
+       return strlen(rstr);
+}
+
+char *inputd(char *form, char *title, char *defstr, int keys, int frame, int mask, int bhelp, int cols, int tmo, int debounce)
+{
+int exs,eys,wxs,wxw,wys,wyw,i,j,xp,yp;
+char trnd[2]={0,0},tch;
+int act_key=-1, last_key=-1, b_key=-1, run=1, ipos=0;
+time_t t1,t2,tm1;
+char knum[12][2]={"1","2","3","4","5","6","7","8","9"," ","0"};
+char kalp[12][5]={"+-*/","abcä","def","ghi","jkl","mnoö","pqrs","tuvü","wxyz","","_,.;"};
+
+       epos=-1;
+       cpos=0;
+       kpos=0;
+       first=1;
+       time(&tm1);
+       if(cols>25)
+       {
+               cols=25;
+       }
+       if(cols<1)
+       {
+               cols=1;
+       }
+       format=form;
+       estr=strdup(form);
+       cnt=strlen(form);
+       
+       i=GetStringLen(title, BIG)+10;
+       j=((cnt>cols)?cols:cnt)*exsz;
+       if(j>i)
+       {
+               i=j;
+       }
+       if(keys)
+       {
+               j=3*bxsz;
+               if(j>i)
+               {
+                       i=j;
+               }
+       }
+       wxw=i+2*xbrd;
+
+       i=(((cnt-1)/cols)+1)*eysz;
+       if(keys)
+       {
+               i+=4*bysz;
+       }
+       wyw=((keys)?4:2)*ybrd+i;
+
+       wxs=((ex-sx)-wxw)/2;
+       wys=(((ey-sy)-wyw)+hsz)/2;
+       exs=wxs+(wxw-((cnt>cols)?cols:cnt)*exsz)/2;
+       eys=wys+ybrd;
+
+       *estr=0;
+       *rstr=0;
+               
+       j=0;
+       for(i=0; i<strlen(format); i++)
+       {
+               tch=format[i];
+               if(IsInput(tch))
+               {
+                       if(epos==-1)
+                       {
+                               epos=i;
+                       }
+                       if(defstr && j<strlen(defstr))
+                       {
+                               estr[i]=defstr[j++];
+                       }
+                       else
+                       {
+                               estr[i]=' ';
+                       }
+               }
+               else
+               {
+                       estr[i]=format[i];
+               }
+       }
+       estr[i]=0;
+
+       RenderBox(wxs-2, wys-hsz-2, wxs+wxw+2, wys+wyw+2, radius, CMH);
+       RenderBox(wxs, wys-hsz, wxs+wxw, wys+wyw, radius, CMC);
+       RenderBox(wxs, wys-hsz, wxs+wxw, wys, radius, CMH);
+       RenderString(title, wxs, wys-15, wxw, CENTER, BIG, CMHT);
+       if(keys)
+       {
+               int bxs=wxs+(wxw-(3*bxsz))/2;
+               int bys=((wys+wyw)-2*ybrd)-4*bysz;
+               
+               for(i=0; i<11; i++)
+               {
+                       if(i!=9)
+                       {
+                               RenderBox(bxs+(i%3)*bxsz, bys+(i/3)*bysz, bxs+((i%3)+1)*bxsz, bys+((i/3)+1)*bysz, radius, CMS);
+                               RenderBox(bxs+(i%3)*bxsz+2, bys+(i/3)*bysz+2, bxs+((i%3)+1)*bxsz-2, bys+((i/3)+1)*bysz-2, radius, CMC);
+                               RenderString(knum[i], bxs+(i%3)*bxsz, bys+(i/3)*bysz+bysz/2, bxsz, CENTER, MED, CMCIT);
+                               RenderString(kalp[i], bxs+(i%3)*bxsz, bys+(i/3)*bysz+bysz-8, bxsz, CENTER, SMALL, CMCIT);
+                               
+                       }
+               }       
+               RenderCircle(bxs,wys+wyw-ybrd-8,RED);
+               RenderString("Groß/Klein",bxs+15,wys+wyw-ybrd+5,3*bxsz,LEFT,SMALL,CMCIT);
+               RenderCircle(bxs+3*bxsz-GetStringLen("löschen",SMALL)-15,wys+wyw-ybrd-8,YELLOW);
+               RenderString("löschen",bxs,wys+wyw-ybrd+5,3*bxsz,RIGHT,SMALL,CMCIT);
+       }
+       
+       while(run)
+       {
+               for(i=0; i<cnt; i++)
+               {
+                       xp=i%cols;
+                       yp=i/cols;
+                       if(frame && IsInput(format[i]))
+                       {
+                               RenderBox(exs+xp*exsz, eys+5+yp*eysz, exs+(xp+1)*exsz, eys+(yp+1)*eysz, radius, CMS);
+                       }
+                       RenderBox(exs+xp*exsz+1, eys+5+yp*eysz+1, exs+(xp+1)*exsz-1, eys+(yp+1)*eysz-1, radius, (epos==i)?CMCS:CMC);
+                       *trnd=(mask && format[i]==NUM && IsNum(estr[i]))?'*':estr[i];
+                       RenderString(trnd, exs+xp*exsz+2, eys+yp*eysz+tys, exsz-2, CENTER, MED, (epos==i)?CMCST:(IsInput(format[i]))?CMCT:CMCIT);
+               }
+               memcpy(lfb, lbb, fix_screeninfo.line_length*var_screeninfo.yres);
+               
+//             sleep(1);
+
+               time(&t1);
+               i=-1;
+               while(i==-1)
+               {
+                       i=GetRCCode();
+                       if(i!=-1)
+                       {
+                               tmo=0;
+                               if(i==b_key)
+                               {
+                                       usleep(debounce*1000);
+                                       while((i=GetRCCode())!=-1);
+                               }
+                               b_key=i;
+                       }
+                       time(&t2);
+                       if(tmo)
+                       {
+                               if((t2-tm1)>=tmo)
+                               {
+                                       i=KEY_EXIT;
+                               }
+                       }
+                       if((((format[epos]!=NUM) && (format[epos]!=HEX)) || ((format[epos]==HEX)&&(strlen(hcod[cpos])>1))) && ((t2-t1)>ndelay) && last_key>=0)
+                       {
+                               act_key=i=-2;
+                               b_key=-3;
+                               NextPos();
+                       }
+               }
+               act_key=i;
+               
+               switch(act_key)
+               {
+                       case KEY_0:
+                               SetCode(0);
+                       break;
+                       
+                       case KEY_1:
+                               SetCode(1);
+                       break;
+                       
+                       case KEY_2:
+                               SetCode(2);
+                       break;
+                       
+                       case KEY_3:
+                               SetCode(3);
+                       break;
+                       
+                       case KEY_4:
+                               SetCode(4);
+                       break;
+                       
+                       case KEY_5:
+                               SetCode(5);
+                       break;
+                       
+                       case KEY_6:
+                               SetCode(6);
+                       break;
+                       
+                       case KEY_7:
+                               SetCode(7);
+                       break;
+                       
+                       case KEY_8:
+                               SetCode(8);
+                       break;
+                       
+                       case KEY_9:
+                               SetCode(9);
+                       break;
+                       
+                       case KEY_RIGHT:
+                               NextPos();
+                               act_key=-2;
+                       break;
+                       
+                       case KEY_LEFT:
+                               PrevPos();
+                               act_key=-2;
+                       break;
+                       
+                       case KEY_VOLUMEUP:
+                               ipos=epos;
+                               while(IsInput(format[ipos+1]) && ((ipos+1)<cnt))
+                               {
+                                       ++ipos;
+                               }
+                               while(ipos>epos)
+                               {
+                                       estr[ipos]=estr[ipos-1];
+                                       --ipos;
+                               }
+                               estr[epos]=' ';
+//                             estr[epos]=((format[epos]=='#')||(format[epos]=='^'))?'0':' ';
+                               act_key=-1;
+                       break;
+
+                       case KEY_VOLUMEDOWN:
+                               ipos=epos+1;
+                               while(IsInput(format[ipos]) && (ipos<cnt))
+                               {
+                                       estr[ipos-1]=estr[ipos];
+                                       ++ipos;
+                               }
+                               estr[ipos-1]=' ';
+//                             estr[ipos-1]=(format[ipos-1]=='#')?'0':' ';
+                               act_key=-1;
+                       break;
+
+                       case KEY_OK:
+                               run=0;
+                       break;
+                       
+                       case KEY_MUTE:
+                               memset(lfb, TRANSP, fix_screeninfo.line_length*var_screeninfo.yres);
+                               usleep(500000L);
+                               while(GetRCCode()!=-1)
+                               {
+                                       usleep(100000L);
+                               }
+                               while(GetRCCode()!=KEY_MUTE)
+                               {
+                                       usleep(500000L);
+                               }
+                               while((act_key=GetRCCode())!=-1)
+                               {
+                                       usleep(100000L);
+                               }
+//                             knew=1;
+                       break;
+
+                       case KEY_UP:
+                               if(epos>=cols)
+                               {
+                                       epos-=cols;
+                                       if(!IsInput(format[epos]))
+                                       {
+                                               NextPos();
+                                       }
+                               }
+                               else
+                               {
+                                       epos=cnt-1;
+                                       if(!IsInput(format[epos]))
+                                       {
+                                               PrevPos();
+                                       }
+                               }
+                               act_key=-2;
+                       break;
+                       
+                       case KEY_DOWN:
+                               if(epos<=(cnt-cols))
+                               {
+                                       epos+=cols;
+                                       if(!IsInput(format[epos]))
+                                       {
+                                               NextPos();
+                                       }
+                               }
+                               else
+                               {
+                                       epos=0;
+                                       if(!IsInput(format[epos]))
+                                       {
+                                               NextPos();
+                                       }
+                               }
+                               act_key=-2;
+                       break;
+                       
+                       case KEY_EXIT:
+                               free(estr);
+                               estr=NULL;
+                               *rstr=0;
+                               run=0;
+                       break;
+                       
+                       case KEY_RED:
+                               if(IsAlpha(estr[epos]))
+                               {
+                                       estr[epos]^=0x20;
+                               }
+                               act_key=-2;
+                       break;
+                       
+                       case KEY_YELLOW:
+                               epos=-1;
+                               for(i=0; i<strlen(format); i++)
+                               {
+                                       if(IsInput(format[i]))
+                                       {
+                                               if(epos==-1)
+                                               {
+                                                       epos=i;
+                                               }
+                                               estr[i]=' ';
+                                       }
+                               }
+                               act_key=-2;
+                       break;
+                       
+                       case KEY_HELP:
+                               if(bhelp)
+                               {
+                                       sprintf(estr,"?");
+                                       run=0;
+                               }
+                       break;
+                       
+                       default:
+                               act_key=-2;
+                       break;
+               }
+               last_key=act_key;
+       }
+       
+       if(estr)
+       {
+               j=0;
+               for(i=0; i<strlen(format); i++)
+               {
+                       if(IsInput(format[i]))
+                       {
+                               rstr[j++]=estr[i];
+                       }
+               }
+               rstr[j]=0;
+               free(estr);
+       }       
+       ReTransform_Msg(rstr);
+       return tstr;
+}
+
diff --git a/inputd.h b/inputd.h
new file mode 100644 (file)
index 0000000..99aac19
--- /dev/null
+++ b/inputd.h
@@ -0,0 +1,11 @@
+#ifndef __INPUTD_H__
+
+#define __INPUTD_H__
+
+extern int instance;
+int get_instance(void);
+void put_instance(int pval);
+char *inputd(char *format, char *title, char *defstr, int keys, int frame, int mask, int bhelp, int cols, int tmo, int debounce);
+
+#endif
+
diff --git a/io.c b/io.c
new file mode 100644 (file)
index 0000000..b4cdaa2
--- /dev/null
+++ b/io.c
@@ -0,0 +1,77 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <errno.h>
+#include <locale.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <linux/fb.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <linux/input.h>
+
+#include "io.h"
+
+#define RC_DEVICE      "/dev/input/nevis_ir"
+
+extern int instance;
+struct input_event ev;
+static unsigned short rccode=-1;
+static int rc;
+
+int InitRC(void)
+{
+       rc = open(RC_DEVICE, O_RDONLY);
+       if(rc == -1)
+       {
+               perror("msgbox <open remote control>");
+               exit(1);
+       }
+       fcntl(rc, F_SETFL, O_NONBLOCK | O_SYNC);
+       while(RCKeyPressed());
+       return 1;
+}
+
+int CloseRC(void)
+{
+       while(RCKeyPressed());
+       close(rc);
+       return 1;
+}
+
+int RCKeyPressed(void)
+{
+       if(read(rc, &ev, sizeof(ev)) == sizeof(ev))
+       {
+               if(ev.value)
+               {
+                       rccode=ev.code;
+                       return 1;
+               }
+       }
+       rccode = -1;
+       return 0;
+}
+
+
+int GetRCCode(void)
+{
+       int rv;
+       
+       if(!RCKeyPressed() || (get_instance()>instance))
+       {
+               return -1;
+       }
+       rv=rccode;
+       while(RCKeyPressed());
+       
+       return rv;
+}
+
+
diff --git a/io.h b/io.h
new file mode 100644 (file)
index 0000000..d7914d4
--- /dev/null
+++ b/io.h
@@ -0,0 +1,11 @@
+#ifndef __IO_H__
+
+#define __IO_H__
+
+#define RC_DEVICE      "/dev/input/nevis_ir"
+
+int InitRC(void);
+int CloseRC(void);
+int RCKeyPressed(void);
+
+#endif
diff --git a/text.c b/text.c
new file mode 100644 (file)
index 0000000..92d2473
--- /dev/null
+++ b/text.c
@@ -0,0 +1,247 @@
+#include "text.h"
+#include "gfx.h"
+#include "io.h"
+
+int FSIZE_BIG=32;
+int FSIZE_MED=24;
+int FSIZE_SMALL=20;
+int TABULATOR=300;
+
+/******************************************************************************
+ * MyFaceRequester
+ ******************************************************************************/
+
+FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface)
+{
+       FT_Error result;
+
+       result = FT_New_Face(library, face_id, 0, aface);
+
+       if(result) printf("msgbox <Font \"%s\" failed>\n", (char*)face_id);
+
+       return result;
+}
+
+/******************************************************************************
+ * RenderChar
+ ******************************************************************************/
+
+int RenderChar(FT_ULong currentchar, int sx, int sy, int ex, int color)
+{
+//     unsigned char pix[4]={oldcmap.red[col],oldcmap.green[col],oldcmap.blue[col],oldcmap.transp[col]};
+//     unsigned char pix[4]={0x80,0x80,0x80,0x80};
+       unsigned char pix[4]={bl[color],gn[color],rd[color],tr[color]};
+       int row, pitch, bit, x = 0, y = 0;
+       FT_UInt glyphindex;
+       FT_Vector kerning;
+       FT_Error error;
+
+       currentchar=currentchar & 0xFF;
+
+       //load char
+
+               if(!(glyphindex = FT_Get_Char_Index(face, (int)currentchar)))
+               {
+//                     printf("msgbox <FT_Get_Char_Index for Char \"%c\" failed\n", (int)currentchar);
+                       return 0;
+               }
+
+
+               if((error = FTC_SBitCache_Lookup(cache, &desc, glyphindex, &sbit, NULL)))
+               {
+//                     printf("msgbox <FTC_SBitCache_Lookup for Char \"%c\" failed with Errorcode 0x%.2X>\n", (int)currentchar, error);
+                       return 0;
+               }
+
+// no kerning used
+/*
+               if(use_kerning)
+               {
+                       FT_Get_Kerning(face, prev_glyphindex, glyphindex, ft_kerning_default, &kerning);
+
+                       prev_glyphindex = glyphindex;
+                       kerning.x >>= 6;
+               }
+               else
+*/
+                       kerning.x = 0;
+
+       //render char
+
+               if(color != -1) /* don't render char, return charwidth only */
+               {
+                       if(sx + sbit->xadvance >= ex) return -1; /* limit to maxwidth */
+
+                       for(row = 0; row < sbit->height; row++)
+                       {
+                               for(pitch = 0; pitch < sbit->pitch; pitch++)
+                               {
+                                       for(bit = 7; bit >= 0; bit--)
+                                       {
+                                               if(pitch*8 + 7-bit >= sbit->width) break; /* render needed bits only */
+
+                                               if((sbit->buffer[row * sbit->pitch + pitch]) & 1<<bit) memcpy(lbb + (startx + sx + sbit->left + kerning.x + x)*4 + fix_screeninfo.line_length*(starty + sy - sbit->top + y),pix,4);
+
+                                               x++;
+                                       }
+                               }
+
+                               x = 0;
+                               y++;
+                       }
+
+               }
+
+       //return charwidth
+
+               return sbit->xadvance + kerning.x;
+}
+
+/******************************************************************************
+ * GetStringLen
+ ******************************************************************************/
+
+int GetStringLen(unsigned char *string, int size)
+{
+int i, found;
+int stringlen = 0;
+
+       //reset kerning
+
+               prev_glyphindex = 0;
+
+       //calc len
+
+               switch (size)
+               {
+                       case SMALL: desc.width = desc.height = FSIZE_SMALL; break;
+                       case MED:   desc.width = desc.height = FSIZE_MED; break;
+                       case BIG:   desc.width = desc.height = FSIZE_BIG; break;
+                       default:    desc.width = desc.height = size; break;
+               }
+               
+               while(*string != '\0')
+               {
+                       stringlen += RenderChar(*string, -1, -1, -1, -1);
+                       string++;
+               }
+
+       return stringlen;
+}
+
+
+void CatchTabs(char *text)
+{
+       int i;
+       char *tptr=text;
+       
+       while((tptr=strstr(tptr,"~T"))!=NULL)
+       {
+               *(++tptr)='t';
+               for(i=0; i<3; i++)
+               {
+                       if(*(++tptr))
+                       {
+                               *tptr=' ';
+                       }
+               }
+       }
+}
+
+/******************************************************************************
+ * RenderString
+ ******************************************************************************/
+
+int RenderString(char *string, int sx, int sy, int maxwidth, int layout, int size, int color)
+{
+       int stringlen, ex, charwidth,i,found;
+       char rstr[BUFSIZE], *rptr=rstr, rc;
+       int varcolor=color;
+
+       //set size
+       
+               strcpy(rstr,string);
+
+               switch (size)
+               {
+                       case SMALL: desc.width = desc.height = FSIZE_SMALL; break;
+                       case MED:   desc.width = desc.height = FSIZE_MED; break;
+                       case BIG:   desc.width = desc.height = FSIZE_BIG; break;
+                       default:    desc.width = desc.height = size; break;
+               }
+               TABULATOR=3*size;
+       //set alignment
+
+               stringlen = GetStringLen(rstr, size);
+
+               if(layout != LEFT)
+               {
+                       switch(layout)
+                       {
+                               case CENTER:    if(stringlen < maxwidth) sx += (maxwidth - stringlen)/2;
+                                               break;
+
+                               case RIGHT:     if(stringlen < maxwidth) sx += maxwidth - stringlen;
+                       }
+               }
+
+       //reset kerning
+
+               prev_glyphindex = 0;
+
+       //render string
+
+               ex = sx + maxwidth;
+
+               while(*rptr != '\0')
+               {
+                       if(*rptr=='~')
+                       {
+                               ++rptr;
+                               rc=*rptr;
+                               found=0;
+                               for(i=0; i<sizeof(sc) && !found; i++)
+                               {
+                                       if(rc==sc[i])
+                                       {
+                                               rc=tc[i];
+                                               found=1;
+                                       }
+                               }
+                               if(found)
+                               {
+                                       if((charwidth = RenderChar(rc, sx, sy, ex, varcolor)) == -1) return sx; /* string > maxwidth */
+                                       sx += charwidth;
+                               }
+                               else
+                               {
+                                       switch(*rptr)
+                                       {
+                                               case 'R': varcolor=RED; break;
+                                               case 'G': varcolor=GREEN; break;
+                                               case 'Y': varcolor=YELLOW; break;
+                                               case 'B': varcolor=BLUE1; break;
+                                               case 'S': varcolor=color; break;
+                                               case 't':                               
+                                                       sx=TABULATOR*((int)(sx/TABULATOR)+1);
+                                                       break;
+                                               case 'T':
+                                                       if(sscanf(rptr+1,"%3d",&i)==1)
+                                                       {
+                                                               rptr+=3;
+                                                               sx=i;
+                                                       }
+                                               break;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               if((charwidth = RenderChar(*rptr, sx, sy, ex, varcolor)) == -1) return sx; /* string > maxwidth */
+                               sx += charwidth;
+                       }
+                       rptr++;
+               }
+       return stringlen;
+}
+
diff --git a/text.h b/text.h
new file mode 100644 (file)
index 0000000..6b1ded5
--- /dev/null
+++ b/text.h
@@ -0,0 +1,16 @@
+#ifndef __TEXT_H__
+
+#define __TEXT_H__
+
+#include "input.h"
+
+extern int FSIZE_BIG;
+extern int FSIZE_MED;
+extern int FSIZE_SMALL;
+
+FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface);
+int RenderString(char *string, int sx, int sy, int maxwidth, int layout, int size, int color);
+int GetStringLen(unsigned char *string, int size);
+void CatchTabs(char *text);
+
+#endif