xev.c revision da39bf31
1f299d47fSmrg/*
2f299d47fSmrg
3f299d47fSmrgCopyright (c) 1988  X Consortium
4f299d47fSmrg
5f299d47fSmrgPermission is hereby granted, free of charge, to any person obtaining
6f299d47fSmrga copy of this software and associated documentation files (the
7f299d47fSmrg"Software"), to deal in the Software without restriction, including
8f299d47fSmrgwithout limitation the rights to use, copy, modify, merge, publish,
9f299d47fSmrgdistribute, sublicense, and/or sell copies of the Software, and to
10f299d47fSmrgpermit persons to whom the Software is furnished to do so, subject to
11f299d47fSmrgthe following conditions:
12f299d47fSmrg
13f299d47fSmrgThe above copyright notice and this permission notice shall be included
14f299d47fSmrgin all copies or substantial portions of the Software.
15f299d47fSmrg
16f299d47fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17f299d47fSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18f299d47fSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19f299d47fSmrgIN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
20f299d47fSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21f299d47fSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22f299d47fSmrgOTHER DEALINGS IN THE SOFTWARE.
23f299d47fSmrg
24f299d47fSmrgExcept as contained in this notice, the name of the X Consortium shall
25f299d47fSmrgnot be used in advertising or otherwise to promote the sale, use or
26f299d47fSmrgother dealings in this Software without prior written authorization
27f299d47fSmrgfrom the X Consortium.
28f299d47fSmrg
29f299d47fSmrg*/
30f299d47fSmrg
31f299d47fSmrg/*
32f299d47fSmrg * Author:  Jim Fulton, MIT X Consortium
33f299d47fSmrg */
34f299d47fSmrg
351a2dd139Smrg#ifdef HAVE_CONFIG_H
361a2dd139Smrg# include "config.h"
371a2dd139Smrg#endif
38f299d47fSmrg#include <stdio.h>
39f299d47fSmrg#include <stdlib.h>
40f299d47fSmrg#include <ctype.h>
41f299d47fSmrg#include <X11/Xlocale.h>
42f299d47fSmrg#include <X11/Xos.h>
43f299d47fSmrg#include <X11/Xlib.h>
44f299d47fSmrg#include <X11/Xutil.h>
45f299d47fSmrg#include <X11/Xproto.h>
461a2dd139Smrg#include <X11/extensions/Xrandr.h>
47f299d47fSmrg
48f299d47fSmrg#define INNER_WINDOW_WIDTH 50
49f299d47fSmrg#define INNER_WINDOW_HEIGHT 50
50f299d47fSmrg#define INNER_WINDOW_BORDER 4
51f299d47fSmrg#define INNER_WINDOW_X 10
52f299d47fSmrg#define INNER_WINDOW_Y 10
53f299d47fSmrg#define OUTER_WINDOW_MIN_WIDTH (INNER_WINDOW_WIDTH + \
54f299d47fSmrg				2 * (INNER_WINDOW_BORDER + INNER_WINDOW_X))
55f299d47fSmrg#define OUTER_WINDOW_MIN_HEIGHT (INNER_WINDOW_HEIGHT + \
56f299d47fSmrg				2 * (INNER_WINDOW_BORDER + INNER_WINDOW_Y))
57f299d47fSmrg#define OUTER_WINDOW_DEF_WIDTH (OUTER_WINDOW_MIN_WIDTH + 100)
58f299d47fSmrg#define OUTER_WINDOW_DEF_HEIGHT (OUTER_WINDOW_MIN_HEIGHT + 100)
59f299d47fSmrg#define OUTER_WINDOW_DEF_X 100
60f299d47fSmrg#define OUTER_WINDOW_DEF_Y 100
611a2dd139Smrg
62f299d47fSmrg
63f299d47fSmrgtypedef unsigned long Pixel;
64f299d47fSmrg
65f299d47fSmrgconst char *Yes = "YES";
66f299d47fSmrgconst char *No = "NO";
67f299d47fSmrgconst char *Unknown = "unknown";
68f299d47fSmrg
69f299d47fSmrgconst char *ProgramName;
70f299d47fSmrgDisplay *dpy;
71f299d47fSmrgint screen;
72f299d47fSmrg
73f299d47fSmrgXIC xic = NULL;
74f299d47fSmrg
75f299d47fSmrgAtom wm_delete_window;
76f299d47fSmrgAtom wm_protocols;
77f299d47fSmrg
781a2dd139SmrgBool have_rr;
791a2dd139Smrgint rr_event_base, rr_error_base;
801a2dd139Smrg
811a2dd139Smrgenum EventMaskIndex {
821a2dd139Smrg    EVENT_MASK_INDEX_CORE,
831a2dd139Smrg    EVENT_MASK_INDEX_RANDR,
841a2dd139Smrg    NUM_EVENT_MASKS
851a2dd139Smrg};
861a2dd139Smrg
87da39bf31Smrgstatic void usage(const char *errmsg) _X_NORETURN;
881a2dd139Smrg
89f299d47fSmrgstatic void
90da39bf31Smrgprologue(XEvent *eventp, const char *event_name)
91f299d47fSmrg{
92f299d47fSmrg    XAnyEvent *e = (XAnyEvent *) eventp;
93f299d47fSmrg
94da39bf31Smrg    printf("\n%s event, serial %ld, synthetic %s, window 0x%lx,\n",
95da39bf31Smrg           event_name, e->serial, e->send_event ? Yes : No, e->window);
96f299d47fSmrg}
97f299d47fSmrg
98f299d47fSmrgstatic void
99da39bf31Smrgdump(char *str, int len)
100f299d47fSmrg{
101f299d47fSmrg    printf("(");
102f299d47fSmrg    len--;
103f299d47fSmrg    while (len-- > 0)
104f299d47fSmrg        printf("%02x ", (unsigned char) *str++);
105f299d47fSmrg    printf("%02x)", (unsigned char) *str++);
106f299d47fSmrg}
107f299d47fSmrg
108f299d47fSmrgstatic void
109da39bf31Smrgdo_KeyPress(XEvent *eventp)
110f299d47fSmrg{
111f299d47fSmrg    XKeyEvent *e = (XKeyEvent *) eventp;
112f299d47fSmrg    KeySym ks;
113f299d47fSmrg    KeyCode kc = 0;
114f299d47fSmrg    Bool kc_set = False;
1151a2dd139Smrg    const char *ksname;
116f299d47fSmrg    int nbytes, nmbbytes = 0;
117da39bf31Smrg    char str[256 + 1];
118f299d47fSmrg    static char *buf = NULL;
119f299d47fSmrg    static int bsize = 8;
120f299d47fSmrg    Status status;
121f299d47fSmrg
122f299d47fSmrg    if (buf == NULL)
123da39bf31Smrg        buf = malloc(bsize);
124f299d47fSmrg
125da39bf31Smrg    nbytes = XLookupString(e, str, 256, &ks, NULL);
126f299d47fSmrg
127f299d47fSmrg    /* not supposed to call XmbLookupString on a key release event */
128f299d47fSmrg    if (e->type == KeyPress && xic) {
129f299d47fSmrg        do {
130da39bf31Smrg            nmbbytes = XmbLookupString(xic, e, buf, bsize - 1, &ks, &status);
131f299d47fSmrg            buf[nmbbytes] = '\0';
132f299d47fSmrg
133f299d47fSmrg            if (status == XBufferOverflow) {
134f299d47fSmrg                bsize = nmbbytes + 1;
135da39bf31Smrg                buf = realloc(buf, bsize);
136f299d47fSmrg            }
137f299d47fSmrg        } while (status == XBufferOverflow);
138f299d47fSmrg    }
139f299d47fSmrg
140f299d47fSmrg    if (ks == NoSymbol)
141da39bf31Smrg        ksname = "NoSymbol";
142f299d47fSmrg    else {
143da39bf31Smrg        if (!(ksname = XKeysymToString(ks)))
144da39bf31Smrg            ksname = "(no name)";
145da39bf31Smrg        kc = XKeysymToKeycode(dpy, ks);
146da39bf31Smrg        kc_set = True;
147f299d47fSmrg    }
1481a2dd139Smrg
149da39bf31Smrg    printf("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
150da39bf31Smrg           e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
151da39bf31Smrg    printf("    state 0x%x, keycode %u (keysym 0x%lx, %s), same_screen %s,\n",
152da39bf31Smrg           e->state, e->keycode, (unsigned long) ks, ksname,
153da39bf31Smrg           e->same_screen ? Yes : No);
154f299d47fSmrg    if (kc_set && e->keycode != kc)
155da39bf31Smrg        printf("    XKeysymToKeycode returns keycode: %u\n", kc);
156da39bf31Smrg    if (nbytes < 0)
157da39bf31Smrg        nbytes = 0;
158da39bf31Smrg    if (nbytes > 256)
159da39bf31Smrg        nbytes = 256;
160f299d47fSmrg    str[nbytes] = '\0';
161da39bf31Smrg    printf("    XLookupString gives %d bytes: ", nbytes);
162f299d47fSmrg    if (nbytes > 0) {
163da39bf31Smrg        dump(str, nbytes);
164da39bf31Smrg        printf(" \"%s\"\n", str);
165da39bf31Smrg    }
166da39bf31Smrg    else {
167da39bf31Smrg        printf("\n");
168f299d47fSmrg    }
169f299d47fSmrg
170f299d47fSmrg    /* not supposed to call XmbLookupString on a key release event */
171f299d47fSmrg    if (e->type == KeyPress && xic) {
172da39bf31Smrg        printf("    XmbLookupString gives %d bytes: ", nmbbytes);
173f299d47fSmrg        if (nmbbytes > 0) {
174da39bf31Smrg            dump(buf, nmbbytes);
175da39bf31Smrg            printf(" \"%s\"\n", buf);
176da39bf31Smrg        }
177da39bf31Smrg        else {
178da39bf31Smrg            printf("\n");
179f299d47fSmrg        }
180f299d47fSmrg    }
181f299d47fSmrg
182da39bf31Smrg    printf("    XFilterEvent returns: %s\n",
183da39bf31Smrg           XFilterEvent(eventp, e->window) ? "True" : "False");
184f299d47fSmrg}
185f299d47fSmrg
186f299d47fSmrgstatic void
187da39bf31Smrgdo_KeyRelease(XEvent *eventp)
188f299d47fSmrg{
189da39bf31Smrg    do_KeyPress(eventp);        /* since it has the same info */
190f299d47fSmrg}
191f299d47fSmrg
192f299d47fSmrgstatic void
193da39bf31Smrgdo_ButtonPress(XEvent *eventp)
194f299d47fSmrg{
195f299d47fSmrg    XButtonEvent *e = (XButtonEvent *) eventp;
196f299d47fSmrg
197da39bf31Smrg    printf("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
198da39bf31Smrg           e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
199da39bf31Smrg    printf("    state 0x%x, button %u, same_screen %s\n",
200da39bf31Smrg           e->state, e->button, e->same_screen ? Yes : No);
201f299d47fSmrg}
202f299d47fSmrg
203f299d47fSmrgstatic void
204da39bf31Smrgdo_ButtonRelease(XEvent *eventp)
205f299d47fSmrg{
206da39bf31Smrg    do_ButtonPress(eventp);     /* since it has the same info */
207f299d47fSmrg}
208f299d47fSmrg
209f299d47fSmrgstatic void
210da39bf31Smrgdo_MotionNotify(XEvent *eventp)
211f299d47fSmrg{
212f299d47fSmrg    XMotionEvent *e = (XMotionEvent *) eventp;
213f299d47fSmrg
214da39bf31Smrg    printf("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
215da39bf31Smrg           e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
216da39bf31Smrg    printf("    state 0x%x, is_hint %u, same_screen %s\n",
217da39bf31Smrg           e->state, e->is_hint, e->same_screen ? Yes : No);
218f299d47fSmrg}
219f299d47fSmrg
220f299d47fSmrgstatic void
221da39bf31Smrgdo_EnterNotify(XEvent *eventp)
222f299d47fSmrg{
223f299d47fSmrg    XCrossingEvent *e = (XCrossingEvent *) eventp;
2241a2dd139Smrg    const char *mode, *detail;
225f299d47fSmrg    char dmode[10], ddetail[10];
226f299d47fSmrg
227f299d47fSmrg    switch (e->mode) {
228da39bf31Smrg    case NotifyNormal:
229da39bf31Smrg        mode = "NotifyNormal";
230da39bf31Smrg        break;
231da39bf31Smrg    case NotifyGrab:
232da39bf31Smrg        mode = "NotifyGrab";
233da39bf31Smrg        break;
234da39bf31Smrg    case NotifyUngrab:
235da39bf31Smrg        mode = "NotifyUngrab";
236da39bf31Smrg        break;
237da39bf31Smrg    case NotifyWhileGrabbed:
238da39bf31Smrg        mode = "NotifyWhileGrabbed";
239da39bf31Smrg        break;
240da39bf31Smrg    default:
241da39bf31Smrg        mode = dmode;
242da39bf31Smrg        snprintf(dmode, sizeof(dmode), "%u", e->mode);
243da39bf31Smrg        break;
244f299d47fSmrg    }
245f299d47fSmrg
246f299d47fSmrg    switch (e->detail) {
247da39bf31Smrg    case NotifyAncestor:
248da39bf31Smrg        detail = "NotifyAncestor";
249da39bf31Smrg        break;
250da39bf31Smrg    case NotifyVirtual:
251da39bf31Smrg        detail = "NotifyVirtual";
252da39bf31Smrg        break;
253da39bf31Smrg    case NotifyInferior:
254da39bf31Smrg        detail = "NotifyInferior";
255da39bf31Smrg        break;
256da39bf31Smrg    case NotifyNonlinear:
257da39bf31Smrg        detail = "NotifyNonlinear";
258da39bf31Smrg        break;
259da39bf31Smrg    case NotifyNonlinearVirtual:
260da39bf31Smrg        detail = "NotifyNonlinearVirtual";
261da39bf31Smrg        break;
262da39bf31Smrg    case NotifyPointer:
263da39bf31Smrg        detail = "NotifyPointer";
264da39bf31Smrg        break;
265da39bf31Smrg    case NotifyPointerRoot:
266da39bf31Smrg        detail = "NotifyPointerRoot";
267da39bf31Smrg        break;
268da39bf31Smrg    case NotifyDetailNone:
269da39bf31Smrg        detail = "NotifyDetailNone";
270da39bf31Smrg        break;
271da39bf31Smrg    default:
272da39bf31Smrg        detail = ddetail;
273da39bf31Smrg        snprintf(ddetail, sizeof(ddetail), "%u", e->detail);
274da39bf31Smrg        break;
275f299d47fSmrg    }
276f299d47fSmrg
277da39bf31Smrg    printf("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
278da39bf31Smrg           e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
279da39bf31Smrg    printf("    mode %s, detail %s, same_screen %s,\n",
280da39bf31Smrg           mode, detail, e->same_screen ? Yes : No);
281da39bf31Smrg    printf("    focus %s, state %u\n", e->focus ? Yes : No, e->state);
282f299d47fSmrg}
283f299d47fSmrg
284f299d47fSmrgstatic void
285da39bf31Smrgdo_LeaveNotify(XEvent *eventp)
286f299d47fSmrg{
287da39bf31Smrg    do_EnterNotify(eventp);     /* since it has same information */
288f299d47fSmrg}
289f299d47fSmrg
290f299d47fSmrgstatic void
291da39bf31Smrgdo_FocusIn(XEvent *eventp)
292f299d47fSmrg{
293f299d47fSmrg    XFocusChangeEvent *e = (XFocusChangeEvent *) eventp;
2941a2dd139Smrg    const char *mode, *detail;
295f299d47fSmrg    char dmode[10], ddetail[10];
296f299d47fSmrg
297f299d47fSmrg    switch (e->mode) {
298da39bf31Smrg    case NotifyNormal:
299da39bf31Smrg        mode = "NotifyNormal";
300da39bf31Smrg        break;
301da39bf31Smrg    case NotifyGrab:
302da39bf31Smrg        mode = "NotifyGrab";
303da39bf31Smrg        break;
304da39bf31Smrg    case NotifyUngrab:
305da39bf31Smrg        mode = "NotifyUngrab";
306da39bf31Smrg        break;
307da39bf31Smrg    case NotifyWhileGrabbed:
308da39bf31Smrg        mode = "NotifyWhileGrabbed";
309da39bf31Smrg        break;
310da39bf31Smrg    default:
311da39bf31Smrg        mode = dmode;
312da39bf31Smrg        snprintf(dmode, sizeof(dmode), "%u", e->mode);
313da39bf31Smrg        break;
314f299d47fSmrg    }
315f299d47fSmrg
316f299d47fSmrg    switch (e->detail) {
317da39bf31Smrg    case NotifyAncestor:
318da39bf31Smrg        detail = "NotifyAncestor";
319da39bf31Smrg        break;
320da39bf31Smrg    case NotifyVirtual:
321da39bf31Smrg        detail = "NotifyVirtual";
322da39bf31Smrg        break;
323da39bf31Smrg    case NotifyInferior:
324da39bf31Smrg        detail = "NotifyInferior";
325da39bf31Smrg        break;
326da39bf31Smrg    case NotifyNonlinear:
327da39bf31Smrg        detail = "NotifyNonlinear";
328da39bf31Smrg        break;
329da39bf31Smrg    case NotifyNonlinearVirtual:
330da39bf31Smrg        detail = "NotifyNonlinearVirtual";
331da39bf31Smrg        break;
332da39bf31Smrg    case NotifyPointer:
333da39bf31Smrg        detail = "NotifyPointer";
334da39bf31Smrg        break;
335da39bf31Smrg    case NotifyPointerRoot:
336da39bf31Smrg        detail = "NotifyPointerRoot";
337da39bf31Smrg        break;
338da39bf31Smrg    case NotifyDetailNone:
339da39bf31Smrg        detail = "NotifyDetailNone";
340da39bf31Smrg        break;
341da39bf31Smrg    default:
342da39bf31Smrg        detail = ddetail;
343da39bf31Smrg        snprintf(ddetail, sizeof(ddetail), "%u", e->detail);
344da39bf31Smrg        break;
345f299d47fSmrg    }
346f299d47fSmrg
347da39bf31Smrg    printf("    mode %s, detail %s\n", mode, detail);
348f299d47fSmrg}
349f299d47fSmrg
350f299d47fSmrgstatic void
351da39bf31Smrgdo_FocusOut(XEvent *eventp)
352f299d47fSmrg{
353da39bf31Smrg    do_FocusIn(eventp);         /* since it has same information */
354f299d47fSmrg}
355f299d47fSmrg
356f299d47fSmrgstatic void
357da39bf31Smrgdo_KeymapNotify(XEvent *eventp)
358f299d47fSmrg{
359f299d47fSmrg    XKeymapEvent *e = (XKeymapEvent *) eventp;
360f299d47fSmrg    int i;
361f299d47fSmrg
362da39bf31Smrg    printf("    keys:  ");
363f299d47fSmrg    for (i = 0; i < 32; i++) {
364da39bf31Smrg        if (i == 16)
365da39bf31Smrg            printf("\n           ");
366da39bf31Smrg        printf("%-3u ", (unsigned int) e->key_vector[i]);
367f299d47fSmrg    }
368da39bf31Smrg    printf("\n");
369f299d47fSmrg}
370f299d47fSmrg
371f299d47fSmrgstatic void
372da39bf31Smrgdo_Expose(XEvent *eventp)
373f299d47fSmrg{
374f299d47fSmrg    XExposeEvent *e = (XExposeEvent *) eventp;
375f299d47fSmrg
376da39bf31Smrg    printf("    (%d,%d), width %d, height %d, count %d\n",
377da39bf31Smrg           e->x, e->y, e->width, e->height, e->count);
378f299d47fSmrg}
379f299d47fSmrg
380f299d47fSmrgstatic void
381da39bf31Smrgdo_GraphicsExpose(XEvent *eventp)
382f299d47fSmrg{
383f299d47fSmrg    XGraphicsExposeEvent *e = (XGraphicsExposeEvent *) eventp;
3841a2dd139Smrg    const char *m;
385f299d47fSmrg    char mdummy[10];
386f299d47fSmrg
387f299d47fSmrg    switch (e->major_code) {
388da39bf31Smrg    case X_CopyArea:
389da39bf31Smrg        m = "CopyArea";
390da39bf31Smrg        break;
391da39bf31Smrg    case X_CopyPlane:
392da39bf31Smrg        m = "CopyPlane";
393da39bf31Smrg        break;
394da39bf31Smrg    default:
395da39bf31Smrg        m = mdummy;
396da39bf31Smrg        snprintf(mdummy, sizeof(mdummy), "%d", e->major_code);
397da39bf31Smrg        break;
398f299d47fSmrg    }
399f299d47fSmrg
400da39bf31Smrg    printf("    (%d,%d), width %d, height %d, count %d,\n",
401da39bf31Smrg           e->x, e->y, e->width, e->height, e->count);
402da39bf31Smrg    printf("    major %s, minor %d\n", m, e->minor_code);
403f299d47fSmrg}
404f299d47fSmrg
405f299d47fSmrgstatic void
406da39bf31Smrgdo_NoExpose(XEvent *eventp)
407f299d47fSmrg{
408f299d47fSmrg    XNoExposeEvent *e = (XNoExposeEvent *) eventp;
4091a2dd139Smrg    const char *m;
410f299d47fSmrg    char mdummy[10];
411f299d47fSmrg
412f299d47fSmrg    switch (e->major_code) {
413da39bf31Smrg    case X_CopyArea:
414da39bf31Smrg        m = "CopyArea";
415da39bf31Smrg        break;
416da39bf31Smrg    case X_CopyPlane:
417da39bf31Smrg        m = "CopyPlane";
418da39bf31Smrg        break;
419da39bf31Smrg    default:
420da39bf31Smrg        m = mdummy;
421da39bf31Smrg        snprintf(mdummy, sizeof(mdummy), "%d", e->major_code);
422da39bf31Smrg        break;
423f299d47fSmrg    }
424f299d47fSmrg
425da39bf31Smrg    printf("    major %s, minor %d\n", m, e->minor_code);
426f299d47fSmrg    return;
427f299d47fSmrg}
428f299d47fSmrg
429f299d47fSmrgstatic void
430da39bf31Smrgdo_VisibilityNotify(XEvent *eventp)
431f299d47fSmrg{
432f299d47fSmrg    XVisibilityEvent *e = (XVisibilityEvent *) eventp;
4331a2dd139Smrg    const char *v;
434f299d47fSmrg    char vdummy[10];
435f299d47fSmrg
436f299d47fSmrg    switch (e->state) {
437da39bf31Smrg    case VisibilityUnobscured:
438da39bf31Smrg        v = "VisibilityUnobscured";
439da39bf31Smrg        break;
440da39bf31Smrg    case VisibilityPartiallyObscured:
441da39bf31Smrg        v = "VisibilityPartiallyObscured";
442da39bf31Smrg        break;
443da39bf31Smrg    case VisibilityFullyObscured:
444da39bf31Smrg        v = "VisibilityFullyObscured";
445da39bf31Smrg        break;
446da39bf31Smrg    default:
447da39bf31Smrg        v = vdummy;
448da39bf31Smrg        snprintf(vdummy, sizeof(vdummy), "%d", e->state);
449da39bf31Smrg        break;
450f299d47fSmrg    }
451f299d47fSmrg
452da39bf31Smrg    printf("    state %s\n", v);
453f299d47fSmrg}
454f299d47fSmrg
455f299d47fSmrgstatic void
456da39bf31Smrgdo_CreateNotify(XEvent *eventp)
457f299d47fSmrg{
458f299d47fSmrg    XCreateWindowEvent *e = (XCreateWindowEvent *) eventp;
459f299d47fSmrg
460da39bf31Smrg    printf("    parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d\n",
461da39bf31Smrg           e->parent, e->window, e->x, e->y, e->width, e->height);
462da39bf31Smrg    printf("border_width %d, override %s\n",
463da39bf31Smrg           e->border_width, e->override_redirect ? Yes : No);
464f299d47fSmrg}
465f299d47fSmrg
466f299d47fSmrgstatic void
467da39bf31Smrgdo_DestroyNotify(XEvent *eventp)
468f299d47fSmrg{
469f299d47fSmrg    XDestroyWindowEvent *e = (XDestroyWindowEvent *) eventp;
470f299d47fSmrg
471da39bf31Smrg    printf("    event 0x%lx, window 0x%lx\n", e->event, e->window);
472f299d47fSmrg}
473f299d47fSmrg
474f299d47fSmrgstatic void
475da39bf31Smrgdo_UnmapNotify(XEvent *eventp)
476f299d47fSmrg{
477f299d47fSmrg    XUnmapEvent *e = (XUnmapEvent *) eventp;
478f299d47fSmrg
479da39bf31Smrg    printf("    event 0x%lx, window 0x%lx, from_configure %s\n",
480da39bf31Smrg           e->event, e->window, e->from_configure ? Yes : No);
481f299d47fSmrg}
482f299d47fSmrg
483f299d47fSmrgstatic void
484da39bf31Smrgdo_MapNotify(XEvent *eventp)
485f299d47fSmrg{
486f299d47fSmrg    XMapEvent *e = (XMapEvent *) eventp;
487f299d47fSmrg
488da39bf31Smrg    printf("    event 0x%lx, window 0x%lx, override %s\n",
489da39bf31Smrg           e->event, e->window, e->override_redirect ? Yes : No);
490f299d47fSmrg}
491f299d47fSmrg
492f299d47fSmrgstatic void
493da39bf31Smrgdo_MapRequest(XEvent *eventp)
494f299d47fSmrg{
495f299d47fSmrg    XMapRequestEvent *e = (XMapRequestEvent *) eventp;
496f299d47fSmrg
497da39bf31Smrg    printf("    parent 0x%lx, window 0x%lx\n", e->parent, e->window);
498f299d47fSmrg}
499f299d47fSmrg
500f299d47fSmrgstatic void
501da39bf31Smrgdo_ReparentNotify(XEvent *eventp)
502f299d47fSmrg{
503f299d47fSmrg    XReparentEvent *e = (XReparentEvent *) eventp;
504f299d47fSmrg
505da39bf31Smrg    printf("    event 0x%lx, window 0x%lx, parent 0x%lx,\n",
506da39bf31Smrg           e->event, e->window, e->parent);
507da39bf31Smrg    printf("    (%d,%d), override %s\n", e->x, e->y,
508da39bf31Smrg           e->override_redirect ? Yes : No);
509f299d47fSmrg}
510f299d47fSmrg
511f299d47fSmrgstatic void
512da39bf31Smrgdo_ConfigureNotify(XEvent *eventp)
513f299d47fSmrg{
514f299d47fSmrg    XConfigureEvent *e = (XConfigureEvent *) eventp;
515f299d47fSmrg
516da39bf31Smrg    printf("    event 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n",
517da39bf31Smrg           e->event, e->window, e->x, e->y, e->width, e->height);
518da39bf31Smrg    printf("    border_width %d, above 0x%lx, override %s\n",
519da39bf31Smrg           e->border_width, e->above, e->override_redirect ? Yes : No);
520f299d47fSmrg}
521f299d47fSmrg
522f299d47fSmrgstatic void
523da39bf31Smrgdo_ConfigureRequest(XEvent *eventp)
524f299d47fSmrg{
525f299d47fSmrg    XConfigureRequestEvent *e = (XConfigureRequestEvent *) eventp;
5261a2dd139Smrg    const char *detail;
527f299d47fSmrg    char ddummy[10];
528f299d47fSmrg
529f299d47fSmrg    switch (e->detail) {
530da39bf31Smrg    case Above:
531da39bf31Smrg        detail = "Above";
532da39bf31Smrg        break;
533da39bf31Smrg    case Below:
534da39bf31Smrg        detail = "Below";
535da39bf31Smrg        break;
536da39bf31Smrg    case TopIf:
537da39bf31Smrg        detail = "TopIf";
538da39bf31Smrg        break;
539da39bf31Smrg    case BottomIf:
540da39bf31Smrg        detail = "BottomIf";
541da39bf31Smrg        break;
542da39bf31Smrg    case Opposite:
543da39bf31Smrg        detail = "Opposite";
544da39bf31Smrg        break;
545da39bf31Smrg    default:
546da39bf31Smrg        detail = ddummy;
547da39bf31Smrg        snprintf(ddummy, sizeof(ddummy), "%d", e->detail);
548da39bf31Smrg        break;
549f299d47fSmrg    }
550f299d47fSmrg
551da39bf31Smrg    printf("    parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n",
552da39bf31Smrg           e->parent, e->window, e->x, e->y, e->width, e->height);
553da39bf31Smrg    printf("    border_width %d, above 0x%lx, detail %s, value 0x%lx\n",
554da39bf31Smrg           e->border_width, e->above, detail, e->value_mask);
555f299d47fSmrg}
556f299d47fSmrg
557f299d47fSmrgstatic void
558da39bf31Smrgdo_GravityNotify(XEvent *eventp)
559f299d47fSmrg{
560f299d47fSmrg    XGravityEvent *e = (XGravityEvent *) eventp;
561f299d47fSmrg
562da39bf31Smrg    printf("    event 0x%lx, window 0x%lx, (%d,%d)\n",
563da39bf31Smrg           e->event, e->window, e->x, e->y);
564f299d47fSmrg}
565f299d47fSmrg
566f299d47fSmrgstatic void
567da39bf31Smrgdo_ResizeRequest(XEvent *eventp)
568f299d47fSmrg{
569f299d47fSmrg    XResizeRequestEvent *e = (XResizeRequestEvent *) eventp;
570f299d47fSmrg
571da39bf31Smrg    printf("    width %d, height %d\n", e->width, e->height);
572f299d47fSmrg}
573f299d47fSmrg
574f299d47fSmrgstatic void
575da39bf31Smrgdo_CirculateNotify(XEvent *eventp)
576f299d47fSmrg{
577f299d47fSmrg    XCirculateEvent *e = (XCirculateEvent *) eventp;
5781a2dd139Smrg    const char *p;
579f299d47fSmrg    char pdummy[10];
580f299d47fSmrg
581f299d47fSmrg    switch (e->place) {
582da39bf31Smrg    case PlaceOnTop:
583da39bf31Smrg        p = "PlaceOnTop";
584da39bf31Smrg        break;
585da39bf31Smrg    case PlaceOnBottom:
586da39bf31Smrg        p = "PlaceOnBottom";
587da39bf31Smrg        break;
588da39bf31Smrg    default:
589da39bf31Smrg        p = pdummy;
590da39bf31Smrg        snprintf(pdummy, sizeof(pdummy), "%d", e->place);
591da39bf31Smrg        break;
592f299d47fSmrg    }
593f299d47fSmrg
594da39bf31Smrg    printf("    event 0x%lx, window 0x%lx, place %s\n", e->event, e->window, p);
595f299d47fSmrg}
596f299d47fSmrg
597f299d47fSmrgstatic void
598da39bf31Smrgdo_CirculateRequest(XEvent *eventp)
599f299d47fSmrg{
600f299d47fSmrg    XCirculateRequestEvent *e = (XCirculateRequestEvent *) eventp;
6011a2dd139Smrg    const char *p;
602f299d47fSmrg    char pdummy[10];
603f299d47fSmrg
604f299d47fSmrg    switch (e->place) {
605da39bf31Smrg    case PlaceOnTop:
606da39bf31Smrg        p = "PlaceOnTop";
607da39bf31Smrg        break;
608da39bf31Smrg    case PlaceOnBottom:
609da39bf31Smrg        p = "PlaceOnBottom";
610da39bf31Smrg        break;
611da39bf31Smrg    default:
612da39bf31Smrg        p = pdummy;
613da39bf31Smrg        snprintf(pdummy, sizeof(pdummy), "%d", e->place);
614da39bf31Smrg        break;
615f299d47fSmrg    }
616f299d47fSmrg
617da39bf31Smrg    printf("    parent 0x%lx, window 0x%lx, place %s\n",
618da39bf31Smrg           e->parent, e->window, p);
619f299d47fSmrg}
620f299d47fSmrg
621f299d47fSmrgstatic void
622da39bf31Smrgdo_PropertyNotify(XEvent *eventp)
623f299d47fSmrg{
624f299d47fSmrg    XPropertyEvent *e = (XPropertyEvent *) eventp;
625da39bf31Smrg    char *aname = XGetAtomName(dpy, e->atom);
6261a2dd139Smrg    const char *s;
627f299d47fSmrg    char sdummy[10];
628f299d47fSmrg
629f299d47fSmrg    switch (e->state) {
630da39bf31Smrg    case PropertyNewValue:
631da39bf31Smrg        s = "PropertyNewValue";
632da39bf31Smrg        break;
633da39bf31Smrg    case PropertyDelete:
634da39bf31Smrg        s = "PropertyDelete";
635da39bf31Smrg        break;
636da39bf31Smrg    default:
637da39bf31Smrg        s = sdummy;
638da39bf31Smrg        snprintf(sdummy, sizeof(sdummy), "%d", e->state);
639da39bf31Smrg        break;
640f299d47fSmrg    }
641f299d47fSmrg
642da39bf31Smrg    printf("    atom 0x%lx (%s), time %lu, state %s\n",
643da39bf31Smrg           e->atom, aname ? aname : Unknown, e->time, s);
644f299d47fSmrg
645da39bf31Smrg    XFree(aname);
646f299d47fSmrg}
647f299d47fSmrg
648f299d47fSmrgstatic void
649da39bf31Smrgdo_SelectionClear(XEvent *eventp)
650f299d47fSmrg{
651f299d47fSmrg    XSelectionClearEvent *e = (XSelectionClearEvent *) eventp;
652da39bf31Smrg    char *sname = XGetAtomName(dpy, e->selection);
653f299d47fSmrg
654da39bf31Smrg    printf("    selection 0x%lx (%s), time %lu\n",
655da39bf31Smrg           e->selection, sname ? sname : Unknown, e->time);
656f299d47fSmrg
657da39bf31Smrg    XFree(sname);
658f299d47fSmrg}
659f299d47fSmrg
660f299d47fSmrgstatic void
661da39bf31Smrgdo_SelectionRequest(XEvent *eventp)
662f299d47fSmrg{
663f299d47fSmrg    XSelectionRequestEvent *e = (XSelectionRequestEvent *) eventp;
664da39bf31Smrg    char *sname = XGetAtomName(dpy, e->selection);
665da39bf31Smrg    char *tname = XGetAtomName(dpy, e->target);
666da39bf31Smrg    char *pname = XGetAtomName(dpy, e->property);
667da39bf31Smrg
668da39bf31Smrg    printf("    owner 0x%lx, requestor 0x%lx, selection 0x%lx (%s),\n",
669da39bf31Smrg           e->owner, e->requestor, e->selection, sname ? sname : Unknown);
670da39bf31Smrg    printf("    target 0x%lx (%s), property 0x%lx (%s), time %lu\n",
671da39bf31Smrg           e->target, tname ? tname : Unknown, e->property,
672da39bf31Smrg           pname ? pname : Unknown, e->time);
673da39bf31Smrg
674da39bf31Smrg    XFree(sname);
675da39bf31Smrg    XFree(tname);
676da39bf31Smrg    XFree(pname);
677f299d47fSmrg}
678f299d47fSmrg
679f299d47fSmrgstatic void
680da39bf31Smrgdo_SelectionNotify(XEvent *eventp)
681f299d47fSmrg{
682f299d47fSmrg    XSelectionEvent *e = (XSelectionEvent *) eventp;
683da39bf31Smrg    char *sname = XGetAtomName(dpy, e->selection);
684da39bf31Smrg    char *tname = XGetAtomName(dpy, e->target);
685da39bf31Smrg    char *pname = XGetAtomName(dpy, e->property);
686da39bf31Smrg
687da39bf31Smrg    printf("    selection 0x%lx (%s), target 0x%lx (%s),\n",
688da39bf31Smrg           e->selection, sname ? sname : Unknown, e->target,
689da39bf31Smrg           tname ? tname : Unknown);
690da39bf31Smrg    printf("    property 0x%lx (%s), time %lu\n",
691da39bf31Smrg           e->property, pname ? pname : Unknown, e->time);
692da39bf31Smrg
693da39bf31Smrg    XFree(sname);
694da39bf31Smrg    XFree(tname);
695da39bf31Smrg    XFree(pname);
696f299d47fSmrg}
697f299d47fSmrg
698f299d47fSmrgstatic void
699da39bf31Smrgdo_ColormapNotify(XEvent *eventp)
700f299d47fSmrg{
701f299d47fSmrg    XColormapEvent *e = (XColormapEvent *) eventp;
7021a2dd139Smrg    const char *s;
703f299d47fSmrg    char sdummy[10];
704f299d47fSmrg
705f299d47fSmrg    switch (e->state) {
706da39bf31Smrg    case ColormapInstalled:
707da39bf31Smrg        s = "ColormapInstalled";
708da39bf31Smrg        break;
709da39bf31Smrg    case ColormapUninstalled:
710da39bf31Smrg        s = "ColormapUninstalled";
711da39bf31Smrg        break;
712da39bf31Smrg    default:
713da39bf31Smrg        s = sdummy;
714da39bf31Smrg        snprintf(sdummy, sizeof(sdummy), "%d", e->state);
715da39bf31Smrg        break;
716f299d47fSmrg    }
717f299d47fSmrg
718da39bf31Smrg    printf("    colormap 0x%lx, new %s, state %s\n",
719da39bf31Smrg           e->colormap, e->new ? Yes : No, s);
720f299d47fSmrg}
721f299d47fSmrg
722f299d47fSmrgstatic void
723da39bf31Smrgdo_ClientMessage(XEvent *eventp)
724f299d47fSmrg{
725f299d47fSmrg    XClientMessageEvent *e = (XClientMessageEvent *) eventp;
726da39bf31Smrg
727da39bf31Smrg    char *mname = XGetAtomName(dpy, e->message_type);
728f299d47fSmrg
729f299d47fSmrg    if (e->message_type == wm_protocols) {
730da39bf31Smrg        char *message = XGetAtomName(dpy, e->data.l[0]);
731da39bf31Smrg
732da39bf31Smrg        printf("    message_type 0x%lx (%s), format %d, message 0x%lx (%s)\n",
733da39bf31Smrg               e->message_type, mname ? mname : Unknown, e->format,
734da39bf31Smrg               e->data.l[0], message);
735da39bf31Smrg        XFree(message);
736f299d47fSmrg    }
737f299d47fSmrg    else {
738da39bf31Smrg        printf("    message_type 0x%lx (%s), format %d\n",
739da39bf31Smrg               e->message_type, mname ? mname : Unknown, e->format);
740f299d47fSmrg    }
741f299d47fSmrg
742da39bf31Smrg    XFree(mname);
743f299d47fSmrg
7441a2dd139Smrg    if (e->format == 32
7451a2dd139Smrg        && e->message_type == wm_protocols
7461a2dd139Smrg        && (Atom) e->data.l[0] == wm_delete_window)
747da39bf31Smrg        exit(0);
748f299d47fSmrg}
749f299d47fSmrg
750f299d47fSmrgstatic void
751da39bf31Smrgdo_MappingNotify(XEvent *eventp)
752f299d47fSmrg{
753f299d47fSmrg    XMappingEvent *e = (XMappingEvent *) eventp;
7541a2dd139Smrg    const char *r;
755f299d47fSmrg    char rdummy[10];
756f299d47fSmrg
757f299d47fSmrg    switch (e->request) {
758da39bf31Smrg    case MappingModifier:
759da39bf31Smrg        r = "MappingModifier";
760da39bf31Smrg        break;
761da39bf31Smrg    case MappingKeyboard:
762da39bf31Smrg        r = "MappingKeyboard";
763da39bf31Smrg        break;
764da39bf31Smrg    case MappingPointer:
765da39bf31Smrg        r = "MappingPointer";
766da39bf31Smrg        break;
767da39bf31Smrg    default:
768da39bf31Smrg        r = rdummy;
769da39bf31Smrg        snprintf(rdummy, sizeof(rdummy), "%d", e->request);
770da39bf31Smrg        break;
771f299d47fSmrg    }
772f299d47fSmrg
773da39bf31Smrg    printf("    request %s, first_keycode %d, count %d\n",
774da39bf31Smrg           r, e->first_keycode, e->count);
775f299d47fSmrg    XRefreshKeyboardMapping(e);
776f299d47fSmrg}
777f299d47fSmrg
7781a2dd139Smrgstatic void
779da39bf31Smrgprint_SubPixelOrder(SubpixelOrder subpixel_order)
7801a2dd139Smrg{
7811a2dd139Smrg    switch (subpixel_order) {
782da39bf31Smrg    case SubPixelUnknown:
783da39bf31Smrg        printf("SubPixelUnknown");
784da39bf31Smrg        return;
785da39bf31Smrg    case SubPixelHorizontalRGB:
786da39bf31Smrg        printf("SubPixelHorizontalRGB");
787da39bf31Smrg        return;
788da39bf31Smrg    case SubPixelHorizontalBGR:
789da39bf31Smrg        printf("SubPixelHorizontalBGR");
790da39bf31Smrg        return;
791da39bf31Smrg    case SubPixelVerticalRGB:
792da39bf31Smrg        printf("SubPixelVerticalRGB");
793da39bf31Smrg        return;
794da39bf31Smrg    case SubPixelVerticalBGR:
795da39bf31Smrg        printf("SubPixelVerticalBGR");
796da39bf31Smrg        return;
797da39bf31Smrg    case SubPixelNone:
798da39bf31Smrg        printf("SubPixelNone");
799da39bf31Smrg        return;
800da39bf31Smrg    default:
801da39bf31Smrg        printf("%d", subpixel_order);
8021a2dd139Smrg    }
8031a2dd139Smrg}
8041a2dd139Smrg
8051a2dd139Smrgstatic void
806da39bf31Smrgprint_Rotation(Rotation rotation)
8071a2dd139Smrg{
8081a2dd139Smrg    if (rotation & RR_Rotate_0)
809da39bf31Smrg        printf("RR_Rotate_0");
8101a2dd139Smrg    else if (rotation & RR_Rotate_90)
811da39bf31Smrg        printf("RR_Rotate_90");
8121a2dd139Smrg    else if (rotation & RR_Rotate_180)
813da39bf31Smrg        printf("RR_Rotate_180");
8141a2dd139Smrg    else if (rotation & RR_Rotate_270)
815da39bf31Smrg        printf("RR_Rotate_270");
8161a2dd139Smrg    else {
817da39bf31Smrg        printf("%d", rotation);
8181a2dd139Smrg        return;
8191a2dd139Smrg    }
8201a2dd139Smrg    if (rotation & RR_Reflect_X)
821da39bf31Smrg        printf(", RR_Reflect_X");
8221a2dd139Smrg    if (rotation & RR_Reflect_Y)
823da39bf31Smrg        printf(", RR_Reflect_Y");
8241a2dd139Smrg}
825f299d47fSmrg
8261a2dd139Smrgstatic void
827da39bf31Smrgprint_Connection(Connection connection)
8281a2dd139Smrg{
8291a2dd139Smrg    switch (connection) {
830da39bf31Smrg    case RR_Connected:
831da39bf31Smrg        printf("RR_Connected");
832da39bf31Smrg        return;
833da39bf31Smrg    case RR_Disconnected:
834da39bf31Smrg        printf("RR_Disconnected");
835da39bf31Smrg        return;
836da39bf31Smrg    case RR_UnknownConnection:
837da39bf31Smrg        printf("RR_UnknownConnection");
838da39bf31Smrg        return;
839da39bf31Smrg    default:
840da39bf31Smrg        printf("%d", connection);
8411a2dd139Smrg    }
8421a2dd139Smrg}
843f299d47fSmrg
844f299d47fSmrgstatic void
845da39bf31Smrgdo_RRScreenChangeNotify(XEvent *eventp)
8461a2dd139Smrg{
8471a2dd139Smrg    XRRScreenChangeNotifyEvent *e = (XRRScreenChangeNotifyEvent *) eventp;
8481a2dd139Smrg
849da39bf31Smrg    XRRUpdateConfiguration(eventp);
850da39bf31Smrg    printf("    root 0x%lx, timestamp %lu, config_timestamp %lu\n",
851da39bf31Smrg           e->root, e->timestamp, e->config_timestamp);
852da39bf31Smrg    printf("    size_index %hu", e->size_index);
853da39bf31Smrg    printf(", subpixel_order ");
854da39bf31Smrg    print_SubPixelOrder(e->subpixel_order);
855da39bf31Smrg    printf("\n    rotation ");
856da39bf31Smrg    print_Rotation(e->rotation);
8571a2dd139Smrg    printf("\n    width %d, height %d, mwidth %d, mheight %d\n",
8581a2dd139Smrg           e->width, e->height, e->mwidth, e->mheight);
8591a2dd139Smrg}
8601a2dd139Smrg
8611a2dd139Smrgstatic void
862da39bf31Smrgdo_RRNotify_OutputChange(XEvent *eventp, XRRScreenResources *screen_resources)
8631a2dd139Smrg{
8641a2dd139Smrg    XRROutputChangeNotifyEvent *e = (XRROutputChangeNotifyEvent *) eventp;
8651a2dd139Smrg    XRROutputInfo *output_info = NULL;
8661a2dd139Smrg    XRRModeInfo *mode_info = NULL;
8671a2dd139Smrg
8681a2dd139Smrg    if (screen_resources) {
8691a2dd139Smrg        int i;
8701a2dd139Smrg
871da39bf31Smrg        output_info = XRRGetOutputInfo(dpy, screen_resources, e->output);
8721a2dd139Smrg        for (i = 0; i < screen_resources->nmode; i++)
8731a2dd139Smrg            if (screen_resources->modes[i].id == e->mode) {
874da39bf31Smrg                mode_info = &screen_resources->modes[i];
875da39bf31Smrg                break;
8761a2dd139Smrg            }
8771a2dd139Smrg    }
878da39bf31Smrg    printf("    subtype XRROutputChangeNotifyEvent\n");
8791a2dd139Smrg    if (output_info)
880da39bf31Smrg        printf("    output %s, ", output_info->name);
8811a2dd139Smrg    else
882da39bf31Smrg        printf("    output %lu, ", e->output);
8831a2dd139Smrg    if (e->crtc)
8841a2dd139Smrg        printf("crtc %lu, ", e->crtc);
8851a2dd139Smrg    else
8861a2dd139Smrg        printf("crtc None, ");
8871a2dd139Smrg    if (mode_info)
888da39bf31Smrg        printf("mode %s (%dx%d)\n", mode_info->name, mode_info->width,
889da39bf31Smrg               mode_info->height);
8901a2dd139Smrg    else if (e->mode)
891da39bf31Smrg        printf("mode %lu\n", e->mode);
8921a2dd139Smrg    else
8931a2dd139Smrg        printf("mode None\n");
894da39bf31Smrg    printf("    rotation ");
895da39bf31Smrg    print_Rotation(e->rotation);
896da39bf31Smrg    printf("\n    connection ");
897da39bf31Smrg    print_Connection(e->connection);
898da39bf31Smrg    printf(", subpixel_order ");
899da39bf31Smrg    print_SubPixelOrder(e->subpixel_order);
900da39bf31Smrg    printf("\n");
901da39bf31Smrg    XRRFreeOutputInfo(output_info);
9021a2dd139Smrg}
9031a2dd139Smrg
9041a2dd139Smrgstatic void
905da39bf31Smrgdo_RRNotify_CrtcChange(XEvent *eventp, XRRScreenResources *screen_resources)
9061a2dd139Smrg{
9071a2dd139Smrg    XRRCrtcChangeNotifyEvent *e = (XRRCrtcChangeNotifyEvent *) eventp;
9081a2dd139Smrg    XRRModeInfo *mode_info = NULL;
9091a2dd139Smrg
9101a2dd139Smrg    if (screen_resources) {
9111a2dd139Smrg        int i;
9121a2dd139Smrg
9131a2dd139Smrg        for (i = 0; i < screen_resources->nmode; i++)
9141a2dd139Smrg            if (screen_resources->modes[i].id == e->mode) {
915da39bf31Smrg                mode_info = &screen_resources->modes[i];
916da39bf31Smrg                break;
9171a2dd139Smrg            }
9181a2dd139Smrg    }
919da39bf31Smrg    printf("    subtype XRRCrtcChangeNotifyEvent\n");
9201a2dd139Smrg    if (e->crtc)
9211a2dd139Smrg        printf("    crtc %lu, ", e->crtc);
9221a2dd139Smrg    else
9231a2dd139Smrg        printf("    crtc None, ");
9241a2dd139Smrg    if (mode_info)
925da39bf31Smrg        printf("mode %s, ", mode_info->name);
9261a2dd139Smrg    else if (e->mode)
927da39bf31Smrg        printf("mode %lu, ", e->mode);
9281a2dd139Smrg    else
9291a2dd139Smrg        printf("mode None, ");
930da39bf31Smrg    printf("rotation ");
931da39bf31Smrg    print_Rotation(e->rotation);
932da39bf31Smrg    printf("\n    x %d, y %d, width %d, height %d\n",
933da39bf31Smrg           e->x, e->y, e->width, e->height);
9341a2dd139Smrg}
9351a2dd139Smrg
9361a2dd139Smrgstatic void
937da39bf31Smrgdo_RRNotify_OutputProperty(XEvent *eventp,
938da39bf31Smrg                           XRRScreenResources *screen_resources)
9391a2dd139Smrg{
9401a2dd139Smrg    XRROutputPropertyNotifyEvent *e = (XRROutputPropertyNotifyEvent *) eventp;
9411a2dd139Smrg    XRROutputInfo *output_info = NULL;
942da39bf31Smrg    char *property = XGetAtomName(dpy, e->property);
9431a2dd139Smrg
9441a2dd139Smrg    if (screen_resources)
945da39bf31Smrg        output_info = XRRGetOutputInfo(dpy, screen_resources, e->output);
946da39bf31Smrg    printf("    subtype XRROutputPropertyChangeNotifyEvent\n");
9471a2dd139Smrg    if (output_info)
948da39bf31Smrg        printf("    output %s, ", output_info->name);
9491a2dd139Smrg    else
950da39bf31Smrg        printf("    output %lu, ", e->output);
951da39bf31Smrg    printf("property %s, timestamp %lu, state ", property, e->timestamp);
9521a2dd139Smrg    if (e->state == PropertyNewValue)
953da39bf31Smrg        printf("NewValue\n");
9541a2dd139Smrg    else if (e->state == PropertyDelete)
955da39bf31Smrg        printf("Delete\n");
9561a2dd139Smrg    else
957da39bf31Smrg        printf("%d\n", e->state);
958da39bf31Smrg    XRRFreeOutputInfo(output_info);
959da39bf31Smrg    XFree(property);
9601a2dd139Smrg}
9611a2dd139Smrg
9621a2dd139Smrgstatic void
963da39bf31Smrgdo_RRNotify(XEvent *eventp)
9641a2dd139Smrg{
9651a2dd139Smrg    XRRNotifyEvent *e = (XRRNotifyEvent *) eventp;
9661a2dd139Smrg    XRRScreenResources *screen_resources;
9671a2dd139Smrg
968da39bf31Smrg    XRRUpdateConfiguration(eventp);
969da39bf31Smrg    screen_resources = XRRGetScreenResources(dpy, e->window);
970da39bf31Smrg    prologue(eventp, "RRNotify");
9711a2dd139Smrg    switch (e->subtype) {
972da39bf31Smrg    case RRNotify_OutputChange:
973da39bf31Smrg        do_RRNotify_OutputChange(eventp, screen_resources);
974da39bf31Smrg        break;
975da39bf31Smrg    case RRNotify_CrtcChange:
976da39bf31Smrg        do_RRNotify_CrtcChange(eventp, screen_resources);
977da39bf31Smrg        break;
978da39bf31Smrg    case RRNotify_OutputProperty:
979da39bf31Smrg        do_RRNotify_OutputProperty(eventp, screen_resources);
980da39bf31Smrg        break;
981da39bf31Smrg    default:
982da39bf31Smrg        printf("    subtype %d\n", e->subtype);
9831a2dd139Smrg    }
984da39bf31Smrg    XRRFreeScreenResources(screen_resources);
9851a2dd139Smrg}
9861a2dd139Smrg
9871a2dd139Smrgstatic void
988da39bf31Smrgset_sizehints(XSizeHints *hintp, int min_width, int min_height,
989da39bf31Smrg              int defwidth, int defheight, int defx, int defy, char *geom)
990f299d47fSmrg{
991f299d47fSmrg    int geom_result;
992f299d47fSmrg
993f299d47fSmrg    /* set the size hints, algorithm from xlib xbiff */
994f299d47fSmrg
995f299d47fSmrg    hintp->width = hintp->min_width = min_width;
996f299d47fSmrg    hintp->height = hintp->min_height = min_height;
997f299d47fSmrg    hintp->flags = PMinSize;
998f299d47fSmrg    hintp->x = hintp->y = 0;
999f299d47fSmrg    geom_result = NoValue;
1000f299d47fSmrg    if (geom != NULL) {
1001da39bf31Smrg        geom_result = XParseGeometry(geom, &hintp->x, &hintp->y,
1002da39bf31Smrg                                     (unsigned int *) &hintp->width,
1003da39bf31Smrg                                     (unsigned int *) &hintp->height);
1004da39bf31Smrg        if ((geom_result & WidthValue) && (geom_result & HeightValue)) {
1005f299d47fSmrg#ifndef max
1006f299d47fSmrg#define max(a,b) ((a) > (b) ? (a) : (b))
1007f299d47fSmrg#endif
1008da39bf31Smrg            hintp->width = max(hintp->width, hintp->min_width);
1009da39bf31Smrg            hintp->height = max(hintp->height, hintp->min_height);
1010da39bf31Smrg            hintp->flags |= USSize;
1011da39bf31Smrg        }
1012da39bf31Smrg        if ((geom_result & XValue) && (geom_result & YValue)) {
1013da39bf31Smrg            hintp->flags += USPosition;
1014da39bf31Smrg        }
1015f299d47fSmrg    }
1016f299d47fSmrg    if (!(hintp->flags & USSize)) {
1017da39bf31Smrg        hintp->width = defwidth;
1018da39bf31Smrg        hintp->height = defheight;
1019da39bf31Smrg        hintp->flags |= PSize;
1020f299d47fSmrg    }
1021f299d47fSmrg/*
1022f299d47fSmrg    if (!(hintp->flags & USPosition)) {
1023f299d47fSmrg	hintp->x = defx;
1024f299d47fSmrg	hintp->y = defy;
1025f299d47fSmrg	hintp->flags |= PPosition;
1026f299d47fSmrg    }
1027f299d47fSmrg */
1028f299d47fSmrg    if (geom_result & XNegative) {
1029da39bf31Smrg        hintp->x = DisplayWidth(dpy, DefaultScreen(dpy)) + hintp->x -
1030da39bf31Smrg            hintp->width;
1031f299d47fSmrg    }
1032f299d47fSmrg    if (geom_result & YNegative) {
1033da39bf31Smrg        hintp->y = DisplayHeight(dpy, DefaultScreen(dpy)) + hintp->y -
1034da39bf31Smrg            hintp->height;
1035f299d47fSmrg    }
1036f299d47fSmrg}
1037f299d47fSmrg
1038f299d47fSmrgstatic void
1039da39bf31Smrgusage(const char *errmsg)
1040f299d47fSmrg{
1041da39bf31Smrg    const char *msg =
1042da39bf31Smrg"    -display displayname                X server to contact\n"
1043da39bf31Smrg"    -geometry geom                      size and location of window\n"
1044da39bf31Smrg"    -bw pixels                          border width in pixels\n"
1045da39bf31Smrg"    -bs {NotUseful,WhenMapped,Always}   backingstore attribute\n"
1046da39bf31Smrg"    -id windowid                        use existing window\n"
1047da39bf31Smrg"    -root                               use root window\n"
1048da39bf31Smrg"    -s                                  set save-unders attribute\n"
1049da39bf31Smrg"    -name string                        window name\n"
1050da39bf31Smrg"    -rv                                 reverse video\n"
1051da39bf31Smrg"    -event event_mask                   select 'event_mask' events\n"
1052da39bf31Smrg"           Supported event masks: keyboard mouse expose visibility structure\n"
1053da39bf31Smrg"                                  substructure focus property colormap\n"
1054da39bf31Smrg"                                  owner_grab_button randr button\n"
1055da39bf31Smrg"           This option can be specified multiple times to select multiple\n"
1056da39bf31Smrg"           event masks.\n"
1057da39bf31Smrg"    -version                            print version and exit\n"
1058da39bf31Smrg"\n";
1059f299d47fSmrg
106005641e18Smrg    if (errmsg != NULL)
1061da39bf31Smrg        fprintf(stderr, "%s: %s\n", ProgramName, errmsg);
106205641e18Smrg
1063da39bf31Smrg    fprintf(stderr, "usage:  %s [-options ...]\n", ProgramName);
1064da39bf31Smrg    fprintf(stderr, "where options include:\n");
1065da39bf31Smrg    fputs(msg, stderr);
1066f299d47fSmrg
1067da39bf31Smrg    exit(1);
1068f299d47fSmrg}
1069f299d47fSmrg
1070f299d47fSmrgstatic int
1071da39bf31Smrgparse_backing_store(const char *s)
1072f299d47fSmrg{
1073da39bf31Smrg    size_t len = strlen(s);
1074f299d47fSmrg
1075da39bf31Smrg    if (strncasecmp(s, "NotUseful", len) == 0)
1076da39bf31Smrg        return (NotUseful);
1077da39bf31Smrg    if (strncasecmp(s, "WhenMapped", len) == 0)
1078da39bf31Smrg        return (WhenMapped);
1079da39bf31Smrg    if (strncasecmp(s, "Always", len) == 0)
1080da39bf31Smrg        return (Always);
1081f299d47fSmrg
1082da39bf31Smrg    fprintf(stderr, "%s: unrecognized argument '%s' for -bs\n", ProgramName, s);
1083da39bf31Smrg    usage(NULL);
1084f299d47fSmrg}
1085f299d47fSmrg
10861a2dd139Smrgstatic Bool
1087da39bf31Smrgparse_event_mask(const char *s, long event_masks[])
10881a2dd139Smrg{
10891a2dd139Smrg    const struct {
10901a2dd139Smrg        const char *name;
10911a2dd139Smrg        enum EventMaskIndex mask_index;
10921a2dd139Smrg        long mask;
10931a2dd139Smrg    } events[] = {
10941a2dd139Smrg        { "keyboard",
10951a2dd139Smrg          EVENT_MASK_INDEX_CORE,
10961a2dd139Smrg          KeyPressMask | KeyReleaseMask | KeymapStateMask },
10971a2dd139Smrg        { "mouse",
10981a2dd139Smrg          EVENT_MASK_INDEX_CORE,
10991a2dd139Smrg          ButtonPressMask | ButtonReleaseMask | EnterWindowMask |
11001a2dd139Smrg          LeaveWindowMask | PointerMotionMask | Button1MotionMask |
11011a2dd139Smrg          Button2MotionMask | Button3MotionMask | Button4MotionMask |
11021a2dd139Smrg          Button5MotionMask | ButtonMotionMask },
1103da39bf31Smrg        { "button",
110405641e18Smrg          EVENT_MASK_INDEX_CORE,
110505641e18Smrg          ButtonPressMask | ButtonReleaseMask },
11061a2dd139Smrg        { "expose",
11071a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11081a2dd139Smrg          ExposureMask },
11091a2dd139Smrg        { "visibility",
11101a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11111a2dd139Smrg          VisibilityChangeMask },
11121a2dd139Smrg        { "structure",
11131a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11141a2dd139Smrg          StructureNotifyMask },
11151a2dd139Smrg        { "substructure",
11161a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11171a2dd139Smrg          SubstructureNotifyMask | SubstructureRedirectMask },
11181a2dd139Smrg        { "focus",
11191a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11201a2dd139Smrg          FocusChangeMask },
11211a2dd139Smrg        { "property",
11221a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11231a2dd139Smrg          PropertyChangeMask },
11241a2dd139Smrg        { "colormap",
11251a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11261a2dd139Smrg          ColormapChangeMask },
11271a2dd139Smrg        { "owner_grab_button",
11281a2dd139Smrg          EVENT_MASK_INDEX_CORE,
11291a2dd139Smrg          OwnerGrabButtonMask },
11301a2dd139Smrg        { "randr",
11311a2dd139Smrg          EVENT_MASK_INDEX_RANDR,
11321a2dd139Smrg          RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask |
11331a2dd139Smrg          RROutputChangeNotifyMask | RROutputPropertyNotifyMask },
11341a2dd139Smrg        { NULL, 0, 0 }
11351a2dd139Smrg    };
11361a2dd139Smrg    int i;
11371a2dd139Smrg
11381a2dd139Smrg    for (i = 0; events[i].name; i++) {
11391a2dd139Smrg        if (!s || !strcmp(s, events[i].name)) {
11401a2dd139Smrg            event_masks[events[i].mask_index] |= events[i].mask;
11411a2dd139Smrg            if (s)
11421a2dd139Smrg                return True;
11431a2dd139Smrg        }
11441a2dd139Smrg    }
11451a2dd139Smrg
114605641e18Smrg    if (s != NULL)
1147da39bf31Smrg        fprintf(stderr, "%s: unrecognized event mask '%s'\n", ProgramName, s);
114805641e18Smrg
11491a2dd139Smrg    return False;
11501a2dd139Smrg}
11511a2dd139Smrg
1152f299d47fSmrgint
1153da39bf31Smrgmain(int argc, char **argv)
1154f299d47fSmrg{
1155f299d47fSmrg    char *displayname = NULL;
1156f299d47fSmrg    char *geom = NULL;
1157f299d47fSmrg    int i;
1158f299d47fSmrg    XSizeHints hints;
1159f299d47fSmrg    int borderwidth = 2;
1160f299d47fSmrg    Window w, subw;
1161f299d47fSmrg    XSetWindowAttributes attr;
1162f299d47fSmrg    XWindowAttributes wattr;
1163f299d47fSmrg    unsigned long mask = 0L;
1164f299d47fSmrg    int done;
11651a2dd139Smrg    const char *name = "Event Tester";
1166f299d47fSmrg    Bool reverse = False;
1167625f88beSmrg    Bool use_root = False;
1168f299d47fSmrg    unsigned long back, fore;
1169f299d47fSmrg    XIM xim;
1170f299d47fSmrg    XIMStyles *xim_styles;
1171f299d47fSmrg    XIMStyle xim_style = 0;
1172f299d47fSmrg    char *modifiers;
1173f299d47fSmrg    char *imvalret;
11741a2dd139Smrg    long event_masks[NUM_EVENT_MASKS];
11751a2dd139Smrg    Bool event_mask_specified = False;
1176f299d47fSmrg
1177f299d47fSmrg    ProgramName = argv[0];
1178f299d47fSmrg
1179da39bf31Smrg    if (setlocale(LC_ALL, "") == NULL) {
1180da39bf31Smrg        fprintf(stderr, "%s: warning: could not set default locale\n",
1181da39bf31Smrg                ProgramName);
1182f299d47fSmrg    }
1183f299d47fSmrg
11841a2dd139Smrg    memset(event_masks, 0, sizeof(event_masks));
11851a2dd139Smrg
1186f299d47fSmrg    w = 0;
1187f299d47fSmrg    for (i = 1; i < argc; i++) {
1188da39bf31Smrg        char *arg = argv[i];
1189da39bf31Smrg
1190da39bf31Smrg        if (arg[0] == '-') {
1191da39bf31Smrg            switch (arg[1]) {
1192da39bf31Smrg            case 'd':          /* -display host:dpy */
1193da39bf31Smrg                if (++i >= argc)
1194da39bf31Smrg                    usage("-display requires an argument");
1195da39bf31Smrg                displayname = argv[i];
1196da39bf31Smrg                continue;
1197da39bf31Smrg            case 'g':          /* -geometry geom */
1198da39bf31Smrg                if (++i >= argc)
1199da39bf31Smrg                    usage("-geometry requires an argument");
1200da39bf31Smrg                geom = argv[i];
1201da39bf31Smrg                continue;
1202da39bf31Smrg            case 'b':
1203da39bf31Smrg                switch (arg[2]) {
1204da39bf31Smrg                case 'w':      /* -bw pixels */
1205da39bf31Smrg                    if (++i >= argc)
1206da39bf31Smrg                        usage("-bw requires an argument");
1207da39bf31Smrg                    borderwidth = atoi(argv[i]);
1208da39bf31Smrg                    continue;
1209da39bf31Smrg                case 's':      /* -bs type */
1210da39bf31Smrg                    if (++i >= argc)
1211da39bf31Smrg                        usage("-bs requires an argument");
1212da39bf31Smrg                    attr.backing_store = parse_backing_store(argv[i]);
1213da39bf31Smrg                    mask |= CWBackingStore;
1214da39bf31Smrg                    continue;
1215da39bf31Smrg                default:
1216da39bf31Smrg                    goto unrecognized;
1217da39bf31Smrg                }
1218da39bf31Smrg            case 'i':          /* -id */
1219da39bf31Smrg                if (++i >= argc)
1220da39bf31Smrg                    usage("-id requires an argument");
1221da39bf31Smrg                sscanf(argv[i], "0x%lx", &w);
1222da39bf31Smrg                if (!w)
1223da39bf31Smrg                    sscanf(argv[i], "%lu", &w);
1224da39bf31Smrg                if (!w) {
1225da39bf31Smrg                    fprintf(stderr,
1226da39bf31Smrg                            "%s: unable to parse argument '%s' for -id\n",
1227da39bf31Smrg                            ProgramName, argv[i]);
1228da39bf31Smrg                    usage(NULL);
1229da39bf31Smrg                }
1230da39bf31Smrg                continue;
1231da39bf31Smrg            case 'n':          /* -name */
1232da39bf31Smrg                if (++i >= argc)
1233da39bf31Smrg                    usage("-name requires an argument");
1234da39bf31Smrg                name = argv[i];
1235da39bf31Smrg                continue;
1236da39bf31Smrg            case 'r':
1237da39bf31Smrg                switch (arg[2]) {
1238da39bf31Smrg                case 'o':      /* -root */
1239da39bf31Smrg                    use_root = True;
1240da39bf31Smrg                    continue;
1241da39bf31Smrg                case 'v':      /* -rv */
1242da39bf31Smrg                    reverse = True;
1243da39bf31Smrg                    continue;
1244da39bf31Smrg                default:
1245da39bf31Smrg                    goto unrecognized;
1246da39bf31Smrg                }
1247da39bf31Smrg                continue;
1248da39bf31Smrg            case 's':          /* -s */
1249da39bf31Smrg                attr.save_under = True;
1250da39bf31Smrg                mask |= CWSaveUnder;
1251da39bf31Smrg                continue;
1252da39bf31Smrg            case 'e':          /* -event */
1253da39bf31Smrg                if (++i >= argc)
1254da39bf31Smrg                    usage("-event requires an argument");
1255da39bf31Smrg                if (!parse_event_mask(argv[i], event_masks))
1256da39bf31Smrg                    usage(NULL);
1257da39bf31Smrg                event_mask_specified = True;
1258da39bf31Smrg                continue;
1259da39bf31Smrg            case 'v':
1260da39bf31Smrg                puts(PACKAGE_STRING);
1261da39bf31Smrg                exit(0);
1262da39bf31Smrg            default:
1263da39bf31Smrg                goto unrecognized;
1264da39bf31Smrg            }                   /* end switch on - */
1265da39bf31Smrg        }
1266da39bf31Smrg        else {
1267da39bf31Smrg unrecognized:
1268da39bf31Smrg            fprintf(stderr, "%s: unrecognized argument '%s'\n",
1269da39bf31Smrg                    ProgramName, arg);
1270da39bf31Smrg            usage(NULL);
1271da39bf31Smrg        }
1272da39bf31Smrg    }                           /* end for over argc */
1273f299d47fSmrg
12741a2dd139Smrg    /* if no -event options were specified, pretend all of them were */
12751a2dd139Smrg    if (!event_mask_specified)
1276da39bf31Smrg        parse_event_mask(NULL, event_masks);
12771a2dd139Smrg
1278da39bf31Smrg    dpy = XOpenDisplay(displayname);
1279f299d47fSmrg    if (!dpy) {
1280da39bf31Smrg        fprintf(stderr, "%s:  unable to open display '%s'\n",
1281da39bf31Smrg                ProgramName, XDisplayName(displayname));
1282da39bf31Smrg        exit(1);
1283f299d47fSmrg    }
1284f299d47fSmrg
1285f299d47fSmrg    /* we're testing the default input method */
1286da39bf31Smrg    modifiers = XSetLocaleModifiers("@im=none");
1287f299d47fSmrg    if (modifiers == NULL) {
1288da39bf31Smrg        fprintf(stderr, "%s:  XSetLocaleModifiers failed\n", ProgramName);
1289f299d47fSmrg    }
1290f299d47fSmrg
1291da39bf31Smrg    xim = XOpenIM(dpy, NULL, NULL, NULL);
1292f299d47fSmrg    if (xim == NULL) {
1293da39bf31Smrg        fprintf(stderr, "%s:  XOpenIM failed\n", ProgramName);
1294f299d47fSmrg    }
1295f299d47fSmrg
1296f299d47fSmrg    if (xim) {
1297da39bf31Smrg        imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL);
1298f299d47fSmrg        if (imvalret != NULL || xim_styles == NULL) {
1299da39bf31Smrg            fprintf(stderr, "%s:  input method doesn't support any styles\n",
1300da39bf31Smrg                    ProgramName);
1301f299d47fSmrg        }
1302f299d47fSmrg
1303f299d47fSmrg        if (xim_styles) {
1304f299d47fSmrg            xim_style = 0;
1305da39bf31Smrg            for (i = 0; i < xim_styles->count_styles; i++) {
1306f299d47fSmrg                if (xim_styles->supported_styles[i] ==
1307f299d47fSmrg                    (XIMPreeditNothing | XIMStatusNothing)) {
1308f299d47fSmrg                    xim_style = xim_styles->supported_styles[i];
1309f299d47fSmrg                    break;
1310f299d47fSmrg                }
1311f299d47fSmrg            }
1312f299d47fSmrg
1313f299d47fSmrg            if (xim_style == 0) {
1314da39bf31Smrg                fprintf(stderr,
1315da39bf31Smrg                        "%s: input method doesn't support the style we support\n",
1316da39bf31Smrg                        ProgramName);
1317f299d47fSmrg            }
1318da39bf31Smrg            XFree(xim_styles);
1319f299d47fSmrg        }
13201a2dd139Smrg    }
1321f299d47fSmrg
1322da39bf31Smrg    screen = DefaultScreen(dpy);
1323f299d47fSmrg
13241a2dd139Smrg    attr.event_mask = event_masks[EVENT_MASK_INDEX_CORE];
1325f299d47fSmrg
1326625f88beSmrg    if (use_root)
1327da39bf31Smrg        w = RootWindow(dpy, screen);
1328625f88beSmrg
1329f299d47fSmrg    if (w) {
1330da39bf31Smrg        XGetWindowAttributes(dpy, w, &wattr);
1331da39bf31Smrg        if (wattr.all_event_masks & ButtonPressMask)
1332da39bf31Smrg            attr.event_mask &= ~ButtonPressMask;
1333da39bf31Smrg        attr.event_mask &= ~SubstructureRedirectMask;
1334da39bf31Smrg        XSelectInput(dpy, w, attr.event_mask);
1335da39bf31Smrg    }
1336da39bf31Smrg    else {
1337da39bf31Smrg        set_sizehints(&hints, OUTER_WINDOW_MIN_WIDTH, OUTER_WINDOW_MIN_HEIGHT,
1338da39bf31Smrg                      OUTER_WINDOW_DEF_WIDTH, OUTER_WINDOW_DEF_HEIGHT,
1339da39bf31Smrg                      OUTER_WINDOW_DEF_X, OUTER_WINDOW_DEF_Y, geom);
1340da39bf31Smrg
1341da39bf31Smrg        if (reverse) {
1342da39bf31Smrg            back = BlackPixel(dpy, screen);
1343da39bf31Smrg            fore = WhitePixel(dpy, screen);
1344da39bf31Smrg        }
1345da39bf31Smrg        else {
1346da39bf31Smrg            back = WhitePixel(dpy, screen);
1347da39bf31Smrg            fore = BlackPixel(dpy, screen);
1348da39bf31Smrg        }
1349da39bf31Smrg
1350da39bf31Smrg        attr.background_pixel = back;
1351da39bf31Smrg        attr.border_pixel = fore;
1352da39bf31Smrg        mask |= (CWBackPixel | CWBorderPixel | CWEventMask);
1353da39bf31Smrg
1354da39bf31Smrg        w = XCreateWindow(dpy, RootWindow(dpy, screen), hints.x, hints.y,
1355da39bf31Smrg                          hints.width, hints.height, borderwidth, 0,
1356da39bf31Smrg                          InputOutput, (Visual *) CopyFromParent, mask, &attr);
1357da39bf31Smrg
1358da39bf31Smrg        XSetStandardProperties(dpy, w, name, NULL, (Pixmap) 0,
1359da39bf31Smrg                               argv, argc, &hints);
1360da39bf31Smrg
1361da39bf31Smrg        subw = XCreateSimpleWindow(dpy, w, INNER_WINDOW_X, INNER_WINDOW_Y,
1362da39bf31Smrg                                   INNER_WINDOW_WIDTH, INNER_WINDOW_HEIGHT,
1363da39bf31Smrg                                   INNER_WINDOW_BORDER,
1364da39bf31Smrg                                   attr.border_pixel, attr.background_pixel);
1365f299d47fSmrg
1366f299d47fSmrg        wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
1367f299d47fSmrg        wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
1368f299d47fSmrg        XSetWMProtocols(dpy, w, &wm_delete_window, 1);
1369f299d47fSmrg
1370da39bf31Smrg        XMapWindow(dpy, subw);  /* map before w so that it appears */
1371da39bf31Smrg        XMapWindow(dpy, w);
1372f299d47fSmrg
1373da39bf31Smrg        printf("Outer window is 0x%lx, inner window is 0x%lx\n", w, subw);
1374f299d47fSmrg    }
1375f299d47fSmrg
1376f299d47fSmrg    if (xim && xim_style) {
1377da39bf31Smrg        xic = XCreateIC(xim,
1378da39bf31Smrg                        XNInputStyle, xim_style,
1379da39bf31Smrg                        XNClientWindow, w, XNFocusWindow, w, NULL);
1380f299d47fSmrg
1381f299d47fSmrg        if (xic == NULL) {
1382da39bf31Smrg            fprintf(stderr, "XCreateIC failed\n");
1383f299d47fSmrg        }
1384f299d47fSmrg    }
1385f299d47fSmrg
1386da39bf31Smrg    have_rr = XRRQueryExtension(dpy, &rr_event_base, &rr_error_base);
13871a2dd139Smrg    if (have_rr) {
13881a2dd139Smrg        int rr_major, rr_minor;
13891a2dd139Smrg
1390da39bf31Smrg        if (XRRQueryVersion(dpy, &rr_major, &rr_minor)) {
13911a2dd139Smrg            int rr_mask = event_masks[EVENT_MASK_INDEX_RANDR];
13921a2dd139Smrg
13931a2dd139Smrg            if (rr_major == 1 && rr_minor <= 1) {
13941a2dd139Smrg                rr_mask &= ~(RRCrtcChangeNotifyMask |
13951a2dd139Smrg                             RROutputChangeNotifyMask |
13961a2dd139Smrg                             RROutputPropertyNotifyMask);
13971a2dd139Smrg            }
13981a2dd139Smrg
1399da39bf31Smrg            XRRSelectInput(dpy, w, rr_mask);
14001a2dd139Smrg        }
14011a2dd139Smrg    }
14021a2dd139Smrg
1403da39bf31Smrg    for (done = 0; !done;) {
1404da39bf31Smrg        XEvent event;
1405da39bf31Smrg
1406da39bf31Smrg        XNextEvent(dpy, &event);
1407da39bf31Smrg
1408da39bf31Smrg        switch (event.type) {
1409da39bf31Smrg        case KeyPress:
1410da39bf31Smrg            prologue(&event, "KeyPress");
1411da39bf31Smrg            do_KeyPress(&event);
1412da39bf31Smrg            break;
1413da39bf31Smrg        case KeyRelease:
1414da39bf31Smrg            prologue(&event, "KeyRelease");
1415da39bf31Smrg            do_KeyRelease(&event);
1416da39bf31Smrg            break;
1417da39bf31Smrg        case ButtonPress:
1418da39bf31Smrg            prologue(&event, "ButtonPress");
1419da39bf31Smrg            do_ButtonPress(&event);
1420da39bf31Smrg            break;
1421da39bf31Smrg        case ButtonRelease:
1422da39bf31Smrg            prologue(&event, "ButtonRelease");
1423da39bf31Smrg            do_ButtonRelease(&event);
1424da39bf31Smrg            break;
1425da39bf31Smrg        case MotionNotify:
1426da39bf31Smrg            prologue(&event, "MotionNotify");
1427da39bf31Smrg            do_MotionNotify(&event);
1428da39bf31Smrg            break;
1429da39bf31Smrg        case EnterNotify:
1430da39bf31Smrg            prologue(&event, "EnterNotify");
1431da39bf31Smrg            do_EnterNotify(&event);
1432da39bf31Smrg            break;
1433da39bf31Smrg        case LeaveNotify:
1434da39bf31Smrg            prologue(&event, "LeaveNotify");
1435da39bf31Smrg            do_LeaveNotify(&event);
1436da39bf31Smrg            break;
1437da39bf31Smrg        case FocusIn:
1438da39bf31Smrg            prologue(&event, "FocusIn");
1439da39bf31Smrg            do_FocusIn(&event);
1440da39bf31Smrg            break;
1441da39bf31Smrg        case FocusOut:
1442da39bf31Smrg            prologue(&event, "FocusOut");
1443da39bf31Smrg            do_FocusOut(&event);
1444da39bf31Smrg            break;
1445da39bf31Smrg        case KeymapNotify:
1446da39bf31Smrg            prologue(&event, "KeymapNotify");
1447da39bf31Smrg            do_KeymapNotify(&event);
1448da39bf31Smrg            break;
1449da39bf31Smrg        case Expose:
1450da39bf31Smrg            prologue(&event, "Expose");
1451da39bf31Smrg            do_Expose(&event);
1452da39bf31Smrg            break;
1453da39bf31Smrg        case GraphicsExpose:
1454da39bf31Smrg            prologue(&event, "GraphicsExpose");
1455da39bf31Smrg            do_GraphicsExpose(&event);
1456da39bf31Smrg            break;
1457da39bf31Smrg        case NoExpose:
1458da39bf31Smrg            prologue(&event, "NoExpose");
1459da39bf31Smrg            do_NoExpose(&event);
1460da39bf31Smrg            break;
1461da39bf31Smrg        case VisibilityNotify:
1462da39bf31Smrg            prologue(&event, "VisibilityNotify");
1463da39bf31Smrg            do_VisibilityNotify(&event);
1464da39bf31Smrg            break;
1465da39bf31Smrg        case CreateNotify:
1466da39bf31Smrg            prologue(&event, "CreateNotify");
1467da39bf31Smrg            do_CreateNotify(&event);
1468da39bf31Smrg            break;
1469da39bf31Smrg        case DestroyNotify:
1470da39bf31Smrg            prologue(&event, "DestroyNotify");
1471da39bf31Smrg            do_DestroyNotify(&event);
1472da39bf31Smrg            break;
1473da39bf31Smrg        case UnmapNotify:
1474da39bf31Smrg            prologue(&event, "UnmapNotify");
1475da39bf31Smrg            do_UnmapNotify(&event);
1476da39bf31Smrg            break;
1477da39bf31Smrg        case MapNotify:
1478da39bf31Smrg            prologue(&event, "MapNotify");
1479da39bf31Smrg            do_MapNotify(&event);
1480da39bf31Smrg            break;
1481da39bf31Smrg        case MapRequest:
1482da39bf31Smrg            prologue(&event, "MapRequest");
1483da39bf31Smrg            do_MapRequest(&event);
1484da39bf31Smrg            break;
1485da39bf31Smrg        case ReparentNotify:
1486da39bf31Smrg            prologue(&event, "ReparentNotify");
1487da39bf31Smrg            do_ReparentNotify(&event);
1488da39bf31Smrg            break;
1489da39bf31Smrg        case ConfigureNotify:
1490da39bf31Smrg            prologue(&event, "ConfigureNotify");
1491da39bf31Smrg            do_ConfigureNotify(&event);
1492da39bf31Smrg            break;
1493da39bf31Smrg        case ConfigureRequest:
1494da39bf31Smrg            prologue(&event, "ConfigureRequest");
1495da39bf31Smrg            do_ConfigureRequest(&event);
1496da39bf31Smrg            break;
1497da39bf31Smrg        case GravityNotify:
1498da39bf31Smrg            prologue(&event, "GravityNotify");
1499da39bf31Smrg            do_GravityNotify(&event);
1500da39bf31Smrg            break;
1501da39bf31Smrg        case ResizeRequest:
1502da39bf31Smrg            prologue(&event, "ResizeRequest");
1503da39bf31Smrg            do_ResizeRequest(&event);
1504da39bf31Smrg            break;
1505da39bf31Smrg        case CirculateNotify:
1506da39bf31Smrg            prologue(&event, "CirculateNotify");
1507da39bf31Smrg            do_CirculateNotify(&event);
1508da39bf31Smrg            break;
1509da39bf31Smrg        case CirculateRequest:
1510da39bf31Smrg            prologue(&event, "CirculateRequest");
1511da39bf31Smrg            do_CirculateRequest(&event);
1512da39bf31Smrg            break;
1513da39bf31Smrg        case PropertyNotify:
1514da39bf31Smrg            prologue(&event, "PropertyNotify");
1515da39bf31Smrg            do_PropertyNotify(&event);
1516da39bf31Smrg            break;
1517da39bf31Smrg        case SelectionClear:
1518da39bf31Smrg            prologue(&event, "SelectionClear");
1519da39bf31Smrg            do_SelectionClear(&event);
1520da39bf31Smrg            break;
1521da39bf31Smrg        case SelectionRequest:
1522da39bf31Smrg            prologue(&event, "SelectionRequest");
1523da39bf31Smrg            do_SelectionRequest(&event);
1524da39bf31Smrg            break;
1525da39bf31Smrg        case SelectionNotify:
1526da39bf31Smrg            prologue(&event, "SelectionNotify");
1527da39bf31Smrg            do_SelectionNotify(&event);
1528da39bf31Smrg            break;
1529da39bf31Smrg        case ColormapNotify:
1530da39bf31Smrg            prologue(&event, "ColormapNotify");
1531da39bf31Smrg            do_ColormapNotify(&event);
1532da39bf31Smrg            break;
1533da39bf31Smrg        case ClientMessage:
1534da39bf31Smrg            prologue(&event, "ClientMessage");
1535da39bf31Smrg            do_ClientMessage(&event);
1536da39bf31Smrg            break;
1537da39bf31Smrg        case MappingNotify:
1538da39bf31Smrg            prologue(&event, "MappingNotify");
1539da39bf31Smrg            do_MappingNotify(&event);
1540da39bf31Smrg            break;
1541da39bf31Smrg        default:
1542da39bf31Smrg            if (have_rr) {
1543da39bf31Smrg                if (event.type == rr_event_base + RRScreenChangeNotify) {
1544da39bf31Smrg                    prologue(&event, "RRScreenChangeNotify");
1545da39bf31Smrg                    do_RRScreenChangeNotify(&event);
1546da39bf31Smrg                    break;
1547da39bf31Smrg                }
1548da39bf31Smrg                if (event.type == rr_event_base + RRNotify) {
1549da39bf31Smrg                    do_RRNotify(&event);
1550da39bf31Smrg                    break;
1551da39bf31Smrg                }
1552da39bf31Smrg            }
1553da39bf31Smrg            printf("Unknown event type %d\n", event.type);
1554da39bf31Smrg            break;
1555da39bf31Smrg        }
1556da39bf31Smrg        fflush(stdout);
1557f299d47fSmrg    }
1558f299d47fSmrg
1559da39bf31Smrg    XCloseDisplay(dpy);
15601a2dd139Smrg    return 0;
1561f299d47fSmrg}
1562