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])