ed192293ff628b9116abff5b19a1ac0fd27f9aa5
[expresskeys.git] / src-expresskeys / on_signal.c
1 /*
2  on_signal.c -- Support ExpressKeys & Touch Strips on a Wacom Intuos3 tablet.
3
4  Copyright (C) 2005-2006 - Mats Johannesson
5
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
19 */
20
21 #include "globals.h"
22
23 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24  Function acts as a signal handler replacement for SIGUSR1
25  On this signal we read a possibly changed configuration file again
26  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
27
28 void re_read_file_config(int signum)
29 {
30
31         struct program *p;
32         struct configstrings *hp;
33
34         FILE *fp;
35         FILE *errorfp;
36
37 /* Open (and truncate) an error log for future reference */
38
39         if ((errorfp = fopen(total_error_file, "w")) == NULL) {
40                 exit_on_error(errorfp, "%s ERROR: Reread - Can not open %s in write mode\n", our_prog_name, total_error_file);
41         }
42
43 /* Read in an existing configuration file */
44
45         p = external_list;
46         hp = human_readable;
47         if ((fp = fopen(total_config_file, "r")) == NULL) {
48                 exit_on_error(errorfp, "%s ERROR: Reread - Can not open %s in read mode\n", our_prog_name, total_config_file);
49         } else {
50                 switch (read_file_config((void *)&p, (void *)&hp, fp)){
51
52                         case 0: /* No errors */
53                         fclose(fp);
54                         break; /* OBS An identical list of error code returns exist in the
55                                         main_setup.c file. So change both when altering. */
56
57                         case 1:
58                         fclose(fp);
59                         exit_on_error(errorfp, "%s ERROR: Reread - No complete record found in %s\n", our_prog_name, total_config_file);
60
61                         case 2:
62                         fclose(fp);
63                         exit_on_error(errorfp, "%s ERROR: Reread - Memory allocation error while parsing %s\n", our_prog_name, total_config_file);
64
65                         case 3:
66                         fclose(fp);
67                         exit_on_error(errorfp, "%s ERROR: Reread - Config File Version 3 or higher not found\n", our_prog_name, "");
68
69                         case 4:
70                         fclose(fp);
71                         exit_on_error(errorfp, "%s ERROR: Reread - A line was too long to handle in the Config File %s\n", our_prog_name, total_config_file);
72
73                         case 5:
74                         fclose(fp);
75                         exit_on_error(errorfp, "%s ERROR: Reread - A program record named \"default\" must exist in %s\n", our_prog_name, total_config_file);
76
77                         default:
78                         fclose(fp);
79                         exit_on_error(errorfp, "%s ERROR: Reread - Unknown error while parsing %s\n", our_prog_name, total_config_file);
80                 }
81         }
82
83         fclose(errorfp);
84 }
85
86 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
87  Function acts as a signal handler replacement for SIGUSR2
88  On this signal we print some choise information to the screen
89  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
90
91 void status_report(int signum)
92 {
93
94         struct program *p;
95         p = external_list;
96         int i;
97
98         fprintf(stderr, "PGR VERSION = %s\n", our_prog_version);
99         fprintf(stderr, "USR HOMEDIR = %s\n", getenv("HOME"));
100         fprintf(stderr, "OUR CNF-DIR = %s\n", total_config_dir);
101         fprintf(stderr, "OUR CNFFILE = %s\n", total_config_file);
102         fprintf(stderr, "OUR PIDFILE = %s\n", total_pid_file);
103         fprintf(stderr, "OUR LOGFILE = %s\n", total_error_file);
104         if (pad1_name) {
105                 fprintf(stderr, "OUR PD1NAME = %s\n", pad1_name);
106         }
107         if (stylus1_name) {
108                 fprintf(stderr, "OUR ST1NAME = %s\n", stylus1_name);
109         }
110         fprintf(stderr, "%s-user = %d\n", configstring, userconfigversion);
111         fprintf(stderr, "%s-ours = %s\n", configstring, configversion);
112         fprintf(stderr, "ConfigHeaderFields = %d\n", configheaderfields);
113         for (i = 0; i < num_list; i++, p++) {
114                 fprintf(stderr, "PGR RECNAME = %s\n", p->class_name);
115                 fprintf(stderr, "ST1 PRCURVE = \"%s\"\n", p->stylus1_presscurve);
116         }
117         fprintf(stderr, "PGR RECORDS = %d\n", num_list);
118         fprintf(stderr, "OUR RUN-PID = %d\n", getpid());
119
120 }
121
122 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
123  Function acts as a signal handler replacement for SIGINT, SIGHUP and
124  SIGTERM. All are normal exit signals. We want to trap them in order to
125  perform some house keeping pre-exit. Delete a PID file and free memory
126  Since it takes care of several signals, it could get invoked recursively
127  if some other signal comes in. We use this "volatile" variable to track
128  the case. At the end we restore the default signal handler and raise it
129  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
130
131 volatile sig_atomic_t clean_up_exit_in_progress = 0;
132 void clean_up_exit(int signum)
133 {
134         int i;
135         struct program *p;
136         p = external_list;
137
138         if (clean_up_exit_in_progress) {
139                 raise(signum);
140         }
141         clean_up_exit_in_progress = 1;
142
143         if ((go_daemon) && (!second_instance)) { /* Prevent accidental deletion */
144                 unlink(total_pid_file);
145         }
146
147         if (total_config_dir) {
148                 free(total_config_dir);
149         }
150
151         if (total_config_file) {
152                 free(total_config_file);
153         }
154
155         if (total_pid_file) {
156                 free(total_pid_file);
157         }
158
159         if (total_error_file) {
160                 free(total_error_file);
161         }
162
163         if (num_list) {
164                 for (i = 0; i < num_list; i++, p++) {
165                         free(p->stylus1_presscurve);
166                         free(p->class_name);
167                 }
168         }
169
170         if (pad1_info_block) {
171                 XFreeDeviceList(pad1_info_block);
172         }
173
174         if (stylus1_info_block) {
175                 XFreeDeviceList(stylus1_info_block);
176         }
177
178 /* pad1_device and stylus1_device should not be explicitly closed by a
179    call to XCloseDevice. It leaves a message from X (in the terminal
180    where X is started from) saying: "ProcXCloseDevice to close or not ?"
181    Like the program "xsetwacom" does on every device change...*/
182
183         if (display) {
184                 XCloseDisplay(display);
185         }
186
187         signal(signum, SIG_DFL);
188         raise(signum);
189 }
190
191 /* End Code */
192