trace.c revision 956cc18d
1956cc18dSsnj/* $XTermId: trace.c,v 1.102 2009/07/03 13:57:08 tom Exp $ */
2d522f475Smrg
3d522f475Smrg/************************************************************
4d522f475Smrg
5956cc18dSsnjCopyright 1997-2008,2009 by Thomas E. Dickey
6d522f475Smrg
7d522f475Smrg                        All Rights Reserved
8d522f475Smrg
9d522f475SmrgPermission to use, copy, modify, and distribute this software and its
10d522f475Smrgdocumentation for any purpose and without fee is hereby granted,
11d522f475Smrgprovided that the above copyright notice appear in all copies and that
12d522f475Smrgboth that copyright notice and this permission notice appear in
13d522f475Smrgsupporting documentation, and that the name of the above listed
14d522f475Smrgcopyright holder(s) not be used in advertising or publicity pertaining
15d522f475Smrgto distribution of the software without specific, written prior
16d522f475Smrgpermission.
17d522f475Smrg
18d522f475SmrgTHE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
19d522f475SmrgTO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20d522f475SmrgAND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
21d522f475SmrgLIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22d522f475SmrgWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23d522f475SmrgACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
24d522f475SmrgOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25d522f475Smrg
26d522f475Smrg********************************************************/
27d522f475Smrg
28d522f475Smrg/*
29d522f475Smrg * debugging support via TRACE macro.
30d522f475Smrg */
31d522f475Smrg
32d522f475Smrg#include <xterm.h>		/* for definition of GCC_UNUSED */
33d522f475Smrg#include <data.h>
34d522f475Smrg#include <trace.h>
35d522f475Smrg
36d522f475Smrg#include <time.h>
37d522f475Smrg#include <stdlib.h>
38d522f475Smrg#include <unistd.h>
39d522f475Smrg#include <sys/types.h>
40d522f475Smrg#include <stdio.h>
41d522f475Smrg#include <stdarg.h>
42d522f475Smrg#include <assert.h>
43d522f475Smrg
44956cc18dSsnj#include <X11/Xatom.h>
45956cc18dSsnj#include <X11/Xmu/Atoms.h>
46956cc18dSsnj
47d522f475Smrg#ifdef HAVE_X11_TRANSLATEI_H
48d522f475Smrg#include <X11/TranslateI.h>
49d522f475Smrg#else
50d522f475Smrg#ifdef __cplusplus
51d522f475Smrgextern "C" {
52d522f475Smrg#endif
53d522f475Smrg
54d522f475Smrg    extern String _XtPrintXlations(Widget w,
55d522f475Smrg				   XtTranslations xlations,
56d522f475Smrg				   Widget accelWidget,
57d522f475Smrg				   _XtBoolean includeRHS);
58d522f475Smrg#ifdef __cplusplus
59d522f475Smrg}
60d522f475Smrg#endif
61d522f475Smrg#endif
62d522f475Smrgchar *trace_who = "parent";
63d522f475Smrg
64d522f475Smrgvoid
65d522f475SmrgTrace(const char *fmt,...)
66d522f475Smrg{
67d522f475Smrg    static FILE *fp;
68d522f475Smrg    static char *trace_out;
69d522f475Smrg    va_list ap;
70d522f475Smrg
71d522f475Smrg    if (fp != 0
72d522f475Smrg	&& trace_who != trace_out) {
73d522f475Smrg	fclose(fp);
74d522f475Smrg	fp = 0;
75d522f475Smrg    }
76d522f475Smrg    trace_out = trace_who;
77d522f475Smrg
78d522f475Smrg    if (!fp) {
79d522f475Smrg	char name[BUFSIZ];
80d522f475Smrg#if 0				/* usually I do not want unique names */
81d522f475Smrg	int unique;
82d522f475Smrg	for (unique = 0;; ++unique) {
83d522f475Smrg	    if (unique)
84d522f475Smrg		sprintf(name, "Trace-%s.out-%d", trace_who, unique);
85d522f475Smrg	    else
86d522f475Smrg		sprintf(name, "Trace-%s.out", trace_who);
87d522f475Smrg	    if ((fp = fopen(name, "r")) == 0) {
88d522f475Smrg		break;
89d522f475Smrg	    }
90d522f475Smrg	    fclose(fp);
91d522f475Smrg	}
92d522f475Smrg#else
93d522f475Smrg	sprintf(name, "Trace-%s.out", trace_who);
94d522f475Smrg#endif
95d522f475Smrg	fp = fopen(name, "w");
96d522f475Smrg	if (fp != 0) {
97d522f475Smrg	    fprintf(fp, "%s\n", xtermVersion());
98d522f475Smrg	    TraceIds(NULL, 0);
99d522f475Smrg	}
100d522f475Smrg    }
101d522f475Smrg    if (!fp)
102d522f475Smrg	abort();
103d522f475Smrg
104d522f475Smrg    va_start(ap, fmt);
105d522f475Smrg    if (fmt != 0) {
106d522f475Smrg	vfprintf(fp, fmt, ap);
107d522f475Smrg	(void) fflush(fp);
108d522f475Smrg    } else {
109d522f475Smrg	(void) fclose(fp);
110d522f475Smrg	(void) fflush(stdout);
111d522f475Smrg	(void) fflush(stderr);
112956cc18dSsnj	(void) visibleChars(NULL, 0);
113956cc18dSsnj	(void) visibleIChars(NULL, 0);
114956cc18dSsnj	(void) visibleIChar(NULL, 0);
115d522f475Smrg    }
116d522f475Smrg    va_end(ap);
117d522f475Smrg}
118d522f475Smrg
119d522f475Smrgvoid
120d522f475SmrgTraceIds(const char *fname, int lnum)
121d522f475Smrg{
122d522f475Smrg    Trace("process %d ", (int) getpid());
123d522f475Smrg#ifdef HAVE_UNISTD_H
124d522f475Smrg    Trace("real (%u/%u) effective (%u/%u)",
125d522f475Smrg	  (unsigned) getuid(), (unsigned) getgid(),
126d522f475Smrg	  (unsigned) geteuid(), (unsigned) getegid());
127d522f475Smrg#endif
128d522f475Smrg    if (fname != 0) {
129d522f475Smrg	Trace(" (%s@%d)\n", fname, lnum);
130d522f475Smrg    } else {
131d522f475Smrg	time_t now = time((time_t *) 0);
132d522f475Smrg	Trace("-- %s", ctime(&now));
133d522f475Smrg    }
134d522f475Smrg}
135d522f475Smrg
136d522f475Smrgstatic void
137d522f475SmrgformatAscii(char *dst, unsigned value)
138d522f475Smrg{
139d522f475Smrg    switch (value) {
140d522f475Smrg    case '\\':
141d522f475Smrg	sprintf(dst, "\\\\");
142d522f475Smrg	break;
143d522f475Smrg    case '\b':
144d522f475Smrg	sprintf(dst, "\\b");
145d522f475Smrg	break;
146d522f475Smrg    case '\n':
147d522f475Smrg	sprintf(dst, "\\n");
148d522f475Smrg	break;
149d522f475Smrg    case '\r':
150d522f475Smrg	sprintf(dst, "\\r");
151d522f475Smrg	break;
152d522f475Smrg    case '\t':
153d522f475Smrg	sprintf(dst, "\\t");
154d522f475Smrg	break;
155d522f475Smrg    default:
156d522f475Smrg	if (E2A(value) < 32 || (E2A(value) >= 127 && E2A(value) < 160))
157d522f475Smrg	    sprintf(dst, "\\%03o", value);
158d522f475Smrg	else
159d522f475Smrg	    sprintf(dst, "%c", CharOf(value));
160d522f475Smrg	break;
161d522f475Smrg    }
162d522f475Smrg}
163d522f475Smrg
164d522f475Smrg#if OPT_DEC_CHRSET
165d522f475Smrg
166d522f475Smrgconst char *
167956cc18dSsnjvisibleChrsetName(unsigned chrset)
168d522f475Smrg{
169d522f475Smrg    const char *result = "?";
170d522f475Smrg    switch (chrset) {
171d522f475Smrg    case CSET_SWL:
172d522f475Smrg	result = "CSET_SWL";
173d522f475Smrg	break;
174d522f475Smrg    case CSET_DHL_TOP:
175d522f475Smrg	result = "CSET_DHL_TOP";
176d522f475Smrg	break;
177d522f475Smrg    case CSET_DHL_BOT:
178d522f475Smrg	result = "CSET_DHL_BOT";
179d522f475Smrg	break;
180d522f475Smrg    case CSET_DWL:
181d522f475Smrg	result = "CSET_DWL";
182d522f475Smrg	break;
183d522f475Smrg    }
184d522f475Smrg    return result;
185d522f475Smrg}
186d522f475Smrg#endif
187d522f475Smrg
188d522f475Smrgchar *
189956cc18dSsnjvisibleChars(Char * buf, unsigned len)
190d522f475Smrg{
191d522f475Smrg    static char *result;
192d522f475Smrg    static unsigned used;
193d522f475Smrg
194956cc18dSsnj    if (buf != 0) {
195956cc18dSsnj	unsigned limit = ((len + 1) * 8) + 1;
196956cc18dSsnj	char *dst;
197956cc18dSsnj
198956cc18dSsnj	if (limit > used) {
199956cc18dSsnj	    used = limit;
200956cc18dSsnj	    result = XtRealloc(result, used);
201956cc18dSsnj	}
202956cc18dSsnj	dst = result;
203956cc18dSsnj	*dst = '\0';
204956cc18dSsnj	while (len--) {
205956cc18dSsnj	    unsigned value = *buf++;
206956cc18dSsnj	    formatAscii(dst, value);
207956cc18dSsnj	    dst += strlen(dst);
208956cc18dSsnj	}
209956cc18dSsnj    } else if (result != 0) {
210956cc18dSsnj	free(result);
211956cc18dSsnj	result = 0;
212956cc18dSsnj	used = 0;
213d522f475Smrg    }
214956cc18dSsnj    return result;
215956cc18dSsnj}
216956cc18dSsnj
217956cc18dSsnjchar *
218956cc18dSsnjvisibleIChars(IChar * buf, unsigned len)
219956cc18dSsnj{
220956cc18dSsnj    static char *result;
221956cc18dSsnj    static unsigned used;
222956cc18dSsnj
223956cc18dSsnj    if (buf != 0) {
224956cc18dSsnj	unsigned limit = ((len + 1) * 8) + 1;
225956cc18dSsnj	char *dst;
226956cc18dSsnj
227956cc18dSsnj	if (limit > used) {
228956cc18dSsnj	    used = limit;
229956cc18dSsnj	    result = XtRealloc(result, used);
230d522f475Smrg	}
231956cc18dSsnj	dst = result;
232956cc18dSsnj	*dst = '\0';
233956cc18dSsnj	while (len--) {
234956cc18dSsnj	    unsigned value = *buf++;
235956cc18dSsnj#if OPT_WIDE_CHARS
236956cc18dSsnj	    if (value > 255)
237956cc18dSsnj		sprintf(dst, "\\u+%04X", value);
238956cc18dSsnj	    else
239d522f475Smrg#endif
240956cc18dSsnj		formatAscii(dst, value);
241956cc18dSsnj	    dst += strlen(dst);
242956cc18dSsnj	}
243956cc18dSsnj    } else if (result != 0) {
244956cc18dSsnj	free(result);
245956cc18dSsnj	result = 0;
246956cc18dSsnj	used = 0;
247d522f475Smrg    }
248d522f475Smrg    return result;
249d522f475Smrg}
250d522f475Smrg
251d522f475Smrgchar *
252d522f475SmrgvisibleIChar(IChar * buf, unsigned len)
253d522f475Smrg{
254d522f475Smrg    static char *result;
255d522f475Smrg    static unsigned used;
256d522f475Smrg
257956cc18dSsnj    if (buf != 0) {
258956cc18dSsnj	unsigned limit = ((len + 1) * 6) + 1;
259956cc18dSsnj	char *dst;
260956cc18dSsnj
261956cc18dSsnj	if (limit > used) {
262956cc18dSsnj	    used = limit;
263956cc18dSsnj	    result = XtRealloc(result, used);
264956cc18dSsnj	}
265956cc18dSsnj	dst = result;
266956cc18dSsnj	while (len--) {
267956cc18dSsnj	    unsigned value = *buf++;
268d522f475Smrg#if OPT_WIDE_CHARS
269956cc18dSsnj	    if (value > 255)
270956cc18dSsnj		sprintf(dst, "\\u+%04X", value);
271956cc18dSsnj	    else
272d522f475Smrg#endif
273956cc18dSsnj		formatAscii(dst, value);
274956cc18dSsnj	    dst += strlen(dst);
275956cc18dSsnj	}
276956cc18dSsnj    } else if (result != 0) {
277956cc18dSsnj	free(result);
278956cc18dSsnj	result = 0;
279956cc18dSsnj	used = 0;
280d522f475Smrg    }
281d522f475Smrg    return result;
282d522f475Smrg}
283d522f475Smrg
284d522f475Smrg#define CASETYPE(name) case name: result = #name; break;
285d522f475Smrg
286d522f475Smrgconst char *
287d522f475SmrgvisibleKeyboardType(xtermKeyboardType type)
288d522f475Smrg{
289d522f475Smrg    const char *result = "?";
290d522f475Smrg    switch (type) {
291d522f475Smrg	CASETYPE(keyboardIsLegacy);	/* bogus vt220 codes for F1-F4, etc. */
292d522f475Smrg	CASETYPE(keyboardIsDefault);
293d522f475Smrg	CASETYPE(keyboardIsHP);
294d522f475Smrg	CASETYPE(keyboardIsSCO);
295d522f475Smrg	CASETYPE(keyboardIsSun);
296d522f475Smrg	CASETYPE(keyboardIsTermcap);
297d522f475Smrg	CASETYPE(keyboardIsVT220);
298d522f475Smrg    }
299d522f475Smrg    return result;
300d522f475Smrg}
301d522f475Smrg
302d522f475Smrgconst char *
303d522f475SmrgvisibleEventType(int type)
304d522f475Smrg{
305d522f475Smrg    const char *result = "?";
306d522f475Smrg    switch (type) {
307d522f475Smrg	CASETYPE(KeyPress);
308d522f475Smrg	CASETYPE(KeyRelease);
309d522f475Smrg	CASETYPE(ButtonPress);
310d522f475Smrg	CASETYPE(ButtonRelease);
311d522f475Smrg	CASETYPE(MotionNotify);
312d522f475Smrg	CASETYPE(EnterNotify);
313d522f475Smrg	CASETYPE(LeaveNotify);
314d522f475Smrg	CASETYPE(FocusIn);
315d522f475Smrg	CASETYPE(FocusOut);
316d522f475Smrg	CASETYPE(KeymapNotify);
317d522f475Smrg	CASETYPE(Expose);
318d522f475Smrg	CASETYPE(GraphicsExpose);
319d522f475Smrg	CASETYPE(NoExpose);
320d522f475Smrg	CASETYPE(VisibilityNotify);
321d522f475Smrg	CASETYPE(CreateNotify);
322d522f475Smrg	CASETYPE(DestroyNotify);
323d522f475Smrg	CASETYPE(UnmapNotify);
324d522f475Smrg	CASETYPE(MapNotify);
325d522f475Smrg	CASETYPE(MapRequest);
326d522f475Smrg	CASETYPE(ReparentNotify);
327d522f475Smrg	CASETYPE(ConfigureNotify);
328d522f475Smrg	CASETYPE(ConfigureRequest);
329d522f475Smrg	CASETYPE(GravityNotify);
330d522f475Smrg	CASETYPE(ResizeRequest);
331d522f475Smrg	CASETYPE(CirculateNotify);
332d522f475Smrg	CASETYPE(CirculateRequest);
333d522f475Smrg	CASETYPE(PropertyNotify);
334d522f475Smrg	CASETYPE(SelectionClear);
335d522f475Smrg	CASETYPE(SelectionRequest);
336d522f475Smrg	CASETYPE(SelectionNotify);
337d522f475Smrg	CASETYPE(ColormapNotify);
338d522f475Smrg	CASETYPE(ClientMessage);
339d522f475Smrg	CASETYPE(MappingNotify);
340d522f475Smrg    }
341d522f475Smrg    return result;
342d522f475Smrg}
343d522f475Smrg
344956cc18dSsnjconst char *
345956cc18dSsnjvisibleSelectionTarget(Display * d, Atom a)
346956cc18dSsnj{
347956cc18dSsnj    const char *result = "?";
348956cc18dSsnj
349956cc18dSsnj    if (a == XA_STRING) {
350956cc18dSsnj	result = "XA_STRING";
351956cc18dSsnj    } else if (a == XA_TEXT(d)) {
352956cc18dSsnj	result = "XA_TEXT()";
353956cc18dSsnj    } else if (a == XA_COMPOUND_TEXT(d)) {
354956cc18dSsnj	result = "XA_COMPOUND_TEXT()";
355956cc18dSsnj    } else if (a == XA_UTF8_STRING(d)) {
356956cc18dSsnj	result = "XA_UTF8_STRING()";
357956cc18dSsnj    } else if (a == XA_TARGETS(d)) {
358956cc18dSsnj	result = "XA_TARGETS()";
359956cc18dSsnj    }
360956cc18dSsnj
361956cc18dSsnj    return result;
362956cc18dSsnj}
363956cc18dSsnj
364d522f475Smrgconst char *
365d522f475SmrgvisibleXError(int code)
366d522f475Smrg{
367d522f475Smrg    static char temp[80];
368d522f475Smrg    const char *result = "?";
369d522f475Smrg    switch (code) {
370d522f475Smrg	CASETYPE(Success);
371d522f475Smrg	CASETYPE(BadRequest);
372d522f475Smrg	CASETYPE(BadValue);
373d522f475Smrg	CASETYPE(BadWindow);
374d522f475Smrg	CASETYPE(BadPixmap);
375d522f475Smrg	CASETYPE(BadAtom);
376d522f475Smrg	CASETYPE(BadCursor);
377d522f475Smrg	CASETYPE(BadFont);
378d522f475Smrg	CASETYPE(BadMatch);
379d522f475Smrg	CASETYPE(BadDrawable);
380d522f475Smrg	CASETYPE(BadAccess);
381d522f475Smrg	CASETYPE(BadAlloc);
382d522f475Smrg	CASETYPE(BadColor);
383d522f475Smrg	CASETYPE(BadGC);
384d522f475Smrg	CASETYPE(BadIDChoice);
385d522f475Smrg	CASETYPE(BadName);
386d522f475Smrg	CASETYPE(BadLength);
387d522f475Smrg	CASETYPE(BadImplementation);
388d522f475Smrg    default:
389d522f475Smrg	sprintf(temp, "%d", code);
390d522f475Smrg	result = temp;
391d522f475Smrg	break;
392d522f475Smrg    }
393d522f475Smrg    return result;
394d522f475Smrg}
395d522f475Smrg
396d522f475Smrg#if OPT_TRACE_FLAGS
397d522f475Smrg#define isScrnFlag(flag) ((flag) == LINEWRAPPED)
398d522f475Smrg
399d522f475Smrgstatic char *
400956cc18dSsnjScrnText(LineData * ld)
401d522f475Smrg{
402956cc18dSsnj    return visibleIChars(ld->charData, ld->lineSize);
403d522f475Smrg}
404d522f475Smrg
405956cc18dSsnj#define SHOW_BAD_LINE(name, ld) \
406956cc18dSsnj	Trace("OOPS " #name " bad row\n")
407d522f475Smrg
408d522f475Smrg#define SHOW_SCRN_FLAG(name,code) \
409956cc18dSsnj	Trace(#name " %s:%s\n", \
410d522f475Smrg	      code ? "*" : "", \
411956cc18dSsnj	      ScrnText(ld))
412d522f475Smrg
413d522f475Smrgvoid
414956cc18dSsnjLineClrFlag(LineData * ld, int flag)
415d522f475Smrg{
416956cc18dSsnj    if (ld == 0) {
417956cc18dSsnj	SHOW_BAD_LINE(LineClrFlag, ld);
418d522f475Smrg	assert(0);
419d522f475Smrg    } else if (isScrnFlag(flag)) {
420956cc18dSsnj	SHOW_SCRN_FLAG(LineClrFlag, 0);
421d522f475Smrg    }
422d522f475Smrg
423956cc18dSsnj    LineFlags(ld) &= ~flag;
424d522f475Smrg}
425d522f475Smrg
426d522f475Smrgvoid
427956cc18dSsnjLineSetFlag(LineData * ld, int flag)
428d522f475Smrg{
429956cc18dSsnj    if (ld == 0) {
430956cc18dSsnj	SHOW_BAD_LINE(LineSetFlag, ld);
431d522f475Smrg	assert(0);
432d522f475Smrg    } else if (isScrnFlag(flag)) {
433956cc18dSsnj	SHOW_SCRN_FLAG(LineSetFlag, 1);
434d522f475Smrg    }
435d522f475Smrg
436956cc18dSsnj    LineFlags(ld) |= flag;
437d522f475Smrg}
438d522f475Smrg
439d522f475Smrgint
440956cc18dSsnjLineTstFlag(LineData ld, int flag)
441d522f475Smrg{
442d522f475Smrg    int code = 0;
443956cc18dSsnj    if (ld == 0) {
444956cc18dSsnj	SHOW_BAD_LINE(LineTstFlag, ld);
445d522f475Smrg    } else {
446956cc18dSsnj	code = LineFlags(ld);
447956cc18dSsnj
448956cc18dSsnj	if (isScrnFlag(flag)) {
449956cc18dSsnj	    SHOW_SCRN_FLAG(LineTstFlag, code);
450d522f475Smrg	}
451d522f475Smrg    }
452d522f475Smrg    return code;
453d522f475Smrg}
454d522f475Smrg#endif /* OPT_TRACE_FLAGS */
455d522f475Smrg
456d522f475Smrgvoid
457d522f475SmrgTraceSizeHints(XSizeHints * hints)
458d522f475Smrg{
459d522f475Smrg    TRACE(("size hints:\n"));
460d522f475Smrg    if (hints->flags & (USPosition | PPosition))
461d522f475Smrg	TRACE(("   position   %d,%d%s%s\n", hints->y, hints->x,
462d522f475Smrg	       hints->flags & USPosition ? " user" : "",
463d522f475Smrg	       hints->flags & PPosition ? " prog" : ""));
464d522f475Smrg    if (hints->flags & (USSize | PSize))
465d522f475Smrg	TRACE(("   size       %d,%d%s%s\n", hints->height, hints->width,
466d522f475Smrg	       hints->flags & USSize ? " user" : "",
467d522f475Smrg	       hints->flags & PSize ? " prog" : ""));
468d522f475Smrg    if (hints->flags & PMinSize)
469d522f475Smrg	TRACE(("   min        %d,%d\n", hints->min_height, hints->min_width));
470d522f475Smrg    if (hints->flags & PMaxSize)
471d522f475Smrg	TRACE(("   max        %d,%d\n", hints->max_height, hints->max_width));
472d522f475Smrg    if (hints->flags & PResizeInc)
473d522f475Smrg	TRACE(("   inc        %d,%d\n", hints->height_inc, hints->width_inc));
4742eaa94a1Schristos    else
4752eaa94a1Schristos	TRACE(("   inc        NONE!\n"));
476d522f475Smrg    if (hints->flags & PAspect)
477d522f475Smrg	TRACE(("   min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y));
478d522f475Smrg    if (hints->flags & PAspect)
479d522f475Smrg	TRACE(("   max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y));
480d522f475Smrg    if (hints->flags & PBaseSize)
481d522f475Smrg	TRACE(("   base       %d,%d\n", hints->base_height, hints->base_width));
482d522f475Smrg    if (hints->flags & PWinGravity)
483d522f475Smrg	TRACE(("   gravity    %d\n", hints->win_gravity));
484d522f475Smrg}
485d522f475Smrg
486d522f475Smrgvoid
487d522f475SmrgTraceWMSizeHints(XtermWidget xw)
488d522f475Smrg{
489d522f475Smrg    XSizeHints sizehints = xw->hints;
490d522f475Smrg
491d522f475Smrg    getXtermSizeHints(xw);
492d522f475Smrg    TraceSizeHints(&xw->hints);
493d522f475Smrg    xw->hints = sizehints;
494d522f475Smrg}
495d522f475Smrg
496d522f475Smrg/*
497d522f475Smrg * Some calls to XGetAtom() will fail, and we don't want to stop.  So we use
498d522f475Smrg * our own error-handler.
499d522f475Smrg */
500d522f475Smrgstatic int
501d522f475Smrgno_error(Display * dpy GCC_UNUSED, XErrorEvent * event GCC_UNUSED)
502d522f475Smrg{
503d522f475Smrg    return 1;
504d522f475Smrg}
505d522f475Smrg
506d522f475Smrgvoid
507d522f475SmrgTraceTranslations(const char *name, Widget w)
508d522f475Smrg{
509d522f475Smrg    String result;
510d522f475Smrg    XErrorHandler save = XSetErrorHandler(no_error);
511d522f475Smrg    XtTranslations xlations;
512d522f475Smrg    Widget xcelerat;
513d522f475Smrg
514d522f475Smrg    TRACE(("TraceTranslations for %s (widget %#lx)\n", name, (long) w));
515d522f475Smrg    if (w) {
516d522f475Smrg	XtVaGetValues(w,
517d522f475Smrg		      XtNtranslations, &xlations,
518d522f475Smrg		      XtNaccelerators, &xcelerat,
519d522f475Smrg		      (XtPointer) 0);
520d522f475Smrg	TRACE(("... xlations %#08lx\n", (long) xlations));
521d522f475Smrg	TRACE(("... xcelerat %#08lx\n", (long) xcelerat));
522d522f475Smrg	result = _XtPrintXlations(w, xlations, xcelerat, True);
523d522f475Smrg	TRACE(("%s\n", result != 0 ? result : "(null)"));
524d522f475Smrg	if (result)
525d522f475Smrg	    XFree(result);
526d522f475Smrg    } else {
527d522f475Smrg	TRACE(("none (widget is null)\n"));
528d522f475Smrg    }
529d522f475Smrg    XSetErrorHandler(save);
530d522f475Smrg}
531d522f475Smrg
5322eaa94a1Schristosint
5332eaa94a1SchristosTraceResizeRequest(const char *fn, int ln, Widget w,
5342eaa94a1Schristos		   Dimension reqwide,
5352eaa94a1Schristos		   Dimension reqhigh,
5362eaa94a1Schristos		   Dimension * gotwide,
5372eaa94a1Schristos		   Dimension * gothigh)
5382eaa94a1Schristos{
5392eaa94a1Schristos    int rc;
5402eaa94a1Schristos
5412eaa94a1Schristos    TRACE(("%s@%d ResizeRequest %dx%d\n", fn, ln, reqhigh, reqwide));
5422eaa94a1Schristos    rc = XtMakeResizeRequest((Widget) w, reqwide, reqhigh, gotwide, gothigh);
5432eaa94a1Schristos    TRACE(("... ResizeRequest -> "));
5442eaa94a1Schristos    if (gothigh && gotwide)
5452eaa94a1Schristos	TRACE(("%dx%d ", *gothigh, *gotwide));
5462eaa94a1Schristos    TRACE(("(%d)\n", rc));
5472eaa94a1Schristos    return rc;
5482eaa94a1Schristos}
5492eaa94a1Schristos
550d522f475Smrg#define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name))
551d522f475Smrg#define XRES_B(name) Trace(#name " = %s\n", BtoS(resp->name))
552d522f475Smrg#define XRES_I(name) Trace(#name " = %d\n", resp->name)
553d522f475Smrg
554d522f475Smrgvoid
555d522f475SmrgTraceXtermResources(void)
556d522f475Smrg{
557d522f475Smrg    XTERM_RESOURCE *resp = &resource;
558d522f475Smrg
559d522f475Smrg    Trace("XTERM_RESOURCE settings:\n");
560d522f475Smrg    XRES_S(xterm_name);
561d522f475Smrg    XRES_S(icon_geometry);
562d522f475Smrg    XRES_S(title);
563d522f475Smrg    XRES_S(icon_name);
564d522f475Smrg    XRES_S(term_name);
565d522f475Smrg    XRES_S(tty_modes);
566d522f475Smrg    XRES_B(hold_screen);
567d522f475Smrg    XRES_B(utmpInhibit);
568d522f475Smrg    XRES_B(utmpDisplayId);
569d522f475Smrg    XRES_B(messages);
570d522f475Smrg#if OPT_SUNPC_KBD
571d522f475Smrg    XRES_B(sunKeyboard);
572d522f475Smrg#endif
573d522f475Smrg#if OPT_HP_FUNC_KEYS
574d522f475Smrg    XRES_B(hpFunctionKeys);
575d522f475Smrg#endif
576d522f475Smrg#if OPT_SCO_FUNC_KEYS
577d522f475Smrg    XRES_B(scoFunctionKeys);
578d522f475Smrg#endif
579d522f475Smrg#if OPT_SUN_FUNC_KEYS
580d522f475Smrg    XRES_B(sunFunctionKeys);
581d522f475Smrg#endif
582d522f475Smrg#if OPT_INITIAL_ERASE
583d522f475Smrg    XRES_B(ptyInitialErase);
584d522f475Smrg    XRES_B(backarrow_is_erase);
585d522f475Smrg#endif
586d522f475Smrg    XRES_B(useInsertMode);
587d522f475Smrg#if OPT_ZICONBEEP
588d522f475Smrg    XRES_I(zIconBeep);
589d522f475Smrg#endif
590d522f475Smrg#if OPT_PTY_HANDSHAKE
591d522f475Smrg    XRES_B(wait_for_map);
592d522f475Smrg    XRES_B(ptyHandshake);
593d522f475Smrg    XRES_B(ptySttySize);
594d522f475Smrg#endif
595d522f475Smrg#if OPT_SAME_NAME
596d522f475Smrg    XRES_B(sameName);
597d522f475Smrg#endif
598d522f475Smrg#if OPT_SESSION_MGT
599d522f475Smrg    XRES_B(sessionMgt);
600d522f475Smrg#endif
601d522f475Smrg}
602d522f475Smrg
603d522f475Smrgvoid
604d522f475SmrgTraceArgv(const char *tag, char **argv)
605d522f475Smrg{
606d522f475Smrg    int n = 0;
607d522f475Smrg
608d522f475Smrg    TRACE(("%s:\n", tag));
609d522f475Smrg    while (*argv != 0) {
610d522f475Smrg	TRACE(("  %d:%s\n", n++, *argv++));
611d522f475Smrg    }
612d522f475Smrg}
613d522f475Smrg
614d522f475Smrgstatic char *
615d522f475Smrgparse_option(char *dst, char *src, int first)
616d522f475Smrg{
617d522f475Smrg    char *s;
618d522f475Smrg
619d522f475Smrg    if (!strncmp(src, "-/+", 3)) {
620956cc18dSsnj	dst[0] = (char) first;
621d522f475Smrg	strcpy(dst + 1, src + 3);
622d522f475Smrg    } else {
623d522f475Smrg	strcpy(dst, src);
624d522f475Smrg    }
625d522f475Smrg    for (s = dst; *s != '\0'; s++) {
626d522f475Smrg	if (*s == '#' || *s == '%' || *s == 'S') {
627d522f475Smrg	    s[1] = '\0';
628d522f475Smrg	} else if (*s == ' ') {
629d522f475Smrg	    *s = '\0';
630d522f475Smrg	    break;
631d522f475Smrg	}
632d522f475Smrg    }
633d522f475Smrg    return dst;
634d522f475Smrg}
635d522f475Smrg
636d522f475Smrgstatic Bool
637d522f475Smrgsame_option(OptionHelp * opt, XrmOptionDescRec * res)
638d522f475Smrg{
639d522f475Smrg    char temp[BUFSIZ];
640d522f475Smrg    return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option);
641d522f475Smrg}
642d522f475Smrg
643d522f475Smrgstatic Bool
644d522f475Smrgstandard_option(char *opt)
645d522f475Smrg{
646d522f475Smrg    static const char *table[] =
647d522f475Smrg    {
648d522f475Smrg	"+rv",
649d522f475Smrg	"+synchronous",
650d522f475Smrg	"-background",
651d522f475Smrg	"-bd",
652d522f475Smrg	"-bg",
653d522f475Smrg	"-bordercolor",
654d522f475Smrg	"-borderwidth",
655d522f475Smrg	"-bw",
656d522f475Smrg	"-display",
657d522f475Smrg	"-fg",
658d522f475Smrg	"-fn",
659d522f475Smrg	"-font",
660d522f475Smrg	"-foreground",
661d522f475Smrg	"-geometry",
662d522f475Smrg	"-iconic",
663d522f475Smrg	"-name",
664d522f475Smrg	"-reverse",
665d522f475Smrg	"-rv",
666d522f475Smrg	"-selectionTimeout",
667d522f475Smrg	"-synchronous",
668d522f475Smrg	"-title",
669d522f475Smrg	"-xnllanguage",
670d522f475Smrg	"-xrm",
671d522f475Smrg	"-xtsessionID",
672d522f475Smrg    };
673d522f475Smrg    Cardinal n;
674d522f475Smrg    char temp[BUFSIZ];
675d522f475Smrg
676d522f475Smrg    opt = parse_option(temp, opt, '-');
677d522f475Smrg    for (n = 0; n < XtNumber(table); n++) {
678d522f475Smrg	if (!strcmp(opt, table[n]))
679d522f475Smrg	    return True;
680d522f475Smrg    }
681d522f475Smrg    return False;
682d522f475Smrg}
683d522f475Smrg
684d522f475Smrg/*
685d522f475Smrg * Analyse the options/help messages for inconsistencies.
686d522f475Smrg */
687d522f475Smrgvoid
688d522f475SmrgTraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count)
689d522f475Smrg{
690d522f475Smrg    OptionHelp *opt_array = sortedOpts(options, resources, res_count);
691d522f475Smrg    size_t j, k;
692d522f475Smrg    XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count);
693d522f475Smrg    Bool first, found;
694d522f475Smrg
695d522f475Smrg    TRACE(("Checking options-tables for inconsistencies:\n"));
696d522f475Smrg
697d522f475Smrg#if 0
698d522f475Smrg    TRACE(("Options listed in help-message:\n"));
699d522f475Smrg    for (j = 0; options[j].opt != 0; j++)
700d522f475Smrg	TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc));
701d522f475Smrg    TRACE(("Options listed in resource-table:\n"));
702d522f475Smrg    for (j = 0; j < res_count; j++)
703d522f475Smrg	TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier));
704d522f475Smrg#endif
705d522f475Smrg
706d522f475Smrg    /* list all options[] not found in resources[] */
707d522f475Smrg    for (j = 0, first = True; options[j].opt != 0; j++) {
708d522f475Smrg	found = False;
709d522f475Smrg	for (k = 0; k < res_count; k++) {
710d522f475Smrg	    if (same_option(&opt_array[j], &res_array[k])) {
711d522f475Smrg		found = True;
712d522f475Smrg		break;
713d522f475Smrg	    }
714d522f475Smrg	}
715d522f475Smrg	if (!found) {
716d522f475Smrg	    if (first) {
717d522f475Smrg		TRACE(("Options listed in help, not found in resource list:\n"));
718d522f475Smrg		first = False;
719d522f475Smrg	    }
720d522f475Smrg	    TRACE(("  %-28s%s\n", opt_array[j].opt,
721d522f475Smrg		   standard_option(opt_array[j].opt) ? " (standard)" : ""));
722d522f475Smrg	}
723d522f475Smrg    }
724d522f475Smrg
725d522f475Smrg    /* list all resources[] not found in options[] */
726d522f475Smrg    for (j = 0, first = True; j < res_count; j++) {
727d522f475Smrg	found = False;
728d522f475Smrg	for (k = 0; options[k].opt != 0; k++) {
729d522f475Smrg	    if (same_option(&opt_array[k], &res_array[j])) {
730d522f475Smrg		found = True;
731d522f475Smrg		break;
732d522f475Smrg	    }
733d522f475Smrg	}
734d522f475Smrg	if (!found) {
735d522f475Smrg	    if (first) {
736d522f475Smrg		TRACE(("Resource list items not found in options-help:\n"));
737d522f475Smrg		first = False;
738d522f475Smrg	    }
739d522f475Smrg	    TRACE(("  %s\n", res_array[j].option));
740d522f475Smrg	}
741d522f475Smrg    }
742d522f475Smrg
743d522f475Smrg    TRACE(("Resource list items that will be ignored by XtOpenApplication:\n"));
744d522f475Smrg    for (j = 0; j < res_count; j++) {
745d522f475Smrg	switch (res_array[j].argKind) {
746d522f475Smrg	case XrmoptionSkipArg:
747d522f475Smrg	    TRACE(("  %-28s {param}\n", res_array[j].option));
748d522f475Smrg	    break;
749d522f475Smrg	case XrmoptionSkipNArgs:
750d522f475Smrg	    TRACE(("  %-28s {%ld params}\n", res_array[j].option, (long)
751d522f475Smrg		   res_array[j].value));
752d522f475Smrg	    break;
753d522f475Smrg	case XrmoptionSkipLine:
754d522f475Smrg	    TRACE(("  %-28s {remainder of line}\n", res_array[j].option));
755d522f475Smrg	    break;
756d522f475Smrg	case XrmoptionIsArg:
757d522f475Smrg	case XrmoptionNoArg:
758d522f475Smrg	case XrmoptionResArg:
759d522f475Smrg	case XrmoptionSepArg:
760d522f475Smrg	case XrmoptionStickyArg:
761d522f475Smrg	default:
762d522f475Smrg	    break;
763d522f475Smrg	}
764d522f475Smrg    }
765d522f475Smrg}
766