Package: lirc-x Version: 0.7.1pre2-2 Severity: normal Tags: patch Here is another patch for irxexec to make it really work in a "production" environment (see http://www.j-pfennig.de/zapdvb). While bug 326703 made irxevent almost unusable the lack of an X11 error makes it to too instable to be used with applications like mplayer (e.g. apps that create a high cpu load). The symptom:
>From time to time irxevet reports a BadWindow X11 error and dies. The attached patch adds such a handler, as well as the options -d (daemon) and -v (verbose). This is just the version that can be downloaded from http://www.j-pfennig.de/zapdvb/download.html . Unfortunately it is difficult to contact the LIRC project, their mail-list is not accessible to most german users that have an internet domain but no postmaster E-Mail account. I hope that this message somehow finds it's way upstream. Juergen Pfennig -- System Information: Debian Release: 3.1 APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.11-7-amd Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Versions of packages lirc-x depends on: ii libc6 2.3.2.ds1-22 GNU C Library: Shared libraries an ii libice6 4.3.0.dfsg.1-14 Inter-Client Exchange library ii liblircclient0 0.7.1pre2-2 LIRC client library ii libsm6 4.3.0.dfsg.1-14 X Window System Session Management ii libx11-6 4.3.0.dfsg.1-14 X Window System protocol client li ii lirc 0.7.1pre2-2 Linux Infra-red Remote Control sup ii xlibs 4.3.0.dfsg.1-14 X Keyboard Extension (XKB) configu -- no debconf information
--- irxevent.c.orig 2004-03-25 21:02:24.000000000 +0100 +++ irxevent.c 2005-09-15 10:40:36.000000000 +0200 @@ -94,15 +94,20 @@ #define DEBUG #ifdef DEBUG -void debugprintf(char *format_str, ...) + +static int bVerbose = 0; +static int bInError = 0; + +static void debugprintf(char *format_str, ...) { va_list ap; va_start(ap,format_str); - vfprintf(stderr,format_str,ap); + if(bVerbose) + vfprintf(stderr,format_str,ap); va_end(ap); } #else -void debugprintf(char *format_str, ...) +static void debugprintf(char *format_str, ...) { } #endif @@ -125,18 +130,18 @@ {NULL,0}, }; -const char *key_delimiter ="-"; -const char *active_window_name ="CurrentWindow"; -const char *root_window_name ="RootWindow"; +static const char *key_delimiter ="-"; +static const char *active_window_name ="CurrentWindow"; +static const char *root_window_name ="RootWindow"; -char *progname; -Display *dpy; -Window root; -XEvent xev; -Window w,subw; +static char *progname; +static Display *dpy; +static Window root; +static XEvent xev; +static Window subw; -Time fake_timestamp() +static Time fake_timestamp() /*seems that xfree86 computes the timestamps like this */ /*strange but it relies on the *1000-32bit-wrap-around */ /*if anybody knows exactly how to do it, please contact me */ @@ -151,7 +156,7 @@ return (Time)tint; } -Window find_window(Window top,char *name) +static Window find_window(Window top,char *name) { char *wname,*iname; XClassHint xch; @@ -210,7 +215,7 @@ return(top); } -Window find_sub_sub_window(Window top,int *x, int *y) +static Window find_sub_sub_window(Window top,int *x, int *y) { Window base; Window *children,foo,target=0; @@ -254,7 +259,7 @@ -Window find_sub_window(Window top,char *name,int *x, int *y) +static Window find_sub_window(Window top,char *name,int *x, int *y) { Window base; Window *children,foo,target=0; @@ -297,7 +302,7 @@ } -Window find_window_focused(Window top,char *name) +static Window find_window_focused(Window top,char *name) { int tmp; Window w, cur, *children, foo; @@ -330,7 +335,7 @@ return(0); } -void make_button(int button,int x,int y,XButtonEvent *xev) +static void make_button(int button,int x,int y,XButtonEvent *xev) { xev->type = ButtonPress; xev->display=dpy; @@ -346,7 +351,7 @@ return; } -void make_key(char *keyname,int x, int y,XKeyEvent *xev) +static void make_key(char *keyname,int x, int y,XKeyEvent *xev) { char *part, *part2; struct keymodlist_t *kmlptr; @@ -389,7 +394,7 @@ return ; } -void sendfocus(Window w,int in_out) +static void sendfocus(Window w,int in_out) { XFocusChangeEvent focev; @@ -404,7 +409,7 @@ return; } -void sendpointer_enter_or_leave(Window w,int in_out) +static void sendpointer_enter_or_leave(Window w,int in_out) { XCrossingEvent crossev; crossev.type=in_out; @@ -427,7 +432,7 @@ return; } -void sendkey(char *keyname,int x,int y,Window w,Window s) +static void sendkey(char *keyname,int x,int y,Window w,Window s) { make_key(keyname ,x,y,(XKeyEvent*)&xev); xev.xkey.window=w; @@ -445,7 +450,7 @@ return; } -void sendbutton(int button, int x, int y, Window w,Window s) +static void sendbutton(int button, int x, int y, Window w,Window s) { make_button(button,x,y,(XButtonEvent*)&xev); xev.xbutton.window=w; @@ -467,6 +472,17 @@ return; } +int errorHandler(Display* di, XErrorEvent* ev) +{ + if(bInError || ev==NULL || di==NULL) return 1; // only 1 msg per key + char buff[512]; buff[0] = 0; + XGetErrorText(di, ev->error_code, buff, sizeof(buff)-1); + if(buff[0]) { + fprintf(stderr, "X11 error: %s\n", buff); + bInError = 1; + } + return 1; +} int check(char *s) { @@ -503,7 +519,9 @@ static struct option long_options[] = { - {"help", no_argument, NULL, 'h'}, + {"daemon", no_argument, NULL, 'd'}, + {"help", no_argument, NULL, 'h'}, + {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0} }; @@ -517,18 +535,27 @@ char *config_file=NULL; int c; int WindowID; + int bDaemon = 0; progname=argv[0]; - while ((c = getopt_long(argc, argv, "hV", long_options, NULL)) != EOF) { + while ((c = getopt_long(argc, argv, "dhvV", long_options, NULL)) != EOF) { switch (c) { + case 'd': + bDaemon = 1; continue; case 'h': - printf("Usage: %s [config file]\n", argv[0]); - printf("\t -h --help \t\tdisplay usage summary\n"); - printf("\t -V --version \t\tdisplay version\n"); + printf("Usage: %s [option]... [config file]\n" + " -d --daemon fork and run in background\n" + " -h --help display usage summary\n" + " -v --verbose report what happens\n" + " -V --version display version\n", progname); return(EXIT_SUCCESS); + case 'v': + bVerbose = 1; + // fall through... case 'V': - printf("%s %s\n", progname, VERSION); + printf("%s %s (zapdvb 2005_09_15)\n", progname, VERSION); + if(bVerbose) break; return(EXIT_SUCCESS); case '?': fprintf(stderr, "unrecognized option: -%c\n", optopt); @@ -552,20 +579,32 @@ } root=RootWindow(dpy,DefaultScreen(dpy)); + // windows may get closed at wrong time. Override default error handler... + XSetErrorHandler(errorHandler); + if(lirc_init("irxevent",1)==-1) exit(EXIT_FAILURE); if(lirc_readconfig(config_file,&config,check)==0) { + + if(bDaemon) { + if(daemon(1, 0) < 0) { + perror("Failed to run as daemon"); + exit(2); + } + } + char *ir; char *c; int ret; - + while(lirc_nextcode(&ir)==0) { if(ir==NULL) continue; while((ret=lirc_code2char(config,ir,&c))==0 && c!=NULL) { - debugprintf("Recieved code: %s Sending event: \n",ir); + debugprintf("Received code: %s Sending event: \n",ir); + bInError = 0; // reset error state, want to see error msg *windowname=0; if(2==sscanf(c,"Key %s Focus WindowID %i",keyname,&WindowID) || @@ -605,6 +644,8 @@ 4==sscanf(c,"xy_Key %d %d %s %s\n",&pointer_x,&pointer_y,keyname,windowname)) { debugprintf("name: %s\n",windowname); WindowID=find_window(root,windowname); + if(WindowID == 0) + continue; } switch(c[0])