FreeBSD 10 clang port
[oweals/cde.git] / cde / lib / DtTerm / TermPrim / TermPrimDebug.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 #ifndef lint
24 #ifdef  VERBOSE_REV_INFO
25 static char rcs_id[] = "$XConsortium: TermPrimDebug.c /main/4 1996/11/21 19:58:15 drk $";
26 #endif  /* VERBOSE_REV_INFO */
27 #endif  /* lint */
28
29 /*                                                                      *
30  * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company               *
31  * (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
32  * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.                *
33  * (c) Copyright 1993, 1994, 1996 Novell, Inc.                          *
34  * (c) Copyright 1996 Digital Equipment Corporation.                    *
35  * (c) Copyright 1996 FUJITSU LIMITED.                                  *
36  * (c) Copyright 1996 Hitachi.                                          *
37  */
38
39 #include <stdio.h>
40 #include <unistd.h>
41 #include <stdlib.h>
42 #if defined(linux) || defined(CSRG_BASED)
43 # include <stdarg.h>
44 #else
45 # include <varargs.h>
46 #endif
47 #include "TermHeader.h"
48 #include "TermPrimDebug.h"
49 #include <signal.h>
50
51 #define X_INCLUDE_STRING_H
52 #define XOS_USE_NO_LOCKING
53 #include <X11/Xos_r.h>
54
55 unsigned char *debugLevel[256] = { NULL }; /* debug level               */
56
57 #ifdef  BBA
58 #pragma BBA_IGNORE
59 #endif  /*BBA*/
60 int
61 isDebugFSet(int c, int f)
62 {
63     int i;
64     
65     _DtTermProcessLock();
66     i = ((f < _TERM_MAX_DEBUG_FLAG) ?
67             debugLevel[c % 256] &&
68             (debugLevel[c % 256][__TERM_DEBUG_BYTE(f)] & __TERM_DEBUG_BIT(f)) :
69             0);
70     _DtTermProcessUnlock();
71     return(i);
72 }
73
74 #ifdef  BBA
75 #pragma BBA_IGNORE
76 #endif  /*BBA*/
77 static
78 void
79 catchExit(void)
80 {
81     int a;
82     int b;
83
84     a = 1;
85     b = a;
86     a = b;
87     return;
88 }
89
90 typedef struct _argArray {
91     char *str;
92     struct _argArray *next;
93 } argArray;
94
95 #ifdef  BBA
96 #pragma BBA_IGNORE
97 #endif  /*BBA*/
98 void
99 setDebugFlags(char *c1)
100 {
101     argArray argHead;
102     argArray *argPtr;
103     int i1;
104     int i2;
105     char *c2;
106     char *c3;
107     char *charList;
108     char *flagList;
109     char charArray[BUFSIZ];
110     unsigned char theseFlags[_TERM_DEBUG_NUM_BYTES];
111     char startChar;
112     char endChar;
113     int startFlag;
114     int endFlag;
115     Boolean isValid;
116     static Boolean catchExitRegistered = False;
117     _Xstrtokparams strtok_buf;
118
119     /* ignore null or empty strings... */
120     if (!c1 || !*c1) {
121         return;
122     }
123
124     /* register our catchExit() function... */
125     _DtTermProcessLock();
126     if (!catchExitRegistered) {
127         (void) atexit(catchExit);
128         catchExitRegistered = True;
129     }
130
131     /* strtok out c1...
132      */
133
134     /* don't destroy the original string... */
135     c2 = malloc(strlen(c1) + 1);
136     (void) strcpy(c2, c1);
137
138
139     argHead.next = (argArray *) 0;
140     argPtr = &argHead;
141     while ((c3 = _XStrtok(c2, " \t\n", strtok_buf))) {
142         /* null out c2 so we won't restart strtok... */
143         c2 = (char *) 0;
144         argPtr->next = (argArray *) malloc(sizeof(argArray));
145         argPtr = argPtr->next;
146         argPtr->next = (argArray *) 0;
147         argPtr->str = c3;
148     }
149
150     /* run through the linked list and parse each string... */
151     for (argPtr = argHead.next; argPtr; argPtr = argPtr->next) {
152         charList = argPtr->str;
153         flagList = (char *) 0;
154         if ((c2 = strchr(argPtr->str, ':'))) {
155             /* null out the ':'... */
156             *c2++ = '\0';
157             flagList = c2;
158         }
159
160         /* fill out the char array... */
161         for (c2 = charArray; *charList; ) {
162             isValid = False;
163             if (isalpha(*charList)) {
164                 isValid = True;
165                 startChar = *charList++;
166             } else {
167                 startChar = 'A';
168             }
169
170             if (*charList == '-') {
171                 isValid = True;
172                 (void) charList++;
173                 if (isalpha(*charList)) {
174                     endChar = *charList++;
175                 } else {
176                     endChar = 'z';
177                 }
178             } else {
179                 endChar = startChar;
180             }
181
182             if (isValid) {
183                 while (startChar <= endChar) {
184                     *c2++ = startChar++;
185                 }
186                 /* null term... */
187                 *c2 = '\0';
188             } else {
189                 break;
190             }
191         }
192
193         /* fill out theseFlags... */
194         (void) memset(theseFlags, '\0', sizeof(theseFlags));
195         if (!flagList || !*flagList) {
196             flagList = strdup("-");
197         }
198
199         c3 = flagList;
200         while ((flagList = _XStrtok(c3, ",", strtok_buf))) {
201             /* null out c3 so we won't restart strtok... */
202             c3 = (char *) 0;
203             if (!flagList || !*flagList) {
204                 continue;
205             }
206             if (isdigit(*flagList)) {
207                 startFlag = strtol(flagList, &flagList, 0);
208             } else {
209                 startFlag = 0;
210             }
211             endFlag = startFlag;
212
213             if (*flagList == '-') {
214                 /* we have a range... */
215                 /* skip over the '-'... */
216                 (void) flagList++;
217                 if (isdigit(*flagList)) {
218                     endFlag = strtol(flagList, (char **) 0, 0);
219                 } else {
220                     endFlag = _TERM_MAX_DEBUG_FLAG - 1;
221                 }
222             }
223
224             if (startFlag < 0) {
225                 startFlag = 0;
226             }
227             if (endFlag > (_TERM_MAX_DEBUG_FLAG - 1)) {
228                 endFlag = _TERM_MAX_DEBUG_FLAG - 1;
229             }
230             for (; startFlag <= endFlag; startFlag++) {
231                 theseFlags[__TERM_DEBUG_BYTE(startFlag)] |=
232                         __TERM_DEBUG_BIT(startFlag);
233             }
234         }
235
236         /* now run through the the char array and or in these flags... */
237         for (c2 = charArray; *c2; c2++) {
238             if (isalpha(*c2)) {
239                 if (!debugLevel[*c2]) {
240                     debugLevel[*c2] =
241                             (unsigned char *) malloc(_TERM_DEBUG_NUM_BYTES);
242                     (void) memset(debugLevel[*c2], '\0', _TERM_DEBUG_NUM_BYTES);
243                 }
244                 for (i1 = 0; i1 < _TERM_DEBUG_NUM_BYTES; i1++) {
245                     debugLevel[*c2][i1] |= theseFlags[i1];
246                 }
247             }
248         }
249     }
250
251     /* dump out a list of set flags... */
252     if (isDebugFSet('v', 0)) {
253         for (i1 = 0; i1 < 256; i1++) {
254             if (debugLevel[i1]) {
255                 (void) fprintf(stderr, "debug flag '%c'  ", i1);
256                 for (i2 = 0; i2 < _TERM_MAX_DEBUG_FLAG; i2++) {
257                     if (i2 > 0 && (0 == i2 % 50)) {
258                         (void) fputs("\n                ", stderr);
259                     }
260                     if (debugLevel[i1][__TERM_DEBUG_BYTE(i2)] &
261                             __TERM_DEBUG_BIT(i2)) {
262                         (void) putc('X', stderr);
263                     } else {
264                         (void) putc('.', stderr);
265                     }
266                 }
267                 (void) putc('\n', stderr);
268             }
269         }
270     }
271     _DtTermProcessUnlock();
272 }
273
274 static Boolean timedOut;
275
276 #ifdef  BBA
277 #pragma BBA_IGNORE
278 #endif  /*BBA*/
279 /*ARGSUSED*/
280 static void
281 ding(int sig)
282 {
283     timedOut = True;
284 }
285
286 #ifdef  BBA
287 #pragma BBA_IGNORE
288 #endif  /*BBA*/
289 void
290 shortSleep(int msec)
291 {
292     struct sigaction action;
293     struct sigaction oldAction;
294     sigset_t sigset;
295     sigset_t oldSigset;
296     struct itimerval itime;
297     struct itimerval oldItime;
298
299     _DtTermProcessLock();
300     timedOut = False;
301
302     /* block SIGALRM... */
303     (void) sigemptyset(&sigset);
304     (void) sigaddset(&sigset, SIGALRM);
305     (void) sigprocmask(SIG_BLOCK, &sigset, &oldSigset);
306
307     /* set up a singnal handler for SIGALRM... */
308     action.sa_handler = ding;
309     action.sa_flags = 0;
310     (void) sigemptyset(&action.sa_mask);
311     (void) sigaction(SIGALRM, &action, &oldAction);
312
313     /* set an alarm... */
314     timerclear(&itime.it_interval);
315     itime.it_value.tv_usec = msec % 1000000;
316     itime.it_value.tv_sec = msec / 1000000;
317     (void) setitimer(ITIMER_REAL, &itime, &oldItime);
318
319     /* unblock SIGALRM and wait for a signal... */
320     (void) sigprocmask(SIG_BLOCK, (sigset_t *) 0, &sigset);
321     (void) sigdelset(&sigset, SIGALRM);
322     while (!timedOut) {
323         sigsuspend(&sigset);
324     }
325
326     /* restore old handler... */
327     (void) sigaction(SIGALRM, &oldAction, (struct sigaction *) 0);
328
329     /* restore old signal mask... */
330     (void) sigprocmask(SIG_SETMASK, &oldSigset, (sigset_t *) 0);
331     _DtTermProcessUnlock();
332 }
333
334 static FILE *timeStampFile = (FILE *) 0;
335
336 #ifdef  BBA
337 #pragma BBA_IGNORE
338 #endif  /*BBA*/
339 void
340 timeStamp(char *msg)
341 {
342     struct timeval tv;
343     struct timezone tz;
344
345     _DtTermProcessLock();
346     if (!timeStampFile) {
347         char *c;
348         char buffer[BUFSIZ];
349
350         if (!(c = getenv("timeStampFileName"))) {
351             (void) sprintf(buffer, "timeStamp-%d", getpid());
352             c = buffer;
353         }
354
355         if (!(timeStampFile = fopen(c, "a"))) {
356             _DtTermProcessUnlock();
357             return;
358         }
359
360         (void) setvbuf(timeStampFile, (char *) 0, _IOLBF, 0);
361     }
362     _DtTermProcessUnlock();
363
364     (void) gettimeofday(&tv, &tz);
365     (void) fprintf(timeStampFile, "%lu %ld %s\n", tv.tv_sec, tv.tv_usec,
366             (msg && *msg) ? msg : "");
367 }
368
369 typedef struct {
370     char                 *string;
371     int                   value;
372 } enumName;
373
374 static enumName eventTypes[] = {
375     {"KeyPress",                2},
376     {"KeyRelease",              3},
377     {"ButtonPress",             4},
378     {"ButtonRelease",           5},
379     {"MotionNotify",            6},
380     {"EnterNotify",             7},
381     {"LeaveNotify",             8},
382     {"FocusIn",                 9},
383     {"FocusOut",                10},
384     {"KeymapNotify",            11},
385     {"Expose",                  12},
386     {"GraphicsExpose",          13},
387     {"NoExpose",                14},
388     {"VisibilityNotify",        15},
389     {"CreateNotify",            16},
390     {"DestroyNotify",           17},
391     {"UnmapNotify",             18},
392     {"MapNotify",               19},
393     {"MapRequest",              20},
394     {"ReparentNotify",          21},
395     {"ConfigureNotify",         22},
396     {"ConfigureRequest",        23},
397     {"GravityNotify",           24},
398     {"ResizeRequest",           25},
399     {"CirculateNotify",         26},
400     {"CirculateRequest",        27},
401     {"PropertyNotify",          28},
402     {"SelectionClear",          29},
403     {"SelectionRequest",        30},
404     {"SelectionNotify",         31},
405     {"ColormapNotify",          32},
406     {"ClientMessage",           33},
407     {"MappingNotify",           34},
408     {"LASTEvent",               35},
409     {NULL},
410 };
411
412 static enumName notifyModes[] = {
413     {"NotifyNormal",            0},
414     {"NotifyGrab",              1},
415     {"NotifyUngrab",            2},
416     {"NotifyWhileGrabbed",      3},
417     {NULL},
418 };
419
420 static enumName notifyDetails[] = {
421     {"NotifyAncestor",          0},
422     {"NotifyVirtual",           1},
423     {"NotifyInferior",          2},
424     {"NotifyNonlinear",         3},
425     {"NotifyNonlinearVirtual",  4},
426     {"NotifyPointer",           5},
427     {"NotifyPointerRoot",       6},
428     {"NotifyDetailNone",        7},
429     {NULL},
430 };
431
432 static enumName boolTypes[] = {
433     {"True",                    1},
434     {"False",                   0},
435     {NULL},
436 };
437
438 static char *
439 enumToName
440 (
441     enumName             *list,
442     int                   value
443 )
444 {
445     int                   i1;
446     char                  buffer[BUFSIZ];
447     static char          *retBuffer = (char *) 0;
448
449     for (i1 = 0; list[i1].string; i1++) {
450         if (list[i1].value == value) {
451             return(list[i1].string);
452         }
453     }
454     (void) sprintf(buffer, "Unknown Value %d", value);
455     retBuffer = realloc(retBuffer, strlen(buffer));
456     (void) strcpy(retBuffer, buffer);
457     return(retBuffer);
458 }
459
460 void
461 _DtTermPrimDebugDumpEvent
462 (
463     FILE                 *f,
464     Widget                w,
465     XEvent               *ev
466 )
467 {
468     _DtTermProcessLock();
469     (void) fprintf(f, ">>  widget: name=\"%s\"  widget=0x%lx  window=0x%lx\n",
470             XtName(w), w, XtWindow(w));
471     (void) fprintf(f, ">> event {\n");
472     (void) fprintf(f, ">>     type=%s;\n",
473             enumToName(eventTypes, ev->xany.type));
474     (void) fprintf(f, ">>     serial=%lu\n", ev->xany.serial);
475     (void) fprintf(f, ">>     send_event=%s\n",
476             enumToName(boolTypes, ev->xany.send_event));
477     (void) fprintf(f, ">>     display=0x%lx\n", ev->xany.display);
478     (void) fprintf(f, ">>     window=0x%lx\n", ev->xany.window);
479     switch (ev->type) {
480     case EnterNotify:
481     case LeaveNotify:
482         (void) fprintf(f, ">>     root=0x%lx\n", ev->xcrossing.root);
483         (void) fprintf(f, ">>     subwindow=0x%lx\n", ev->xcrossing.subwindow);
484         (void) fprintf(f, ">>     mode=%s\n",
485                 enumToName(notifyModes, ev->xcrossing.mode));
486         (void) fprintf(f, ">>     detail=%s\n",
487                 enumToName(notifyDetails, ev->xcrossing.detail));
488         (void) fprintf(f, ">>     focus=%s\n",
489                 enumToName(boolTypes, ev->xcrossing.focus));
490         break;
491
492     case FocusIn:
493     case FocusOut:
494         (void) fprintf(f, ">>     mode=%s\n",
495                 enumToName(notifyModes, ev->xcrossing.mode));
496         (void) fprintf(f, ">>     detail=%s\n",
497                 enumToName(notifyDetails, ev->xcrossing.detail));
498         break;
499     }
500     (void) fprintf(f, ">> }\n");
501     _DtTermProcessUnlock();
502 }