version 0.2.1 v0.2.1
authorMats Johannesson <devel@bredband.net>
Thu, 26 Jun 2008 18:15:20 +0000 (14:15 -0400)
committerAristeu Rozanski <arozansk@redhat.com>
Thu, 26 Jun 2008 18:15:20 +0000 (14:15 -0400)
* Added support for faking mouse button events. Denis DerSarkisian
sent a function called "fake_event" (top of event_loop.c) which
in essence acts like a traffic cop, steering true keycodes to
XTestFakeKeyEvent and a set of false ones to XTestFakeButtonEvent.
The fake codes can be entered as 991 to 997 in the configuration
file, simulating mouse buttons 1 to 7.

Only existing mouse buttons, defined through the driver of the
active core pointer, can be simulated. I added discovery code to
prevent a crash if someone tries to use a nonexistent mouse button
in the range 1 to 7.

The code author wanted his touch strips to act like a mouse's scroll
wheel through the use of mouse buttons 4 - 5 (Up/Down) and 6 - 7
(Left/Right). I only have a three button mouse, the Wacom puck is
not a core pointer, but can make good use of the new functionality
in eg the web browser Opera:

[...]
20 Right Pad - Button 14: 993 # Button 14
21 Right Pad - Button 14 Plus: 991 # Extra key
[...]
24 Right Pad - Button 16: 991 # Button 16
25 Right Pad - Button 16 Plus: 993 # Extra key
[...]

With those definitions I step backwards (14) and forwards (16) in
the visited page history. Opera's "forward" can also take me to
the "Next" linked page, so it's very convenient when having a long
reading session.

* Expanded the "-v" (verbose mode) printing to cover more execution
points and be a lot more detailed.

* Racked my brain and added some more knowledge to the BUGS file.

AUTHORS
BUGS
ChangeLog
NEWS
USAGE
src-server/config_read.c
src-server/config_write.c
src-server/event_loop.c
src-server/globals.h
src-server/on_signal.c

diff --git a/AUTHORS b/AUTHORS
index 426a2e0..c2fd697 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -5,3 +5,6 @@ Spammers around the globe rejoice. Obfuscating addresses is necessary:
 Mats Johannesson MAINTAINER, BUGS and QUESTIONS handler:
 "devel" followed by "bredband" which is a "net" domain.
 
+Denis DerSarkisian Support for faking mouse button events:
+"hdfssk" and then "gmail" the clueless "com" company to thank.
+
diff --git a/BUGS b/BUGS
index 10710ca..cab9aa8 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -5,17 +5,31 @@ _Known bugs marked with FIXME in the code_
 to chance. The behaviour when reading in the next line/part, after
 having cut a line longer than MAXBUFFER, is totally unpredictable.
 
+Also doesn't handle situations where multiple fields are specified
+on the same line, or if the program record begin/end "%%" sign is
+written in a field line. Possibly other cases.
+
 ! The exit_on_error function drops the EXIT_KO when callig
 clean_up_exit. It becomes a normal EXIT_OK signal for any controlling
 parent.
 
 _Possible bugs, unmarked_
 
-! I've tried to break the parsing of the configuration file with
-different scenarios, but am limited by my imagination of how
-broken a file can be...
+! In eg Gimp, if expresskeys is started with the option to handle a pen,
+my core pointer (an USB mouse) and the Wacom puck do not draw through
+button 1 or react to mouse button 2 and 3 presses until the Wacom stylus
+has come into proximity for the first time. After the first proximity,
+the mouse and puck react normally. Strange...
 
 _Known bugs, unmarked_
 
-! Should ignore a pen mode 999 definition in the "Plus" button fields.
+! Should check that only valid keycodes (and our fake ones) are used
+in a program definition. Should ignore erroneous spaces in the class
+name field.
+
+! Pressing a pad button with one program window in focus, moving the
+focus to another program window and then releasing the button, leaves
+the first program in a confused mind regarding the keyboard state.
+Returning the focus and pressing the button again (or another that
+has an effect) restores the sanity.
 
index 9708b1c..5b3c665 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,44 @@
 
+_Version 0.2.1 2 May 2005_
+
+* Added support for faking mouse button events. "Anonymous1"
+(I have not received permission to use his real name or e-mail)
+sent a function called "fake_event" (top of event_loop.c) which
+in essence acts like a traffic cop, steering true keycodes to
+XTestFakeKeyEvent and a set of false ones to XTestFakeButtonEvent.
+The fake codes can be entered as 991 to 997 in the configuration
+file, simulating mouse buttons 1 to 7.
+
+Only existing mouse buttons, defined through the driver of the
+active core pointer, can be simulated. I added discovery code to
+prevent a crash if someone tries to use a nonexistent mouse button
+in the range 1 to 7.
+
+The code author wanted his touch strips to act like a mouse's scroll
+wheel through the use of mouse buttons 4 - 5 (Up/Down) and 6 - 7
+(Left/Right). I only have a three button mouse, the Wacom puck is
+not a core pointer, but can make good use of the new functionality
+in eg the web browser Opera:
+
+[...]
+20 Right Pad - Button 14:      993             # Button 14
+21 Right Pad - Button 14 Plus: 991             # Extra key
+[...]
+24 Right Pad - Button 16:      991             # Button 16
+25 Right Pad - Button 16 Plus: 993             # Extra key
+[...]
+
+With those definitions I step backwards (14) and forwards (16) in
+the visited page history. Opera's "forward" can also take me to
+the "Next" linked page, so it's very convenient when having a long
+reading session.
+
+* Expanded the "-v" (verbose mode) printing to cover more execution
+points and be a lot more detailed.
+
+* Racked my brain and added some more knowledge to the BUGS file.
+
+
 _Version 0.2.0 29 April 2005_
 
 (NOTE: A version of this archive was pulled from the website after a
diff --git a/NEWS b/NEWS
index 3e6fed3..5d0adfc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,9 @@
 
-_Changes since last version. Executive edition_
+_Changes since last version. Executive summary_
 
-- New configuration file format.
+- Support for faking mouse button events.
 
-- Another command line option: "-v" (verbose mode).
+- Expanded the "-v" (verbose mode) printing.
 
-- Some code simplifications.
+- Added some more knowledge to the BUGS file.
 
diff --git a/USAGE b/USAGE
index 837582f..9b57f6e 100644 (file)
--- a/USAGE
+++ b/USAGE
@@ -109,6 +109,16 @@ Change direction of the movement by switching the "Up" and "Down" values.
 Both pad buttons and touch strips can send two keys at a time if so
 configured through usage of the "Plus" keycode fields.
 
+If you want a button to do a mouse button press instead of a keypress,
+use a value between 991 and 997 in the corresponding keycode field, where
+991 represents mouse button 1, 992 button 2, and so on. Only existing mouse
+buttons, defined through the driver of the active core pointer, can be
+simulated. If buttons 4 and 5 are available they normally control vertical
+scrolling, like the mouse's scroll wheel (button 4 scrolls up, button 5
+scrolls down.) If buttons 6 and 7 are available they may control horizontal
+scrolling (button 6 scrolls left, button 7 scrolls right) or may match
+extra buttons on the mouse.
+
 If you want a button to do pen mode toggling between Absolute and Relative,
 use the value 999 in the corresponding keycode field. To be able to switch
 mode anywhere each program block must contain one 999 definition. And,
index 310fb82..058f392 100644 (file)
@@ -60,7 +60,7 @@ int read_file_config(int *ip, FILE *fp)
 /* Begin by making sure that the Config File Version number is present before
    a record begins. We exit if it's lacking or the number doesn't match up */
 
-/* FIXME Unpredictable behaviour on lines longer than MAXBUFFER! */
+/* FIXME Unpredictable behaviour on lines longer than MAXBUFFER etc. See BUGS */
 
        while ((fgets(line_buffer, MAXBUFFER, fp)) != NULL) {
                if ((delimiter_first = (strchr(line_buffer, '#'))) != NULL) {
@@ -78,6 +78,9 @@ int read_file_config(int *ip, FILE *fp)
                        token = strtok(buffer, ":");
                        token = strtok(NULL, ignore);
                        strcpy(buffer, token);
+                       if (be_verbose) {
+                               fprintf(stderr, "Config File Version on disk = %s Expected = %d\n", buffer, CONFIG_VERSION);
+                       }
                        if ((atoi(buffer)) != CONFIG_VERSION) {
                                return 3;
                        }
@@ -93,7 +96,7 @@ int read_file_config(int *ip, FILE *fp)
    A global counter variable of full record instances is updated before the
    function exits to reflect the new state. */
 
-/* FIXME Unpredictable behaviour on lines longer than MAXBUFFER! */
+/* FIXME Unpredictable behaviour on lines longer than MAXBUFFER etc. See BUGS */
 
        while ((fgets(line_buffer, MAXBUFFER, fp)) != NULL) {
                if (num_record < MAXRECORDS) {
@@ -125,7 +128,7 @@ int read_file_config(int *ip, FILE *fp)
                                                        }
                                                        field_index = &p->handle_touch;
 
-/* FIXME Unpredictable behaviour on lines longer than MAXBUFFER! */
+/* FIXME Unpredictable behaviour on lines longer than MAXBUFFER etc. See BUGS */
 
                                                        while ((fgets(line_buffer, MAXBUFFER, fp)) != NULL) {
                                                                if ((delimiter_first = (strchr(line_buffer, '%'))) != NULL &&
@@ -154,6 +157,9 @@ int read_file_config(int *ip, FILE *fp)
                                                                num_record++;
                                                                p++;
                                                        } else {
+                                                               if (be_verbose) {
+                                                                       fprintf(stderr, "%s skipped! (fields were too few)\n", p->class_name);
+                                                               }
                                                                free(p->class_name);
                                                        }
                                                        num_field = 0;
index 888050d..e635c8b 100644 (file)
@@ -55,6 +55,9 @@ int write_file_config_header(FILE *fp)
        fprintf(fp, "# Use the value 999 as a keycode to enable pen mode toggling. To be able\n");
        fprintf(fp, "# to switch mode anywhere each program block must then contain one 999\n");
        fprintf(fp, "# definition.\n\n");
+       fprintf(fp, "# Use the values 991 to 997 for simulating mouse buttons 1 to 7. Only existing\n");
+       fprintf(fp, "# mouse buttons, defined through the driver of the active core pointer, can be\n");
+       fprintf(fp, "# simulated.\n\n");
        fprintf(fp, "# Each program record is enclosed between two sets of double percentage signs.\n");
        fprintf(fp, "# Each program field begins after a colon \":\". Whitespace (tabs and spaces)\n");
        fprintf(fp, "# are ignored in the keycode fields, but spaces are recorded when in a\n");
index 40520a3..ed67751 100644 (file)
 
 #include "globals.h"
 
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Function acts like a traffic cop for keycodes. Sends real keycodes to
+ XTestFakeKeyEvent. Interprets fake keycodes (currently keycodes standing
+ in for mouse button presses) and sends them to the appropriate function.
+ Only existing mouse buttons, defined through the driver of the active core
+ pointer, can be simulated. If you run this function in a graphical debugger,
+ the mouse _will_ be effected.
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+int fake_event(Display *display, unsigned int keycode, Bool is_press,
+               unsigned long delay)
+{
+       if ((MOUSE_BUTTON_MIN < keycode) && (keycode < MOUSE_BUTTON_MAX)) {
+               /* mouse button code */
+               if (be_verbose) {
+                       fprintf(stderr, "MOUSE: ");
+               }
+
+               int i;
+               unsigned char button_map[MOUSE_BUTTON_MAX - MOUSE_BUTTON_MIN];
+               for (i = 0; i < (MOUSE_BUTTON_MAX - MOUSE_BUTTON_MIN); i++) {
+                       button_map[i] = '\0';
+               }
+
+               XGetPointerMapping(display, button_map, sizeof(button_map));
+               unsigned int button = keycode - MOUSE_BUTTON_MIN;
+               unsigned int real_button = button_map[button - 1];
+
+               if (real_button) {
+                       if (be_verbose) {
+                               fprintf(stderr, "Real button %d found: ", button);
+                       }
+                       return XTestFakeButtonEvent(display, button, is_press, delay);
+               } else {
+                       if (be_verbose) {
+                               fprintf(stderr, "No real button %d found! ", button);
+                       }
+                       return 0;
+               }
+       } else {
+               /* keycode */
+               if (be_verbose) {
+                       fprintf(stderr, "KEYBD: ");
+               }
+               return XTestFakeKeyEvent(display, keycode, is_press, delay);
+       }
+}
+
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  Function waits perpetually for the X server to deliver information
  about events from the input device. Receipt of an event that we've
  registered for (button press/release and motion) triggers a good deal
- of activity in a setup phase, after which we send the fake key press
+ of activity in a setup phase, after which we send the fake key press.
+ A button press or release will always cause first a motion and then 
+ a button event. That's why you'll see the focus window name being
+ printed twice if running with the verbose flag set.
  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 
 int use_events(Display *display)
@@ -116,7 +167,7 @@ int use_events(Display *display)
                if (children) XFree((char *)children);
 
                if (be_verbose) {
-                       fprintf(stderr, "PGR RUNNAME = %s\n", p->class_name);
+                       fprintf(stderr, "PGR FOCUS = %s\n", p->class_name);
                }
 
 /* Finally start to look at the actual event. Touch Strips come first */
@@ -148,33 +199,45 @@ int use_events(Display *display)
                                if (rotation > 1) {
                                        if ((rotation < old_rotation) && (old_rotation <= elder_rotation)) {
                                                if (p->l_touch_up) {
-                                                       XTestFakeKeyEvent(display, p->l_touch_up, True, CurrentTime);
+                                                       fake_event(display, p->l_touch_up, True, CurrentTime);
                                                        if (be_verbose) {
-                                                               fprintf(stderr, "KEY LTCHUP = %d\n", p->l_touch_up);
+                                                               fprintf(stderr, "LTCHUP = %d dn\n", p->l_touch_up);
                                                        }
                                                        if (p->l_touch_up_plus) {
-                                                               XTestFakeKeyEvent(display, p->l_touch_up_plus, True, CurrentTime);
-                                                               XTestFakeKeyEvent(display, p->l_touch_up_plus, False, CurrentTime);
+                                                               fake_event(display, p->l_touch_up_plus, True, CurrentTime);
                                                                if (be_verbose) {
-                                                                       fprintf(stderr, "KEY LTCHUP+ = %d\n", p->l_touch_up_plus);
+                                                                       fprintf(stderr, "LTCHUP+ = %d dn\n", p->l_touch_up_plus);
+                                                               }
+                                                               fake_event(display, p->l_touch_up_plus, False, CurrentTime);
+                                                               if (be_verbose) {
+                                                                       fprintf(stderr, "LTCHUP+ = %d up\n", p->l_touch_up_plus);
                                                                }
                                                        }
-                                                       XTestFakeKeyEvent(display, p->l_touch_up, False, CurrentTime);
+                                                       fake_event(display, p->l_touch_up, False, CurrentTime);
+                                                       if (be_verbose) {
+                                                               fprintf(stderr, "LTCHUP = %d up\n", p->l_touch_up);
+                                                       }
                                                }
                                        } else if ((rotation > old_rotation) && (old_rotation >= elder_rotation)) {
                                                if (p->l_touch_down) {
-                                                       XTestFakeKeyEvent(display, p->l_touch_down, True, CurrentTime);
+                                                       fake_event(display, p->l_touch_down, True, CurrentTime);
                                                        if (be_verbose) {
-                                                               fprintf(stderr, "KEY LTCHDN = %d\n", p->l_touch_down);
+                                                               fprintf(stderr, "LTCHDN = %d dn\n", p->l_touch_down);
                                                        }
                                                        if (p->l_touch_down_plus) {
-                                                               XTestFakeKeyEvent(display, p->l_touch_down_plus, True, CurrentTime);
-                                                               XTestFakeKeyEvent(display, p->l_touch_down_plus, False, CurrentTime);
+                                                               fake_event(display, p->l_touch_down_plus, True, CurrentTime);
                                                                if (be_verbose) {
-                                                                       fprintf(stderr, "KEY LTCHDN+ = %d\n", p->l_touch_down_plus);
+                                                                       fprintf(stderr, "LTCHDN+ = %d dn\n", p->l_touch_down_plus);
                                                                }
+                                                               fake_event(display, p->l_touch_down_plus, False, CurrentTime);
+                                                               if (be_verbose) {
+                                                                       fprintf(stderr, "LTCHDN+ = %d up\n", p->l_touch_down_plus);
+                                                               }
+                                                       }
+                                                       fake_event(display, p->l_touch_down, False, CurrentTime);
+                                                       if (be_verbose) {
+                                                               fprintf(stderr, "LTCHDN = %d up\n", p->l_touch_down);
                                                        }
-                                                       XTestFakeKeyEvent(display, p->l_touch_down, False, CurrentTime);
                                                }
                                        }
                                elder_rotation = old_rotation;
@@ -186,33 +249,45 @@ int use_events(Display *display)
                                if (throttle > 1) {
                                        if ((throttle < old_throttle) && (old_throttle <= elder_throttle)) {
                                                if (p->r_touch_up) {
-                                                       XTestFakeKeyEvent(display, p->r_touch_up, True, CurrentTime);
+                                                       fake_event(display, p->r_touch_up, True, CurrentTime);
                                                        if (be_verbose) {
-                                                               fprintf(stderr, "KEY RTCHUP = %d\n", p->r_touch_up);
+                                                               fprintf(stderr, "RTCHUP = %d dn\n", p->r_touch_up);
                                                        }
                                                        if (p->r_touch_up_plus) {
-                                                               XTestFakeKeyEvent(display, p->r_touch_up_plus, True, CurrentTime);
-                                                               XTestFakeKeyEvent(display, p->r_touch_up_plus, False, CurrentTime);
+                                                               fake_event(display, p->r_touch_up_plus, True, CurrentTime);
+                                                               if (be_verbose) {
+                                                                       fprintf(stderr, "RTCHUP+ = %d dn\n", p->r_touch_up_plus);
+                                                               }
+                                                               fake_event(display, p->r_touch_up_plus, False, CurrentTime);
                                                                if (be_verbose) {
-                                                                       fprintf(stderr, "KEY RTCHUP+ = %d\n", p->r_touch_up_plus);
+                                                                       fprintf(stderr, "RTCHUP+ = %d up\n", p->r_touch_up_plus);
                                                                }
                                                        }
-                                                       XTestFakeKeyEvent(display, p->r_touch_up, False, CurrentTime);
+                                                       fake_event(display, p->r_touch_up, False, CurrentTime);
+                                                       if (be_verbose) {
+                                                               fprintf(stderr, "RTCHUP = %d up\n", p->r_touch_up);
+                                                       }
                                                }
                                        } else if ((throttle > old_throttle) && (old_throttle >= elder_throttle)) {
                                                if (p->r_touch_down) {
-                                                       XTestFakeKeyEvent(display, p->r_touch_down, True, CurrentTime);
+                                                       fake_event(display, p->r_touch_down, True, CurrentTime);
                                                        if (be_verbose) {
-                                                               fprintf(stderr, "KEY RTCHDN = %d\n", p->r_touch_down);
+                                                               fprintf(stderr, "RTCHDN = %d dn\n", p->r_touch_down);
                                                        }
                                                        if (p->r_touch_down_plus) {
-                                                               XTestFakeKeyEvent(display, p->r_touch_down_plus, True, CurrentTime);
-                                                               XTestFakeKeyEvent(display, p->r_touch_down_plus, False, CurrentTime);
+                                                               fake_event(display, p->r_touch_down_plus, True, CurrentTime);
+                                                               if (be_verbose) {
+                                                                       fprintf(stderr, "RTCHDN+ = %d dn\n", p->r_touch_down_plus);
+                                                               }
+                                                               fake_event(display, p->r_touch_down_plus, False, CurrentTime);
                                                                if (be_verbose) {
-                                                                       fprintf(stderr, "KEY RTCHDN+ = %d\n", p->r_touch_down_plus);
+                                                                       fprintf(stderr, "RTCHDN+ = %d up\n", p->r_touch_down_plus);
                                                                }
                                                        }
-                                                       XTestFakeKeyEvent(display, p->r_touch_down, False, CurrentTime);
+                                                       fake_event(display, p->r_touch_down, False, CurrentTime);
+                                                       if (be_verbose) {
+                                                               fprintf(stderr, "RTCHDN = %d up\n", p->r_touch_down);
+                                                       }
                                                }
                                        }
                                elder_throttle = old_throttle;
@@ -223,9 +298,8 @@ int use_events(Display *display)
 
 /* Now see if the event concerned the pad buttons. Not much to talk about.
    We follow the configuration definitions, and handle a pen if requested
-   to do so. Ah yes, the xinput-1.2 program reveals Wacom to have numbered
-   the buttons 9, 10, 11, 12 on the left side and 13, 14, 15, 16 on the
-   right. Template:
+   to do so. Wacom have numbered the buttons 9, 10, 11, 12 on the left side
+   and 13, 14, 15, 16 on the right. Template:
 
 Left ExpressKey Pad
 ------------ 
@@ -263,23 +337,23 @@ Right ExpressKey Pad
 
                        if (*button_index == TOGGLE_PEN) {
                                if (handle_pen) {
-                                       toggle_pen_mode(display, pen_name);
                                        if (be_verbose) {
-                                               fprintf(stderr, "BTN %d = %d\n", button->button, *button_index);
+                                               fprintf(stderr, "BTN %d = %d dn\n", button->button, *button_index);
                                        }
+                                       toggle_pen_mode(display, pen_name);
                                }
                        } else {
                                if (*button_index) {
-                                       XTestFakeKeyEvent(display, *button_index, True, CurrentTime );
+                                       fake_event(display, *button_index, True, CurrentTime );
                                        if (be_verbose) {
-                                               fprintf(stderr, "BTN %d = %d\n", button->button, *button_index);
+                                               fprintf(stderr, "BTN %d = %d dn\n", button->button, *button_index);
                                        }
                                }
                                button_index++;
                                if (*button_index) {
-                                       XTestFakeKeyEvent(display, *button_index, True, CurrentTime );
+                                       fake_event(display, *button_index, True, CurrentTime );
                                        if (be_verbose) {
-                                               fprintf(stderr, "BTN+ %d = %d\n", button->button, *button_index);
+                                               fprintf(stderr, "BTN+ %d = %d dn\n", button->button, *button_index);
                                        }
                                }
                        }
@@ -300,21 +374,21 @@ Right ExpressKey Pad
 
                        if (*button_index == TOGGLE_PEN) {
                                if (be_verbose) {
-                                       fprintf(stderr, "BTN %d = %d\n", button->button, *button_index);
+                                       fprintf(stderr, "BTN %d = %d up\n", button->button, *button_index);
                                }
                        } else {
                                button_index++;
                                if (*button_index) {
-                                       XTestFakeKeyEvent(display, *button_index, False, CurrentTime );
+                                       fake_event(display, *button_index, False, CurrentTime );
                                        if (be_verbose) {
-                                               fprintf(stderr, "BTN+ %d = %d\n", button->button, *button_index);
+                                               fprintf(stderr, "BTN+ %d = %d up\n", button->button, *button_index);
                                        }
                                }
                                button_index--;
                                if (*button_index) {
-                                       XTestFakeKeyEvent(display, *button_index, False, CurrentTime );
+                                       fake_event(display, *button_index, False, CurrentTime );
                                        if (be_verbose) {
-                                               fprintf(stderr, "BTN %d = %d\n", button->button, *button_index);
+                                               fprintf(stderr, "BTN %d = %d up\n", button->button, *button_index);
                                        }
                                }
                        }
index 80fc44a..347ed06 100644 (file)
 #define EXIT_OK 0
 #define EXIT_KO 1
 #define NON_VALID -1
+enum {                 /* Strings signaling key's use as a mouse button */
+       MOUSE_BUTTON_MIN = 990,
+       MOUSE_1,
+       MOUSE_2,
+       MOUSE_3,
+       MOUSE_4,
+       MOUSE_5,
+       MOUSE_6,
+       MOUSE_7,
+       MOUSE_BUTTON_MAX
+};     
 #define TOGGLE_PEN 999 /* String signaling the key's use as a mode toggle */
 #define MAXRECORDS 64  /* Max program definitions to handle (enough? ;-) */
 #define MAXFIELDS 25   /* Max entries (minus program name) in each record */
index a5fb126..7ef1d09 100644 (file)
@@ -127,13 +127,9 @@ void clean_up_exit(int signum)
                XFreeDeviceList(pen_info_block);
        }
 
-       if (pad_device) {
-               XCloseDevice(display, pad_device);
-       }
-
-       if (pen_device) {
-               XCloseDevice(display, pen_device);
-       }
+/* pad_device and pen_device should not be explicitly closed by a
+   call to XCloseDevice. It leaves a message from X (in the terminal
+   where X is started from) saying: "ProcXCloseDevice to close or not ?" */
 
        if (display) {
                XCloseDisplay(display);