From c276b1c1bb264a147a8646e79e18e26c3ef52000 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Tue, 18 Feb 2003 06:13:44 +0000 Subject: [lcd4linux @ 2003-02-18 06:13:44 by reinelt] X11 driver fixes and cleanup --- README.X11 | 4 +- XWindow.c | 652 ++++++++++++++++++++++++++++++------------------------------- 2 files changed, 327 insertions(+), 329 deletions(-) diff --git a/README.X11 b/README.X11 index 7b55624..0fb3dbf 100644 --- a/README.X11 +++ b/README.X11 @@ -1,5 +1,5 @@ # -# $Id: README.X11,v 1.2 2000/04/03 04:46:38 reinelt Exp $ +# $Id: README.X11,v 1.3 2003/02/18 06:13:44 reinelt Exp $ # This is the README file for the X11 display driver for lcd4linux @@ -34,7 +34,7 @@ pixelsize*pixelsize pixels. If you want to, you can emulate the gap between this lcd cells by specifying a pixelgap greater than zero. Sometimes there's a gap between characters, too. You can specify this gap (in pixels again) horizontally and vertically. Usually this gap -is the same size as a cell (which is pixelsize+pixelgap). If you specify +is the same size as a cell (which is pixelsize+pixelgap). If you specify either the row gap or the column gap as -1, this cell size will be used instead. diff --git a/XWindow.c b/XWindow.c index c16155c..90c9c99 100644 --- a/XWindow.c +++ b/XWindow.c @@ -1,4 +1,4 @@ -/* $Id: XWindow.c,v 1.28 2003/02/17 06:06:12 reinelt Exp $ +/* $Id: XWindow.c,v 1.29 2003/02/18 06:13:44 reinelt Exp $ * * X11 Driver for LCD4Linux * @@ -20,6 +20,9 @@ * * * $Log: XWindow.c,v $ + * Revision 1.29 2003/02/18 06:13:44 reinelt + * X11 driver fixes and cleanup + * * Revision 1.28 2003/02/17 06:06:12 reinelt * small bug in X11 driver: omit pixel gap between cahracters * @@ -152,6 +155,7 @@ #include "bar.h" #include "pixmap.h" + /* glibc 2.1 requires defining semun ourselves */ #ifdef _SEM_SEMUN_UNDEFINED union semun { @@ -162,7 +166,6 @@ union semun { }; #endif -#define BARS ( BAR_L | BAR_R | BAR_U | BAR_D | BAR_H2 | BAR_V2 | BAR_T) static LCD Lcd; static Display *dp; @@ -175,7 +178,7 @@ static GC gc,gcb,gch; static XColor co[3]; static Pixmap pmback; -static unsigned char *BackupLCDpixmap; +static unsigned char *LCDpixmap2; static char *rgbfg,*rgbbg,*rgbhg; static int pixel=-1; /*pointsize in pixel*/ static int pgap=0; /*gap between points */ @@ -192,374 +195,369 @@ static int semid=-1; static int shmid=-1; static int ppid; /*parent pid*/ -static void acquire_lock() { -struct sembuf sembuf; - sembuf.sem_num=0; - sembuf.sem_op=-1; - sembuf.sem_flg=0; - semop(semid,&sembuf,1); /* get mutex */ + +static void acquire_lock() +{ + struct sembuf sembuf; + sembuf.sem_num=0; + sembuf.sem_op=-1; + sembuf.sem_flg=0; + semop(semid,&sembuf,1); /* get mutex */ } -static void release_lock() { -struct sembuf sembuf; - sembuf.sem_num=0; - sembuf.sem_op=1; - sembuf.sem_flg=0; - semop(semid,&sembuf,1); /* free mutex */ + +static void release_lock() +{ + struct sembuf sembuf; + sembuf.sem_num=0; + sembuf.sem_op=1; + sembuf.sem_flg=0; + semop(semid,&sembuf,1); /* free mutex */ } -static void semcleanup() { -union semun arg; - if (semid>-1) semctl(semid,0,IPC_RMID,arg); + +static void semcleanup() +{ + union semun arg; + if (semid>-1) semctl(semid,0,IPC_RMID,arg); } -static void shmcleanup() { - if (shmid>-1) shmctl(shmid,IPC_RMID,NULL); + +static void shmcleanup() +{ + if (shmid>-1) shmctl(shmid,IPC_RMID,NULL); } -static void quit_updater() { -int i; - if (async_updater_pid>1) { - i=async_updater_pid; - async_updater_pid=1; - kill(i,9); - waitpid(i,&i,0); - } + +static void quit_updater() +{ + int i; + if (async_updater_pid>1) { + i=async_updater_pid; + async_updater_pid=1; + kill(i,9); + waitpid(i,&i,0); + } } -static void sig_updater(int sig) { - kill(ppid,sig); - exit(0); + +static void sig_updater(int sig) +{ + kill(ppid,sig); + exit(0); } -static void init_signals() { -unsigned int ignsig=(1<10) { - error ("X11: bad font '%s'",s); - return -1; - } - if (sscanf(s=cfg_get("pixel")?:"4+1","%d+%d",&pixel,&pgap)!=2 - || pixel<1 || pgap<0) { - error ("X11: bad pixel '%s'",s); - return -1; - } - if (sscanf(s=cfg_get("gap")?:"3x3","%dx%d",&cgap,&rgap)!=2 - || cgap<-1 || rgap<-1) { - error ("X11: bad gap '%s'",s); - return -1; - } - if (rgap<0) rgap=pixel+pgap; - if (cgap<0) cgap=pixel+pgap; - border=atoi(cfg_get("border")?:"0"); - rgbfg=cfg_get("foreground")?:"#000000"; - rgbbg=cfg_get("background")?:"#80d000"; - rgbhg=cfg_get("halfground")?:"#70c000"; - if (*rgbfg=='\\') rgbfg++; - if (*rgbbg=='\\') rgbbg++; - if (*rgbhg=='\\') rgbhg++; - - if (pix_init(rows,cols,xres,yres)==-1) return -1; - if (init_x(rows,cols,xres,yres)==-1) return -1; - init_signals(); - if (init_shm(rows*cols*xres*yres,&BackupLCDpixmap)==-1) return -1; - memset(BackupLCDpixmap,0xff,rows*yres*cols*xres); - if (init_thread(rows*cols*xres*yres)==-1) return -1; - Self->rows=rows; - Self->cols=cols; - Self->xres=xres; - Self->yres=yres; - Lcd=*Self; - - pix_clear(); - return 0; + +int xlcdinit(LCD *Self) +{ + char *s; + + if (sscanf(s=cfg_get("size")?:"20x4","%dx%d",&cols,&rows)!=2 + || rows<1 || cols<1) { + error ("X11: bad size '%s'",s); + return -1; + } + if (sscanf(s=cfg_get("font")?:"5x8","%dx%d",&xres,&yres)!=2 + || xres<5 || yres>10) { + error ("X11: bad font '%s'",s); + return -1; + } + if (sscanf(s=cfg_get("pixel")?:"4+1","%d+%d",&pixel,&pgap)!=2 + || pixel<1 || pgap<0) { + error ("X11: bad pixel '%s'",s); + return -1; + } + if (sscanf(s=cfg_get("gap")?:"3x3","%dx%d",&cgap,&rgap)!=2 + || cgap<-1 || rgap<-1) { + error ("X11: bad gap '%s'",s); + return -1; + } + if (rgap<0) rgap=pixel+pgap; + if (cgap<0) cgap=pixel+pgap; + border=atoi(cfg_get("border")?:"0"); + rgbfg=cfg_get("foreground")?:"#000000"; + rgbbg=cfg_get("background")?:"#80d000"; + rgbhg=cfg_get("halfground")?:"#70c000"; + if (*rgbfg=='\\') rgbfg++; + if (*rgbbg=='\\') rgbbg++; + if (*rgbhg=='\\') rgbhg++; + + if (pix_init(rows,cols,xres,yres)==-1) return -1; + if (init_x(rows,cols,xres,yres)==-1) return -1; + init_signals(); + if (init_shm(rows*cols*xres*yres,&LCDpixmap2)==-1) return -1; + memset(LCDpixmap2,0xff,rows*yres*cols*xres); + if (init_thread(rows*cols*xres*yres)==-1) return -1; + Self->rows=rows; + Self->cols=cols; + Self->xres=xres; + Self->yres=yres; + Lcd=*Self; + + pix_clear(); + return 0; } -int xlcdclear() { - return pix_clear(); + +int xlcdclear() +{ + return pix_clear(); } -int xlcdput(int row,int col,char *text) { - return pix_put(row,col,text); + +int xlcdput(int row,int col,char *text) +{ + return pix_put(row,col,text); } -int xlcdbar(int type, int row, int col, int max, int len1, int len2) { - return pix_bar(type,row,col,max,len1,len2); + +int xlcdbar(int type, int row, int col, int max, int len1, int len2) +{ + return pix_bar(type,row,col,max,len1,len2); } + int xlcdflush() { -int dirty; -int i,j,igap,jgap,pos; -int x,y; - - acquire_lock(); - dirty=pos=igap=jgap=0; - y=border; - for(i=0;ipxnr*(pixel+pgap)+(pxnr/xres)*cgap; - * f^-1: pxnr -> f^-1(bitpos) = see paper - */ - x-=border; - y-=border; - if (x>=dimx || y>=dimy || x+width<0 || y+height<0) - return; /*border doesnt need update*/ - if (x<0) x=0; - if (y<0) y=0; - if (x+width>dimx) width=dimx-x; - if (y+height>dimy) height=dimy-y; - /* - * now we have to find out where the box starts - * with respects to the LCDpixmap coordinates - */ - /* upper left corner */ - xfrom=xres*(x/boxw); /*start at col.no*/ - i=(x%boxw); /*pixelpos rel. char*/ - if (i>xres*pixel+(xres-1)*pgap) /*in cgap zone*/ - xfrom+=xres; - else { - xfrom+=i/(pixel+pgap); /*character element*/ - if (i%(pixel+pgap)>=pixel) /*in pgap zone*/ - xfrom++; - } - yfrom=yres*(y/boxh); /*start at row.no*/ - i=(y%boxh); /*pixelpos rel. char*/ - if (i>yres*pixel+(yres-1)*pgap) /*in rgap zone*/ - yfrom+=yres; - else { - yfrom+=i/(pixel+pgap); /*character element*/ - if (i%(pixel+pgap)>=pixel) /*in pgag zone*/ - yfrom++; - } - /*lower right corner*/ - x+=width-1; - y+=height-1; - xto=xres*(x/boxw)+(x%boxw)/(pixel+pgap); - yto=yres*(y/boxh)+(y%boxh)/(pixel+pgap); - - pos=yfrom*xres*cols+xfrom; - wy=border+yfrom*(pixel+pgap)+(yfrom/yres)*(rgap-pgap); - wx=border+xfrom*(pixel+pgap)+(xfrom/xres)*(cgap-pgap); - wpos=pos; xpix=xres*cols; - igap=yfrom%yres; wjgap=xfrom%xres; - for(i=yfrom;i<=yto;i++) { - dx=wx; - jgap=wjgap; - for(j=xfrom;j<=xto;j++) { - XFillRectangle(dp,w, - BackupLCDpixmap[wpos++]?gc:gch, - dx,wy, - pixel,pixel); - dx+=pixel+pgap; -#if 0 - // this is wrong! MR - if (++jgap==xres) { dx+=cgap-pgap; jgap=0; } -#endif - } - wy+=pixel+pgap; - if (++igap==yres) { wy+=rgap-pgap; igap=0; } - pos+=xpix; - wpos=pos; - } - XSync(dp,False); +static void update(int x,int y,int width,int height) +{ + /* + * theory of operation: + * instead of the old, fully-featured but complicated update + * region calculation, we do an update of the whole display, + * but check before every pixel if the pixel region is inside + * the update region. + */ + + int x0, y0; + int x1, y1; + int row, col; + int dirty; + + x0=x-pixel; + y0=y-pixel; + x1=x+pixel+width; + y1=y+pixel+height; + + dirty=0; + for(row=0;rowy1) continue; + for(col=0;colx1) continue; + int p=row*cols*xres+col; + XFillRectangle(dp,w,LCDpixmap2[p]?gc:gch,x,y,pixel,pixel); + dirty=1; + } + } + if (dirty) XSync(dp,False); } -static int async_update() { -XSetWindowAttributes wa; -XEvent ev; - - if ((dp=XOpenDisplay(NULL))==NULL) - return -1; - wa.event_mask=ExposureMask; - XChangeWindowAttributes(dp,w,CWEventMask,&wa); - for(;;) { - XWindowEvent(dp,w,ExposureMask,&ev); - if (ev.type==Expose) { - acquire_lock(); - update(ev.xexpose.x,ev.xexpose.y, - ev.xexpose.width,ev.xexpose.height); - release_lock(); - } - } + +static int async_update() +{ + XSetWindowAttributes wa; + XEvent ev; + + if ((dp=XOpenDisplay(NULL))==NULL) + return -1; + wa.event_mask=ExposureMask; + XChangeWindowAttributes(dp,w,CWEventMask,&wa); + for(;;) { + XWindowEvent(dp,w,ExposureMask,&ev); + if (ev.type==Expose) { + acquire_lock(); + update(ev.xexpose.x,ev.xexpose.y, + ev.xexpose.width,ev.xexpose.height); + release_lock(); + } + } } + LCD XWindow[] = { - { "X11",0,0,0,0,BARS,0,xlcdinit,xlcdclear,xlcdput,xlcdbar,NULL,xlcdflush,xlcdquit }, - { NULL } + { name: "X11", + rows: 0, + cols: 0, + xres: 0, + yres: 0, + bars: BAR_L | BAR_R | BAR_U | BAR_D | BAR_H2 | BAR_V2 | BAR_T, + gpos: 0, + init: xlcdinit, + clear: xlcdclear, + put: xlcdput, + bar: xlcdbar, + gpo: NULL, + flush: xlcdflush, + quit: xlcdquit + }, + { NULL } }; -- cgit v1.2.3