2 * Original code posted to comp.sources.x
3 * Modifications by Russ Cox <rsc@swtch.com>.
8 From: mikew@wyse.wyse.com (Mike Wexler)
9 Newsgroups: comp.sources.x
10 Subject: v02i056: subroutine to print events in human readable form, Part01/01
11 Message-ID: <1935@wyse.wyse.com>
12 Date: 22 Dec 88 19:28:25 GMT
13 Organization: Wyse Technology, San Jose
15 Approved: mikew@wyse.com
17 Submitted-by: richsun!darkstar!ken
18 Posting-number: Volume 2, Issue 56
19 Archive-name: showevent/part01
22 There are times during debugging when it would be real useful to be able to
23 print the fields of an event in a human readable form. Too many times I found
24 myself scrounging around in section 8 of the Xlib manual looking for the valid
25 fields for the events I wanted to see, then adding printf's to display the
26 numeric values of the fields, and then scanning through X.h trying to decode
27 the cryptic detail and state fields. After playing with xev, I decided to
28 write a couple of standard functions that I could keep in a library and call
29 on whenever I needed a little debugging verbosity. The first function,
30 GetType(), is useful for returning the string representation of the type of
31 an event. The second function, ShowEvent(), is used to display all the fields
32 of an event in a readable format. The functions are not complicated, in fact,
33 they are mind-numbingly boring - but that's just the point nobody wants to
34 spend the time writing functions like this, they just want to have them when
37 A simple, sample program is included which does little else but to demonstrate
38 the use of these two functions. These functions have saved me many an hour
39 during debugging and I hope you find some benefit to these. If you have any
40 comments, suggestions, improvements, or if you find any blithering errors you
41 can get it touch with me at the following location:
47 #include <X11/Intrinsic.h>
48 #include <X11/Xproto.h>
49 #include "printevent.h"
51 static char* sep = " ";
53 /******************************************************************************/
54 /**** Miscellaneous routines to convert values to their string equivalents ****/
55 /******************************************************************************/
57 /* Returns the string equivalent of a boolean parameter */
73 /* Returns the string equivalent of a property notify state */
75 PropertyState(int state)
78 case PropertyNewValue:
79 return ("PropertyNewValue");
82 return ("PropertyDelete");
89 /* Returns the string equivalent of a visibility notify state */
91 VisibilityState(int state)
94 case VisibilityUnobscured:
95 return ("VisibilityUnobscured");
97 case VisibilityPartiallyObscured:
98 return ("VisibilityPartiallyObscured");
100 case VisibilityFullyObscured:
101 return ("VisibilityFullyObscured");
108 /* Returns the string equivalent of a timestamp */
110 ServerTime(Time time)
117 static char buffer[32];
130 sprintf(buffer, "%lu day%s %02lu:%02lu:%02lu.%03lu",
131 day, day == 1 ? "" : "(s)", hr, min, sec, msec);
133 sprintf(buffer, "%lud%luh%lum%lu.%03lds", day, hr, min, sec, msec);
137 /* Simple structure to ease the interpretation of masks */
138 typedef struct MaskType MaskType;
145 /* Returns the string equivalent of a mask of buttons and/or modifier keys */
147 ButtonAndOrModifierState(unsigned int state)
149 static char buffer[256];
150 static MaskType masks[] = {
151 {Button1Mask, "Button1Mask"},
152 {Button2Mask, "Button2Mask"},
153 {Button3Mask, "Button3Mask"},
154 {Button4Mask, "Button4Mask"},
155 {Button5Mask, "Button5Mask"},
156 {ShiftMask, "ShiftMask"},
157 {LockMask, "LockMask"},
158 {ControlMask, "ControlMask"},
159 {Mod1Mask, "Mod1Mask"},
160 {Mod2Mask, "Mod2Mask"},
161 {Mod3Mask, "Mod3Mask"},
162 {Mod4Mask, "Mod4Mask"},
163 {Mod5Mask, "Mod5Mask"},
165 int num_masks = sizeof(masks) / sizeof(MaskType);
167 Boolean first = True;
171 for (i = 0; i < num_masks; i++)
172 if (state & masks[i].value)
175 strcpy(buffer, masks[i].string);
177 strcat(buffer, " | ");
178 strcat(buffer, masks[i].string);
183 /* Returns the string equivalent of a mask of configure window values */
185 ConfigureValueMask(unsigned int valuemask)
187 static char buffer[256];
188 static MaskType masks[] = {
191 {CWWidth, "CWWidth"},
192 {CWHeight, "CWHeight"},
193 {CWBorderWidth, "CWBorderWidth"},
194 {CWSibling, "CWSibling"},
195 {CWStackMode, "CWStackMode"},
197 int num_masks = sizeof(masks) / sizeof(MaskType);
199 Boolean first = True;
203 for (i = 0; i < num_masks; i++)
204 if (valuemask & masks[i].value)
207 strcpy(buffer, masks[i].string);
209 strcat(buffer, " | ");
210 strcat(buffer, masks[i].string);
216 /* Returns the string equivalent of a motion hint */
222 return ("NotifyNormal");
225 return ("NotifyHint");
232 /* Returns the string equivalent of an id or the value "None" */
236 static char buffer[16];
241 sprintf(buffer, "0x%x", value);
246 /* Returns the string equivalent of a colormap state */
248 ColormapState(int state)
251 case ColormapInstalled:
252 return ("ColormapInstalled");
254 case ColormapUninstalled:
255 return ("ColormapUninstalled");
262 /* Returns the string equivalent of a crossing detail */
264 CrossingDetail(int detail)
268 return ("NotifyAncestor");
271 return ("NotifyInferior");
274 return ("NotifyVirtual");
276 case NotifyNonlinear:
277 return ("NotifyNonlinear");
279 case NotifyNonlinearVirtual:
280 return ("NotifyNonlinearVirtual");
287 /* Returns the string equivalent of a focus change detail */
289 FocusChangeDetail(int detail)
293 return ("NotifyAncestor");
296 return ("NotifyInferior");
299 return ("NotifyVirtual");
301 case NotifyNonlinear:
302 return ("NotifyNonlinear");
304 case NotifyNonlinearVirtual:
305 return ("NotifyNonlinearVirtual");
308 return ("NotifyPointer");
310 case NotifyPointerRoot:
311 return ("NotifyPointerRoot");
313 case NotifyDetailNone:
314 return ("NotifyDetailNone");
321 /* Returns the string equivalent of a configure detail */
323 ConfigureDetail(int detail)
346 /* Returns the string equivalent of a grab mode */
352 return ("NotifyNormal");
355 return ("NotifyGrab");
358 return ("NotifyUngrab");
360 case NotifyWhileGrabbed:
361 return ("NotifyWhileGrabbed");
368 /* Returns the string equivalent of a mapping request */
370 MappingRequest(int request)
373 case MappingModifier:
374 return ("MappingModifier");
376 case MappingKeyboard:
377 return ("MappingKeyboard");
380 return ("MappingPointer");
387 /* Returns the string equivalent of a stacking order place */
393 return ("PlaceOnTop");
396 return ("PlaceOnBottom");
403 /* Returns the string equivalent of a major code */
407 static char buffer[32];
411 return ("X_CopyArea");
414 return ("X_CopyPlane");
417 sprintf(buffer, "0x%x", code);
422 /* Returns the string equivalent the keycode contained in the key event */
424 Keycode(XKeyEvent *ev)
426 static char buffer[256];
431 XLookupString(ev, string, 64, &keysym_str, NULL);
433 if (keysym_str == NoSymbol)
434 keysym_name = "NoSymbol";
435 else if (!(keysym_name = XKeysymToString(keysym_str)))
436 keysym_name = "(no name)";
437 sprintf(buffer, "%u (keysym 0x%x \"%s\")",
438 (int)ev->keycode, (int)keysym_str, keysym_name);
442 /* Returns the string equivalent of an atom or "None"*/
444 AtomName(Display *dpy, Atom atom)
446 static char buffer[256];
452 atom_name = XGetAtomName(dpy, atom);
453 strncpy(buffer, atom_name, 256);
458 /******************************************************************************/
459 /**** Routines to print out readable values for the field of various events ***/
460 /******************************************************************************/
463 VerbMotion(XMotionEvent *ev)
465 printf("window=0x%x%s", (int)ev->window, sep);
466 printf("root=0x%x%s", (int)ev->root, sep);
467 printf("subwindow=0x%x%s", (int)ev->subwindow, sep);
468 printf("time=%s%s", ServerTime(ev->time), sep);
469 printf("x=%d y=%d%s", ev->x, ev->y, sep);
470 printf("x_root=%d y_root=%d%s", ev->x_root, ev->y_root, sep);
471 printf("state=%s%s", ButtonAndOrModifierState(ev->state), sep);
472 printf("is_hint=%s%s", IsHint(ev->is_hint), sep);
473 printf("same_screen=%s\n", TorF(ev->same_screen));
477 VerbButton(XButtonEvent *ev)
479 printf("window=0x%x%s", (int)ev->window, sep);
480 printf("root=0x%x%s", (int)ev->root, sep);
481 printf("subwindow=0x%x%s", (int)ev->subwindow, sep);
482 printf("time=%s%s", ServerTime(ev->time), sep);
483 printf("x=%d y=%d%s", ev->x, ev->y, sep);
484 printf("x_root=%d y_root=%d%s", ev->x_root, ev->y_root, sep);
485 printf("state=%s%s", ButtonAndOrModifierState(ev->state), sep);
486 printf("button=%s%s", ButtonAndOrModifierState(ev->button), sep);
487 printf("same_screen=%s\n", TorF(ev->same_screen));
491 VerbColormap(XColormapEvent *ev)
493 printf("window=0x%x%s", (int)ev->window, sep);
494 printf("colormap=%s%s", MaybeNone(ev->colormap), sep);
495 printf("new=%s%s", TorF(ev->new), sep);
496 printf("state=%s\n", ColormapState(ev->state));
500 VerbCrossing(XCrossingEvent *ev)
502 printf("window=0x%x%s", (int)ev->window, sep);
503 printf("root=0x%x%s", (int)ev->root, sep);
504 printf("subwindow=0x%x%s", (int)ev->subwindow, sep);
505 printf("time=%s%s", ServerTime(ev->time), sep);
506 printf("x=%d y=%d%s", ev->x, ev->y, sep);
507 printf("x_root=%d y_root=%d%s", ev->x_root, ev->y_root, sep);
508 printf("mode=%s%s", GrabMode(ev->mode), sep);
509 printf("detail=%s%s", CrossingDetail(ev->detail), sep);
510 printf("same_screen=%s%s", TorF(ev->same_screen), sep);
511 printf("focus=%s%s", TorF(ev->focus), sep);
512 printf("state=%s\n", ButtonAndOrModifierState(ev->state));
516 VerbExpose(XExposeEvent *ev)
518 printf("window=0x%x%s", (int)ev->window, sep);
519 printf("x=%d y=%d%s", ev->x, ev->y, sep);
520 printf("width=%d height=%d%s", ev->width, ev->height, sep);
521 printf("count=%d\n", ev->count);
525 VerbGraphicsExpose(XGraphicsExposeEvent *ev)
527 printf("drawable=0x%x%s", (int)ev->drawable, sep);
528 printf("x=%d y=%d%s", ev->x, ev->y, sep);
529 printf("width=%d height=%d%s", ev->width, ev->height, sep);
530 printf("major_code=%s%s", MajorCode(ev->major_code), sep);
531 printf("minor_code=%d\n", ev->minor_code);
535 VerbNoExpose(XNoExposeEvent *ev)
537 printf("drawable=0x%x%s", (int)ev->drawable, sep);
538 printf("major_code=%s%s", MajorCode(ev->major_code), sep);
539 printf("minor_code=%d\n", ev->minor_code);
543 VerbFocus(XFocusChangeEvent *ev)
545 printf("window=0x%x%s", (int)ev->window, sep);
546 printf("mode=%s%s", GrabMode(ev->mode), sep);
547 printf("detail=%s\n", FocusChangeDetail(ev->detail));
551 VerbKeymap(XKeymapEvent *ev)
555 printf("window=0x%x%s", (int)ev->window, sep);
556 printf("key_vector=");
557 for (i = 0; i < 32; i++)
558 printf("%02x", ev->key_vector[i]);
563 VerbKey(XKeyEvent *ev)
565 printf("window=0x%x%s", (int)ev->window, sep);
566 printf("root=0x%x%s", (int)ev->root, sep);
568 printf("subwindow=0x%x%s", (int)ev->subwindow, sep);
569 printf("time=%s%s", ServerTime(ev->time), sep);
570 printf("[%d,%d]%s", ev->x, ev->y, sep);
571 printf("root=[%d,%d]%s", ev->x_root, ev->y_root, sep);
573 printf("state=%s%s", ButtonAndOrModifierState(ev->state), sep);
574 printf("keycode=%s%s", Keycode(ev), sep);
576 printf("!same_screen", TorF(ev->same_screen));
580 printf("window=0x%x%s", (int)ev->window, sep);
581 printf("root=0x%x%s", (int)ev->root, sep);
582 printf("subwindow=0x%x%s", (int)ev->subwindow, sep);
583 printf("time=%s%s", ServerTime(ev->time), sep);
584 printf("x=%d y=%d%s", ev->x, ev->y, sep);
585 printf("x_root=%d y_root=%d%s", ev->x_root, ev->y_root, sep);
586 printf("state=%s%s", ButtonAndOrModifierState(ev->state), sep);
587 printf("keycode=%s%s", Keycode(ev), sep);
588 printf("same_screen=%s\n", TorF(ev->same_screen));
592 VerbProperty(XPropertyEvent *ev)
594 printf("window=0x%x%s", (int)ev->window, sep);
595 printf("atom=%s%s", AtomName(ev->display, ev->atom), sep);
596 printf("time=%s%s", ServerTime(ev->time), sep);
597 printf("state=%s\n", PropertyState(ev->state));
601 VerbResizeRequest(XResizeRequestEvent *ev)
603 printf("window=0x%x%s", (int)ev->window, sep);
604 printf("width=%d height=%d\n", ev->width, ev->height);
608 VerbCirculate(XCirculateEvent *ev)
610 printf("event=0x%x%s", (int)ev->event, sep);
611 printf("window=0x%x%s", (int)ev->window, sep);
612 printf("place=%s\n", Place(ev->place));
616 VerbConfigure(XConfigureEvent *ev)
618 printf("event=0x%x%s", (int)ev->event, sep);
619 printf("window=0x%x%s", (int)ev->window, sep);
620 printf("x=%d y=%d%s", ev->x, ev->y, sep);
621 printf("width=%d height=%d%s", ev->width, ev->height, sep);
622 printf("border_width=%d%s", ev->border_width, sep);
623 printf("above=%s%s", MaybeNone(ev->above), sep);
624 printf("override_redirect=%s\n", TorF(ev->override_redirect));
628 VerbCreateWindow(XCreateWindowEvent *ev)
630 printf("parent=0x%x%s", (int)ev->parent, sep);
631 printf("window=0x%x%s", (int)ev->window, sep);
632 printf("x=%d y=%d%s", ev->x, ev->y, sep);
633 printf("width=%d height=%d%s", ev->width, ev->height, sep);
634 printf("border_width=%d%s", ev->border_width, sep);
635 printf("override_redirect=%s\n", TorF(ev->override_redirect));
639 VerbDestroyWindow(XDestroyWindowEvent *ev)
641 printf("event=0x%x%s", (int)ev->event, sep);
642 printf("window=0x%x\n", (int)ev->window);
646 VerbGravity(XGravityEvent *ev)
648 printf("event=0x%x%s", (int)ev->event, sep);
649 printf("window=0x%x%s", (int)ev->window, sep);
650 printf("x=%d y=%d\n", ev->x, ev->y);
654 VerbMap(XMapEvent *ev)
656 printf("event=0x%x%s", (int)ev->event, sep);
657 printf("window=0x%x%s", (int)ev->window, sep);
658 printf("override_redirect=%s\n", TorF(ev->override_redirect));
662 VerbReparent(XReparentEvent *ev)
664 printf("event=0x%x%s", (int)ev->event, sep);
665 printf("window=0x%x%s", (int)ev->window, sep);
666 printf("parent=0x%x%s", (int)ev->parent, sep);
667 printf("x=%d y=%d%s", ev->x, ev->y, sep);
668 printf("override_redirect=%s\n", TorF(ev->override_redirect));
672 VerbUnmap(XUnmapEvent *ev)
674 printf("event=0x%x%s", (int)ev->event, sep);
675 printf("window=0x%x%s", (int)ev->window, sep);
676 printf("from_configure=%s\n", TorF(ev->from_configure));
680 VerbCirculateRequest(XCirculateRequestEvent *ev)
682 printf("parent=0x%x%s", (int)ev->parent, sep);
683 printf("window=0x%x%s", (int)ev->window, sep);
684 printf("place=%s\n", Place(ev->place));
688 VerbConfigureRequest(XConfigureRequestEvent *ev)
690 printf("parent=0x%x%s", (int)ev->parent, sep);
691 printf("window=0x%x%s", (int)ev->window, sep);
692 printf("x=%d y=%d%s", ev->x, ev->y, sep);
693 printf("width=%d height=%d%s", ev->width, ev->height, sep);
694 printf("border_width=%d%s", ev->border_width, sep);
695 printf("above=%s%s", MaybeNone(ev->above), sep);
696 printf("detail=%s%s", ConfigureDetail(ev->detail), sep);
697 printf("value_mask=%s\n", ConfigureValueMask(ev->value_mask));
701 VerbMapRequest(XMapRequestEvent *ev)
703 printf("parent=0x%x%s", (int)ev->parent, sep);
704 printf("window=0x%x\n", (int)ev->window);
708 VerbClient(XClientMessageEvent *ev)
712 printf("window=0x%x%s", (int)ev->window, sep);
713 printf("message_type=%s%s", AtomName(ev->display, ev->message_type), sep);
714 printf("format=%d\n", ev->format);
715 printf("data (shown as longs)=");
716 for (i = 0; i < 5; i++)
717 printf(" 0x%08lx", ev->data.l[i]);
722 VerbMapping(XMappingEvent *ev)
724 printf("window=0x%x%s", (int)ev->window, sep);
725 printf("request=%s%s", MappingRequest(ev->request), sep);
726 printf("first_keycode=0x%x%s", ev->first_keycode, sep);
727 printf("count=0x%x\n", ev->count);
731 VerbSelectionClear(XSelectionClearEvent *ev)
733 printf("window=0x%x%s", (int)ev->window, sep);
734 printf("selection=%s%s", AtomName(ev->display, ev->selection), sep);
735 printf("time=%s\n", ServerTime(ev->time));
739 VerbSelection(XSelectionEvent *ev)
741 printf("requestor=0x%x%s", (int)ev->requestor, sep);
742 printf("selection=%s%s", AtomName(ev->display, ev->selection), sep);
743 printf("target=%s%s", AtomName(ev->display, ev->target), sep);
744 printf("property=%s%s", AtomName(ev->display, ev->property), sep);
745 printf("time=%s\n", ServerTime(ev->time));
749 VerbSelectionRequest(XSelectionRequestEvent *ev)
751 printf("owner=0x%x%s", (int)ev->owner, sep);
752 printf("requestor=0x%x%s", (int)ev->requestor, sep);
753 printf("selection=%s%s", AtomName(ev->display, ev->selection), sep);
754 printf("target=%s%s", AtomName(ev->display, ev->target), sep);
755 printf("property=%s%s", AtomName(ev->display, ev->property), sep);
756 printf("time=%s\n", ServerTime(ev->time));
760 VerbVisibility(XVisibilityEvent *ev)
762 printf("window=0x%x%s", (int)ev->window, sep);
763 printf("state=%s\n", VisibilityState(ev->state));
766 /******************************************************************************/
767 /************ Return the string representation for type of an event ***********/
768 /******************************************************************************/
770 char *eventtype(XEvent *ev)
772 static char buffer[20];
778 return ("KeyRelease");
780 return ("ButtonPress");
782 return ("ButtonRelease");
784 return ("MotionNotify");
786 return ("EnterNotify");
788 return ("LeaveNotify");
794 return ("KeymapNotify");
798 return ("GraphicsExpose");
801 case VisibilityNotify:
802 return ("VisibilityNotify");
804 return ("CreateNotify");
806 return ("DestroyNotify");
808 return ("UnmapNotify");
810 return ("MapNotify");
812 return ("MapRequest");
814 return ("ReparentNotify");
815 case ConfigureNotify:
816 return ("ConfigureNotify");
817 case ConfigureRequest:
818 return ("ConfigureRequest");
820 return ("GravityNotify");
822 return ("ResizeRequest");
823 case CirculateNotify:
824 return ("CirculateNotify");
825 case CirculateRequest:
826 return ("CirculateRequest");
828 return ("PropertyNotify");
830 return ("SelectionClear");
831 case SelectionRequest:
832 return ("SelectionRequest");
833 case SelectionNotify:
834 return ("SelectionNotify");
836 return ("ColormapNotify");
838 return ("ClientMessage");
840 return ("MappingNotify");
842 sprintf(buffer, "%d", ev->type);
846 /******************************************************************************/
847 /**************** Print the values of all fields for any event ****************/
848 /******************************************************************************/
850 void printevent(XEvent *e)
852 XAnyEvent *ev = (void*)e;
854 printf("%3ld %-20s ", ev->serial, eventtype(e));
856 printf("(sendevent) ");
858 printf("type=%s%s", eventtype(e), sep);
859 printf("serial=%lu%s", ev->serial, sep);
860 printf("send_event=%s%s", TorF(ev->send_event), sep);
861 printf("display=0x%p%s", ev->display, sep);
866 VerbMotion((void*)ev);
871 VerbButton((void*)ev);
875 VerbColormap((void*)ev);
880 VerbCrossing((void*)ev);
884 VerbExpose((void*)ev);
888 VerbGraphicsExpose((void*)ev);
892 VerbNoExpose((void*)ev);
897 VerbFocus((void*)ev);
901 VerbKeymap((void*)ev);
910 VerbProperty((void*)ev);
914 VerbResizeRequest((void*)ev);
917 case CirculateNotify:
918 VerbCirculate((void*)ev);
921 case ConfigureNotify:
922 VerbConfigure((void*)ev);
926 VerbCreateWindow((void*)ev);
930 VerbDestroyWindow((void*)ev);
934 VerbGravity((void*)ev);
942 VerbReparent((void*)ev);
946 VerbUnmap((void*)ev);
949 case CirculateRequest:
950 VerbCirculateRequest((void*)ev);
953 case ConfigureRequest:
954 VerbConfigureRequest((void*)ev);
958 VerbMapRequest((void*)ev);
962 VerbClient((void*)ev);
966 VerbMapping((void*)ev);
970 VerbSelectionClear((void*)ev);
973 case SelectionNotify:
974 VerbSelection((void*)ev);
977 case SelectionRequest:
978 VerbSelectionRequest((void*)ev);
981 case VisibilityNotify:
982 VerbVisibility((void*)ev);