aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2003-02-18 06:13:44 +0000
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2003-02-18 06:13:44 +0000
commit4289644864996c97eddb8f7f558f20d2871bb512 (patch)
treec0106d80e362112f449da5ac157d2d939eef8815
parentd7879f1cb421259a20d4531e0b46a9913702b086 (diff)
downloadlcd4linux-4289644864996c97eddb8f7f558f20d2871bb512.tar.gz
[lcd4linux @ 2003-02-18 06:13:44 by reinelt]
X11 driver fixes and cleanup git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@181 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
-rw-r--r--README.X114
-rw-r--r--XWindow.c652
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<<SIGBUS)|(1<<SIGFPE)|(1<<SIGSEGV)|
- (1<<SIGTSTP)|(1<<SIGCHLD)|(1<<SIGCONT)|
- (1<<SIGTTIN)|(1<<SIGWINCH);
-int i;
- for(i=0;i<NSIG;i++)
- if (((1<<i)&ignsig)==0)
- signal(i,sig_updater);
+static void init_signals()
+{
+ unsigned int ignsig=(1<<SIGBUS)|(1<<SIGFPE)|(1<<SIGSEGV)|
+ (1<<SIGTSTP)|(1<<SIGCHLD)|(1<<SIGCONT)|
+ (1<<SIGTTIN)|(1<<SIGWINCH);
+ int i;
+ for(i=0;i<NSIG;i++)
+ if (((1<<i)&ignsig)==0)
+ signal(i,sig_updater);
+
}
-static int init_shm(int nbytes,unsigned char **buf) {
-
- shmid=shmget(IPC_PRIVATE,nbytes,SHM_R|SHM_W);
- if (shmid==-1) {
- error ("X11: shmget() failed: %s", strerror(errno));
- return -1;
- }
- *buf=shmat(shmid,NULL,0);
- if (*buf==NULL) {
- error ("X11: shmat() failed: %s", strerror(errno));
- return -1;
- }
- return 0;
+
+static int init_shm(int nbytes,unsigned char **buf)
+{
+ shmid=shmget(IPC_PRIVATE,nbytes,SHM_R|SHM_W);
+ if (shmid==-1) {
+ error ("X11: shmget() failed: %s", strerror(errno));
+ return -1;
+ }
+ *buf=shmat(shmid,NULL,0);
+ if (*buf==NULL) {
+ error ("X11: shmat() failed: %s", strerror(errno));
+ return -1;
+ }
+ return 0;
}
-static int init_thread(int bufsiz) {
-union semun semun;
/* acording to SUN-Solaris man-pages: */
-
-#define SEM_ALTER 0200
-
- semid=semget(IPC_PRIVATE,1,SEM_ALTER);
- if (semid==-1) {
- error ("X11: semget() failed: %s", strerror(errno));
- return -1;
- }
- semun.val=1;
- semctl(semid,0,SETVAL,semun);
-
- ppid=getpid();
- switch(async_updater_pid=fork()) {
- case -1:
- error ("X11: fork() failed: %s", strerror(errno));
- return -1;
- case 0:
- async_update();
- error ("X11: async_update failed");
- kill(ppid,SIGTERM);
- exit(-1);
- default:
- break;
- }
- signal(SIGCHLD,quit_updater);
- atexit(quit_updater);
- return 0;
+#define SEM_ALTER 0200
+
+static int init_thread(int bufsiz)
+{
+ union semun semun;
+
+ semid=semget(IPC_PRIVATE,1,SEM_ALTER);
+ if (semid==-1) {
+ error ("X11: semget() failed: %s", strerror(errno));
+ return -1;
+ }
+ semun.val=1;
+ semctl(semid,0,SETVAL,semun);
+
+ ppid=getpid();
+ switch(async_updater_pid=fork()) {
+ case -1:
+ error ("X11: fork() failed: %s", strerror(errno));
+ return -1;
+ case 0:
+ async_update();
+ error ("X11: async_update failed");
+ kill(ppid,SIGTERM);
+ exit(-1);
+ default:
+ break;
+ }
+ signal(SIGCHLD,quit_updater);
+ atexit(quit_updater);
+ return 0;
}
-static int init_x(int rows,int cols,int xres,int yres) {
-XSetWindowAttributes wa;
-XSizeHints size_hints;
-XColor co_dummy;
-XEvent ev;
-
- if ((dp=XOpenDisplay(NULL))==NULL) {
- error ("X11: can't open display");
- return -1;
- }
- sc=DefaultScreen(dp);
- gc=DefaultGC(dp,sc);
- vi=DefaultVisual(dp,sc);
- dd=DefaultDepth(dp,sc);
- rw=DefaultRootWindow(dp);
- cm=DefaultColormap(dp,sc);
-
- if (XAllocNamedColor(dp,cm,rgbfg,&co[0],&co_dummy)==False) {
- error ("X11: can't alloc foreground color '%s'",
- rgbfg);
- return -1;
- }
- if (XAllocNamedColor(dp,cm,rgbbg,&co[1],&co_dummy)==False) {
- error ("X11: can't alloc background color '%s'",
- rgbbg);
- return -1;
- }
- if (XAllocNamedColor(dp,cm,rgbhg,&co[2],&co_dummy)==False) {
- error ("X11: can't alloc halfground color '%s'",
- rgbhg);
- return -1;
- }
- boxw=xres*pixel+(xres-1)*pgap+cgap;
- boxh=yres*pixel+(yres-1)*pgap+rgap;
- dimx=cols*xres*pixel+cols*(xres-1)*pgap+(cols-1)*cgap;
- dimy=rows*yres*pixel+rows*(yres-1)*pgap+(rows-1)*rgap;
- wa.event_mask=ExposureMask;
- w=XCreateWindow(dp,rw,0,0,dimx+2*border,dimy+2*border,0,0,
- InputOutput,vi,CWEventMask,&wa);
- pmback=XCreatePixmap(dp,w,dimx,dimy,dd);
- size_hints.min_width=size_hints.max_width=dimx+2*border;
- size_hints.min_height=size_hints.max_height=dimy+2*border;
- size_hints.flags=PPosition|PSize|PMinSize|PMaxSize;
- XSetWMProperties(dp,w,NULL,NULL,NULL,0,&size_hints,NULL,NULL);
- XSetForeground(dp,gc,co[0].pixel);
- XSetBackground(dp,gc,co[1].pixel);
- gcb=XCreateGC(dp,w,0,NULL);
- XSetForeground(dp,gcb,co[1].pixel);
- XSetBackground(dp,gcb,co[0].pixel);
- gch=XCreateGC(dp,w,0,NULL);
- XSetForeground(dp,gch,co[2].pixel);
- XSetBackground(dp,gch,co[0].pixel);
- XFillRectangle(dp,pmback,gcb,0,0,dimx,dimy);
- XSetWindowBackground(dp,w,co[1].pixel);
- XClearWindow(dp,w);
- XStoreName(dp,w,"XLCD4Linux");
- XMapWindow(dp,w);
- XFlush(dp);
- for(;;) {
- XNextEvent(dp,&ev);
- if (ev.type==Expose && ev.xexpose.count==0)
- break;
- }
- return 0;
+
+static int init_x(int rows,int cols,int xres,int yres)
+{
+ XSetWindowAttributes wa;
+ XSizeHints size_hints;
+ XColor co_dummy;
+ XEvent ev;
+
+ if ((dp=XOpenDisplay(NULL))==NULL) {
+ error ("X11: can't open display");
+ return -1;
+ }
+ sc=DefaultScreen(dp);
+ gc=DefaultGC(dp,sc);
+ vi=DefaultVisual(dp,sc);
+ dd=DefaultDepth(dp,sc);
+ rw=DefaultRootWindow(dp);
+ cm=DefaultColormap(dp,sc);
+
+ if (XAllocNamedColor(dp,cm,rgbfg,&co[0],&co_dummy)==False) {
+ error ("X11: can't alloc foreground color '%s'",
+ rgbfg);
+ return -1;
+ }
+ if (XAllocNamedColor(dp,cm,rgbbg,&co[1],&co_dummy)==False) {
+ error ("X11: can't alloc background color '%s'",
+ rgbbg);
+ return -1;
+ }
+ if (XAllocNamedColor(dp,cm,rgbhg,&co[2],&co_dummy)==False) {
+ error ("X11: can't alloc halfground color '%s'",
+ rgbhg);
+ return -1;
+ }
+ boxw=xres*pixel+(xres-1)*pgap+cgap;
+ boxh=yres*pixel+(yres-1)*pgap+rgap;
+ dimx=cols*xres*pixel+(cols*xres-1)*pgap+(cols-1)*cgap;
+ dimy=rows*yres*pixel+(rows*yres-1)*pgap+(rows-1)*rgap;
+ wa.event_mask=ExposureMask;
+ w=XCreateWindow(dp,rw,0,0,dimx+2*border,dimy+2*border,0,0,
+ InputOutput,vi,CWEventMask,&wa);
+ pmback=XCreatePixmap(dp,w,dimx,dimy,dd);
+ size_hints.min_width=size_hints.max_width=dimx+2*border;
+ size_hints.min_height=size_hints.max_height=dimy+2*border;
+ size_hints.flags=PPosition|PSize|PMinSize|PMaxSize;
+ XSetWMProperties(dp,w,NULL,NULL,NULL,0,&size_hints,NULL,NULL);
+ XSetForeground(dp,gc,co[0].pixel);
+ XSetBackground(dp,gc,co[1].pixel);
+ gcb=XCreateGC(dp,w,0,NULL);
+ XSetForeground(dp,gcb,co[1].pixel);
+ XSetBackground(dp,gcb,co[0].pixel);
+ gch=XCreateGC(dp,w,0,NULL);
+ XSetForeground(dp,gch,co[2].pixel);
+ XSetBackground(dp,gch,co[0].pixel);
+ XFillRectangle(dp,pmback,gcb,0,0,dimx,dimy);
+ XSetWindowBackground(dp,w,co[1].pixel);
+ XClearWindow(dp,w);
+ XStoreName(dp,w,"XLCD4Linux");
+ XMapWindow(dp,w);
+ XFlush(dp);
+ for(;;) {
+ XNextEvent(dp,&ev);
+ if (ev.type==Expose && ev.xexpose.count==0)
+ break;
+ }
+ 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,&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;i<rows*yres;i++) {
- x=border;
- for(j=0;j<cols*xres;j++) {
- if (LCDpixmap[pos]^BackupLCDpixmap[pos]) {
- XFillRectangle(dp,w,
- LCDpixmap[pos]?gc:gch,
- x,y,
- pixel,pixel);
- BackupLCDpixmap[pos]=LCDpixmap[pos];
- dirty=1;
- }
- x+=pixel+pgap;
-#if 0
- // this is wrong! MR
- if (++jgap==xres) { x+=cgap-pgap; jgap=0; }
-#endif
- pos++;
- }
- y+=pixel+pgap;
- if (++igap==yres) { y+=rgap-pgap; igap=0; }
- }
- if (dirty) XSync(dp,False);
- release_lock();
- return 0;
+ int dirty;
+ int row,col;
+
+ acquire_lock();
+ dirty=0;
+ for(row=0;row<rows*yres;row++) {
+ int y=border+(row/yres)*rgap+row*(pixel+pgap);
+ for(col=0;col<cols*xres;col++) {
+ int x=border+(col/xres)*cgap+col*(pixel+pgap);
+ int p=row*cols*xres+col;
+ if (LCDpixmap[p]^LCDpixmap2[p]) {
+ XFillRectangle(dp,w,LCDpixmap[p]?gc:gch,x,y,pixel,pixel);
+ LCDpixmap2[p]=LCDpixmap[p];
+ dirty=1;
+ }
+ }
+ }
+ if (dirty) XSync(dp,False);
+ release_lock();
+ return 0;
}
-int xlcdquit(void) {
- error("xlcdquit");
- semcleanup();
- shmcleanup();
- quit_updater();
- return 0;
+
+int xlcdquit(void)
+{
+ semcleanup();
+ shmcleanup();
+ quit_updater();
+ return 0;
}
+
/*
* this one should only be called from the updater-thread
* no user serviceable parts inside
*/
-static void update(int x,int y,int width,int height) {
-int i,j,igap,jgap,wjgap,pos,wpos,xpix;
-int xfrom,yfrom;
-int xto,yto;
-int dx,wx,wy;
-
- /*
- * theory of operation:
- * f:bitpos->pxnr*(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;row<rows*yres;row++) {
+ int y=border+(row/yres)*rgap+row*(pixel+pgap);
+ if (y<y0 || y>y1) continue;
+ for(col=0;col<cols*xres;col++) {
+ int x=border+(col/xres)*cgap+col*(pixel+pgap);
+ if (x<x0 || x>x1) 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 }
};