trace.c revision 20d2c4d2
120d2c4d2Smrg/* $XTermId: trace.c,v 1.115 2010/06/15 22:40:28 tom Exp $ */
2d522f475Smrg
320d2c4d2Smrg/*
420d2c4d2Smrg *
520d2c4d2Smrg * Copyright 1997-2009,2010 by Thomas E. Dickey
620d2c4d2Smrg *
720d2c4d2Smrg *                         All Rights Reserved
820d2c4d2Smrg *
920d2c4d2Smrg * Permission is hereby granted, free of charge, to any person obtaining a
1020d2c4d2Smrg * copy of this software and associated documentation files (the
1120d2c4d2Smrg * "Software"), to deal in the Software without restriction, including
1220d2c4d2Smrg * without limitation the rights to use, copy, modify, merge, publish,
1320d2c4d2Smrg * distribute, sublicense, and/or sell copies of the Software, and to
1420d2c4d2Smrg * permit persons to whom the Software is furnished to do so, subject to
1520d2c4d2Smrg * the following conditions:
1620d2c4d2Smrg *
1720d2c4d2Smrg * The above copyright notice and this permission notice shall be included
1820d2c4d2Smrg * in all copies or substantial portions of the Software.
1920d2c4d2Smrg *
2020d2c4d2Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2120d2c4d2Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2220d2c4d2Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2320d2c4d2Smrg * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
2420d2c4d2Smrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2520d2c4d2Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2620d2c4d2Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2720d2c4d2Smrg *
2820d2c4d2Smrg * Except as contained in this notice, the name(s) of the above copyright
2920d2c4d2Smrg * holders shall not be used in advertising or otherwise to promote the
3020d2c4d2Smrg * sale, use or other dealings in this Software without prior written
3120d2c4d2Smrg * authorization.
3220d2c4d2Smrg *
3320d2c4d2Smrg */
34d522f475Smrg
35d522f475Smrg/*
36d522f475Smrg * debugging support via TRACE macro.
37d522f475Smrg */
38d522f475Smrg
39d522f475Smrg#include <xterm.h>		/* for definition of GCC_UNUSED */
40d522f475Smrg#include <data.h>
41d522f475Smrg#include <trace.h>
42d522f475Smrg
43d522f475Smrg#include <time.h>
44d522f475Smrg#include <stdlib.h>
45d522f475Smrg#include <unistd.h>
46d522f475Smrg#include <sys/types.h>
47d522f475Smrg#include <stdio.h>
48d522f475Smrg#include <stdarg.h>
49d522f475Smrg#include <assert.h>
50d522f475Smrg
51956cc18dSsnj#include <X11/Xatom.h>
52956cc18dSsnj#include <X11/Xmu/Atoms.h>
53956cc18dSsnj
54d522f475Smrg#ifdef HAVE_X11_TRANSLATEI_H
55d522f475Smrg#include <X11/TranslateI.h>
56d522f475Smrg#else
57d522f475Smrg#ifdef __cplusplus
58d522f475Smrgextern "C" {
59d522f475Smrg#endif
60d522f475Smrg
61d522f475Smrg    extern String _XtPrintXlations(Widget w,
62d522f475Smrg				   XtTranslations xlations,
63d522f475Smrg				   Widget accelWidget,
64d522f475Smrg				   _XtBoolean includeRHS);
65d522f475Smrg#ifdef __cplusplus
66d522f475Smrg}
67d522f475Smrg#endif
68d522f475Smrg#endif
6920d2c4d2Smrgconst char *trace_who = "parent";
7020d2c4d2Smrg
7120d2c4d2Smrgstatic FILE *trace_fp;
72d522f475Smrg
73d522f475Smrgvoid
74d522f475SmrgTrace(const char *fmt,...)
75d522f475Smrg{
7620d2c4d2Smrg    static const char *trace_out;
77d522f475Smrg    va_list ap;
78d522f475Smrg
7920d2c4d2Smrg    if (trace_fp != 0
80d522f475Smrg	&& trace_who != trace_out) {
8120d2c4d2Smrg	fclose(trace_fp);
8220d2c4d2Smrg	trace_fp = 0;
83d522f475Smrg    }
84d522f475Smrg    trace_out = trace_who;
85d522f475Smrg
8620d2c4d2Smrg    if (!trace_fp) {
87d522f475Smrg	char name[BUFSIZ];
88d522f475Smrg#if 0				/* usually I do not want unique names */
89d522f475Smrg	int unique;
90d522f475Smrg	for (unique = 0;; ++unique) {
91d522f475Smrg	    if (unique)
92d522f475Smrg		sprintf(name, "Trace-%s.out-%d", trace_who, unique);
93d522f475Smrg	    else
94d522f475Smrg		sprintf(name, "Trace-%s.out", trace_who);
9520d2c4d2Smrg	    if ((trace_fp = fopen(name, "r")) == 0) {
96d522f475Smrg		break;
97d522f475Smrg	    }
9820d2c4d2Smrg	    fclose(trace_fp);
99d522f475Smrg	}
100d522f475Smrg#else
101d522f475Smrg	sprintf(name, "Trace-%s.out", trace_who);
102d522f475Smrg#endif
10320d2c4d2Smrg	trace_fp = fopen(name, "w");
10420d2c4d2Smrg	if (trace_fp != 0) {
10520d2c4d2Smrg	    fprintf(trace_fp, "%s\n", xtermVersion());
106d522f475Smrg	    TraceIds(NULL, 0);
107d522f475Smrg	}
108d522f475Smrg    }
10920d2c4d2Smrg    if (!trace_fp)
110d522f475Smrg	abort();
111d522f475Smrg
112d522f475Smrg    va_start(ap, fmt);
11320d2c4d2Smrg    vfprintf(trace_fp, fmt, ap);
11420d2c4d2Smrg    (void) fflush(trace_fp);
11520d2c4d2Smrg    va_end(ap);
11620d2c4d2Smrg}
11720d2c4d2Smrg
11820d2c4d2Smrgvoid
11920d2c4d2SmrgTraceClose(void)
12020d2c4d2Smrg{
12120d2c4d2Smrg    if (trace_fp != 0) {
12220d2c4d2Smrg	(void) fclose(trace_fp);
123d522f475Smrg	(void) fflush(stdout);
124d522f475Smrg	(void) fflush(stderr);
125956cc18dSsnj	(void) visibleChars(NULL, 0);
126956cc18dSsnj	(void) visibleIChars(NULL, 0);
127956cc18dSsnj	(void) visibleIChar(NULL, 0);
12820d2c4d2Smrg	trace_fp = 0;
129d522f475Smrg    }
130d522f475Smrg}
131d522f475Smrg
132d522f475Smrgvoid
133d522f475SmrgTraceIds(const char *fname, int lnum)
134d522f475Smrg{
135d522f475Smrg    Trace("process %d ", (int) getpid());
136d522f475Smrg#ifdef HAVE_UNISTD_H
137d522f475Smrg    Trace("real (%u/%u) effective (%u/%u)",
138d522f475Smrg	  (unsigned) getuid(), (unsigned) getgid(),
139d522f475Smrg	  (unsigned) geteuid(), (unsigned) getegid());
140d522f475Smrg#endif
141d522f475Smrg    if (fname != 0) {
142d522f475Smrg	Trace(" (%s@%d)\n", fname, lnum);
143d522f475Smrg    } else {
144d522f475Smrg	time_t now = time((time_t *) 0);
145d522f475Smrg	Trace("-- %s", ctime(&now));
146d522f475Smrg    }
147d522f475Smrg}
148d522f475Smrg
149d522f475Smrgstatic void
150d522f475SmrgformatAscii(char *dst, unsigned value)
151d522f475Smrg{
152d522f475Smrg    switch (value) {
153d522f475Smrg    case '\\':
154d522f475Smrg	sprintf(dst, "\\\\");
155d522f475Smrg	break;
156d522f475Smrg    case '\b':
157d522f475Smrg	sprintf(dst, "\\b");
158d522f475Smrg	break;
159d522f475Smrg    case '\n':
160d522f475Smrg	sprintf(dst, "\\n");
161d522f475Smrg	break;
162d522f475Smrg    case '\r':
163d522f475Smrg	sprintf(dst, "\\r");
164d522f475Smrg	break;
165d522f475Smrg    case '\t':
166d522f475Smrg	sprintf(dst, "\\t");
167d522f475Smrg	break;
168d522f475Smrg    default:
169d522f475Smrg	if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160))
170d522f475Smrg	    sprintf(dst, "\\%03o", value);
171d522f475Smrg	else
172d522f475Smrg	    sprintf(dst, "%c", CharOf(value));
173d522f475Smrg	break;
174d522f475Smrg    }
175d522f475Smrg}
176d522f475Smrg
177d522f475Smrg#if OPT_DEC_CHRSET
178d522f475Smrg
179d522f475Smrgconst char *
180956cc18dSsnjvisibleChrsetName(unsigned chrset)
181d522f475Smrg{
182d522f475Smrg    const char *result = "?";
183d522f475Smrg    switch (chrset) {
184d522f475Smrg    case CSET_SWL:
185d522f475Smrg	result = "CSET_SWL";
186d522f475Smrg	break;
187d522f475Smrg    case CSET_DHL_TOP:
188d522f475Smrg	result = "CSET_DHL_TOP";
189d522f475Smrg	break;
190d522f475Smrg    case CSET_DHL_BOT:
191d522f475Smrg	result = "CSET_DHL_BOT";
192d522f475Smrg	break;
193d522f475Smrg    case CSET_DWL:
194d522f475Smrg	result = "CSET_DWL";
195d522f475Smrg	break;
196d522f475Smrg    }
197d522f475Smrg    return result;
198d522f475Smrg}
199d522f475Smrg#endif
200d522f475Smrg
201d522f475Smrgchar *
20220d2c4d2SmrgvisibleChars(const Char * buf, unsigned len)
203d522f475Smrg{
204d522f475Smrg    static char *result;
205d522f475Smrg    static unsigned used;
206d522f475Smrg
207956cc18dSsnj    if (buf != 0) {
208956cc18dSsnj	unsigned limit = ((len + 1) * 8) + 1;
209956cc18dSsnj	char *dst;
210956cc18dSsnj
211956cc18dSsnj	if (limit > used) {
212956cc18dSsnj	    used = limit;
213956cc18dSsnj	    result = XtRealloc(result, used);
214956cc18dSsnj	}
21520d2c4d2Smrg	if (result != 0) {
21620d2c4d2Smrg	    dst = result;
21720d2c4d2Smrg	    *dst = '\0';
21820d2c4d2Smrg	    while (len--) {
21920d2c4d2Smrg		unsigned value = *buf++;
22020d2c4d2Smrg		formatAscii(dst, value);
22120d2c4d2Smrg		dst += strlen(dst);
22220d2c4d2Smrg	    }
223956cc18dSsnj	}
224956cc18dSsnj    } else if (result != 0) {
225956cc18dSsnj	free(result);
226956cc18dSsnj	result = 0;
227956cc18dSsnj	used = 0;
228d522f475Smrg    }
229956cc18dSsnj    return result;
230956cc18dSsnj}
231956cc18dSsnj
232956cc18dSsnjchar *
233956cc18dSsnjvisibleIChars(IChar * buf, unsigned len)
234956cc18dSsnj{
235956cc18dSsnj    static char *result;
236956cc18dSsnj    static unsigned used;
237956cc18dSsnj
238956cc18dSsnj    if (buf != 0) {
239956cc18dSsnj	unsigned limit = ((len + 1) * 8) + 1;
240956cc18dSsnj	char *dst;
241956cc18dSsnj
242956cc18dSsnj	if (limit > used) {
243956cc18dSsnj	    used = limit;
244956cc18dSsnj	    result = XtRealloc(result, used);
245d522f475Smrg	}
24620d2c4d2Smrg	if (result != 0) {
24720d2c4d2Smrg	    dst = result;
24820d2c4d2Smrg	    *dst = '\0';
24920d2c4d2Smrg	    while (len--) {
25020d2c4d2Smrg		unsigned value = *buf++;
251956cc18dSsnj#if OPT_WIDE_CHARS
25220d2c4d2Smrg		if (value > 255)
25320d2c4d2Smrg		    sprintf(dst, "\\u+%04X", value);
25420d2c4d2Smrg		else
255d522f475Smrg#endif
25620d2c4d2Smrg		    formatAscii(dst, value);
25720d2c4d2Smrg		dst += strlen(dst);
25820d2c4d2Smrg	    }
259956cc18dSsnj	}
260956cc18dSsnj    } else if (result != 0) {
261956cc18dSsnj	free(result);
262956cc18dSsnj	result = 0;
263956cc18dSsnj	used = 0;
264d522f475Smrg    }
265d522f475Smrg    return result;
266d522f475Smrg}
267d522f475Smrg
268d522f475Smrgchar *
269d522f475SmrgvisibleIChar(IChar * buf, unsigned len)
270d522f475Smrg{
271d522f475Smrg    static char *result;
272d522f475Smrg    static unsigned used;
273d522f475Smrg
274956cc18dSsnj    if (buf != 0) {
27520d2c4d2Smrg	unsigned limit = ((len + 1) * 8) + 1;
276956cc18dSsnj	char *dst;
277956cc18dSsnj
278956cc18dSsnj	if (limit > used) {
279956cc18dSsnj	    used = limit;
280956cc18dSsnj	    result = XtRealloc(result, used);
281956cc18dSsnj	}
28220d2c4d2Smrg	if (result != 0) {
28320d2c4d2Smrg	    dst = result;
28420d2c4d2Smrg	    while (len--) {
28520d2c4d2Smrg		unsigned value = *buf++;
286d522f475Smrg#if OPT_WIDE_CHARS
28720d2c4d2Smrg		if (value > 255)
28820d2c4d2Smrg		    sprintf(dst, "\\u+%04X", value);
28920d2c4d2Smrg		else
290d522f475Smrg#endif
29120d2c4d2Smrg		    formatAscii(dst, value);
29220d2c4d2Smrg		dst += strlen(dst);
29320d2c4d2Smrg	    }
294956cc18dSsnj	}
295956cc18dSsnj    } else if (result != 0) {
296956cc18dSsnj	free(result);
297956cc18dSsnj	result = 0;
298956cc18dSsnj	used = 0;
299d522f475Smrg    }
300d522f475Smrg    return result;
301d522f475Smrg}
302d522f475Smrg
303d522f475Smrg#define CASETYPE(name) case name: result = #name; break;
304d522f475Smrg
305d522f475Smrgconst char *
306d522f475SmrgvisibleKeyboardType(xtermKeyboardType type)
307d522f475Smrg{
308d522f475Smrg    const char *result = "?";
309d522f475Smrg    switch (type) {
310d522f475Smrg	CASETYPE(keyboardIsLegacy);	/* bogus vt220 codes for F1-F4, etc. */
311d522f475Smrg	CASETYPE(keyboardIsDefault);
312d522f475Smrg	CASETYPE(keyboardIsHP);
313d522f475Smrg	CASETYPE(keyboardIsSCO);
314d522f475Smrg	CASETYPE(keyboardIsSun);
315d522f475Smrg	CASETYPE(keyboardIsTermcap);
316d522f475Smrg	CASETYPE(keyboardIsVT220);
317d522f475Smrg    }
318d522f475Smrg    return result;
319d522f475Smrg}
320d522f475Smrg
321d522f475Smrgconst char *
322d522f475SmrgvisibleEventType(int type)
323d522f475Smrg{
324d522f475Smrg    const char *result = "?";
325d522f475Smrg    switch (type) {
326d522f475Smrg	CASETYPE(KeyPress);
327d522f475Smrg	CASETYPE(KeyRelease);
328d522f475Smrg	CASETYPE(ButtonPress);
329d522f475Smrg	CASETYPE(ButtonRelease);
330d522f475Smrg	CASETYPE(MotionNotify);
331d522f475Smrg	CASETYPE(EnterNotify);
332d522f475Smrg	CASETYPE(LeaveNotify);
333d522f475Smrg	CASETYPE(FocusIn);
334d522f475Smrg	CASETYPE(FocusOut);
335d522f475Smrg	CASETYPE(KeymapNotify);
336d522f475Smrg	CASETYPE(Expose);
337d522f475Smrg	CASETYPE(GraphicsExpose);
338d522f475Smrg	CASETYPE(NoExpose);
339d522f475Smrg	CASETYPE(VisibilityNotify);
340d522f475Smrg	CASETYPE(CreateNotify);
341d522f475Smrg	CASETYPE(DestroyNotify);
342d522f475Smrg	CASETYPE(UnmapNotify);
343d522f475Smrg	CASETYPE(MapNotify);
344d522f475Smrg	CASETYPE(MapRequest);
345d522f475Smrg	CASETYPE(ReparentNotify);
346d522f475Smrg	CASETYPE(ConfigureNotify);
347d522f475Smrg	CASETYPE(ConfigureRequest);
348d522f475Smrg	CASETYPE(GravityNotify);
349d522f475Smrg	CASETYPE(ResizeRequest);
350d522f475Smrg	CASETYPE(CirculateNotify);
351d522f475Smrg	CASETYPE(CirculateRequest);
352d522f475Smrg	CASETYPE(PropertyNotify);
353d522f475Smrg	CASETYPE(SelectionClear);
354d522f475Smrg	CASETYPE(SelectionRequest);
355d522f475Smrg	CASETYPE(SelectionNotify);
356d522f475Smrg	CASETYPE(ColormapNotify);
357d522f475Smrg	CASETYPE(ClientMessage);
358d522f475Smrg	CASETYPE(MappingNotify);
359d522f475Smrg    }
360d522f475Smrg    return result;
361d522f475Smrg}
362d522f475Smrg
36320d2c4d2Smrgconst char *
36420d2c4d2SmrgvisibleNotifyDetail(int code)
36520d2c4d2Smrg{
36620d2c4d2Smrg    const char *result = "?";
36720d2c4d2Smrg    switch (code) {
36820d2c4d2Smrg	CASETYPE(NotifyAncestor);
36920d2c4d2Smrg	CASETYPE(NotifyVirtual);
37020d2c4d2Smrg	CASETYPE(NotifyInferior);
37120d2c4d2Smrg	CASETYPE(NotifyNonlinear);
37220d2c4d2Smrg	CASETYPE(NotifyNonlinearVirtual);
37320d2c4d2Smrg	CASETYPE(NotifyPointer);
37420d2c4d2Smrg	CASETYPE(NotifyPointerRoot);
37520d2c4d2Smrg	CASETYPE(NotifyDetailNone);
37620d2c4d2Smrg    }
37720d2c4d2Smrg    return result;
37820d2c4d2Smrg}
37920d2c4d2Smrg
380956cc18dSsnjconst char *
381956cc18dSsnjvisibleSelectionTarget(Display * d, Atom a)
382956cc18dSsnj{
383956cc18dSsnj    const char *result = "?";
384956cc18dSsnj
385956cc18dSsnj    if (a == XA_STRING) {
386956cc18dSsnj	result = "XA_STRING";
387956cc18dSsnj    } else if (a == XA_TEXT(d)) {
388956cc18dSsnj	result = "XA_TEXT()";
389956cc18dSsnj    } else if (a == XA_COMPOUND_TEXT(d)) {
390956cc18dSsnj	result = "XA_COMPOUND_TEXT()";
391956cc18dSsnj    } else if (a == XA_UTF8_STRING(d)) {
392956cc18dSsnj	result = "XA_UTF8_STRING()";
393956cc18dSsnj    } else if (a == XA_TARGETS(d)) {
394956cc18dSsnj	result = "XA_TARGETS()";
395956cc18dSsnj    }
396956cc18dSsnj
397956cc18dSsnj    return result;
398956cc18dSsnj}
399956cc18dSsnj
400d522f475Smrgconst char *
401d522f475SmrgvisibleXError(int code)
402d522f475Smrg{
403d522f475Smrg    static char temp[80];
404d522f475Smrg    const char *result = "?";
405d522f475Smrg    switch (code) {
406d522f475Smrg	CASETYPE(Success);
407d522f475Smrg	CASETYPE(BadRequest);
408d522f475Smrg	CASETYPE(BadValue);
409d522f475Smrg	CASETYPE(BadWindow);
410d522f475Smrg	CASETYPE(BadPixmap);
411d522f475Smrg	CASETYPE(BadAtom);
412d522f475Smrg	CASETYPE(BadCursor);
413d522f475Smrg	CASETYPE(BadFont);
414d522f475Smrg	CASETYPE(BadMatch);
415d522f475Smrg	CASETYPE(BadDrawable);
416d522f475Smrg	CASETYPE(BadAccess);
417d522f475Smrg	CASETYPE(BadAlloc);
418d522f475Smrg	CASETYPE(BadColor);
419d522f475Smrg	CASETYPE(BadGC);
420d522f475Smrg	CASETYPE(BadIDChoice);
421d522f475Smrg	CASETYPE(BadName);
422d522f475Smrg	CASETYPE(BadLength);
423d522f475Smrg	CASETYPE(BadImplementation);
424d522f475Smrg    default:
425d522f475Smrg	sprintf(temp, "%d", code);
426d522f475Smrg	result = temp;
427d522f475Smrg	break;
428d522f475Smrg    }
429d522f475Smrg    return result;
430d522f475Smrg}
431d522f475Smrg
432d522f475Smrg#if OPT_TRACE_FLAGS
433d522f475Smrg#define isScrnFlag(flag) ((flag) == LINEWRAPPED)
434d522f475Smrg
435d522f475Smrgstatic char *
436956cc18dSsnjScrnText(LineData * ld)
437d522f475Smrg{
438956cc18dSsnj    return visibleIChars(ld->charData, ld->lineSize);
439d522f475Smrg}
440d522f475Smrg
441956cc18dSsnj#define SHOW_BAD_LINE(name, ld) \
442956cc18dSsnj	Trace("OOPS " #name " bad row\n")
443d522f475Smrg
444d522f475Smrg#define SHOW_SCRN_FLAG(name,code) \
445956cc18dSsnj	Trace(#name " %s:%s\n", \
446d522f475Smrg	      code ? "*" : "", \
447956cc18dSsnj	      ScrnText(ld))
448d522f475Smrg
449d522f475Smrgvoid
450956cc18dSsnjLineClrFlag(LineData * ld, int flag)
451d522f475Smrg{
452956cc18dSsnj    if (ld == 0) {
453956cc18dSsnj	SHOW_BAD_LINE(LineClrFlag, ld);
454d522f475Smrg	assert(0);
455d522f475Smrg    } else if (isScrnFlag(flag)) {
456956cc18dSsnj	SHOW_SCRN_FLAG(LineClrFlag, 0);
457d522f475Smrg    }
458d522f475Smrg
459956cc18dSsnj    LineFlags(ld) &= ~flag;
460d522f475Smrg}
461d522f475Smrg
462d522f475Smrgvoid
463956cc18dSsnjLineSetFlag(LineData * ld, int flag)
464d522f475Smrg{
465956cc18dSsnj    if (ld == 0) {
466956cc18dSsnj	SHOW_BAD_LINE(LineSetFlag, ld);
467d522f475Smrg	assert(0);
468d522f475Smrg    } else if (isScrnFlag(flag)) {
469956cc18dSsnj	SHOW_SCRN_FLAG(LineSetFlag, 1);
470d522f475Smrg    }
471d522f475Smrg
472956cc18dSsnj    LineFlags(ld) |= flag;
473d522f475Smrg}
474d522f475Smrg
475d522f475Smrgint
476956cc18dSsnjLineTstFlag(LineData ld, int flag)
477d522f475Smrg{
478d522f475Smrg    int code = 0;
479956cc18dSsnj    if (ld == 0) {
480956cc18dSsnj	SHOW_BAD_LINE(LineTstFlag, ld);
481d522f475Smrg    } else {
482956cc18dSsnj	code = LineFlags(ld);
483956cc18dSsnj
484956cc18dSsnj	if (isScrnFlag(flag)) {
485956cc18dSsnj	    SHOW_SCRN_FLAG(LineTstFlag, code);
486d522f475Smrg	}
487d522f475Smrg    }
488d522f475Smrg    return code;
489d522f475Smrg}
490d522f475Smrg#endif /* OPT_TRACE_FLAGS */
491d522f475Smrg
49220d2c4d2Smrgvoid
49320d2c4d2SmrgTraceFocus(Widget w, XEvent * ev)
49420d2c4d2Smrg{
49520d2c4d2Smrg    TRACE(("trace_focus event type %d:%s\n",
49620d2c4d2Smrg	   ev->type, visibleEventType(ev->type)));
49720d2c4d2Smrg    switch (ev->type) {
49820d2c4d2Smrg    case FocusIn:
49920d2c4d2Smrg    case FocusOut:
50020d2c4d2Smrg	{
50120d2c4d2Smrg	    XFocusChangeEvent *event = (XFocusChangeEvent *) ev;
50220d2c4d2Smrg	    TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail)));
50320d2c4d2Smrg	    TRACE(("\tmode:   %d\n", event->mode));
50420d2c4d2Smrg	    TRACE(("\twindow: %#lx\n", event->window));
50520d2c4d2Smrg	}
50620d2c4d2Smrg	break;
50720d2c4d2Smrg    case EnterNotify:
50820d2c4d2Smrg    case LeaveNotify:
50920d2c4d2Smrg	{
51020d2c4d2Smrg	    XCrossingEvent *event = (XCrossingEvent *) ev;
51120d2c4d2Smrg	    TRACE(("\tdetail:    %s\n", visibleNotifyDetail(event->detail)));
51220d2c4d2Smrg	    TRACE(("\tmode:      %d\n", event->mode));
51320d2c4d2Smrg	    TRACE(("\twindow:    %#lx\n", event->window));
51420d2c4d2Smrg	    TRACE(("\troot:      %#lx\n", event->root));
51520d2c4d2Smrg	    TRACE(("\tsubwindow: %#lx\n", event->subwindow));
51620d2c4d2Smrg	}
51720d2c4d2Smrg	break;
51820d2c4d2Smrg    }
51920d2c4d2Smrg    while (w != 0) {
52020d2c4d2Smrg	TRACE(("w %p -> %#lx\n", (void *) w, XtWindow(w)));
52120d2c4d2Smrg	w = XtParent(w);
52220d2c4d2Smrg    }
52320d2c4d2Smrg}
52420d2c4d2Smrg
525d522f475Smrgvoid
526d522f475SmrgTraceSizeHints(XSizeHints * hints)
527d522f475Smrg{
528d522f475Smrg    TRACE(("size hints:\n"));
529d522f475Smrg    if (hints->flags & (USPosition | PPosition))
530d522f475Smrg	TRACE(("   position   %d,%d%s%s\n", hints->y, hints->x,
531d522f475Smrg	       hints->flags & USPosition ? " user" : "",
532d522f475Smrg	       hints->flags & PPosition ? " prog" : ""));
533d522f475Smrg    if (hints->flags & (USSize | PSize))
534d522f475Smrg	TRACE(("   size       %d,%d%s%s\n", hints->height, hints->width,
535d522f475Smrg	       hints->flags & USSize ? " user" : "",
536d522f475Smrg	       hints->flags & PSize ? " prog" : ""));
537d522f475Smrg    if (hints->flags & PMinSize)
538d522f475Smrg	TRACE(("   min        %d,%d\n", hints->min_height, hints->min_width));
539d522f475Smrg    if (hints->flags & PMaxSize)
540d522f475Smrg	TRACE(("   max        %d,%d\n", hints->max_height, hints->max_width));
541d522f475Smrg    if (hints->flags & PResizeInc)
542d522f475Smrg	TRACE(("   inc        %d,%d\n", hints->height_inc, hints->width_inc));
5432eaa94a1Schristos    else
5442eaa94a1Schristos	TRACE(("   inc        NONE!\n"));
545d522f475Smrg    if (hints->flags & PAspect)
546d522f475Smrg	TRACE(("   min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y));
547d522f475Smrg    if (hints->flags & PAspect)
548d522f475Smrg	TRACE(("   max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y));
549d522f475Smrg    if (hints->flags & PBaseSize)
550d522f475Smrg	TRACE(("   base       %d,%d\n", hints->base_height, hints->base_width));
551d522f475Smrg    if (hints->flags & PWinGravity)
552d522f475Smrg	TRACE(("   gravity    %d\n", hints->win_gravity));
553d522f475Smrg}
554d522f475Smrg
555d522f475Smrgvoid
556d522f475SmrgTraceWMSizeHints(XtermWidget xw)
557d522f475Smrg{
558d522f475Smrg    XSizeHints sizehints = xw->hints;
559d522f475Smrg
560d522f475Smrg    getXtermSizeHints(xw);
561d522f475Smrg    TraceSizeHints(&xw->hints);
562d522f475Smrg    xw->hints = sizehints;
563d522f475Smrg}
564d522f475Smrg
565d522f475Smrg/*
566d522f475Smrg * Some calls to XGetAtom() will fail, and we don't want to stop.  So we use
567d522f475Smrg * our own error-handler.
568d522f475Smrg */
569d522f475Smrgstatic int
570d522f475Smrgno_error(Display * dpy GCC_UNUSED, XErrorEvent * event GCC_UNUSED)
571d522f475Smrg{
572d522f475Smrg    return 1;
573d522f475Smrg}
574d522f475Smrg
575d522f475Smrgvoid
576d522f475SmrgTraceTranslations(const char *name, Widget w)
577d522f475Smrg{
578d522f475Smrg    String result;
579d522f475Smrg    XErrorHandler save = XSetErrorHandler(no_error);
580d522f475Smrg    XtTranslations xlations;
581d522f475Smrg    Widget xcelerat;
582d522f475Smrg
58320d2c4d2Smrg    TRACE(("TraceTranslations for %s (widget %#lx) {{\n", name, (long) w));
584d522f475Smrg    if (w) {
585d522f475Smrg	XtVaGetValues(w,
586d522f475Smrg		      XtNtranslations, &xlations,
587d522f475Smrg		      XtNaccelerators, &xcelerat,
588d522f475Smrg		      (XtPointer) 0);
589d522f475Smrg	TRACE(("... xlations %#08lx\n", (long) xlations));
590d522f475Smrg	TRACE(("... xcelerat %#08lx\n", (long) xcelerat));
591d522f475Smrg	result = _XtPrintXlations(w, xlations, xcelerat, True);
59220d2c4d2Smrg	TRACE(("%s\n", NonNull(result)));
593d522f475Smrg	if (result)
59420d2c4d2Smrg	    XFree((char *) result);
595d522f475Smrg    } else {
596d522f475Smrg	TRACE(("none (widget is null)\n"));
597d522f475Smrg    }
59820d2c4d2Smrg    TRACE(("}}\n"));
599d522f475Smrg    XSetErrorHandler(save);
600d522f475Smrg}
601d522f475Smrg
6022eaa94a1Schristosint
6032eaa94a1SchristosTraceResizeRequest(const char *fn, int ln, Widget w,
6042eaa94a1Schristos		   Dimension reqwide,
6052eaa94a1Schristos		   Dimension reqhigh,
6062eaa94a1Schristos		   Dimension * gotwide,
6072eaa94a1Schristos		   Dimension * gothigh)
6082eaa94a1Schristos{
6092eaa94a1Schristos    int rc;
6102eaa94a1Schristos
6112eaa94a1Schristos    TRACE(("%s@%d ResizeRequest %dx%d\n", fn, ln, reqhigh, reqwide));
6122eaa94a1Schristos    rc = XtMakeResizeRequest((Widget) w, reqwide, reqhigh, gotwide, gothigh);
6132eaa94a1Schristos    TRACE(("... ResizeRequest -> "));
6142eaa94a1Schristos    if (gothigh && gotwide)
6152eaa94a1Schristos	TRACE(("%dx%d ", *gothigh, *gotwide));
6162eaa94a1Schristos    TRACE(("(%d)\n", rc));
6172eaa94a1Schristos    return rc;
6182eaa94a1Schristos}
6192eaa94a1Schristos
620d522f475Smrg#define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name))
621d522f475Smrg#define XRES_B(name) Trace(#name " = %s\n", BtoS(resp->name))
622d522f475Smrg#define XRES_I(name) Trace(#name " = %d\n", resp->name)
623d522f475Smrg
624d522f475Smrgvoid
625d522f475SmrgTraceXtermResources(void)
626d522f475Smrg{
627d522f475Smrg    XTERM_RESOURCE *resp = &resource;
628d522f475Smrg
629d522f475Smrg    Trace("XTERM_RESOURCE settings:\n");
630d522f475Smrg    XRES_S(xterm_name);
631d522f475Smrg    XRES_S(icon_geometry);
632d522f475Smrg    XRES_S(title);
633d522f475Smrg    XRES_S(icon_name);
634d522f475Smrg    XRES_S(term_name);
635d522f475Smrg    XRES_S(tty_modes);
636d522f475Smrg    XRES_B(hold_screen);
637d522f475Smrg    XRES_B(utmpInhibit);
638d522f475Smrg    XRES_B(utmpDisplayId);
639d522f475Smrg    XRES_B(messages);
640d522f475Smrg#if OPT_SUNPC_KBD
641d522f475Smrg    XRES_B(sunKeyboard);
642d522f475Smrg#endif
643d522f475Smrg#if OPT_HP_FUNC_KEYS
644d522f475Smrg    XRES_B(hpFunctionKeys);
645d522f475Smrg#endif
646d522f475Smrg#if OPT_SCO_FUNC_KEYS
647d522f475Smrg    XRES_B(scoFunctionKeys);
648d522f475Smrg#endif
649d522f475Smrg#if OPT_SUN_FUNC_KEYS
650d522f475Smrg    XRES_B(sunFunctionKeys);
651d522f475Smrg#endif
652d522f475Smrg#if OPT_INITIAL_ERASE
653d522f475Smrg    XRES_B(ptyInitialErase);
654d522f475Smrg    XRES_B(backarrow_is_erase);
655d522f475Smrg#endif
656d522f475Smrg    XRES_B(useInsertMode);
657d522f475Smrg#if OPT_ZICONBEEP
658d522f475Smrg    XRES_I(zIconBeep);
659d522f475Smrg#endif
660d522f475Smrg#if OPT_PTY_HANDSHAKE
661d522f475Smrg    XRES_B(wait_for_map);
662d522f475Smrg    XRES_B(ptyHandshake);
663d522f475Smrg    XRES_B(ptySttySize);
664d522f475Smrg#endif
665d522f475Smrg#if OPT_SAME_NAME
666d522f475Smrg    XRES_B(sameName);
667d522f475Smrg#endif
668d522f475Smrg#if OPT_SESSION_MGT
669d522f475Smrg    XRES_B(sessionMgt);
670d522f475Smrg#endif
671d522f475Smrg}
672d522f475Smrg
673d522f475Smrgvoid
674d522f475SmrgTraceArgv(const char *tag, char **argv)
675d522f475Smrg{
676d522f475Smrg    int n = 0;
677d522f475Smrg
678d522f475Smrg    TRACE(("%s:\n", tag));
679d522f475Smrg    while (*argv != 0) {
680d522f475Smrg	TRACE(("  %d:%s\n", n++, *argv++));
681d522f475Smrg    }
682d522f475Smrg}
683d522f475Smrg
684d522f475Smrgstatic char *
68520d2c4d2Smrgparse_option(char *dst, String src, int first)
686d522f475Smrg{
687d522f475Smrg    char *s;
688d522f475Smrg
689d522f475Smrg    if (!strncmp(src, "-/+", 3)) {
690956cc18dSsnj	dst[0] = (char) first;
691d522f475Smrg	strcpy(dst + 1, src + 3);
692d522f475Smrg    } else {
693d522f475Smrg	strcpy(dst, src);
694d522f475Smrg    }
695d522f475Smrg    for (s = dst; *s != '\0'; s++) {
696d522f475Smrg	if (*s == '#' || *s == '%' || *s == 'S') {
697d522f475Smrg	    s[1] = '\0';
698d522f475Smrg	} else if (*s == ' ') {
699d522f475Smrg	    *s = '\0';
700d522f475Smrg	    break;
701d522f475Smrg	}
702d522f475Smrg    }
703d522f475Smrg    return dst;
704d522f475Smrg}
705d522f475Smrg
706d522f475Smrgstatic Bool
707d522f475Smrgsame_option(OptionHelp * opt, XrmOptionDescRec * res)
708d522f475Smrg{
709d522f475Smrg    char temp[BUFSIZ];
710d522f475Smrg    return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option);
711d522f475Smrg}
712d522f475Smrg
713d522f475Smrgstatic Bool
71420d2c4d2Smrgstandard_option(String opt)
715d522f475Smrg{
716d522f475Smrg    static const char *table[] =
717d522f475Smrg    {
718d522f475Smrg	"+rv",
719d522f475Smrg	"+synchronous",
720d522f475Smrg	"-background",
721d522f475Smrg	"-bd",
722d522f475Smrg	"-bg",
723d522f475Smrg	"-bordercolor",
724d522f475Smrg	"-borderwidth",
725d522f475Smrg	"-bw",
726d522f475Smrg	"-display",
727d522f475Smrg	"-fg",
728d522f475Smrg	"-fn",
729d522f475Smrg	"-font",
730d522f475Smrg	"-foreground",
731d522f475Smrg	"-geometry",
732d522f475Smrg	"-iconic",
733d522f475Smrg	"-name",
734d522f475Smrg	"-reverse",
735d522f475Smrg	"-rv",
736d522f475Smrg	"-selectionTimeout",
737d522f475Smrg	"-synchronous",
738d522f475Smrg	"-title",
739d522f475Smrg	"-xnllanguage",
740d522f475Smrg	"-xrm",
741d522f475Smrg	"-xtsessionID",
742d522f475Smrg    };
743d522f475Smrg    Cardinal n;
744d522f475Smrg    char temp[BUFSIZ];
745d522f475Smrg
746d522f475Smrg    opt = parse_option(temp, opt, '-');
747d522f475Smrg    for (n = 0; n < XtNumber(table); n++) {
748d522f475Smrg	if (!strcmp(opt, table[n]))
749d522f475Smrg	    return True;
750d522f475Smrg    }
751d522f475Smrg    return False;
752d522f475Smrg}
753d522f475Smrg
754d522f475Smrg/*
755d522f475Smrg * Analyse the options/help messages for inconsistencies.
756d522f475Smrg */
757d522f475Smrgvoid
758d522f475SmrgTraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count)
759d522f475Smrg{
760d522f475Smrg    OptionHelp *opt_array = sortedOpts(options, resources, res_count);
761d522f475Smrg    size_t j, k;
762d522f475Smrg    XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count);
763d522f475Smrg    Bool first, found;
764d522f475Smrg
765d522f475Smrg    TRACE(("Checking options-tables for inconsistencies:\n"));
766d522f475Smrg
767d522f475Smrg#if 0
768d522f475Smrg    TRACE(("Options listed in help-message:\n"));
769d522f475Smrg    for (j = 0; options[j].opt != 0; j++)
770d522f475Smrg	TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc));
771d522f475Smrg    TRACE(("Options listed in resource-table:\n"));
772d522f475Smrg    for (j = 0; j < res_count; j++)
773d522f475Smrg	TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier));
774d522f475Smrg#endif
775d522f475Smrg
776d522f475Smrg    /* list all options[] not found in resources[] */
777d522f475Smrg    for (j = 0, first = True; options[j].opt != 0; j++) {
778d522f475Smrg	found = False;
779d522f475Smrg	for (k = 0; k < res_count; k++) {
780d522f475Smrg	    if (same_option(&opt_array[j], &res_array[k])) {
781d522f475Smrg		found = True;
782d522f475Smrg		break;
783d522f475Smrg	    }
784d522f475Smrg	}
785d522f475Smrg	if (!found) {
786d522f475Smrg	    if (first) {
787d522f475Smrg		TRACE(("Options listed in help, not found in resource list:\n"));
788d522f475Smrg		first = False;
789d522f475Smrg	    }
790d522f475Smrg	    TRACE(("  %-28s%s\n", opt_array[j].opt,
791d522f475Smrg		   standard_option(opt_array[j].opt) ? " (standard)" : ""));
792d522f475Smrg	}
793d522f475Smrg    }
794d522f475Smrg
795d522f475Smrg    /* list all resources[] not found in options[] */
796d522f475Smrg    for (j = 0, first = True; j < res_count; j++) {
797d522f475Smrg	found = False;
798d522f475Smrg	for (k = 0; options[k].opt != 0; k++) {
799d522f475Smrg	    if (same_option(&opt_array[k], &res_array[j])) {
800d522f475Smrg		found = True;
801d522f475Smrg		break;
802d522f475Smrg	    }
803d522f475Smrg	}
804d522f475Smrg	if (!found) {
805d522f475Smrg	    if (first) {
806d522f475Smrg		TRACE(("Resource list items not found in options-help:\n"));
807d522f475Smrg		first = False;
808d522f475Smrg	    }
809d522f475Smrg	    TRACE(("  %s\n", res_array[j].option));
810d522f475Smrg	}
811d522f475Smrg    }
812d522f475Smrg
813d522f475Smrg    TRACE(("Resource list items that will be ignored by XtOpenApplication:\n"));
814d522f475Smrg    for (j = 0; j < res_count; j++) {
815d522f475Smrg	switch (res_array[j].argKind) {
816d522f475Smrg	case XrmoptionSkipArg:
817d522f475Smrg	    TRACE(("  %-28s {param}\n", res_array[j].option));
818d522f475Smrg	    break;
819d522f475Smrg	case XrmoptionSkipNArgs:
820d522f475Smrg	    TRACE(("  %-28s {%ld params}\n", res_array[j].option, (long)
821d522f475Smrg		   res_array[j].value));
822d522f475Smrg	    break;
823d522f475Smrg	case XrmoptionSkipLine:
824d522f475Smrg	    TRACE(("  %-28s {remainder of line}\n", res_array[j].option));
825d522f475Smrg	    break;
826d522f475Smrg	case XrmoptionIsArg:
827d522f475Smrg	case XrmoptionNoArg:
828d522f475Smrg	case XrmoptionResArg:
829d522f475Smrg	case XrmoptionSepArg:
830d522f475Smrg	case XrmoptionStickyArg:
831d522f475Smrg	default:
832d522f475Smrg	    break;
833d522f475Smrg	}
834d522f475Smrg    }
835d522f475Smrg}
836