printevent.c (21469B)
1 /* 2 * Original code posted to comp.sources.x 3 * Modifications by Russ Cox <rsc@swtch.com>. 4 * Further modifications by Kris Maglione <maglione.k at Gmail> 5 */ 6 7 /* 8 * Path: uunet!wyse!mikew From: mikew@wyse.wyse.com (Mike Wexler) Newsgroups: 9 * comp.sources.x Subject: v02i056: subroutine to print events in human 10 * readable form, Part01/01 Message-ID: <1935@wyse.wyse.com> Date: 22 Dec 88 11 * 19:28:25 GMT Organization: Wyse Technology, San Jose Lines: 1093 Approved: 12 * mikew@wyse.com 13 * 14 * Submitted-by: richsun!darkstar!ken Posting-number: Volume 2, Issue 56 15 * Archive-name: showevent/part01 16 * 17 * 18 * There are times during debugging when it would be real useful to be able to 19 * print the fields of an event in a human readable form. Too many times I 20 * found myself scrounging around in section 8 of the Xlib manual looking for 21 * the valid fields for the events I wanted to see, then adding printf's to 22 * display the numeric values of the fields, and then scanning through X.h 23 * trying to decode the cryptic detail and state fields. After playing with 24 * xev, I decided to write a couple of standard functions that I could keep 25 * in a library and call on whenever I needed a little debugging verbosity. 26 * The first function, GetType(), is useful for returning the string 27 * representation of the type of an event. The second function, ShowEvent(), 28 * is used to display all the fields of an event in a readable format. The 29 * functions are not complicated, in fact, they are mind-numbingly boring - 30 * but that's just the point nobody wants to spend the time writing functions 31 * like this, they just want to have them when they need them. 32 * 33 * A simple, sample program is included which does little else but to 34 * demonstrate the use of these two functions. These functions have saved me 35 * many an hour during debugging and I hope you find some benefit to these. 36 * If you have any comments, suggestions, improvements, or if you find any 37 * blithering errors you can get it touch with me at the following location: 38 * 39 * ken@richsun.UUCP 40 */ 41 42 #include <stdarg.h> 43 #include <bio.h> 44 #include <stuff/x.h> 45 #include <stuff/util.h> 46 #include "printevent.h" 47 #define Window XWindow 48 #define unmask _unmask 49 50 #define nil ((void*)0) 51 52 typedef struct Pair Pair; 53 54 struct Pair { 55 int key; 56 char *val; 57 }; 58 59 static char* sep = " "; 60 61 static char * 62 search(Pair *lst, int key, char *(*def)(int)) { 63 for(; lst->val; lst++) 64 if(lst->key == key) 65 return lst->val; 66 return def(key); 67 } 68 69 static char* 70 unmask(Pair *list, uint val) 71 { 72 Pair *p; 73 char *s, *end; 74 int n; 75 76 buffer[0] = '\0'; 77 end = buffer + sizeof buffer; 78 s = buffer; 79 80 n = 0; 81 s = utfecpy(s, end, "("); 82 for (p = list; p->val; p++) 83 if (val & p->key) { 84 if(n++) 85 s = utfecpy(s, end, "|"); 86 s = utfecpy(s, end, p->val); 87 } 88 utfecpy(s, end, ")"); 89 90 return buffer; 91 } 92 93 static char * 94 strhex(int key) { 95 sprint(buffer, "0x%x", key); 96 return buffer; 97 } 98 99 static char * 100 strdec(int key) { 101 sprint(buffer, "%d", key); 102 return buffer; 103 } 104 105 static char * 106 strign(int key) { 107 USED(key); 108 109 return "?"; 110 } 111 112 /******************************************************************************/ 113 /**** Miscellaneous routines to convert values to their string equivalents ****/ 114 /******************************************************************************/ 115 116 static void 117 TInt(Fmt *b, va_list *ap) { 118 fmtprint(b, "%d", va_arg(*ap, int)); 119 } 120 121 static void 122 TWindow(Fmt *b, va_list *ap) { 123 Window w; 124 125 w = va_arg(*ap, Window); 126 fmtprint(b, "0x%ux", (uint)w); 127 } 128 129 static void 130 TData(Fmt *b, va_list *ap) { 131 long *l; 132 int i; 133 134 l = va_arg(*ap, long*); 135 fmtprint(b, "{"); 136 for (i = 0; i < 5; i++) { 137 if(i > 0) 138 fmtprint(b, ", "); 139 fmtprint(b, "0x%08lx", l[i]); 140 } 141 fmtprint(b, "}"); 142 } 143 144 /* Returns the string equivalent of a timestamp */ 145 static void 146 TTime(Fmt *b, va_list *ap) { 147 ldiv_t d; 148 ulong msec; 149 ulong sec; 150 ulong min; 151 ulong hr; 152 ulong day; 153 Time time; 154 155 time = va_arg(*ap, Time); 156 157 msec = time/1000; 158 d = ldiv(msec, 60); 159 msec = time-msec*1000; 160 161 sec = d.rem; 162 d = ldiv(d.quot, 60); 163 min = d.rem; 164 d = ldiv(d.quot, 24); 165 hr = d.rem; 166 day = d.quot; 167 168 #ifdef notdef 169 sprintf(buffer, "%lu day%s %02lu:%02lu:%02lu.%03lu", 170 day, day == 1 ? "" : "(s)", hr, min, sec, msec); 171 #endif 172 173 fmtprint(b, "%ludd_%ludh_%ludm_%lud.%03luds", day, hr, min, sec, msec); 174 } 175 176 /* Returns the string equivalent of a boolean parameter */ 177 static void 178 TBool(Fmt *b, va_list *ap) { 179 static Pair list[] = { 180 {True, "True"}, 181 {False, "False"}, 182 {0, nil}, 183 }; 184 Bool key; 185 186 key = va_arg(*ap, Bool); 187 fmtprint(b, "%s", search(list, key, strign)); 188 } 189 190 /* Returns the string equivalent of a property notify state */ 191 static void 192 TPropState(Fmt *b, va_list *ap) { 193 static Pair list[] = { 194 {PropertyNewValue, "PropertyNewValue"}, 195 {PropertyDelete, "PropertyDelete"}, 196 {0, nil}, 197 }; 198 uint key; 199 200 key = va_arg(*ap, uint); 201 fmtprint(b, "%s", search(list, key, strign)); 202 } 203 204 /* Returns the string equivalent of a visibility notify state */ 205 static void 206 TVis(Fmt *b, va_list *ap) { 207 static Pair list[] = { 208 {VisibilityUnobscured, "VisibilityUnobscured"}, 209 {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"}, 210 {VisibilityFullyObscured, "VisibilityFullyObscured"}, 211 {0, nil}, 212 }; 213 int key; 214 215 key = va_arg(*ap, int); 216 fmtprint(b, "%s", search(list, key, strign)); 217 } 218 219 /* Returns the string equivalent of a mask of buttons and/or modifier keys */ 220 static void 221 TModState(Fmt *b, va_list *ap) { 222 static Pair list[] = { 223 {Button1Mask, "Button1Mask"}, 224 {Button2Mask, "Button2Mask"}, 225 {Button3Mask, "Button3Mask"}, 226 {Button4Mask, "Button4Mask"}, 227 {Button5Mask, "Button5Mask"}, 228 {ShiftMask, "ShiftMask"}, 229 {LockMask, "LockMask"}, 230 {ControlMask, "ControlMask"}, 231 {Mod1Mask, "Mod1Mask"}, 232 {Mod2Mask, "Mod2Mask"}, 233 {Mod3Mask, "Mod3Mask"}, 234 {Mod4Mask, "Mod4Mask"}, 235 {Mod5Mask, "Mod5Mask"}, 236 {0, nil}, 237 }; 238 uint state; 239 240 state = va_arg(*ap, uint); 241 fmtprint(b, "%s", unmask(list, state)); 242 } 243 244 /* Returns the string equivalent of a mask of configure window values */ 245 static void 246 TConfMask(Fmt *b, va_list *ap) { 247 static Pair list[] = { 248 {CWX, "CWX"}, 249 {CWY, "CWY"}, 250 {CWWidth, "CWWidth"}, 251 {CWHeight, "CWHeight"}, 252 {CWBorderWidth, "CWBorderWidth"}, 253 {CWSibling, "CWSibling"}, 254 {CWStackMode, "CWStackMode"}, 255 {0, nil}, 256 }; 257 uint valuemask; 258 259 valuemask = va_arg(*ap, uint); 260 fmtprint(b, "%s", unmask(list, valuemask)); 261 } 262 263 /* Returns the string equivalent of a motion hint */ 264 #if 0 265 static void 266 IsHint(Fmt *b, va_list *ap) { 267 static Pair list[] = { 268 {NotifyNormal, "NotifyNormal"}, 269 {NotifyHint, "NotifyHint"}, 270 {0, nil}, 271 }; 272 char key; 273 274 key = va_arg(*ap, char); 275 fmtprint(b, "%s", search(list, key, strign)); 276 } 277 #endif 278 279 /* Returns the string equivalent of an id or the value "None" */ 280 static void 281 TIntNone(Fmt *b, va_list *ap) { 282 static Pair list[] = { 283 {None, "None"}, 284 {0, nil}, 285 }; 286 int key; 287 288 key = va_arg(*ap, int); 289 fmtprint(b, "%s", search(list, key, strhex)); 290 } 291 292 /* Returns the string equivalent of a colormap state */ 293 static void 294 TColMap(Fmt *b, va_list *ap) { 295 static Pair list[] = { 296 {ColormapInstalled, "ColormapInstalled"}, 297 {ColormapUninstalled, "ColormapUninstalled"}, 298 {0, nil}, 299 }; 300 int key; 301 302 key = va_arg(*ap, int); 303 fmtprint(b, "%s", search(list, key, strign)); 304 } 305 306 /* Returns the string equivalent of a crossing detail */ 307 static void 308 TXing(Fmt *b, va_list *ap) { 309 static Pair list[] = { 310 {NotifyAncestor, "NotifyAncestor"}, 311 {NotifyInferior, "NotifyInferior"}, 312 {NotifyVirtual, "NotifyVirtual"}, 313 {NotifyNonlinear, "NotifyNonlinear"}, 314 {NotifyNonlinearVirtual, "NotifyNonlinearVirtual"}, 315 {0, nil}, 316 }; 317 int key; 318 319 key = va_arg(*ap, int); 320 fmtprint(b, "%s", search(list, key, strign)); 321 } 322 323 /* Returns the string equivalent of a focus change detail */ 324 static void 325 TFocus(Fmt *b, va_list *ap) { 326 static Pair list[] = { 327 {NotifyAncestor, "NotifyAncestor"}, 328 {NotifyInferior, "NotifyInferior"}, 329 {NotifyVirtual, "NotifyVirtual"}, 330 {NotifyNonlinear, "NotifyNonlinear"}, 331 {NotifyNonlinearVirtual, "NotifyNonlinearVirtual"}, 332 {NotifyPointer, "NotifyPointer"}, 333 {NotifyPointerRoot, "NotifyPointerRoot"}, 334 {NotifyDetailNone, "NotifyDetailNone"}, 335 {0, nil}, 336 }; 337 int key; 338 339 key = va_arg(*ap, int); 340 fmtprint(b, "%s", search(list, key, strign)); 341 } 342 343 /* Returns the string equivalent of a configure detail */ 344 static void 345 TConfDetail(Fmt *b, va_list *ap) { 346 static Pair list[] = { 347 {Above, "Above"}, 348 {Below, "Below"}, 349 {TopIf, "TopIf"}, 350 {BottomIf, "BottomIf"}, 351 {Opposite, "Opposite"}, 352 {0, nil}, 353 }; 354 int key; 355 356 key = va_arg(*ap, int); 357 fmtprint(b, "%s", search(list, key, strign)); 358 } 359 360 /* Returns the string equivalent of a grab mode */ 361 static void 362 TGrabMode(Fmt *b, va_list *ap) { 363 static Pair list[] = { 364 {NotifyNormal, "NotifyNormal"}, 365 {NotifyGrab, "NotifyGrab"}, 366 {NotifyUngrab, "NotifyUngrab"}, 367 {NotifyWhileGrabbed, "NotifyWhileGrabbed"}, 368 {0, nil}, 369 }; 370 int key; 371 372 key = va_arg(*ap, int); 373 fmtprint(b, "%s", search(list, key, strign)); 374 } 375 376 /* Returns the string equivalent of a mapping request */ 377 static void 378 TMapping(Fmt *b, va_list *ap) { 379 static Pair list[] = { 380 {MappingModifier, "MappingModifier"}, 381 {MappingKeyboard, "MappingKeyboard"}, 382 {MappingPointer, "MappingPointer"}, 383 {0, nil}, 384 }; 385 int key; 386 387 key = va_arg(*ap, int); 388 fmtprint(b, "%s", search(list, key, strign)); 389 } 390 391 /* Returns the string equivalent of a stacking order place */ 392 static void 393 TPlace(Fmt *b, va_list *ap) { 394 static Pair list[] = { 395 {PlaceOnTop, "PlaceOnTop"}, 396 {PlaceOnBottom, "PlaceOnBottom"}, 397 {0, nil}, 398 }; 399 int key; 400 401 key = va_arg(*ap, int); 402 fmtprint(b, "%s", search(list, key, strign)); 403 } 404 405 /* Returns the string equivalent of a major code */ 406 static void 407 TMajor(Fmt *b, va_list *ap) { 408 static char *list[] = { XMajors }; 409 char *s; 410 uint key; 411 412 key = va_arg(*ap, uint); 413 s = "<nil>"; 414 if(key < nelem(list)) 415 s = list[key]; 416 fmtprint(b, "%s", s); 417 } 418 419 static char* 420 eventtype(int key) { 421 static Pair list[] = { 422 {ButtonPress, "ButtonPress"}, 423 {ButtonRelease, "ButtonRelease"}, 424 {CirculateNotify, "CirculateNotify"}, 425 {CirculateRequest, "CirculateRequest"}, 426 {ClientMessage, "ClientMessage"}, 427 {ColormapNotify, "ColormapNotify"}, 428 {ConfigureNotify, "ConfigureNotify"}, 429 {ConfigureRequest, "ConfigureRequest"}, 430 {CreateNotify, "CreateNotify"}, 431 {DestroyNotify, "DestroyNotify"}, 432 {EnterNotify, "EnterNotify"}, 433 {Expose, "Expose"}, 434 {FocusIn, "FocusIn"}, 435 {FocusOut, "FocusOut"}, 436 {GraphicsExpose, "GraphicsExpose"}, 437 {GravityNotify, "GravityNotify"}, 438 {KeyPress, "KeyPress"}, 439 {KeyRelease, "KeyRelease"}, 440 {KeymapNotify, "KeymapNotify"}, 441 {LeaveNotify, "LeaveNotify"}, 442 {MapNotify, "MapNotify"}, 443 {MapRequest, "MapRequest"}, 444 {MappingNotify, "MappingNotify"}, 445 {MotionNotify, "MotionNotify"}, 446 {NoExpose, "NoExpose"}, 447 {PropertyNotify, "PropertyNotify"}, 448 {ReparentNotify, "ReparentNotify"}, 449 {ResizeRequest, "ResizeRequest"}, 450 {SelectionClear, "SelectionClear"}, 451 {SelectionNotify, "SelectionNotify"}, 452 {SelectionRequest, "SelectionRequest"}, 453 {UnmapNotify, "UnmapNotify"}, 454 {VisibilityNotify, "VisibilityNotify"}, 455 {0, nil}, 456 }; 457 return search(list, key, strdec); 458 } 459 /* Returns the string equivalent the keycode contained in the key event */ 460 static void 461 TKeycode(Fmt *b, va_list *ap) { 462 KeySym keysym_str; 463 XKeyEvent *ev; 464 char *keysym_name; 465 466 ev = va_arg(*ap, XKeyEvent*); 467 468 XLookupString(ev, buffer, sizeof buffer, &keysym_str, nil); 469 470 if (keysym_str == NoSymbol) 471 keysym_name = "NoSymbol"; 472 else 473 keysym_name = XKeysymToString(keysym_str); 474 if(keysym_name == nil) 475 keysym_name = "(no name)"; 476 477 fmtprint(b, "%ud (keysym 0x%x \"%s\")", (int)ev->keycode, 478 (int)keysym_str, keysym_name); 479 } 480 481 /* Returns the string equivalent of an atom or "None" */ 482 static void 483 TAtom(Fmt *b, va_list *ap) { 484 485 fmtstrcpy(b, atomname(va_arg(*ap, Atom))); 486 } 487 488 #define _(m) #m, ev->m 489 #define TEnd nil 490 typedef void (*Tfn)(Fmt*, va_list*); 491 492 static int 493 pevent(Fmt *fmt, void *e, ...) { 494 va_list ap; 495 Tfn fn; 496 XAnyEvent *ev; 497 char *key; 498 int n; 499 500 ev = e; 501 fmtprint(fmt, "%3ld %-20s ", ev->serial, eventtype(ev->type)); 502 if(ev->send_event) 503 fmtstrcpy(fmt, "(sendevent) "); 504 505 n = 0; 506 va_start(ap, e); 507 for(;;) { 508 fn = va_arg(ap, Tfn); 509 if(fn == TEnd) 510 break; 511 512 if(n++ != 0) 513 fmtprint(fmt, "%s", sep); 514 515 key = va_arg(ap, char*); 516 fmtprint(fmt, "%s=", key); 517 fn(fmt, &ap); 518 } 519 va_end(ap); 520 return 0; 521 } 522 523 /*****************************************************************************/ 524 /*** Routines to print out readable values for the field of various events ***/ 525 /*****************************************************************************/ 526 527 static int 528 VerbMotion(Fmt *fmt, XEvent *e) { 529 XMotionEvent *ev = &e->xmotion; 530 531 return pevent(fmt, ev, 532 TWindow, _(window), 533 TWindow, _(root), 534 TWindow, _(subwindow), 535 TTime, _(time), 536 TInt, _(x), TInt, _(y), 537 TInt, _(x_root), TInt, _(y_root), 538 TModState, _(state), 539 TBool, _(same_screen), 540 TEnd 541 ); 542 //fprintf(stderr, "is_hint=%s%s", IsHint(ev->is_hint), sep); 543 } 544 545 static int 546 VerbButton(Fmt *fmt, XEvent *e) { 547 XButtonEvent *ev = &e->xbutton; 548 549 return pevent(fmt, ev, 550 TWindow, _(window), 551 TWindow, _(root), 552 TWindow, _(subwindow), 553 TTime, _(time), 554 TInt, _(x), TInt, _(y), 555 TInt, _(x_root), TInt, _(y_root), 556 TModState, _(state), 557 TInt, _(button), 558 TBool, _(same_screen), 559 TEnd 560 ); 561 } 562 563 static int 564 VerbColormap(Fmt *fmt, XEvent *e) { 565 XColormapEvent *ev = &e->xcolormap; 566 567 return pevent(fmt, ev, 568 TWindow, _(window), 569 TIntNone, _(colormap), 570 TBool, _(new), 571 TColMap, _(state), 572 TEnd 573 ); 574 } 575 576 static int 577 VerbCrossing(Fmt *fmt, XEvent *e) { 578 XCrossingEvent *ev = &e->xcrossing; 579 580 return pevent(fmt, ev, 581 TWindow, _(window), 582 TWindow, _(root), 583 TWindow, _(subwindow), 584 TTime, _(time), 585 TInt, _(x), TInt, _(y), 586 TInt, _(x_root), TInt, _(y_root), 587 TGrabMode, _(mode), 588 TXing, _(detail), 589 TBool, _(same_screen), 590 TBool, _(focus), 591 TModState, _(state), 592 TEnd 593 ); 594 } 595 596 static int 597 VerbExpose(Fmt *fmt, XEvent *e) { 598 XExposeEvent *ev = &e->xexpose; 599 600 return pevent(fmt, ev, 601 TWindow, _(window), 602 TInt, _(x), TInt, _(y), 603 TInt, _(width), TInt, _(height), 604 TInt, _(count), 605 TEnd 606 ); 607 } 608 609 static int 610 VerbGraphicsExpose(Fmt *fmt, XEvent *e) { 611 XGraphicsExposeEvent *ev = &e->xgraphicsexpose; 612 613 return pevent(fmt, ev, 614 TWindow, _(drawable), 615 TInt, _(x), TInt, _(y), 616 TInt, _(width), TInt, _(height), 617 TMajor, _(major_code), 618 TInt, _(minor_code), 619 TEnd 620 ); 621 } 622 623 static int 624 VerbNoExpose(Fmt *fmt, XEvent *e) { 625 XNoExposeEvent *ev = &e->xnoexpose; 626 627 return pevent(fmt, ev, 628 TWindow, _(drawable), 629 TMajor, _(major_code), 630 TInt, _(minor_code), 631 TEnd 632 ); 633 } 634 635 static int 636 VerbFocus(Fmt *fmt, XEvent *e) { 637 XFocusChangeEvent *ev = &e->xfocus; 638 639 return pevent(fmt, ev, 640 TWindow, _(window), 641 TGrabMode, _(mode), 642 TFocus, _(detail), 643 TEnd 644 ); 645 } 646 647 static int 648 VerbKeymap(Fmt *fmt, XEvent *e) { 649 XKeymapEvent *ev = &e->xkeymap; 650 int i; 651 652 fmtprint(fmt, "window=0x%x%s", (int)ev->window, sep); 653 fmtprint(fmt, "key_vector="); 654 for (i = 0; i < 32; i++) 655 fmtprint(fmt, "%02x", ev->key_vector[i]); 656 fmtprint(fmt, "\n"); 657 return 0; 658 } 659 660 static int 661 VerbKey(Fmt *fmt, XEvent *e) { 662 XKeyEvent *ev = &e->xkey; 663 664 return pevent(fmt, ev, 665 TWindow, _(window), 666 TWindow, _(root), 667 TWindow, _(subwindow), 668 TTime, _(time), 669 TInt, _(x), TInt, _(y), 670 TInt, _(x_root), TInt, _(y_root), 671 TModState, _(state), 672 TKeycode, "keycode", ev, 673 TBool, _(same_screen), 674 TEnd 675 ); 676 } 677 678 static int 679 VerbProperty(Fmt *fmt, XEvent *e) { 680 XPropertyEvent *ev = &e->xproperty; 681 682 return pevent(fmt, ev, 683 TWindow, _(window), 684 TAtom, _(atom), 685 TTime, _(time), 686 TPropState, _(state), 687 TEnd 688 ); 689 } 690 691 static int 692 VerbResizeRequest(Fmt *fmt, XEvent *e) { 693 XResizeRequestEvent *ev = &e->xresizerequest; 694 695 return pevent(fmt, ev, 696 TWindow, _(window), 697 TInt, _(width), TInt, _(height), 698 TEnd 699 ); 700 } 701 702 static int 703 VerbCirculate(Fmt *fmt, XEvent *e) { 704 XCirculateEvent *ev = &e->xcirculate; 705 706 return pevent(fmt, ev, 707 TWindow, _(event), 708 TWindow, _(window), 709 TPlace, _(place), 710 TEnd 711 ); 712 } 713 714 static int 715 VerbConfigure(Fmt *fmt, XEvent *e) { 716 XConfigureEvent *ev = &e->xconfigure; 717 718 return pevent(fmt, ev, 719 TWindow, _(event), 720 TWindow, _(window), 721 TInt, _(x), TInt, _(y), 722 TInt, _(width), TInt, _(height), 723 TInt, _(border_width), 724 TIntNone, _(above), 725 TBool, _(override_redirect), 726 TEnd 727 ); 728 } 729 730 static int 731 VerbCreateWindow(Fmt *fmt, XEvent *e) { 732 XCreateWindowEvent *ev = &e->xcreatewindow; 733 734 return pevent(fmt, ev, 735 TWindow, _(parent), 736 TWindow, _(window), 737 TInt, _(x), TInt, _(y), 738 TInt, _(width), TInt, _(height), 739 TInt, _(border_width), 740 TBool, _(override_redirect), 741 TEnd 742 ); 743 } 744 745 static int 746 VerbDestroyWindow(Fmt *fmt, XEvent *e) { 747 XDestroyWindowEvent *ev = &e->xdestroywindow; 748 749 return pevent(fmt, ev, 750 TWindow, _(event), 751 TWindow, _(window), 752 TEnd 753 ); 754 } 755 756 static int 757 VerbGravity(Fmt *fmt, XEvent *e) { 758 XGravityEvent *ev = &e->xgravity; 759 760 return pevent(fmt, ev, 761 TWindow, _(event), 762 TWindow, _(window), 763 TInt, _(x), TInt, _(y), 764 TEnd 765 ); 766 } 767 768 static int 769 VerbMap(Fmt *fmt, XEvent *e) { 770 XMapEvent *ev = &e->xmap; 771 772 return pevent(fmt, ev, 773 TWindow, _(event), 774 TWindow, _(window), 775 TBool, _(override_redirect), 776 TEnd 777 ); 778 } 779 780 static int 781 VerbReparent(Fmt *fmt, XEvent *e) { 782 XReparentEvent *ev = &e->xreparent; 783 784 return pevent(fmt, ev, 785 TWindow, _(event), 786 TWindow, _(window), 787 TWindow, _(parent), 788 TInt, _(x), TInt, _(y), 789 TBool, _(override_redirect), 790 TEnd 791 ); 792 } 793 794 static int 795 VerbUnmap(Fmt *fmt, XEvent *e) { 796 XUnmapEvent *ev = &e->xunmap; 797 798 return pevent(fmt, ev, 799 TWindow, _(event), 800 TWindow, _(window), 801 TBool, _(from_configure), 802 TEnd 803 ); 804 } 805 806 static int 807 VerbCirculateRequest(Fmt *fmt, XEvent *e) { 808 XCirculateRequestEvent *ev = &e->xcirculaterequest; 809 810 return pevent(fmt, ev, 811 TWindow, _(parent), 812 TWindow, _(window), 813 TPlace, _(place), 814 TEnd 815 ); 816 } 817 818 static int 819 VerbConfigureRequest(Fmt *fmt, XEvent *e) { 820 XConfigureRequestEvent *ev = &e->xconfigurerequest; 821 822 return pevent(fmt, ev, 823 TWindow, _(parent), 824 TWindow, _(window), 825 TInt, _(x), TInt, _(y), 826 TInt, _(width), TInt, _(height), 827 TInt, _(border_width), 828 TIntNone, _(above), 829 TConfDetail, _(detail), 830 TConfMask, _(value_mask), 831 TEnd 832 ); 833 } 834 835 static int 836 VerbMapRequest(Fmt *fmt, XEvent *e) { 837 XMapRequestEvent *ev = &e->xmaprequest; 838 839 return pevent(fmt, ev, 840 TWindow, _(parent), 841 TWindow, _(window), 842 TEnd 843 ); 844 } 845 846 static int 847 VerbClient(Fmt *fmt, XEvent *e) { 848 XClientMessageEvent *ev = &e->xclient; 849 850 return pevent(fmt, ev, 851 TWindow, _(window), 852 TAtom, _(message_type), 853 TInt, _(format), 854 TData, "data (as longs)", &ev->data, 855 TEnd 856 ); 857 } 858 859 static int 860 VerbMapping(Fmt *fmt, XEvent *e) { 861 XMappingEvent *ev = &e->xmapping; 862 863 return pevent(fmt, ev, 864 TWindow, _(window), 865 TMapping, _(request), 866 TWindow, _(first_keycode), 867 TWindow, _(count), 868 TEnd 869 ); 870 } 871 872 static int 873 VerbSelectionClear(Fmt *fmt, XEvent *e) { 874 XSelectionClearEvent *ev = &e->xselectionclear; 875 876 return pevent(fmt, ev, 877 TWindow, _(window), 878 TAtom, _(selection), 879 TTime, _(time), 880 TEnd 881 ); 882 } 883 884 static int 885 VerbSelection(Fmt *fmt, XEvent *e) { 886 XSelectionEvent *ev = &e->xselection; 887 888 return pevent(fmt, ev, 889 TWindow, _(requestor), 890 TAtom, _(selection), 891 TAtom, _(target), 892 TAtom, _(property), 893 TTime, _(time), 894 TEnd 895 ); 896 } 897 898 static int 899 VerbSelectionRequest(Fmt *fmt, XEvent *e) { 900 XSelectionRequestEvent *ev = &e->xselectionrequest; 901 902 return pevent(fmt, ev, 903 TWindow, _(owner), 904 TWindow, _(requestor), 905 TAtom, _(selection), 906 TAtom, _(target), 907 TAtom, _(property), 908 TTime, _(time), 909 TEnd 910 ); 911 } 912 913 static int 914 VerbVisibility(Fmt *fmt, XEvent *e) { 915 XVisibilityEvent *ev = &e->xvisibility; 916 917 return pevent(fmt, ev, 918 TWindow, _(window), 919 TVis, _(state), 920 TEnd 921 ); 922 } 923 924 /******************************************************************************/ 925 /**************** Print the values of all fields for any event ****************/ 926 /******************************************************************************/ 927 928 typedef struct Handler Handler; 929 struct Handler { 930 int key; 931 int (*fn)(Fmt*, XEvent*); 932 }; 933 934 int 935 fmtevent(Fmt *fmt) { 936 XEvent *e; 937 XAnyEvent *ev; 938 /* 939 fprintf(stderr, "type=%s%s", eventtype(e->xany.type), sep); 940 fprintf(stderr, "serial=%lu%s", ev->serial, sep); 941 fprintf(stderr, "send_event=%s%s", TorF(ev->send_event), sep); 942 fprintf(stderr, "display=0x%p%s", ev->display, sep); 943 */ 944 static Handler fns[] = { 945 {MotionNotify, VerbMotion}, 946 {ButtonPress, VerbButton}, 947 {ButtonRelease, VerbButton}, 948 {ColormapNotify, VerbColormap}, 949 {EnterNotify, VerbCrossing}, 950 {LeaveNotify, VerbCrossing}, 951 {Expose, VerbExpose}, 952 {GraphicsExpose, VerbGraphicsExpose}, 953 {NoExpose, VerbNoExpose}, 954 {FocusIn, VerbFocus}, 955 {FocusOut, VerbFocus}, 956 {KeymapNotify, VerbKeymap}, 957 {KeyPress, VerbKey}, 958 {KeyRelease, VerbKey}, 959 {PropertyNotify, VerbProperty}, 960 {ResizeRequest, VerbResizeRequest}, 961 {CirculateNotify, VerbCirculate}, 962 {ConfigureNotify, VerbConfigure}, 963 {CreateNotify, VerbCreateWindow}, 964 {DestroyNotify, VerbDestroyWindow}, 965 {GravityNotify, VerbGravity}, 966 {MapNotify, VerbMap}, 967 {ReparentNotify, VerbReparent}, 968 {UnmapNotify, VerbUnmap}, 969 {CirculateRequest, VerbCirculateRequest}, 970 {ConfigureRequest, VerbConfigureRequest}, 971 {MapRequest, VerbMapRequest}, 972 {ClientMessage, VerbClient}, 973 {MappingNotify, VerbMapping}, 974 {SelectionClear, VerbSelectionClear}, 975 {SelectionNotify, VerbSelection}, 976 {SelectionRequest, VerbSelectionRequest}, 977 {VisibilityNotify, VerbVisibility}, 978 {0, nil}, 979 }; 980 Handler *p; 981 982 e = va_arg(fmt->args, XEvent*); 983 ev = &e->xany; 984 985 for (p = fns; p->fn; p++) 986 if (p->key == ev->type) 987 return p->fn(fmt, e); 988 return 1; 989 } 990