version 0.1.4 v0.1.4
authorMats Johannesson <devel@bredband.net>
Thu, 26 Jun 2008 18:06:46 +0000 (14:06 -0400)
committerAristeu Rozanski <arozansk@redhat.com>
Thu, 26 Jun 2008 18:06:46 +0000 (14:06 -0400)
* Memory bugfix. Running the program under Valgrind to catch memory
leaks and other errors I finally saw the reason for me needing
heap_protect kludges. Doing XFreeDeviceList on a structure and then
reading data from the freed memory only works through luck...

* Took the opportunity to free lingering memory allocations at program
exit. It's not strictly necessary since the OS should reclaim it all,
but looks nice in the Valgrind summary. There's still one left that
I can't find the souce of. It belongs to XextCreateExtension apparently.

* Bugfix: Had forgotten to close the error.log after writing to it in
the exit_on_error function. Also, that function shouldn't do a final
exit(EXIT_KO) but instead jump to clean_up_exit(SIGTERM). However,
doing that it won't return the EXIT_KO to any parent. I'd have to
change the signal handling to achieve this.

* Bugfix: The config file version tag was meant to look like:

Version: 1

and nothing else, for now... The confusion and uncertainty stems from
doing this before a final format has been chosen. There are many factors
to consider, so bear with me.

* Reverted to the "expresskeys" base name on compile output and shell
files. When writing code it's more convenient with a short name, but
any final product should have a consistent naming.

17 files changed:
ChangeLog
Copyright
INSTALL
Makefile [moved from makefile with 50% similarity]
README
USAGE
expresskeys-reread.sh [moved from ekeys-reread.sh with 53% similarity]
expresskeys-terminate.sh [moved from ekeys-terminate.sh with 66% similarity]
src-client/Makefile [moved from src-client/makefile with 100% similarity]
src-server/Makefile [moved from src-server/makefile with 95% similarity]
src-server/config_read.c
src-server/get_device.c
src-server/globals.c
src-server/globals.h
src-server/main_setup.c
src-server/on_error.c
src-server/on_signal.c

index b6a0247..c242d0c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,35 @@
 
+_Version 0.1.4 24 April 2005_
+
+* Memory bugfix. Running the program under Valgrind to catch memory
+leaks and other errors I finally saw the reason for me needing
+heap_protect kludges. Doing XFreeDeviceList on a structure and then
+reading data from the freed memory only works through luck...
+
+* Took the opportunity to free lingering memory allocations at program
+exit. It's not strictly necessary since the OS should reclaim it all,
+but looks nice in the Valgrind summary. There's still one left that
+I can't find the souce of. It belongs to XextCreateExtension apparently.
+
+* Bugfix: Had forgotten to close the error.log after writing to it in
+the exit_on_error function. Also, that function shouldn't do a final
+exit(EXIT_KO) but instead jump to clean_up_exit(SIGTERM). However,
+doing that it won't return the EXIT_KO to any parent. I'd have to
+change the signal handling to achieve this.
+
+* Bugfix: The config file version tag was meant to look like:
+
+Version: 1
+
+and nothing else, for now... The confusion and uncertainty stems from
+doing this before a final format has been chosen. There are many factors
+to consider, so bear with me.
+
+* Reverted to the "expresskeys" base name on compile output and shell
+files. When writing code it's more convenient with a short name, but
+any final product should have a consistent naming.
+
+
 _Version 0.1.3 21 April 2005_
 
 * Just internal code cleanup/restructuring after having begun reading
index ec74b4a..1bfdaad 100644 (file)
--- a/Copyright
+++ b/Copyright
@@ -1,5 +1,5 @@
 
-ExpressKeys was written by Mats Johannesson aka Voluspa in 2005.
+Mats Johannesson aka Voluspa began writing expresskeys in 2005.
 The original framework (one big .c file) built heavily on some
 functions in Frederic Lepied's xinput-1.2 from 1996. Without that
 smooth entrypoint the program had remained a pipe dream for sure.
diff --git a/INSTALL b/INSTALL
index 36d33e5..a90b08a 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,10 +1,6 @@
 
-The USAGE file contains all necessary information for a proper
-configuration and execution of this program. Some extra knowledge
-might be had by reading the ChangeLog files. I'm a talkative guy.
-
-After that read, take a look in the extremely simple Makefile in
-src-server if setting CFLAGS is your want. Next step is to type:
+Take a look in the extremely simple Makefile in the src-server
+directory if setting CFLAGS is your want. Next step is to type:
 
 make
 
similarity index 50%
rename from makefile
rename to Makefile
index 5336577..da918e1 100644 (file)
--- a/makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
 
 all:
        $(MAKE) -C src-server
-       mv src-server/ekeys .
+       mv src-server/expresskeys .
 
 #      $(MAKE) -C src-client
 #      mv src-client/cekeys .
 clean:
-       rm -f ekeys cekeys src-server/*.o src-client/*.o
+       rm -f expresskeys cekeys src-server/*.o src-client/*.o
 
diff --git a/README b/README
index 7e4c99f..c074810 100644 (file)
--- a/README
+++ b/README
@@ -1,9 +1,20 @@
 
 This program gives basic linux support for the ExpressKeys and
-Touch Strips of a Wacom Intuos3 tablet.
+Touch Strips of a Wacom Intuos3 tablet. Latest version can be found at:
+
+http://web.telia.com/~u46133770/wacom/index.html
+
+The USAGE file lists all the important and current key points for
+program configuration and execution.
+
+The INSTALL file keeps compilation information.
+
+AUTHORS and Copyright speak of who it was that wrote the code. The
+latter also gives explicit permission for the code and program usage.
+
+LICENSE is a copy of the GNU General Public License Version 2.
 
 Reading the ChangeLog files from bottom and up can kill some time and
-provide historic insight. It essentially is all the available user
-documentation. However, since info change over time I'll try to list
-all the important and accurate key points in the USAGE file.
+provide historic insight. They constitute a very outdated user
+documentation.
 
diff --git a/USAGE b/USAGE
index a1e9008..b3bfee2 100644 (file)
--- a/USAGE
+++ b/USAGE
@@ -18,7 +18,7 @@ in proximity.
 
 ///////////////////////////////////////////////////////////////////////////
 
-USAGE of ekeys (expresskeys):
+USAGE of expresskeys:
 
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
@@ -28,17 +28,17 @@ USAGE of ekeys (expresskeys):
 
 * Command line can be:
 
-ekeys <pad-device-name> [<pen-device-name>] [-d]
+expresskeys <pad-device-name> [<pen-device-name>] [-d]
 
 Where the pad name is mandatory. Specify a pen name
 if you want the program to handle pen mode switches.
 Use -d to make the program a daemon (run in the background).
 
-Example: ekeys pad stylus -d
+Example: expresskeys pad stylus -d
 
 The names are the "Identifier" strings in your X config file (xorg.conf)
-Myself I start ekeys just before the window manager in my .xinitrc with:
-/usr/local/bin/ekeys pad stylus -d
+Myself I start expresskeys just before the window manager in my 
+.xinitrc with: /usr/local/bin/expresskeys pad stylus -d
 
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
@@ -56,8 +56,8 @@ recreated whenever a configuration file is missing on program start.
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 * The configuration file is re-read upon receipt of the signal SIGUSR1.
-Do a "kill -USR1 <pid-of-ekeys>" after a config file edit (or -USR2).
-The included shell script "ekeys-reread.sh" will do it for you.
+Do a "kill -USR1 <pid-of-expresskeys>" after a config file edit (or -USR2).
+The included shell script "expresskeys-reread.sh" will do it for you.
 
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
similarity index 53%
rename from ekeys-reread.sh
rename to expresskeys-reread.sh
index 9c72f4e..c81bdfc 100755 (executable)
@@ -1,16 +1,16 @@
 #!/bin/sh
 
-# Reread ekeys config file.
+# Re-read expresskeys config file.
 
 if [ -f ~/.expresskeys/expresskeys.pid ]; then
 
-   echo "Rereading ekeys config file."
+   echo "Re-reading expresskeys config file."
 
    /bin/kill -USR1 `/bin/cat ~/.expresskeys/expresskeys.pid | /bin/head -n 1`
 
 else
 
-   echo "ekeys doesn't seem to be running..."
+   echo "expresskeys doesn't seem to be running..."
 
 fi
 
similarity index 66%
rename from ekeys-terminate.sh
rename to expresskeys-terminate.sh
index 0754d29..9a5f197 100755 (executable)
@@ -1,10 +1,10 @@
 #!/bin/sh
 
-# Terminate ekeys by its PID number.
+# Terminate expresskeys by its PID number.
 
 if [ -f ~/.expresskeys/expresskeys.pid ]; then
 
-   echo "Will try to terminate ekeys."
+   echo "Will try to terminate expresskeys."
 
    /bin/kill -TERM `/bin/cat ~/.expresskeys/expresskeys.pid | /bin/head -n 1`
 
@@ -18,7 +18,7 @@ if [ -f ~/.expresskeys/expresskeys.pid ]; then
 
 else
 
-   echo "ekeys doesn't seem to be running..."
+   echo "expresskeys doesn't seem to be running..."
 
 fi
 
similarity index 100%
rename from src-client/makefile
rename to src-client/Makefile
similarity index 95%
rename from src-server/makefile
rename to src-server/Makefile
index 66d06cd..b622db9 100644 (file)
@@ -6,7 +6,7 @@ INCLUDES = -I/usr/X11R6/lib
 LDFLAGS = -L/usr/X11R6/lib
 LIBS = -lX11 -lXext -lXi -lXtst
 
-TARGET = ekeys
+TARGET = expresskeys
 
 SRCS = globals.c config_read.c config_write.c on_error.c on_signal.c \
        pen_mode.c get_device.c reg_events.c event_loop.c main_setup.c
index 21e79e1..1054b8f 100644 (file)
@@ -42,13 +42,6 @@ int read_file_config(int *ip, FILE *fp)
        int num_field = 0;
 
        char buffer [MAXBUFFER];
-       char *heap_protect;
-
-/* Put a dummy heap protection in place... */
-
-       if ((heap_protect = (char *)malloc(1024)) == NULL) {
-               return 2; 
-       }
 
 /* Previously allocated memory for the program names must be released */
 /* on subsequent reads of the config file. At program start the flag is 0 */
@@ -191,9 +184,9 @@ int read_file_config(int *ip, FILE *fp)
                }
        }
        if (!num_record) {
+               num_list = 0;
                return 1;
        }
-       free(heap_protect);
        num_list = num_record;
        return 0;
 }
index 44e77c4..9d65f35 100644 (file)
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 /* Function queries the X server for input devices. It only cares about non */
 /* core ones, and compares them with what was specified on the command line. */
-/* The "info" is a scratch XDeviceInfo construct which is freed by the  */
-/* caller after having set a permanent global copy for later reference */
+/* The "info" is a XDeviceInfo construct whos address is transferred to a */
+/* permanent global copy for freeing at program exit */
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 
-int get_device_info(Display *display, char *name)
+int get_device_info(Display *display, XDeviceInfo *info, char *name)
 {
        int             i;
        int             nr_devices;
 
        info = XListInputDevices(display, &nr_devices);
 
+       if (pad_info_block) {
+               pen_info_block = info;
+       } else {
+               pad_info_block = info;
+       }
+
        for(i = 0; i < nr_devices; i++) {
                if ((info[i].use == IsXExtensionDevice) &&
                (strcmp (info[i].name, name) == 0)) {
index 72510d8..87aeef0 100644 (file)
@@ -22,7 +22,8 @@
 #include "globals.h"
 
 Display *display;
-XDeviceInfo *info;
+XDeviceInfo *pad_info_block;
+XDeviceInfo *pen_info_block;
 XDeviceInfo *pad_info;
 XDeviceInfo *pen_info;
 XDevice *pad_device;
index c28230f..9d4b356 100644 (file)
@@ -24,6 +24,8 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
+/* For the basename call */
+#include <libgen.h>
 /* For the daemon, getpid and unlink calls */
 #include <unistd.h>
 /* For the mkdir call */
@@ -79,30 +81,23 @@ extern int button_release_type;     /* Event type to keep track of - Pad Buttons */
 
 /* Global X functions */
 extern Display *display;       /* Active display. An X thing */
-extern XDeviceInfo *info;      /* Scratch while fishing for pad and pen info */
+extern XDeviceInfo *pad_info_block;    /* Base address - searching pad info */
+extern XDeviceInfo *pen_info_block; /* Base address - searching pen info */
 extern XDeviceInfo *pad_info;  /* Keeps all X knowledge of the pad device */
 extern XDeviceInfo *pen_info;  /* Keeps all X knowledge of the pen device */
 extern XDevice *pad_device;    /* The actual pointer to the pad device */
 extern XDevice *pen_device;    /* The actual pointer to the pen device */
 
 /* Our global (internal) functions */
-/* In config_read.c */
-extern int read_file_config(int *ip, FILE *fp);
-/* In config_write.c */
 extern int write_file_config(int *ip, FILE *fp);
-/* In event_loop.c */
+extern int read_file_config(int *ip, FILE *fp);
+extern int get_device_info(Display *display, XDeviceInfo *info, char *name);
+extern int register_events(Display *display, XDeviceInfo *pad_info, char *name);
+extern int toggle_pen_mode(Display *display, char *name);
 extern int use_events(Display *display);
-/* In get_device.c */
-extern int get_device_info(Display *display, char *name);
-/* In on_error.c */
-extern int exit_on_error(FILE *fp, char *string1, char *string2, char *string3);
-/* In on_signal.c */
+extern void exit_on_error(FILE *fp, char *string1, char *string2, char *string3);
 extern void re_read_file_config(int signum);
 extern void clean_up_exit(int signum);
-/* In pen_mode.c */
-extern int toggle_pen_mode(Display *display, char *name);
-/* In reg_events.c */
-extern int register_events(Display *display, XDeviceInfo *pad_info, char *name);
 
 /* Our global structures */
 /* The internal_list is initialized in globals.c */
index 0b773c3..91b35ef 100644 (file)
@@ -24,7 +24,7 @@
 int main (int argc, char *argv[])
 {
 
-       our_prog_name = argv[0];
+       our_prog_name = basename(argv[0]);
 
        struct program *p;
 
@@ -37,7 +37,7 @@ int main (int argc, char *argv[])
 /* Prelaunch sanity checks: See if X is OK */
 
        if ((display = XOpenDisplay(NULL)) == NULL) {
-               fprintf(stderr, "%s ERROR: Can not connect to your X Server\n", our_prog_name);
+               exit_on_error(errorfp, "%s ERROR: Can not connect to your X Server\n", our_prog_name, "");
                exit(EXIT_KO); 
        }
        screen = DefaultScreen(display);
@@ -49,20 +49,6 @@ int main (int argc, char *argv[])
                exit_on_error(errorfp, "%s ERROR: Can not find your HOME directory!\n", our_prog_name, "");
        }
 
-/* This is silly, but in order to keep the heap from being stomped on */
-/* by malloc and even automatic allocations we first need to allocate */
-/* a slight bit of memory. Here I use 1024 bytes, which seems enough. */
-/* Not doing this results in random errors when changing the code. */
-/* The "heap_protect" memory is freed before we leave the function */
-/* Another solution is to allocate a fair bit of memory in the actual */
-/* malloc that stomps on the heap. But it seems even sillier to use */
-/* a 1024 byte string when only needing 41, than this workaround is*/
-
-       char *heap_protect;
-       if ((heap_protect = (char *)malloc(1024)) == NULL) {
-               exit_on_error(errorfp, "%s ERROR: Memory allocation trouble at stage 1!\n", our_prog_name, "");
-       }
-
 /* Concatenate the home directory string with the string of our preferred*/
 /* configuration file directory. The address to the whole string is then */
 /* copied to a global pointer, so we won't have to perform this part again */
@@ -174,14 +160,12 @@ int main (int argc, char *argv[])
                fprintf(stderr, "\n");
                fprintf(stderr, "Example: %s pad stylus -d\n", our_prog_name);
                fprintf(stderr, "\n");
-               XCloseDisplay(display);
-               exit(EXIT_KO);
+               exit_on_error(errorfp, "", "", "");
        }
 
 /* See if the pad is for real, and if it is active */
 
-       pad_info = (void *) get_device_info(display, argv[1]);
-       XFreeDeviceList(info);
+       pad_info = (void *) get_device_info(display, pad_info_block, argv[1]);
        if (!pad_info) {
                exit_on_error(errorfp, "%s ERROR: Can not find pad device: %s\n", our_prog_name, argv[1]);
        }
@@ -200,8 +184,7 @@ int main (int argc, char *argv[])
                        if (strcmp(argv[i], "-d") != 0) {
                                pen_name = argv[i];
                                handle_pen = 1;
-                               pen_info = (void *) get_device_info(display, argv[i]);
-                               XFreeDeviceList(info);
+                               pen_info = (void *) get_device_info(display, pen_info_block, argv[i]);
                                if (!pen_info) {
                                        exit_on_error(errorfp, "%s ERROR: Can not find pen device: %s\n", our_prog_name, pen_name);
                                }
@@ -227,7 +210,7 @@ int main (int argc, char *argv[])
        } else {
                rewind(fp);
                if (fgetc(fp) == EOF) {
-                       fprintf(fp, "Config File Version %d:\n\n", CONFIG_VERSION);
+                       fprintf(fp, "Version: %d\n\n", CONFIG_VERSION);
                        for (p = internal_list; p < internal_list + num_list; p++) {
                                write_file_config((void *)&p, fp);
                                if (ferror(fp)) {
@@ -251,12 +234,15 @@ int main (int argc, char *argv[])
                        break;
 
                        case 1:
+                       fclose(fp);
                        exit_on_error(errorfp, "%s ERROR: No complete record found in %s\n", our_prog_name, total_config_file);
                        
                        case 2:
+                       fclose(fp);
                        exit_on_error(errorfp, "%s ERROR: Memory allocation error while parsing %s\n", our_prog_name, total_config_file);
                        
                        default:
+                       fclose(fp);
                        exit_on_error(errorfp, "%s ERROR: Unknown error while parsing %s\n", our_prog_name, total_config_file);
                }
        }
@@ -296,14 +282,12 @@ int main (int argc, char *argv[])
                                }
                        }
                }
-               fclose(errorfp); /* Close error log */
-               free(heap_protect); /* free the dummy heap protect */
+               fclose(errorfp);
                use_events(display); /* <-- Our true launch! The event loop */
        } else {
                exit_on_error(errorfp, "%s ERROR: Could not register any events!\n", our_prog_name, "");
        }
 
-       XCloseDisplay(display);
        exit(EXIT_OK);
 
 }
index a9cc0e7..163f19a 100644 (file)
 #include "globals.h"
 
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* Function prints out the error strings from a caller and exits */
+/* Function prints out the error strings from a caller and terminates */
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 
-int exit_on_error(FILE *fp, char *string1, char *string2, char *string3)
+void exit_on_error(FILE *fp, char *string1, char *string2, char *string3)
 {
 
        if (fp) {
                fprintf(fp, string1, string2, string3);
+               fclose(fp);
        }
 
        fprintf(stderr, string1, string2, string3);
-       XCloseDisplay(display);
-       exit(EXIT_KO);
+       clean_up_exit(SIGTERM);
 
 }
 
index ecf0d5a..3a3ac67 100644 (file)
@@ -53,12 +53,15 @@ void re_read_file_config(int signum)
                        break;
 
                        case 1:
+                       fclose(fp);
                        exit_on_error(errorfp, "%s ERROR: Reread - No complete record found in %s\n", our_prog_name, total_config_file);
                        
                        case 2:
+                       fclose(fp);
                        exit_on_error(errorfp, "%s ERROR: Reread - Memory allocation error while parsing %s\n", our_prog_name, total_config_file);
                        
                        default:
+                       fclose(fp);
                        exit_on_error(errorfp, "%s ERROR: Reread - Unknown error while parsing %s\n", our_prog_name, total_config_file);
                }
        }
@@ -69,7 +72,7 @@ void re_read_file_config(int signum)
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 /* Function acts as a signal handler replacement for SIGINT, SIGHUP and */
 /* SIGTERM. All are normal exit signals. We want to trap them in order to */
-/* perform some house keeping pre-exit. Here it deletes a possible PID file */
+/* perform some house keeping pre-exit. Delete a PID file and free memory */
 /* Since it takes care of several signals, it could get invoked recursively */
 /* if some other signal comes in. We use this "volatile" variable to track */
 /* the case. At the end we restore the default signal handler and raise it */
@@ -78,6 +81,10 @@ void re_read_file_config(int signum)
 volatile sig_atomic_t clean_up_exit_in_progress = 0;
 void clean_up_exit(int signum)
 {
+       int i;
+       struct program *p;
+       p = external_list;
+
        if (clean_up_exit_in_progress) {
                raise(signum);
        }
@@ -86,8 +93,52 @@ void clean_up_exit(int signum)
        if (go_daemon) {
                unlink(total_pid_file);
        }
-       
+
+       if (total_config_dir) {
+               free(total_config_dir);
+       }
+
+       if (total_config_file) {
+               free(total_config_file);
+       }
+
+       if (total_pid_file) {
+               free(total_pid_file);
+       }
+
+       if (total_error_file) {
+               free(total_error_file);
+       }
+
+       if (num_list) {
+               for (i = 0; i < num_list; i++, p++) {
+                       free(p->class_name);
+               }
+       }
+
+       if (pad_info_block) {
+               XFreeDeviceList(pad_info_block);
+       }
+
+       if (pen_info_block) {
+               XFreeDeviceList(pen_info_block);
+       }
+
+       if (pad_device) {
+               XCloseDevice(display, pad_device);
+       }
+
+       if (pen_device) {
+               XCloseDevice(display, pen_device);
+       }
+
+       if (display) {
+               XCloseDisplay(display);
+       }
+
        signal(signum, SIG_DFL);
        raise(signum);
 }
 
+/* End Code */
+