1 /* $XTermId: trace.c,v 1.234 2021/09/14 20:09:56 tom Exp $ */
2
3 /*
4 * Copyright 1997-2020,2021 by Thomas E. Dickey
5 *
6 * All Rights Reserved
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Except as contained in this notice, the name(s) of the above copyright
28 * holders shall not be used in advertising or otherwise to promote the
29 * sale, use or other dealings in this Software without prior written
30 * authorization.
31 */
32
33 /*
34 * debugging support via TRACE macro.
35 */
36
37 #include <xterm.h> /* for definition of GCC_UNUSED */
38 #include <xstrings.h>
39 #include <wcwidth.h>
40 #include <version.h>
41
42 #if OPT_TRACE
43
44 #include <data.h>
45 #include <trace.h>
46
47 #include <time.h>
48 #include <stdlib.h>
49 #include <unistd.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <stdio.h>
53 #include <assert.h>
54
55 #include <X11/Xatom.h>
56 #include <X11/Xmu/Atoms.h>
57 #include <X11/Xmu/Error.h>
58
59 #ifdef HAVE_X11_TRANSLATEI_H
60 #include <X11/ConvertI.h>
61 #include <X11/TranslateI.h>
62 #else
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67 extern String _XtPrintXlations(Widget w,
68 XtTranslations xlations,
69 Widget accelWidget,
70 _XtBoolean includeRHS);
71 #ifdef __cplusplus
72 }
73 #endif
74 #endif
75 const char *trace_who = "parent";
76
77 static FILE *trace_fp;
78
79 static FILE *
TraceOpen(void)80 TraceOpen(void)
81 {
82 static const char *trace_out;
83
84 if (trace_fp != 0
85 && trace_who != trace_out) {
86 fclose(trace_fp);
87 trace_fp = 0;
88 }
89 trace_out = trace_who;
90
91 if (!trace_fp) {
92 static char dot[] = ".";
93 mode_t oldmask = umask(077);
94 /*
95 * Put the trace-file in user's home-directory if the current
96 * directory is not writable.
97 */
98 char *home = (access(dot, R_OK | W_OK) == 0) ? dot : getenv("HOME");
99 char *name = malloc(strlen(home) + strlen(trace_who) + 50);
100 #if OPT_TRACE_UNIQUE /* usually I do not want unique names */
101 int unique;
102 for (unique = 0;; ++unique) {
103 if (unique)
104 sprintf(name, "%s/Trace-%s.out-%d", home, trace_who, unique);
105 else
106 sprintf(name, "%s/Trace-%s.out", home, trace_who);
107 if ((trace_fp = fopen(name, "r")) == 0) {
108 break;
109 }
110 fclose(trace_fp);
111 }
112 #else
113 sprintf(name, "%s/Trace-%s.out", home, trace_who);
114 #endif
115 trace_fp = fopen(name, "w");
116 if (trace_fp != 0) {
117 fprintf(trace_fp, "%s\n", xtermVersion());
118 TraceIds(NULL, 0);
119 }
120 if (!trace_fp) {
121 xtermWarning("Cannot open \"%s\"\n", name);
122 exit(EXIT_FAILURE);
123 }
124 (void) umask(oldmask);
125 free(name);
126 }
127 return trace_fp;
128 }
129
130 void
Trace(const char * fmt,...)131 Trace(const char *fmt, ...)
132 {
133 va_list ap;
134 FILE *fp = TraceOpen();
135
136 va_start(ap, fmt);
137 vfprintf(fp, fmt, ap);
138 (void) fflush(fp);
139 va_end(ap);
140 }
141
142 void
TraceVA(const char * fmt,va_list ap)143 TraceVA(const char *fmt, va_list ap)
144 {
145 FILE *fp = TraceOpen();
146
147 vfprintf(fp, fmt, ap);
148 (void) fflush(fp);
149 }
150
151 void
TraceClose(void)152 TraceClose(void)
153 {
154 if (trace_fp != 0) {
155 (void) fclose(trace_fp);
156 (void) fflush(stdout);
157 (void) fflush(stderr);
158 (void) visibleChars(NULL, 0);
159 (void) visibleIChars(NULL, 0);
160 trace_fp = 0;
161 }
162 }
163
164 void
TraceXError(Display * d,XErrorEvent * ev)165 TraceXError(Display *d, XErrorEvent *ev)
166 {
167 FILE *fp = TraceOpen();
168 (void) XmuPrintDefaultErrorMessage(d, ev, fp);
169 (void) fflush(fp);
170 }
171
172 void
TraceIds(const char * fname,int lnum)173 TraceIds(const char *fname, int lnum)
174 {
175 Trace("process %d ", (int) getpid());
176 #ifdef HAVE_UNISTD_H
177 Trace("real (%u/%u) effective (%u/%u)",
178 (unsigned) getuid(), (unsigned) getgid(),
179 (unsigned) geteuid(), (unsigned) getegid());
180 #endif
181 if (fname != 0) {
182 Trace(" (%s@%d)\n", fname, lnum);
183 } else {
184 time_t now = time((time_t *) 0);
185 Trace("-- %s", ctime(&now));
186 }
187 }
188
189 void
TraceTime(const char * fname,int lnum)190 TraceTime(const char *fname, int lnum)
191 {
192 time_t now;
193 if (fname != 0) {
194 Trace("datetime (%s@%d) ", fname, lnum);
195 }
196 now = time((time_t *) 0);
197 Trace("-- %s", ctime(&now));
198 }
199
200 static void
formatAscii(char * dst,unsigned value)201 formatAscii(char *dst, unsigned value)
202 {
203 switch (value) {
204 case '\\':
205 sprintf(dst, "\\\\");
206 break;
207 case '\b':
208 sprintf(dst, "\\b");
209 break;
210 case '\n':
211 sprintf(dst, "\\n");
212 break;
213 case '\r':
214 sprintf(dst, "\\r");
215 break;
216 case '\t':
217 sprintf(dst, "\\t");
218 break;
219 default:
220 if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160))
221 sprintf(dst, "\\%03o", value & 0xff);
222 else
223 sprintf(dst, "%c", CharOf(value));
224 break;
225 }
226 }
227
228 #if OPT_DEC_CHRSET
229
230 const char *
visibleDblChrset(unsigned chrset)231 visibleDblChrset(unsigned chrset)
232 {
233 const char *result = "?";
234 switch (chrset) {
235 case CSET_SWL:
236 result = "CSET_SWL";
237 break;
238 case CSET_DHL_TOP:
239 result = "CSET_DHL_TOP";
240 break;
241 case CSET_DHL_BOT:
242 result = "CSET_DHL_BOT";
243 break;
244 case CSET_DWL:
245 result = "CSET_DWL";
246 break;
247 }
248 return result;
249 }
250 #endif
251
252 const char *
visibleScsCode(DECNRCM_codes chrset)253 visibleScsCode(DECNRCM_codes chrset)
254 {
255 #define MAP(to,from) case from: result = to ":" #from; break
256 const char *result = "<ERR>";
257 switch ((DECNRCM_codes) chrset) {
258 MAP("B", nrc_ASCII);
259 MAP("A", nrc_British);
260 MAP("A", nrc_British_Latin_1);
261 MAP("&4", nrc_DEC_Cyrillic);
262 MAP("0", nrc_DEC_Spec_Graphic);
263 MAP("1", nrc_DEC_Alt_Chars);
264 MAP("2", nrc_DEC_Alt_Graphics);
265 MAP("<", nrc_DEC_Supp);
266 MAP("%5", nrc_DEC_Supp_Graphic);
267 MAP(">", nrc_DEC_Technical);
268 MAP("4", nrc_Dutch);
269 MAP("5", nrc_Finnish);
270 MAP("C", nrc_Finnish2);
271 MAP("R", nrc_French);
272 MAP("f", nrc_French2);
273 MAP("Q", nrc_French_Canadian);
274 MAP("9", nrc_French_Canadian2);
275 MAP("K", nrc_German);
276 MAP("\"?", nrc_DEC_Greek_Supp);
277 MAP("\">", nrc_Greek);
278 MAP("F", nrc_ISO_Greek_Supp);
279 MAP("\"4", nrc_DEC_Hebrew_Supp);
280 MAP("%=", nrc_Hebrew);
281 MAP("H", nrc_ISO_Hebrew_Supp);
282 MAP("Y", nrc_Italian);
283 MAP("A", nrc_ISO_Latin_1_Supp);
284 MAP("B", nrc_ISO_Latin_2_Supp);
285 MAP("M", nrc_ISO_Latin_5_Supp);
286 MAP("L", nrc_ISO_Latin_Cyrillic);
287 MAP("`", nrc_Norwegian_Danish);
288 MAP("E", nrc_Norwegian_Danish2);
289 MAP("6", nrc_Norwegian_Danish3);
290 MAP("%6", nrc_Portugese);
291 MAP("&5", nrc_Russian);
292 MAP("%3", nrc_SCS_NRCS);
293 MAP("Z", nrc_Spanish);
294 MAP("7", nrc_Swedish);
295 MAP("H", nrc_Swedish2);
296 MAP("=", nrc_Swiss);
297 MAP("%2", nrc_Turkish);
298 MAP("%0", nrc_DEC_Turkish_Supp);
299 MAP("<UNK>", nrc_Unknown);
300 }
301 #undef MAP
302 return result;
303 }
304
305 const char *
visibleChars(const Char * buf,unsigned len)306 visibleChars(const Char *buf, unsigned len)
307 {
308 static char *result;
309 static unsigned used;
310
311 if (buf != 0) {
312 unsigned limit = ((len + 1) * 8) + 1;
313
314 if (limit > used) {
315 used = limit;
316 result = XtRealloc(result, used);
317 }
318 if (result != 0) {
319 char *dst = result;
320 *dst = '\0';
321 while (len--) {
322 unsigned value = *buf++;
323 formatAscii(dst, value);
324 dst += strlen(dst);
325 }
326 }
327 } else {
328 FreeAndNull(result);
329 used = 0;
330 }
331 return NonNull(result);
332 }
333
334 const char *
visibleEventMode(EventMode value)335 visibleEventMode(EventMode value)
336 {
337 const char *result;
338 switch (value) {
339 case NORMAL:
340 result = "NORMAL";
341 break;
342 case LEFTEXTENSION:
343 result = "LEFTEXTENSION";
344 break;
345 case RIGHTEXTENSION:
346 result = "RIGHTEXTENSION";
347 break;
348 default:
349 result = "?";
350 break;
351 }
352 return result;
353 }
354
355 const char *
visibleIChars(const IChar * buf,unsigned len)356 visibleIChars(const IChar *buf, unsigned len)
357 {
358 static char *result;
359 static unsigned used;
360
361 if (buf != 0) {
362 unsigned limit = ((len + 1) * 12) + 1;
363
364 if (limit > used) {
365 used = limit;
366 result = XtRealloc(result, used);
367 }
368 if (result != 0) {
369 char *dst = result;
370 *dst = '\0';
371 while (len--) {
372 unsigned value = *buf++;
373 #if OPT_WIDE_CHARS
374 if (value > 255)
375 sprintf(dst, "\\U+%04X", value);
376 else
377 #endif
378 formatAscii(dst, value);
379 dst += strlen(dst);
380 }
381 }
382 } else {
383 FreeAndNull(result);
384 used = 0;
385 }
386 return NonNull(result);
387 }
388
389 const char *
visibleUChar(unsigned chr)390 visibleUChar(unsigned chr)
391 {
392 IChar buf[1];
393 buf[0] = (IChar) chr;
394 return visibleIChars(buf, 1);
395 }
396
397 const char *
visibleEventType(int type)398 visibleEventType(int type)
399 {
400 const char *result = "?";
401 switch (type) {
402 CASETYPE(KeyPress);
403 CASETYPE(KeyRelease);
404 CASETYPE(ButtonPress);
405 CASETYPE(ButtonRelease);
406 CASETYPE(MotionNotify);
407 CASETYPE(EnterNotify);
408 CASETYPE(LeaveNotify);
409 CASETYPE(FocusIn);
410 CASETYPE(FocusOut);
411 CASETYPE(KeymapNotify);
412 CASETYPE(Expose);
413 CASETYPE(GraphicsExpose);
414 CASETYPE(NoExpose);
415 CASETYPE(VisibilityNotify);
416 CASETYPE(CreateNotify);
417 CASETYPE(DestroyNotify);
418 CASETYPE(UnmapNotify);
419 CASETYPE(MapNotify);
420 CASETYPE(MapRequest);
421 CASETYPE(ReparentNotify);
422 CASETYPE(ConfigureNotify);
423 CASETYPE(ConfigureRequest);
424 CASETYPE(GravityNotify);
425 CASETYPE(ResizeRequest);
426 CASETYPE(CirculateNotify);
427 CASETYPE(CirculateRequest);
428 CASETYPE(PropertyNotify);
429 CASETYPE(SelectionClear);
430 CASETYPE(SelectionRequest);
431 CASETYPE(SelectionNotify);
432 CASETYPE(ColormapNotify);
433 CASETYPE(ClientMessage);
434 CASETYPE(MappingNotify);
435 }
436 return result;
437 }
438
439 const char *
visibleMappingMode(int code)440 visibleMappingMode(int code)
441 {
442 const char *result = "?";
443 switch (code) {
444 CASETYPE(MappingModifier);
445 CASETYPE(MappingKeyboard);
446 CASETYPE(MappingPointer);
447 }
448 return result;
449 }
450
451 const char *
visibleNotifyMode(int code)452 visibleNotifyMode(int code)
453 {
454 const char *result = "?";
455 switch (code) {
456 CASETYPE(NotifyNormal);
457 CASETYPE(NotifyGrab);
458 CASETYPE(NotifyUngrab);
459 CASETYPE(NotifyWhileGrabbed);
460 }
461 return result;
462 }
463
464 const char *
visibleNotifyDetail(int code)465 visibleNotifyDetail(int code)
466 {
467 const char *result = "?";
468 switch (code) {
469 CASETYPE(NotifyAncestor);
470 CASETYPE(NotifyVirtual);
471 CASETYPE(NotifyInferior);
472 CASETYPE(NotifyNonlinear);
473 CASETYPE(NotifyNonlinearVirtual);
474 CASETYPE(NotifyPointer);
475 CASETYPE(NotifyPointerRoot);
476 CASETYPE(NotifyDetailNone);
477 }
478 return result;
479 }
480
481 const char *
visibleSelectionTarget(Display * d,Atom a)482 visibleSelectionTarget(Display *d, Atom a)
483 {
484 const char *result = "?";
485
486 if (a == XA_STRING) {
487 result = "XA_STRING";
488 } else if (a == XA_TEXT(d)) {
489 result = "XA_TEXT()";
490 } else if (a == XA_COMPOUND_TEXT(d)) {
491 result = "XA_COMPOUND_TEXT()";
492 } else if (a == XA_UTF8_STRING(d)) {
493 result = "XA_UTF8_STRING()";
494 } else if (a == XA_TARGETS(d)) {
495 result = "XA_TARGETS()";
496 }
497
498 return result;
499 }
500
501 const char *
visibleTekparse(int code)502 visibleTekparse(int code)
503 {
504 static const struct {
505 int code;
506 const char *name;
507 } table[] = {
508 #include "Tekparse.cin"
509 };
510 const char *result = "?";
511 Cardinal n;
512 for (n = 0; n < XtNumber(table); ++n) {
513 if (table[n].code == code) {
514 result = table[n].name;
515 break;
516 }
517 }
518 return result;
519 }
520
521 const char *
visibleVTparse(int code)522 visibleVTparse(int code)
523 {
524 static const struct {
525 int code;
526 const char *name;
527 } table[] = {
528 #include "VTparse.cin"
529 };
530 const char *result = "?";
531 Cardinal n;
532 for (n = 0; n < XtNumber(table); ++n) {
533 if (table[n].code == code) {
534 result = table[n].name;
535 break;
536 }
537 }
538 return result;
539 }
540
541 const char *
visibleXError(int code)542 visibleXError(int code)
543 {
544 static char temp[80];
545 const char *result = "?";
546 switch (code) {
547 CASETYPE(Success);
548 CASETYPE(BadRequest);
549 CASETYPE(BadValue);
550 CASETYPE(BadWindow);
551 CASETYPE(BadPixmap);
552 CASETYPE(BadAtom);
553 CASETYPE(BadCursor);
554 CASETYPE(BadFont);
555 CASETYPE(BadMatch);
556 CASETYPE(BadDrawable);
557 CASETYPE(BadAccess);
558 CASETYPE(BadAlloc);
559 CASETYPE(BadColor);
560 CASETYPE(BadGC);
561 CASETYPE(BadIDChoice);
562 CASETYPE(BadName);
563 CASETYPE(BadLength);
564 CASETYPE(BadImplementation);
565 default:
566 sprintf(temp, "%d", code);
567 result = temp;
568 break;
569 }
570 return result;
571 }
572
573 #if OPT_TRACE_FLAGS
574 #define isScrnFlag(flag) ((flag) == LINEWRAPPED)
575
576 static char *
ScrnText(LineData * ld)577 ScrnText(LineData *ld)
578 {
579 return visibleIChars(ld->charData, ld->lineSize);
580 }
581
582 #define SHOW_BAD_LINE(name, ld) \
583 Trace("OOPS " #name " bad row\n")
584
585 #define SHOW_SCRN_FLAG(name,code) \
586 Trace(#name " %s:%s\n", \
587 code ? "*" : "", \
588 ScrnText(ld))
589
590 void
LineClrFlag(LineData * ld,int flag)591 LineClrFlag(LineData *ld, int flag)
592 {
593 if (ld == 0) {
594 SHOW_BAD_LINE(LineClrFlag, ld);
595 assert(0);
596 } else if (isScrnFlag(flag)) {
597 SHOW_SCRN_FLAG(LineClrFlag, 0);
598 }
599
600 LineFlags(ld) &= ~flag;
601 }
602
603 void
LineSetFlag(LineData * ld,int flag)604 LineSetFlag(LineData *ld, int flag)
605 {
606 if (ld == 0) {
607 SHOW_BAD_LINE(LineSetFlag, ld);
608 assert(0);
609 } else if (isScrnFlag(flag)) {
610 SHOW_SCRN_FLAG(LineSetFlag, 1);
611 }
612
613 LineFlags(ld) |= flag;
614 }
615
616 int
LineTstFlag(LineData ld,int flag)617 LineTstFlag(LineData ld, int flag)
618 {
619 int code = 0;
620 if (ld == 0) {
621 SHOW_BAD_LINE(LineTstFlag, ld);
622 } else {
623 code = LineFlags(ld);
624
625 if (isScrnFlag(flag)) {
626 SHOW_SCRN_FLAG(LineTstFlag, code);
627 }
628 }
629 return code;
630 }
631 #endif /* OPT_TRACE_FLAGS */
632
633 const char *
TraceAtomName(Display * dpy,Atom atom)634 TraceAtomName(Display *dpy, Atom atom)
635 {
636 static char *result;
637 free(result);
638 if (atom != 0) {
639 result = XGetAtomName(dpy, atom);
640 } else {
641 result = x_strdup("NONE");
642 }
643 return result;
644 }
645
646 /*
647 * Trace the normal or alternate screen, showing color values up to 16, e.g.,
648 * for debugging with vttest.
649 */
650 void
TraceScreen(XtermWidget xw,int whichBuf)651 TraceScreen(XtermWidget xw, int whichBuf)
652 {
653 TScreen *screen = TScreenOf(xw);
654
655 if (screen->editBuf_index[whichBuf]) {
656 int row;
657
658 TRACE(("TraceScreen %d:\n", whichBuf));
659 for (row = 0; row <= screen->max_row; ++row) {
660 LineData *ld = getLineData(screen, row);
661
662 TRACE((" %3d:", row));
663 if (ld != 0) {
664 int col;
665
666 for (col = 0; col < ld->lineSize; ++col) {
667 int ch = (int) ld->charData[col];
668 if (ch < ' ')
669 ch = ' ';
670 if (ch >= 127)
671 ch = '#';
672 TRACE(("%c", ch));
673 }
674 TRACE((":\n"));
675
676 #if 0
677 TRACE((" xx:"));
678 for (col = 0; col < ld->lineSize; ++col) {
679 unsigned attrs = ld->attribs[col];
680 char ch;
681 if (attrs & PROTECTED) {
682 ch = '*';
683 } else if (attrs & BLINK) {
684 ch = 'B';
685 } else if (attrs & CHARDRAWN) {
686 ch = '+';
687 } else {
688 ch = ' ';
689 }
690 TRACE(("%c", ch));
691 }
692 TRACE((":\n"));
693 #endif
694
695 #if 0
696 TRACE((" fg:"));
697 for (col = 0; col < ld->lineSize; ++col) {
698 unsigned fg = extract_fg(xw, ld->color[col], ld->attribs[col]);
699 if (fg > 15)
700 fg = 15;
701 TRACE(("%1x", fg));
702 }
703 TRACE((":\n"));
704
705 TRACE((" bg:"));
706 for (col = 0; col < ld->lineSize; ++col) {
707 unsigned bg = extract_bg(xw, ld->color[col], ld->attribs[col]);
708 if (bg > 15)
709 bg = 15;
710 TRACE(("%1x", bg));
711 }
712 TRACE((":\n"));
713 #endif
714 } else {
715 TRACE(("null lineData\n"));
716 }
717 }
718 } else {
719 TRACE(("TraceScreen %d is nil\n", whichBuf));
720 }
721 }
722
723 static char *
formatEventMask(char * target,unsigned source,Boolean buttons)724 formatEventMask(char *target, unsigned source, Boolean buttons)
725 {
726 #define DATA(name) { name ## Mask, #name }
727 static struct {
728 unsigned mask;
729 const char *name;
730 } table[] = {
731 DATA(Shift),
732 DATA(Lock),
733 DATA(Control),
734 DATA(Mod1),
735 DATA(Mod2),
736 DATA(Mod3),
737 DATA(Mod4),
738 DATA(Mod5),
739 DATA(Button1),
740 DATA(Button2),
741 DATA(Button3),
742 DATA(Button4),
743 DATA(Button5),
744 };
745 #undef DATA
746 Cardinal n;
747 char marker = L_CURL;
748 char *base = target;
749
750 for (n = 0; n < XtNumber(table); ++n) {
751 if (!buttons && (table[n].mask >= Button1Mask))
752 continue;
753 if ((table[n].mask & source)) {
754 UIntClr(source, table[n].mask);
755 sprintf(target, "%c%s", marker, table[n].name);
756 target += strlen(target);
757 marker = '|';
758 }
759 }
760
761 if (source != 0) {
762 sprintf(target, "%c?%#x", marker, source);
763 target += strlen(target);
764 marker = '|';
765 }
766
767 if (marker == L_CURL)
768 *target++ = L_CURL;
769 *target++ = R_CURL;
770
771 *target = '\0';
772 return base;
773 }
774
775 void
TraceEvent(const char * tag,XEvent * ev,String * params,Cardinal * num_params)776 TraceEvent(const char *tag, XEvent *ev, String *params, Cardinal *num_params)
777 {
778 char mask_buffer[160];
779
780 TRACE(("Event #%lu %s: %#lx %s",
781 ev->xany.serial,
782 tag,
783 ev->xany.window,
784 visibleEventType(ev->type)));
785
786 switch (ev->type) {
787 case KeyPress:
788 /* FALLTHRU */
789 case KeyRelease:
790 TRACE((" keycode 0x%04X %s",
791 ev->xkey.keycode,
792 formatEventMask(mask_buffer, ev->xkey.state, False)));
793 break;
794 case ButtonPress:
795 /* FALLTHRU */
796 case ButtonRelease:
797 TRACE((" button %u state %#x %s",
798 ev->xbutton.button,
799 ev->xbutton.state,
800 formatEventMask(mask_buffer, ev->xbutton.state, True)));
801 break;
802 case MotionNotify:
803 TRACE((" (%d,%d) state %#x %s",
804 ev->xmotion.y_root,
805 ev->xmotion.x_root,
806 ev->xmotion.state,
807 formatEventMask(mask_buffer, ev->xmotion.state, True)));
808 break;
809 case EnterNotify:
810 case LeaveNotify:
811 TRACE((" at %d,%d root %d,%d %s %s",
812 ev->xcrossing.y,
813 ev->xcrossing.x,
814 ev->xcrossing.y_root,
815 ev->xcrossing.x_root,
816 visibleNotifyMode(ev->xcrossing.mode),
817 visibleNotifyDetail(ev->xcrossing.detail)));
818 break;
819 case FocusIn:
820 case FocusOut:
821 TRACE((" %s %s",
822 visibleNotifyMode(ev->xfocus.mode),
823 visibleNotifyDetail(ev->xfocus.detail)));
824 break;
825 case MapNotify:
826 TRACE((" event %#lx %s",
827 ev->xmap.event,
828 ev->xmap.override_redirect ? "override" : ""));
829 break;
830 case UnmapNotify:
831 TRACE((" event %#lx %s",
832 ev->xunmap.event,
833 ev->xunmap.from_configure ? "configure" : ""));
834 break;
835 case ReparentNotify:
836 TRACE((" at %d,%d event %#lx parent %#lx %s",
837 ev->xreparent.y,
838 ev->xreparent.x,
839 ev->xreparent.event,
840 ev->xreparent.parent,
841 ev->xreparent.override_redirect ? "override" : ""));
842 break;
843 case ConfigureNotify:
844 TRACE((" at %d,%d size %dx%d bd %d above %#lx",
845 ev->xconfigure.y,
846 ev->xconfigure.x,
847 ev->xconfigure.height,
848 ev->xconfigure.width,
849 ev->xconfigure.border_width,
850 ev->xconfigure.above));
851 break;
852 case CreateNotify:
853 TRACE((" at %d,%d size %dx%d bd %d",
854 ev->xcreatewindow.y,
855 ev->xcreatewindow.x,
856 ev->xcreatewindow.height,
857 ev->xcreatewindow.width,
858 ev->xcreatewindow.border_width));
859 break;
860 case ResizeRequest:
861 TRACE((" size %dx%d",
862 ev->xresizerequest.height,
863 ev->xresizerequest.width));
864 break;
865 case PropertyNotify:
866 TRACE((" %s %s",
867 TraceAtomName(XtDisplay(toplevel), ev->xproperty.atom),
868 ((ev->xproperty.state == PropertyNewValue)
869 ? "NewValue"
870 : ((ev->xproperty.state == PropertyDelete)
871 ? "Delete"
872 : "?"))));
873
874 break;
875 case Expose:
876 TRACE((" at %d,%d size %dx%d count %d",
877 ev->xexpose.y,
878 ev->xexpose.x,
879 ev->xexpose.height,
880 ev->xexpose.width,
881 ev->xexpose.count));
882 break;
883 case MappingNotify:
884 TRACE((" %s first_keycode %d count %d",
885 visibleMappingMode(ev->xmapping.request),
886 ev->xmapping.first_keycode,
887 ev->xmapping.count));
888 break;
889 case VisibilityNotify:
890 TRACE((" state %d",
891 ev->xvisibility.state));
892 break;
893 case KeymapNotify:
894 {
895 Cardinal j;
896 for (j = 0; j < XtNumber(ev->xkeymap.key_vector); ++j) {
897 if (ev->xkeymap.key_vector[j] != 0) {
898 Cardinal k;
899 for (k = 0; k < 8; ++k) {
900 if (ev->xkeymap.key_vector[j] & (1 << k)) {
901 TRACE((" key%u", (j * 8) + k));
902 }
903 }
904 }
905 }
906 }
907 break;
908 case NoExpose:
909 TRACE((" send_event:%d display %p major:%d minor:%d",
910 ev->xnoexpose.send_event,
911 (void *) ev->xnoexpose.display,
912 ev->xnoexpose.major_code,
913 ev->xnoexpose.minor_code));
914 break;
915 case GraphicsExpose:
916 TRACE((" send_event:%d display %p major:%d minor:%d",
917 ev->xgraphicsexpose.send_event,
918 (void *) ev->xgraphicsexpose.display,
919 ev->xgraphicsexpose.major_code,
920 ev->xgraphicsexpose.minor_code));
921 break;
922 case SelectionClear:
923 TRACE((" selection:%s",
924 TraceAtomName(ev->xselectionclear.display,
925 ev->xselectionclear.selection)));
926 break;
927 case SelectionRequest:
928 TRACE((" owner:%#lx requestor:%#lx",
929 ev->xselectionrequest.owner,
930 ev->xselectionrequest.requestor));
931 TRACE((" selection:%s",
932 TraceAtomName(ev->xselectionrequest.display,
933 ev->xselectionrequest.selection)));
934 TRACE((" target:%s",
935 TraceAtomName(ev->xselectionrequest.display,
936 ev->xselectionrequest.target)));
937 TRACE((" property:%s",
938 TraceAtomName(ev->xselectionrequest.display,
939 ev->xselectionrequest.property)));
940 break;
941 default:
942 TRACE((":FIXME"));
943 break;
944 }
945 TRACE(("\n"));
946 if (params != 0 && *num_params != 0) {
947 Cardinal n;
948 for (n = 0; n < *num_params; ++n) {
949 TRACE((" param[%d] = %s\n", n, params[n]));
950 }
951 }
952 }
953
954 #if OPT_RENDERFONT && OPT_WIDE_CHARS
955 void
TraceFallback(XtermWidget xw,const char * tag,unsigned wc,int n,XftFont * font)956 TraceFallback(XtermWidget xw, const char *tag, unsigned wc, int n, XftFont *font)
957 {
958 TScreen *screen = TScreenOf(xw);
959 XGlyphInfo gi;
960 int expect = my_wcwidth((wchar_t) wc);
961 int hijack = mk_wcwidth_cjk((wchar_t) wc);
962 int actual;
963
964 XftTextExtents32(screen->display, font, &wc, 1, &gi);
965 actual = ((gi.xOff + FontWidth(screen) - 1)
966 / FontWidth(screen));
967
968 TRACE(("FALLBACK #%d %s U+%04X %d,%d pos,"
969 " %d,%d off," " %dx%d size,"
970 " %d/%d next," " %d vs %d/%d cells%s\n",
971 n + 1, tag, wc,
972 gi.y, gi.x,
973 gi.yOff, gi.xOff,
974 gi.height, gi.width,
975 font->max_advance_width,
976 FontWidth(screen),
977 actual, expect, hijack,
978 ((actual != expect)
979 ? ((actual == hijack)
980 ? " OOPS"
981 : " oops")
982 : "")));
983 }
984 #endif /* OPT_RENDERFONT */
985
986 void
TraceFocus(Widget w,XEvent * ev)987 TraceFocus(Widget w, XEvent *ev)
988 {
989 TRACE(("trace_focus event type %d:%s\n",
990 ev->type, visibleEventType(ev->type)));
991 switch (ev->type) {
992 case FocusIn:
993 case FocusOut:
994 {
995 XFocusChangeEvent *event = (XFocusChangeEvent *) ev;
996 TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail)));
997 TRACE(("\tmode: %s\n", visibleNotifyMode(event->mode)));
998 TRACE(("\twindow: %#lx\n", event->window));
999 }
1000 break;
1001 case EnterNotify:
1002 case LeaveNotify:
1003 {
1004 XCrossingEvent *event = (XCrossingEvent *) ev;
1005 TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail)));
1006 TRACE(("\tmode: %s\n", visibleNotifyMode(event->mode)));
1007 TRACE(("\twindow: %#lx\n", event->window));
1008 TRACE(("\tfocus: %d\n", event->focus));
1009 TRACE(("\troot: %#lx\n", event->root));
1010 TRACE(("\tsubwindow: %#lx\n", event->subwindow));
1011 }
1012 break;
1013 }
1014 while (w != 0) {
1015 TRACE(("w %p -> %#lx\n", (void *) w, XtWindow(w)));
1016 w = XtParent(w);
1017 }
1018 }
1019
1020 void
TraceSizeHints(XSizeHints * hints)1021 TraceSizeHints(XSizeHints * hints)
1022 {
1023 TRACE(("size hints:\n"));
1024 if (hints->flags & (USPosition | PPosition)) {
1025 TRACE((" position %d,%d%s%s\n", hints->y, hints->x,
1026 (hints->flags & USPosition) ? " user" : "",
1027 (hints->flags & PPosition) ? " prog" : ""));
1028 }
1029 if (hints->flags & (USSize | PSize)) {
1030 TRACE((" size %d,%d%s%s\n", hints->height, hints->width,
1031 (hints->flags & USSize) ? " user" : "",
1032 (hints->flags & PSize) ? " prog" : ""));
1033 }
1034 if (hints->flags & PMinSize) {
1035 TRACE((" min %d,%d\n", hints->min_height, hints->min_width));
1036 }
1037 if (hints->flags & PMaxSize) {
1038 TRACE((" max %d,%d\n", hints->max_height, hints->max_width));
1039 }
1040 if (hints->flags & PResizeInc) {
1041 TRACE((" inc %d,%d\n", hints->height_inc, hints->width_inc));
1042 } else {
1043 TRACE((" inc NONE!\n"));
1044 }
1045 if (hints->flags & PAspect) {
1046 TRACE((" min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y));
1047 TRACE((" max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y));
1048 }
1049 if (hints->flags & PBaseSize) {
1050 TRACE((" base %d,%d\n", hints->base_height, hints->base_width));
1051 }
1052 if (hints->flags & PWinGravity) {
1053 TRACE((" gravity %d\n", hints->win_gravity));
1054 }
1055 }
1056
1057 static void
TraceEventMask(const char * tag,long mask)1058 TraceEventMask(const char *tag, long mask)
1059 {
1060 #define DATA(name) { name##Mask, #name }
1061 /* *INDENT-OFF* */
1062 static struct {
1063 long mask;
1064 const char *name;
1065 } table[] = {
1066 DATA(KeyPress),
1067 DATA(KeyRelease),
1068 DATA(ButtonPress),
1069 DATA(ButtonRelease),
1070 DATA(EnterWindow),
1071 DATA(LeaveWindow),
1072 DATA(PointerMotion),
1073 DATA(PointerMotionHint),
1074 DATA(Button1Motion),
1075 DATA(Button2Motion),
1076 DATA(Button3Motion),
1077 DATA(Button4Motion),
1078 DATA(Button5Motion),
1079 DATA(ButtonMotion),
1080 DATA(KeymapState),
1081 DATA(Exposure),
1082 DATA(VisibilityChange),
1083 DATA(StructureNotify),
1084 DATA(ResizeRedirect),
1085 DATA(SubstructureNotify),
1086 DATA(SubstructureRedirect),
1087 DATA(FocusChange),
1088 DATA(PropertyChange),
1089 DATA(ColormapChange),
1090 DATA(OwnerGrabButton),
1091 };
1092 #undef DATA
1093 Cardinal n;
1094 /* *INDENT-ON* */
1095
1096 for (n = 0; n < XtNumber(table); ++n) {
1097 if (table[n].mask & mask) {
1098 TRACE(("%s %s\n", tag, table[n].name));
1099 }
1100 }
1101 }
1102
1103 void
TraceWindowAttributes(XWindowAttributes * attrs)1104 TraceWindowAttributes(XWindowAttributes * attrs)
1105 {
1106 TRACE(("window attributes:\n"));
1107 TRACE((" position %d,%d\n", attrs->y, attrs->x));
1108 TRACE((" size %dx%d\n", attrs->height, attrs->width));
1109 TRACE((" border %d\n", attrs->border_width));
1110 TRACE((" depth %d\n", attrs->depth));
1111 TRACE((" bit_gravity %d\n", attrs->bit_gravity));
1112 TRACE((" win_gravity %d\n", attrs->win_gravity));
1113 TRACE((" root %#lx\n", (long) attrs->root));
1114 TRACE((" class %s\n", ((attrs->class == InputOutput)
1115 ? "InputOutput"
1116 : ((attrs->class == InputOnly)
1117 ? "InputOnly"
1118 : "unknown"))));
1119 TRACE((" map_state %s\n", ((attrs->map_state == IsUnmapped)
1120 ? "IsUnmapped"
1121 : ((attrs->map_state == IsUnviewable)
1122 ? "IsUnviewable"
1123 : ((attrs->map_state == IsViewable)
1124 ? "IsViewable"
1125 : "unknown")))));
1126 TRACE((" all_events\n"));
1127 TraceEventMask(" ", attrs->all_event_masks);
1128 TRACE((" your_events\n"));
1129 TraceEventMask(" ", attrs->your_event_mask);
1130 TRACE((" no_propagate\n"));
1131 TraceEventMask(" ", attrs->do_not_propagate_mask);
1132 }
1133
1134 void
TraceWMSizeHints(XtermWidget xw)1135 TraceWMSizeHints(XtermWidget xw)
1136 {
1137 XSizeHints sizehints = xw->hints;
1138
1139 getXtermSizeHints(xw);
1140 TraceSizeHints(&xw->hints);
1141 xw->hints = sizehints;
1142 }
1143
1144 const char *
ModifierName(unsigned modifier)1145 ModifierName(unsigned modifier)
1146 {
1147 const char *s = "";
1148 if (modifier & ShiftMask)
1149 s = " Shift";
1150 else if (modifier & LockMask)
1151 s = " Lock";
1152 else if (modifier & ControlMask)
1153 s = " Control";
1154 else if (modifier & Mod1Mask)
1155 s = " Mod1";
1156 else if (modifier & Mod2Mask)
1157 s = " Mod2";
1158 else if (modifier & Mod3Mask)
1159 s = " Mod3";
1160 else if (modifier & Mod4Mask)
1161 s = " Mod4";
1162 else if (modifier & Mod5Mask)
1163 s = " Mod5";
1164 return s;
1165 }
1166
1167 void
TraceTranslations(const char * name,Widget w)1168 TraceTranslations(const char *name, Widget w)
1169 {
1170 String result;
1171 XErrorHandler save = XSetErrorHandler(ignore_x11_error);
1172 XtTranslations xlations;
1173 Widget xcelerat;
1174
1175 TRACE(("TraceTranslations for %s (widget %#lx) " TRACE_L "\n",
1176 name, (long) w));
1177 if (w) {
1178 XtVaGetValues(w,
1179 XtNtranslations, &xlations,
1180 XtNaccelerators, &xcelerat,
1181 (XtPointer) 0);
1182 TRACE(("... xlations %#08lx\n", (long) xlations));
1183 TRACE(("... xcelerat %#08lx\n", (long) xcelerat));
1184 result = _XtPrintXlations(w, xlations, xcelerat, True);
1185 TRACE(("%s\n", NonNull(result)));
1186 if (result)
1187 XFree((char *) result);
1188 } else {
1189 TRACE(("none (widget is null)\n"));
1190 }
1191 TRACE((TRACE_R "\n"));
1192 XSetErrorHandler(save);
1193 }
1194
1195 XtGeometryResult
TraceResizeRequest(const char * fn,int ln,Widget w,unsigned reqwide,unsigned reqhigh,Dimension * gotwide,Dimension * gothigh)1196 TraceResizeRequest(const char *fn, int ln, Widget w,
1197 unsigned reqwide,
1198 unsigned reqhigh,
1199 Dimension *gotwide,
1200 Dimension *gothigh)
1201 {
1202 XtGeometryResult rc;
1203
1204 TRACE(("%s@%d ResizeRequest %ux%u\n", fn, ln, reqhigh, reqwide));
1205 rc = XtMakeResizeRequest((Widget) w,
1206 (Dimension) reqwide,
1207 (Dimension) reqhigh,
1208 gotwide, gothigh);
1209 TRACE(("... ResizeRequest -> "));
1210 if (gothigh && gotwide)
1211 TRACE(("%dx%d ", *gothigh, *gotwide));
1212 TRACE(("(%d)\n", rc));
1213 return rc;
1214 }
1215
1216 #define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name))
1217 #define XRES_B(name) Trace(#name " = %s\n", MtoS(resp->name))
1218 #define XRES_I(name) Trace(#name " = %d\n", resp->name)
1219
1220 void
TraceXtermResources(void)1221 TraceXtermResources(void)
1222 {
1223 XTERM_RESOURCE *resp = &resource;
1224
1225 Trace("XTERM_RESOURCE settings:\n");
1226 XRES_S(icon_geometry);
1227 XRES_S(title);
1228 XRES_S(icon_hint);
1229 XRES_S(icon_name);
1230 XRES_S(term_name);
1231 XRES_S(tty_modes);
1232 XRES_I(minBufSize);
1233 XRES_I(maxBufSize);
1234 XRES_B(hold_screen);
1235 XRES_B(utmpInhibit);
1236 XRES_B(utmpDisplayId);
1237 XRES_B(messages);
1238 XRES_S(menuLocale);
1239 XRES_S(omitTranslation);
1240 XRES_S(keyboardType);
1241 #ifdef HAVE_LIB_XCURSOR
1242 XRES_S(cursorTheme);
1243 #endif
1244 #if OPT_PRINT_ON_EXIT
1245 XRES_I(printModeNow);
1246 XRES_I(printModeOnXError);
1247 XRES_I(printOptsNow);
1248 XRES_I(printOptsOnXError);
1249 XRES_S(printFileNow);
1250 XRES_S(printFileOnXError);
1251 #endif
1252 #if OPT_SUNPC_KBD
1253 XRES_B(sunKeyboard);
1254 #endif
1255 #if OPT_HP_FUNC_KEYS
1256 XRES_B(hpFunctionKeys);
1257 #endif
1258 #if OPT_SCO_FUNC_KEYS
1259 XRES_B(scoFunctionKeys);
1260 #endif
1261 #if OPT_SUN_FUNC_KEYS
1262 XRES_B(sunFunctionKeys);
1263 #endif
1264 #if OPT_INITIAL_ERASE
1265 XRES_B(ptyInitialErase);
1266 XRES_B(backarrow_is_erase);
1267 #endif
1268 XRES_B(useInsertMode);
1269 #if OPT_ZICONBEEP
1270 XRES_I(zIconBeep);
1271 XRES_S(zIconFormat);
1272 #endif
1273 #if OPT_PTY_HANDSHAKE
1274 XRES_B(wait_for_map);
1275 XRES_B(ptyHandshake);
1276 XRES_B(ptySttySize);
1277 #endif
1278 #if OPT_REPORT_CCLASS
1279 XRES_B(reportCClass);
1280 #endif
1281 #if OPT_REPORT_COLORS
1282 XRES_B(reportColors);
1283 #endif
1284 #if OPT_REPORT_FONTS
1285 XRES_B(reportFonts);
1286 #endif
1287 #if OPT_REPORT_ICONS
1288 XRES_B(reportIcons);
1289 #endif
1290 #if OPT_SAME_NAME
1291 XRES_B(sameName);
1292 #endif
1293 #if OPT_SESSION_MGT
1294 XRES_B(sessionMgt);
1295 #endif
1296 #if OPT_TOOLBAR
1297 XRES_B(toolBar);
1298 #endif
1299 #if OPT_MAXIMIZE
1300 XRES_B(maximized);
1301 XRES_S(fullscreen_s);
1302 #endif
1303 #if USE_DOUBLE_BUFFER
1304 XRES_B(buffered);
1305 XRES_I(buffered_fps);
1306 #endif
1307 }
1308
1309 void
TraceArgv(const char * tag,char ** argv)1310 TraceArgv(const char *tag, char **argv)
1311 {
1312 TRACE(("%s:\n", tag));
1313 if (argv != 0) {
1314 int n = 0;
1315
1316 while (*argv != 0) {
1317 TRACE((" %d:%s\n", n++, *argv++));
1318 }
1319 }
1320 }
1321
1322 static char *
parse_option(char * dst,String src,int first)1323 parse_option(char *dst, String src, int first)
1324 {
1325 char *s;
1326
1327 if (!strncmp(src, "-/+", (size_t) 3)) {
1328 dst[0] = (char) first;
1329 strcpy(dst + 1, src + 3);
1330 } else {
1331 strcpy(dst, src);
1332 }
1333 for (s = dst; *s != '\0'; s++) {
1334 if (*s == '#' || *s == '%' || *s == 'S') {
1335 s[1] = '\0';
1336 } else if (*s == ' ') {
1337 *s = '\0';
1338 break;
1339 }
1340 }
1341 return dst;
1342 }
1343
1344 static Bool
same_option(OptionHelp * opt,XrmOptionDescRec * res)1345 same_option(OptionHelp * opt, XrmOptionDescRec * res)
1346 {
1347 char temp[BUFSIZ];
1348 return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option);
1349 }
1350
1351 static Bool
standard_option(String opt)1352 standard_option(String opt)
1353 {
1354 static const char *table[] =
1355 {
1356 "+rv",
1357 "+synchronous",
1358 "-background",
1359 "-bd",
1360 "-bg",
1361 "-bordercolor",
1362 "-borderwidth",
1363 "-bw",
1364 "-display",
1365 "-fg",
1366 "-fn",
1367 "-font",
1368 "-foreground",
1369 "-geometry",
1370 "-iconic",
1371 "-name",
1372 "-reverse",
1373 "-rv",
1374 "-selectionTimeout",
1375 "-synchronous",
1376 "-title",
1377 "-xnllanguage",
1378 "-xrm",
1379 "-xtsessionID",
1380 };
1381 Cardinal n;
1382 char temp[BUFSIZ];
1383
1384 opt = parse_option(temp, opt, '-');
1385 for (n = 0; n < XtNumber(table); n++) {
1386 if (!strcmp(opt, table[n]))
1387 return True;
1388 }
1389 return False;
1390 }
1391
1392 /*
1393 * Analyse the options/help messages for inconsistencies.
1394 */
1395 void
TraceOptions(OptionHelp * options,XrmOptionDescRec * resources,Cardinal res_count)1396 TraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count)
1397 {
1398 OptionHelp *opt_array = sortedOpts(options, resources, res_count);
1399 size_t j, k;
1400 XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count);
1401 Bool first, found;
1402
1403 TRACE(("Checking options-tables for inconsistencies:\n"));
1404
1405 #if 0
1406 TRACE(("Options listed in help-message:\n"));
1407 for (j = 0; options[j].opt != 0; j++)
1408 TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc));
1409 TRACE(("Options listed in resource-table:\n"));
1410 for (j = 0; j < res_count; j++)
1411 TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier));
1412 #endif
1413
1414 /* list all options[] not found in resources[] */
1415 for (j = 0, first = True; options[j].opt != 0; j++) {
1416 found = False;
1417 for (k = 0; k < res_count; k++) {
1418 if (same_option(&opt_array[j], &res_array[k])) {
1419 found = True;
1420 break;
1421 }
1422 }
1423 if (!found) {
1424 if (first) {
1425 TRACE(("Options listed in help, not found in resource list:\n"));
1426 first = False;
1427 }
1428 TRACE((" %-28s%s\n", opt_array[j].opt,
1429 standard_option(opt_array[j].opt) ? " (standard)" : ""));
1430 }
1431 }
1432
1433 /* list all resources[] not found in options[] */
1434 for (j = 0, first = True; j < res_count; j++) {
1435 found = False;
1436 for (k = 0; options[k].opt != 0; k++) {
1437 if (same_option(&opt_array[k], &res_array[j])) {
1438 found = True;
1439 break;
1440 }
1441 }
1442 if (!found) {
1443 if (first) {
1444 TRACE(("Resource list items not found in options-help:\n"));
1445 first = False;
1446 }
1447 TRACE((" %s\n", res_array[j].option));
1448 }
1449 }
1450
1451 TRACE(("Resource list items that will be ignored by XtOpenApplication:\n"));
1452 for (j = 0; j < res_count; j++) {
1453 switch (res_array[j].argKind) {
1454 case XrmoptionSkipArg:
1455 TRACE((" %-28s {param}\n", res_array[j].option));
1456 break;
1457 case XrmoptionSkipNArgs:
1458 TRACE((" %-28s {%ld params}\n", res_array[j].option, (long)
1459 res_array[j].value));
1460 break;
1461 case XrmoptionSkipLine:
1462 TRACE((" %-28s {remainder of line}\n", res_array[j].option));
1463 break;
1464 case XrmoptionIsArg:
1465 case XrmoptionNoArg:
1466 case XrmoptionResArg:
1467 case XrmoptionSepArg:
1468 case XrmoptionStickyArg:
1469 default:
1470 break;
1471 }
1472 }
1473 }
1474 #else
1475 extern void empty_trace(void);
1476 void
empty_trace(void)1477 empty_trace(void)
1478 {
1479 }
1480 #endif
1481