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