xev.c revision 625f88be
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
35f299d47fSmrg#include <stdio.h>
36f299d47fSmrg#include <stdlib.h>
37f299d47fSmrg#include <ctype.h>
38f299d47fSmrg#include <X11/Xlocale.h>
39f299d47fSmrg#include <X11/Xos.h>
40f299d47fSmrg#include <X11/Xlib.h>
41f299d47fSmrg#include <X11/Xutil.h>
42f299d47fSmrg#include <X11/Xproto.h>
43f299d47fSmrg
44f299d47fSmrg#define INNER_WINDOW_WIDTH 50
45f299d47fSmrg#define INNER_WINDOW_HEIGHT 50
46f299d47fSmrg#define INNER_WINDOW_BORDER 4
47f299d47fSmrg#define INNER_WINDOW_X 10
48f299d47fSmrg#define INNER_WINDOW_Y 10
49f299d47fSmrg#define OUTER_WINDOW_MIN_WIDTH (INNER_WINDOW_WIDTH + \
50f299d47fSmrg				2 * (INNER_WINDOW_BORDER + INNER_WINDOW_X))
51f299d47fSmrg#define OUTER_WINDOW_MIN_HEIGHT (INNER_WINDOW_HEIGHT + \
52f299d47fSmrg				2 * (INNER_WINDOW_BORDER + INNER_WINDOW_Y))
53f299d47fSmrg#define OUTER_WINDOW_DEF_WIDTH (OUTER_WINDOW_MIN_WIDTH + 100)
54f299d47fSmrg#define OUTER_WINDOW_DEF_HEIGHT (OUTER_WINDOW_MIN_HEIGHT + 100)
55f299d47fSmrg#define OUTER_WINDOW_DEF_X 100
56f299d47fSmrg#define OUTER_WINDOW_DEF_Y 100
57f299d47fSmrg
58f299d47fSmrg
59f299d47fSmrgtypedef unsigned long Pixel;
60f299d47fSmrg
61f299d47fSmrgconst char *Yes = "YES";
62f299d47fSmrgconst char *No = "NO";
63f299d47fSmrgconst char *Unknown = "unknown";
64f299d47fSmrg
65f299d47fSmrgconst char *ProgramName;
66f299d47fSmrgDisplay *dpy;
67f299d47fSmrgint screen;
68f299d47fSmrg
69f299d47fSmrgXIC xic = NULL;
70f299d47fSmrg
71f299d47fSmrgAtom wm_delete_window;
72f299d47fSmrgAtom wm_protocols;
73f299d47fSmrg
74f299d47fSmrgstatic void
75f299d47fSmrgprologue (XEvent *eventp, char *event_name)
76f299d47fSmrg{
77f299d47fSmrg    XAnyEvent *e = (XAnyEvent *) eventp;
78f299d47fSmrg
79f299d47fSmrg    printf ("\n%s event, serial %ld, synthetic %s, window 0x%lx,\n",
80f299d47fSmrg	    event_name, e->serial, e->send_event ? Yes : No, e->window);
81f299d47fSmrg}
82f299d47fSmrg
83f299d47fSmrgstatic void
84f299d47fSmrgdump (char *str, int len)
85f299d47fSmrg{
86f299d47fSmrg    printf("(");
87f299d47fSmrg    len--;
88f299d47fSmrg    while (len-- > 0)
89f299d47fSmrg        printf("%02x ", (unsigned char) *str++);
90f299d47fSmrg    printf("%02x)", (unsigned char) *str++);
91f299d47fSmrg}
92f299d47fSmrg
93f299d47fSmrgstatic void
94f299d47fSmrgdo_KeyPress (XEvent *eventp)
95f299d47fSmrg{
96f299d47fSmrg    XKeyEvent *e = (XKeyEvent *) eventp;
97f299d47fSmrg    KeySym ks;
98f299d47fSmrg    KeyCode kc = 0;
99f299d47fSmrg    Bool kc_set = False;
100f299d47fSmrg    char *ksname;
101f299d47fSmrg    int nbytes, nmbbytes = 0;
102f299d47fSmrg    char str[256+1];
103f299d47fSmrg    static char *buf = NULL;
104f299d47fSmrg    static int bsize = 8;
105f299d47fSmrg    Status status;
106f299d47fSmrg
107f299d47fSmrg    if (buf == NULL)
108f299d47fSmrg      buf = malloc (bsize);
109f299d47fSmrg
110f299d47fSmrg    nbytes = XLookupString (e, str, 256, &ks, NULL);
111f299d47fSmrg
112f299d47fSmrg    /* not supposed to call XmbLookupString on a key release event */
113f299d47fSmrg    if (e->type == KeyPress && xic) {
114f299d47fSmrg        do {
115f299d47fSmrg            nmbbytes = XmbLookupString (xic, e, buf, bsize - 1, &ks, &status);
116f299d47fSmrg            buf[nmbbytes] = '\0';
117f299d47fSmrg
118f299d47fSmrg            if (status == XBufferOverflow) {
119f299d47fSmrg                bsize = nmbbytes + 1;
120f299d47fSmrg                buf = realloc (buf, bsize);
121f299d47fSmrg            }
122f299d47fSmrg        } while (status == XBufferOverflow);
123f299d47fSmrg    }
124f299d47fSmrg
125f299d47fSmrg    if (ks == NoSymbol)
126f299d47fSmrg	ksname = "NoSymbol";
127f299d47fSmrg    else {
128f299d47fSmrg	if (!(ksname = XKeysymToString (ks)))
129f299d47fSmrg	    ksname = "(no name)";
130f299d47fSmrg	kc = XKeysymToKeycode(dpy, ks);
131f299d47fSmrg	kc_set = True;
132f299d47fSmrg    }
133f299d47fSmrg
134f299d47fSmrg    printf ("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
135f299d47fSmrg	    e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
136f299d47fSmrg    printf ("    state 0x%x, keycode %u (keysym 0x%lx, %s), same_screen %s,\n",
137f299d47fSmrg	    e->state, e->keycode, (unsigned long) ks, ksname,
138f299d47fSmrg	    e->same_screen ? Yes : No);
139f299d47fSmrg    if (kc_set && e->keycode != kc)
140f299d47fSmrg	printf ("    XKeysymToKeycode returns keycode: %u\n",kc);
141f299d47fSmrg    if (nbytes < 0) nbytes = 0;
142f299d47fSmrg    if (nbytes > 256) nbytes = 256;
143f299d47fSmrg    str[nbytes] = '\0';
144f299d47fSmrg    printf ("    XLookupString gives %d bytes: ", nbytes);
145f299d47fSmrg    if (nbytes > 0) {
146f299d47fSmrg        dump (str, nbytes);
147f299d47fSmrg        printf (" \"%s\"\n", str);
148f299d47fSmrg    } else {
149f299d47fSmrg    	printf ("\n");
150f299d47fSmrg    }
151f299d47fSmrg
152f299d47fSmrg    /* not supposed to call XmbLookupString on a key release event */
153f299d47fSmrg    if (e->type == KeyPress && xic) {
154f299d47fSmrg        printf ("    XmbLookupString gives %d bytes: ", nmbbytes);
155f299d47fSmrg        if (nmbbytes > 0) {
156f299d47fSmrg           dump (buf, nmbbytes);
157f299d47fSmrg           printf (" \"%s\"\n", buf);
158f299d47fSmrg        } else {
159f299d47fSmrg    	   printf ("\n");
160f299d47fSmrg        }
161f299d47fSmrg    }
162f299d47fSmrg
163f299d47fSmrg    printf ("    XFilterEvent returns: %s\n",
164f299d47fSmrg	    XFilterEvent (eventp, e->window) ? "True" : "False");
165f299d47fSmrg}
166f299d47fSmrg
167f299d47fSmrgstatic void
168f299d47fSmrgdo_KeyRelease (XEvent *eventp)
169f299d47fSmrg{
170f299d47fSmrg    do_KeyPress (eventp);		/* since it has the same info */
171f299d47fSmrg}
172f299d47fSmrg
173f299d47fSmrgstatic void
174f299d47fSmrgdo_ButtonPress (XEvent *eventp)
175f299d47fSmrg{
176f299d47fSmrg    XButtonEvent *e = (XButtonEvent *) eventp;
177f299d47fSmrg
178f299d47fSmrg    printf ("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
179f299d47fSmrg	    e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
180f299d47fSmrg    printf ("    state 0x%x, button %u, same_screen %s\n",
181f299d47fSmrg	    e->state, e->button, e->same_screen ? Yes : No);
182f299d47fSmrg}
183f299d47fSmrg
184f299d47fSmrgstatic void
185f299d47fSmrgdo_ButtonRelease (XEvent *eventp)
186f299d47fSmrg{
187f299d47fSmrg    do_ButtonPress (eventp);		/* since it has the same info */
188f299d47fSmrg}
189f299d47fSmrg
190f299d47fSmrgstatic void
191f299d47fSmrgdo_MotionNotify (XEvent *eventp)
192f299d47fSmrg{
193f299d47fSmrg    XMotionEvent *e = (XMotionEvent *) eventp;
194f299d47fSmrg
195f299d47fSmrg    printf ("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
196f299d47fSmrg	    e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
197f299d47fSmrg    printf ("    state 0x%x, is_hint %u, same_screen %s\n",
198f299d47fSmrg	    e->state, e->is_hint, e->same_screen ? Yes : No);
199f299d47fSmrg}
200f299d47fSmrg
201f299d47fSmrgstatic void
202f299d47fSmrgdo_EnterNotify (XEvent *eventp)
203f299d47fSmrg{
204f299d47fSmrg    XCrossingEvent *e = (XCrossingEvent *) eventp;
205f299d47fSmrg    char *mode, *detail;
206f299d47fSmrg    char dmode[10], ddetail[10];
207f299d47fSmrg
208f299d47fSmrg    switch (e->mode) {
209f299d47fSmrg      case NotifyNormal:  mode = "NotifyNormal"; break;
210f299d47fSmrg      case NotifyGrab:  mode = "NotifyGrab"; break;
211f299d47fSmrg      case NotifyUngrab:  mode = "NotifyUngrab"; break;
212f299d47fSmrg      case NotifyWhileGrabbed:  mode = "NotifyWhileGrabbed"; break;
213f299d47fSmrg      default:  mode = dmode, sprintf (dmode, "%u", e->mode); break;
214f299d47fSmrg    }
215f299d47fSmrg
216f299d47fSmrg    switch (e->detail) {
217f299d47fSmrg      case NotifyAncestor:  detail = "NotifyAncestor"; break;
218f299d47fSmrg      case NotifyVirtual:  detail = "NotifyVirtual"; break;
219f299d47fSmrg      case NotifyInferior:  detail = "NotifyInferior"; break;
220f299d47fSmrg      case NotifyNonlinear:  detail = "NotifyNonlinear"; break;
221f299d47fSmrg      case NotifyNonlinearVirtual:  detail = "NotifyNonlinearVirtual"; break;
222f299d47fSmrg      case NotifyPointer:  detail = "NotifyPointer"; break;
223f299d47fSmrg      case NotifyPointerRoot:  detail = "NotifyPointerRoot"; break;
224f299d47fSmrg      case NotifyDetailNone:  detail = "NotifyDetailNone"; break;
225f299d47fSmrg      default:  detail = ddetail; sprintf (ddetail, "%u", e->detail); break;
226f299d47fSmrg    }
227f299d47fSmrg
228f299d47fSmrg    printf ("    root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n",
229f299d47fSmrg	    e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root);
230f299d47fSmrg    printf ("    mode %s, detail %s, same_screen %s,\n",
231f299d47fSmrg	    mode, detail, e->same_screen ? Yes : No);
232f299d47fSmrg    printf ("    focus %s, state %u\n", e->focus ? Yes : No, e->state);
233f299d47fSmrg}
234f299d47fSmrg
235f299d47fSmrgstatic void
236f299d47fSmrgdo_LeaveNotify (XEvent *eventp)
237f299d47fSmrg{
238f299d47fSmrg    do_EnterNotify (eventp);		/* since it has same information */
239f299d47fSmrg}
240f299d47fSmrg
241f299d47fSmrgstatic void
242f299d47fSmrgdo_FocusIn (XEvent *eventp)
243f299d47fSmrg{
244f299d47fSmrg    XFocusChangeEvent *e = (XFocusChangeEvent *) eventp;
245f299d47fSmrg    char *mode, *detail;
246f299d47fSmrg    char dmode[10], ddetail[10];
247f299d47fSmrg
248f299d47fSmrg    switch (e->mode) {
249f299d47fSmrg      case NotifyNormal:  mode = "NotifyNormal"; break;
250f299d47fSmrg      case NotifyGrab:  mode = "NotifyGrab"; break;
251f299d47fSmrg      case NotifyUngrab:  mode = "NotifyUngrab"; break;
252f299d47fSmrg      case NotifyWhileGrabbed:  mode = "NotifyWhileGrabbed"; break;
253f299d47fSmrg      default:  mode = dmode, sprintf (dmode, "%u", e->mode); break;
254f299d47fSmrg    }
255f299d47fSmrg
256f299d47fSmrg    switch (e->detail) {
257f299d47fSmrg      case NotifyAncestor:  detail = "NotifyAncestor"; break;
258f299d47fSmrg      case NotifyVirtual:  detail = "NotifyVirtual"; break;
259f299d47fSmrg      case NotifyInferior:  detail = "NotifyInferior"; break;
260f299d47fSmrg      case NotifyNonlinear:  detail = "NotifyNonlinear"; break;
261f299d47fSmrg      case NotifyNonlinearVirtual:  detail = "NotifyNonlinearVirtual"; break;
262f299d47fSmrg      case NotifyPointer:  detail = "NotifyPointer"; break;
263f299d47fSmrg      case NotifyPointerRoot:  detail = "NotifyPointerRoot"; break;
264f299d47fSmrg      case NotifyDetailNone:  detail = "NotifyDetailNone"; break;
265f299d47fSmrg      default:  detail = ddetail; sprintf (ddetail, "%u", e->detail); break;
266f299d47fSmrg    }
267f299d47fSmrg
268f299d47fSmrg    printf ("    mode %s, detail %s\n", mode, detail);
269f299d47fSmrg}
270f299d47fSmrg
271f299d47fSmrgstatic void
272f299d47fSmrgdo_FocusOut (XEvent *eventp)
273f299d47fSmrg{
274f299d47fSmrg    do_FocusIn (eventp);		/* since it has same information */
275f299d47fSmrg}
276f299d47fSmrg
277f299d47fSmrgstatic void
278f299d47fSmrgdo_KeymapNotify (XEvent *eventp)
279f299d47fSmrg{
280f299d47fSmrg    XKeymapEvent *e = (XKeymapEvent *) eventp;
281f299d47fSmrg    int i;
282f299d47fSmrg
283f299d47fSmrg    printf ("    keys:  ");
284f299d47fSmrg    for (i = 0; i < 32; i++) {
285f299d47fSmrg	if (i == 16) printf ("\n           ");
286f299d47fSmrg	printf ("%-3u ", (unsigned int) e->key_vector[i]);
287f299d47fSmrg    }
288f299d47fSmrg    printf ("\n");
289f299d47fSmrg}
290f299d47fSmrg
291f299d47fSmrgstatic void
292f299d47fSmrgdo_Expose (XEvent *eventp)
293f299d47fSmrg{
294f299d47fSmrg    XExposeEvent *e = (XExposeEvent *) eventp;
295f299d47fSmrg
296f299d47fSmrg    printf ("    (%d,%d), width %d, height %d, count %d\n",
297f299d47fSmrg	    e->x, e->y, e->width, e->height, e->count);
298f299d47fSmrg}
299f299d47fSmrg
300f299d47fSmrgstatic void
301f299d47fSmrgdo_GraphicsExpose (XEvent *eventp)
302f299d47fSmrg{
303f299d47fSmrg    XGraphicsExposeEvent *e = (XGraphicsExposeEvent *) eventp;
304f299d47fSmrg    char *m;
305f299d47fSmrg    char mdummy[10];
306f299d47fSmrg
307f299d47fSmrg    switch (e->major_code) {
308f299d47fSmrg      case X_CopyArea:  m = "CopyArea";  break;
309f299d47fSmrg      case X_CopyPlane:  m = "CopyPlane";  break;
310f299d47fSmrg      default:  m = mdummy; sprintf (mdummy, "%d", e->major_code); break;
311f299d47fSmrg    }
312f299d47fSmrg
313f299d47fSmrg    printf ("    (%d,%d), width %d, height %d, count %d,\n",
314f299d47fSmrg	    e->x, e->y, e->width, e->height, e->count);
315f299d47fSmrg    printf ("    major %s, minor %d\n", m, e->minor_code);
316f299d47fSmrg}
317f299d47fSmrg
318f299d47fSmrgstatic void
319f299d47fSmrgdo_NoExpose (XEvent *eventp)
320f299d47fSmrg{
321f299d47fSmrg    XNoExposeEvent *e = (XNoExposeEvent *) eventp;
322f299d47fSmrg    char *m;
323f299d47fSmrg    char mdummy[10];
324f299d47fSmrg
325f299d47fSmrg    switch (e->major_code) {
326f299d47fSmrg      case X_CopyArea:  m = "CopyArea";  break;
327f299d47fSmrg      case X_CopyPlane:  m = "CopyPlane";  break;
328f299d47fSmrg      default:  m = mdummy; sprintf (mdummy, "%d", e->major_code); break;
329f299d47fSmrg    }
330f299d47fSmrg
331f299d47fSmrg    printf ("    major %s, minor %d\n", m, e->minor_code);
332f299d47fSmrg    return;
333f299d47fSmrg}
334f299d47fSmrg
335f299d47fSmrgstatic void
336f299d47fSmrgdo_VisibilityNotify (XEvent *eventp)
337f299d47fSmrg{
338f299d47fSmrg    XVisibilityEvent *e = (XVisibilityEvent *) eventp;
339f299d47fSmrg    char *v;
340f299d47fSmrg    char vdummy[10];
341f299d47fSmrg
342f299d47fSmrg    switch (e->state) {
343f299d47fSmrg      case VisibilityUnobscured:  v = "VisibilityUnobscured"; break;
344f299d47fSmrg      case VisibilityPartiallyObscured:  v = "VisibilityPartiallyObscured"; break;
345f299d47fSmrg      case VisibilityFullyObscured:  v = "VisibilityFullyObscured"; break;
346f299d47fSmrg      default:  v = vdummy; sprintf (vdummy, "%d", e->state); break;
347f299d47fSmrg    }
348f299d47fSmrg
349f299d47fSmrg    printf ("    state %s\n", v);
350f299d47fSmrg}
351f299d47fSmrg
352f299d47fSmrgstatic void
353f299d47fSmrgdo_CreateNotify (XEvent *eventp)
354f299d47fSmrg{
355f299d47fSmrg    XCreateWindowEvent *e = (XCreateWindowEvent *) eventp;
356f299d47fSmrg
357f299d47fSmrg    printf ("    parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d\n",
358f299d47fSmrg	    e->parent, e->window, e->x, e->y, e->width, e->height);
359f299d47fSmrg    printf ("border_width %d, override %s\n",
360f299d47fSmrg	    e->border_width, e->override_redirect ? Yes : No);
361f299d47fSmrg}
362f299d47fSmrg
363f299d47fSmrgstatic void
364f299d47fSmrgdo_DestroyNotify (XEvent *eventp)
365f299d47fSmrg{
366f299d47fSmrg    XDestroyWindowEvent *e = (XDestroyWindowEvent *) eventp;
367f299d47fSmrg
368f299d47fSmrg    printf ("    event 0x%lx, window 0x%lx\n", e->event, e->window);
369f299d47fSmrg}
370f299d47fSmrg
371f299d47fSmrgstatic void
372f299d47fSmrgdo_UnmapNotify (XEvent *eventp)
373f299d47fSmrg{
374f299d47fSmrg    XUnmapEvent *e = (XUnmapEvent *) eventp;
375f299d47fSmrg
376f299d47fSmrg    printf ("    event 0x%lx, window 0x%lx, from_configure %s\n",
377f299d47fSmrg	    e->event, e->window, e->from_configure ? Yes : No);
378f299d47fSmrg}
379f299d47fSmrg
380f299d47fSmrgstatic void
381f299d47fSmrgdo_MapNotify (XEvent *eventp)
382f299d47fSmrg{
383f299d47fSmrg    XMapEvent *e = (XMapEvent *) eventp;
384f299d47fSmrg
385f299d47fSmrg    printf ("    event 0x%lx, window 0x%lx, override %s\n",
386f299d47fSmrg	    e->event, e->window, e->override_redirect ? Yes : No);
387f299d47fSmrg}
388f299d47fSmrg
389f299d47fSmrgstatic void
390f299d47fSmrgdo_MapRequest (XEvent *eventp)
391f299d47fSmrg{
392f299d47fSmrg    XMapRequestEvent *e = (XMapRequestEvent *) eventp;
393f299d47fSmrg
394f299d47fSmrg    printf ("    parent 0x%lx, window 0x%lx\n", e->parent, e->window);
395f299d47fSmrg}
396f299d47fSmrg
397f299d47fSmrgstatic void
398f299d47fSmrgdo_ReparentNotify (XEvent *eventp)
399f299d47fSmrg{
400f299d47fSmrg    XReparentEvent *e = (XReparentEvent *) eventp;
401f299d47fSmrg
402f299d47fSmrg    printf ("    event 0x%lx, window 0x%lx, parent 0x%lx,\n",
403f299d47fSmrg	    e->event, e->window, e->parent);
404f299d47fSmrg    printf ("    (%d,%d), override %s\n", e->x, e->y,
405f299d47fSmrg	    e->override_redirect ? Yes : No);
406f299d47fSmrg}
407f299d47fSmrg
408f299d47fSmrgstatic void
409f299d47fSmrgdo_ConfigureNotify (XEvent *eventp)
410f299d47fSmrg{
411f299d47fSmrg    XConfigureEvent *e = (XConfigureEvent *) eventp;
412f299d47fSmrg
413f299d47fSmrg    printf ("    event 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n",
414f299d47fSmrg	    e->event, e->window, e->x, e->y, e->width, e->height);
415f299d47fSmrg    printf ("    border_width %d, above 0x%lx, override %s\n",
416f299d47fSmrg	    e->border_width, e->above, e->override_redirect ? Yes : No);
417f299d47fSmrg}
418f299d47fSmrg
419f299d47fSmrgstatic void
420f299d47fSmrgdo_ConfigureRequest (XEvent *eventp)
421f299d47fSmrg{
422f299d47fSmrg    XConfigureRequestEvent *e = (XConfigureRequestEvent *) eventp;
423f299d47fSmrg    char *detail;
424f299d47fSmrg    char ddummy[10];
425f299d47fSmrg
426f299d47fSmrg    switch (e->detail) {
427f299d47fSmrg      case Above:  detail = "Above";  break;
428f299d47fSmrg      case Below:  detail = "Below";  break;
429f299d47fSmrg      case TopIf:  detail = "TopIf";  break;
430f299d47fSmrg      case BottomIf:  detail = "BottomIf"; break;
431f299d47fSmrg      case Opposite:  detail = "Opposite"; break;
432f299d47fSmrg      default:  detail = ddummy; sprintf (ddummy, "%d", e->detail); break;
433f299d47fSmrg    }
434f299d47fSmrg
435f299d47fSmrg    printf ("    parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n",
436f299d47fSmrg	    e->parent, e->window, e->x, e->y, e->width, e->height);
437f299d47fSmrg    printf ("    border_width %d, above 0x%lx, detail %s, value 0x%lx\n",
438f299d47fSmrg	    e->border_width, e->above, detail, e->value_mask);
439f299d47fSmrg}
440f299d47fSmrg
441f299d47fSmrgstatic void
442f299d47fSmrgdo_GravityNotify (XEvent *eventp)
443f299d47fSmrg{
444f299d47fSmrg    XGravityEvent *e = (XGravityEvent *) eventp;
445f299d47fSmrg
446f299d47fSmrg    printf ("    event 0x%lx, window 0x%lx, (%d,%d)\n",
447f299d47fSmrg	    e->event, e->window, e->x, e->y);
448f299d47fSmrg}
449f299d47fSmrg
450f299d47fSmrgstatic void
451f299d47fSmrgdo_ResizeRequest (XEvent *eventp)
452f299d47fSmrg{
453f299d47fSmrg    XResizeRequestEvent *e = (XResizeRequestEvent *) eventp;
454f299d47fSmrg
455f299d47fSmrg    printf ("    width %d, height %d\n", e->width, e->height);
456f299d47fSmrg}
457f299d47fSmrg
458f299d47fSmrgstatic void
459f299d47fSmrgdo_CirculateNotify (XEvent *eventp)
460f299d47fSmrg{
461f299d47fSmrg    XCirculateEvent *e = (XCirculateEvent *) eventp;
462f299d47fSmrg    char *p;
463f299d47fSmrg    char pdummy[10];
464f299d47fSmrg
465f299d47fSmrg    switch (e->place) {
466f299d47fSmrg      case PlaceOnTop:  p = "PlaceOnTop"; break;
467f299d47fSmrg      case PlaceOnBottom:  p = "PlaceOnBottom"; break;
468f299d47fSmrg      default:  p = pdummy; sprintf (pdummy, "%d", e->place); break;
469f299d47fSmrg    }
470f299d47fSmrg
471f299d47fSmrg    printf ("    event 0x%lx, window 0x%lx, place %s\n",
472f299d47fSmrg	    e->event, e->window, p);
473f299d47fSmrg}
474f299d47fSmrg
475f299d47fSmrgstatic void
476f299d47fSmrgdo_CirculateRequest (XEvent *eventp)
477f299d47fSmrg{
478f299d47fSmrg    XCirculateRequestEvent *e = (XCirculateRequestEvent *) eventp;
479f299d47fSmrg    char *p;
480f299d47fSmrg    char pdummy[10];
481f299d47fSmrg
482f299d47fSmrg    switch (e->place) {
483f299d47fSmrg      case PlaceOnTop:  p = "PlaceOnTop"; break;
484f299d47fSmrg      case PlaceOnBottom:  p = "PlaceOnBottom"; break;
485f299d47fSmrg      default:  p = pdummy; sprintf (pdummy, "%d", e->place); break;
486f299d47fSmrg    }
487f299d47fSmrg
488f299d47fSmrg    printf ("    parent 0x%lx, window 0x%lx, place %s\n",
489f299d47fSmrg	    e->parent, e->window, p);
490f299d47fSmrg}
491f299d47fSmrg
492f299d47fSmrgstatic void
493f299d47fSmrgdo_PropertyNotify (XEvent *eventp)
494f299d47fSmrg{
495f299d47fSmrg    XPropertyEvent *e = (XPropertyEvent *) eventp;
496f299d47fSmrg    char *aname = XGetAtomName (dpy, e->atom);
497f299d47fSmrg    char *s;
498f299d47fSmrg    char sdummy[10];
499f299d47fSmrg
500f299d47fSmrg    switch (e->state) {
501f299d47fSmrg      case PropertyNewValue:  s = "PropertyNewValue"; break;
502f299d47fSmrg      case PropertyDelete:  s = "PropertyDelete"; break;
503f299d47fSmrg      default:  s = sdummy; sprintf (sdummy, "%d", e->state); break;
504f299d47fSmrg    }
505f299d47fSmrg
506f299d47fSmrg    printf ("    atom 0x%lx (%s), time %lu, state %s\n",
507f299d47fSmrg	   e->atom, aname ? aname : Unknown, e->time,  s);
508f299d47fSmrg
509f299d47fSmrg    if (aname) XFree (aname);
510f299d47fSmrg}
511f299d47fSmrg
512f299d47fSmrgstatic void
513f299d47fSmrgdo_SelectionClear (XEvent *eventp)
514f299d47fSmrg{
515f299d47fSmrg    XSelectionClearEvent *e = (XSelectionClearEvent *) eventp;
516f299d47fSmrg    char *sname = XGetAtomName (dpy, e->selection);
517f299d47fSmrg
518f299d47fSmrg    printf ("    selection 0x%lx (%s), time %lu\n",
519f299d47fSmrg	    e->selection, sname ? sname : Unknown, e->time);
520f299d47fSmrg
521f299d47fSmrg    if (sname) XFree (sname);
522f299d47fSmrg}
523f299d47fSmrg
524f299d47fSmrgstatic void
525f299d47fSmrgdo_SelectionRequest (XEvent *eventp)
526f299d47fSmrg{
527f299d47fSmrg    XSelectionRequestEvent *e = (XSelectionRequestEvent *) eventp;
528f299d47fSmrg    char *sname = XGetAtomName (dpy, e->selection);
529f299d47fSmrg    char *tname = XGetAtomName (dpy, e->target);
530f299d47fSmrg    char *pname = XGetAtomName (dpy, e->property);
531f299d47fSmrg
532f299d47fSmrg    printf ("    owner 0x%lx, requestor 0x%lx, selection 0x%lx (%s),\n",
533f299d47fSmrg	    e->owner, e->requestor, e->selection, sname ? sname : Unknown);
534f299d47fSmrg    printf ("    target 0x%lx (%s), property 0x%lx (%s), time %lu\n",
535f299d47fSmrg	    e->target, tname ? tname : Unknown, e->property,
536f299d47fSmrg	    pname ? pname : Unknown, e->time);
537f299d47fSmrg
538f299d47fSmrg    if (sname) XFree (sname);
539f299d47fSmrg    if (tname) XFree (tname);
540f299d47fSmrg    if (pname) XFree (pname);
541f299d47fSmrg}
542f299d47fSmrg
543f299d47fSmrgstatic void
544f299d47fSmrgdo_SelectionNotify (XEvent *eventp)
545f299d47fSmrg{
546f299d47fSmrg    XSelectionEvent *e = (XSelectionEvent *) eventp;
547f299d47fSmrg    char *sname = XGetAtomName (dpy, e->selection);
548f299d47fSmrg    char *tname = XGetAtomName (dpy, e->target);
549f299d47fSmrg    char *pname = XGetAtomName (dpy, e->property);
550f299d47fSmrg
551f299d47fSmrg    printf ("    selection 0x%lx (%s), target 0x%lx (%s),\n",
552f299d47fSmrg	    e->selection, sname ? sname : Unknown, e->target,
553f299d47fSmrg	    tname ? tname : Unknown);
554f299d47fSmrg    printf ("    property 0x%lx (%s), time %lu\n",
555f299d47fSmrg	    e->property, pname ? pname : Unknown, e->time);
556f299d47fSmrg
557f299d47fSmrg    if (sname) XFree (sname);
558f299d47fSmrg    if (tname) XFree (tname);
559f299d47fSmrg    if (pname) XFree (pname);
560f299d47fSmrg}
561f299d47fSmrg
562f299d47fSmrgstatic void
563f299d47fSmrgdo_ColormapNotify (XEvent *eventp)
564f299d47fSmrg{
565f299d47fSmrg    XColormapEvent *e = (XColormapEvent *) eventp;
566f299d47fSmrg    char *s;
567f299d47fSmrg    char sdummy[10];
568f299d47fSmrg
569f299d47fSmrg    switch (e->state) {
570f299d47fSmrg      case ColormapInstalled:  s = "ColormapInstalled"; break;
571f299d47fSmrg      case ColormapUninstalled:  s = "ColormapUninstalled"; break;
572f299d47fSmrg      default:  s = sdummy; sprintf (sdummy, "%d", e->state); break;
573f299d47fSmrg    }
574f299d47fSmrg
575f299d47fSmrg    printf ("    colormap 0x%lx, new %s, state %s\n",
576f299d47fSmrg	    e->colormap, e->new ? Yes : No, s);
577f299d47fSmrg}
578f299d47fSmrg
579f299d47fSmrgstatic void
580f299d47fSmrgdo_ClientMessage (XEvent *eventp)
581f299d47fSmrg{
582f299d47fSmrg    XClientMessageEvent *e = (XClientMessageEvent *) eventp;
583f299d47fSmrg    char *mname = XGetAtomName (dpy, e->message_type);
584f299d47fSmrg
585f299d47fSmrg    if (e->message_type == wm_protocols) {
586f299d47fSmrg        char *message = XGetAtomName (dpy, e->data.l[0]);
587f299d47fSmrg        printf ("    message_type 0x%lx (%s), format %d, message 0x%lx (%s)\n",
588f299d47fSmrg                e->message_type, mname ? mname : Unknown, e->format, e->data.l[0], message);
589f299d47fSmrg        if (message) XFree (message);
590f299d47fSmrg    }
591f299d47fSmrg    else {
592f299d47fSmrg        printf ("    message_type 0x%lx (%s), format %d\n",
593f299d47fSmrg                e->message_type, mname ? mname : Unknown, e->format);
594f299d47fSmrg    }
595f299d47fSmrg
596f299d47fSmrg    if (mname) XFree (mname);
597f299d47fSmrg
598f299d47fSmrg    if (e->format == 32
599f299d47fSmrg        && e->message_type == wm_protocols
600f299d47fSmrg        && (Atom) e->data.l[0] == wm_delete_window)
601f299d47fSmrg        exit (0);
602f299d47fSmrg}
603f299d47fSmrg
604f299d47fSmrgstatic void
605f299d47fSmrgdo_MappingNotify (XEvent *eventp)
606f299d47fSmrg{
607f299d47fSmrg    XMappingEvent *e = (XMappingEvent *) eventp;
608f299d47fSmrg    char *r;
609f299d47fSmrg    char rdummy[10];
610f299d47fSmrg
611f299d47fSmrg    switch (e->request) {
612f299d47fSmrg      case MappingModifier:  r = "MappingModifier"; break;
613f299d47fSmrg      case MappingKeyboard:  r = "MappingKeyboard"; break;
614f299d47fSmrg      case MappingPointer:  r = "MappingPointer"; break;
615f299d47fSmrg      default:  r = rdummy; sprintf (rdummy, "%d", e->request); break;
616f299d47fSmrg    }
617f299d47fSmrg
618f299d47fSmrg    printf ("    request %s, first_keycode %d, count %d\n",
619f299d47fSmrg	    r, e->first_keycode, e->count);
620f299d47fSmrg    XRefreshKeyboardMapping(e);
621f299d47fSmrg}
622f299d47fSmrg
623f299d47fSmrg
624f299d47fSmrg
625f299d47fSmrgstatic void
626f299d47fSmrgset_sizehints (XSizeHints *hintp, int min_width, int min_height,
627f299d47fSmrg	       int defwidth, int defheight, int defx, int defy,
628f299d47fSmrg	       char *geom)
629f299d47fSmrg{
630f299d47fSmrg    int geom_result;
631f299d47fSmrg
632f299d47fSmrg    /* set the size hints, algorithm from xlib xbiff */
633f299d47fSmrg
634f299d47fSmrg    hintp->width = hintp->min_width = min_width;
635f299d47fSmrg    hintp->height = hintp->min_height = min_height;
636f299d47fSmrg    hintp->flags = PMinSize;
637f299d47fSmrg    hintp->x = hintp->y = 0;
638f299d47fSmrg    geom_result = NoValue;
639f299d47fSmrg    if (geom != NULL) {
640f299d47fSmrg        geom_result = XParseGeometry (geom, &hintp->x, &hintp->y,
641f299d47fSmrg				      (unsigned int *)&hintp->width,
642f299d47fSmrg				      (unsigned int *)&hintp->height);
643f299d47fSmrg	if ((geom_result & WidthValue) && (geom_result & HeightValue)) {
644f299d47fSmrg#ifndef max
645f299d47fSmrg#define max(a,b) ((a) > (b) ? (a) : (b))
646f299d47fSmrg#endif
647f299d47fSmrg	    hintp->width = max (hintp->width, hintp->min_width);
648f299d47fSmrg	    hintp->height = max (hintp->height, hintp->min_height);
649f299d47fSmrg	    hintp->flags |= USSize;
650f299d47fSmrg	}
651f299d47fSmrg	if ((geom_result & XValue) && (geom_result & YValue)) {
652f299d47fSmrg	    hintp->flags += USPosition;
653f299d47fSmrg	}
654f299d47fSmrg    }
655f299d47fSmrg    if (!(hintp->flags & USSize)) {
656f299d47fSmrg	hintp->width = defwidth;
657f299d47fSmrg	hintp->height = defheight;
658f299d47fSmrg	hintp->flags |= PSize;
659f299d47fSmrg    }
660f299d47fSmrg/*
661f299d47fSmrg    if (!(hintp->flags & USPosition)) {
662f299d47fSmrg	hintp->x = defx;
663f299d47fSmrg	hintp->y = defy;
664f299d47fSmrg	hintp->flags |= PPosition;
665f299d47fSmrg    }
666f299d47fSmrg */
667f299d47fSmrg    if (geom_result & XNegative) {
668f299d47fSmrg	hintp->x = DisplayWidth (dpy, DefaultScreen (dpy)) + hintp->x -
669f299d47fSmrg		    hintp->width;
670f299d47fSmrg    }
671f299d47fSmrg    if (geom_result & YNegative) {
672f299d47fSmrg	hintp->y = DisplayHeight (dpy, DefaultScreen (dpy)) + hintp->y -
673f299d47fSmrg		    hintp->height;
674f299d47fSmrg    }
675f299d47fSmrg}
676f299d47fSmrg
677f299d47fSmrg
678f299d47fSmrg#if defined(__GNUC__) && \
679f299d47fSmrg    ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))
680f299d47fSmrgstatic void usage (void) __attribute__((__noreturn__));
681f299d47fSmrg#endif
682f299d47fSmrgstatic void
683f299d47fSmrgusage (void)
684f299d47fSmrg{
685f299d47fSmrg    static const char *msg[] = {
686f299d47fSmrg"    -display displayname                X server to contact",
687f299d47fSmrg"    -geometry geom                      size and location of window",
688f299d47fSmrg"    -bw pixels                          border width in pixels",
689f299d47fSmrg"    -bs {NotUseful,WhenMapped,Always}   backingstore attribute",
690f299d47fSmrg"    -id windowid                        use existing window",
691625f88beSmrg"    -root                               use root window",
692f299d47fSmrg"    -s                                  set save-unders attribute",
693f299d47fSmrg"    -name string                        window name",
694f299d47fSmrg"    -rv                                 reverse video",
695f299d47fSmrg"",
696f299d47fSmrgNULL};
697f299d47fSmrg    const char **cpp;
698f299d47fSmrg
699f299d47fSmrg    fprintf (stderr, "usage:  %s [-options ...]\n", ProgramName);
700f299d47fSmrg    fprintf (stderr, "where options include:\n");
701f299d47fSmrg
702f299d47fSmrg    for (cpp = msg; *cpp; cpp++)
703f299d47fSmrg	fprintf (stderr, "%s\n", *cpp);
704f299d47fSmrg
705f299d47fSmrg    exit (1);
706f299d47fSmrg}
707f299d47fSmrg
708f299d47fSmrgstatic int
709f299d47fSmrgparse_backing_store (char *s)
710f299d47fSmrg{
711f299d47fSmrg    int len = strlen (s);
712f299d47fSmrg    char *cp;
713f299d47fSmrg
714f299d47fSmrg    for (cp = s; *cp; cp++) {
715f299d47fSmrg	if (isascii (*cp) && isupper (*cp))
716f299d47fSmrg	    *cp = tolower (*cp);
717f299d47fSmrg    }
718f299d47fSmrg
719f299d47fSmrg    if (strncmp (s, "notuseful", len) == 0) return (NotUseful);
720f299d47fSmrg    if (strncmp (s, "whenmapped", len) == 0) return (WhenMapped);
721f299d47fSmrg    if (strncmp (s, "always", len) == 0) return (Always);
722f299d47fSmrg
723f299d47fSmrg    usage ();
724f299d47fSmrg}
725f299d47fSmrg
726f299d47fSmrgint
727f299d47fSmrgmain (int argc, char **argv)
728f299d47fSmrg{
729f299d47fSmrg    char *displayname = NULL;
730f299d47fSmrg    char *geom = NULL;
731f299d47fSmrg    int i;
732f299d47fSmrg    XSizeHints hints;
733f299d47fSmrg    int borderwidth = 2;
734f299d47fSmrg    Window w, subw;
735f299d47fSmrg    XSetWindowAttributes attr;
736f299d47fSmrg    XWindowAttributes wattr;
737f299d47fSmrg    unsigned long mask = 0L;
738f299d47fSmrg    int done;
739f299d47fSmrg    char *name = "Event Tester";
740f299d47fSmrg    Bool reverse = False;
741625f88beSmrg    Bool use_root = False;
742f299d47fSmrg    unsigned long back, fore;
743f299d47fSmrg    XIM xim;
744f299d47fSmrg    XIMStyles *xim_styles;
745f299d47fSmrg    XIMStyle xim_style = 0;
746f299d47fSmrg    char *modifiers;
747f299d47fSmrg    char *imvalret;
748f299d47fSmrg
749f299d47fSmrg    ProgramName = argv[0];
750f299d47fSmrg
751f299d47fSmrg    if (setlocale(LC_ALL,"") == NULL) {
752f299d47fSmrg	fprintf(stderr, "%s: warning: could not set default locale\n",
753f299d47fSmrg		ProgramName);
754f299d47fSmrg    }
755f299d47fSmrg
756f299d47fSmrg    w = 0;
757f299d47fSmrg    for (i = 1; i < argc; i++) {
758f299d47fSmrg	char *arg = argv[i];
759f299d47fSmrg
760f299d47fSmrg	if (arg[0] == '-') {
761f299d47fSmrg	    switch (arg[1]) {
762f299d47fSmrg	      case 'd':			/* -display host:dpy */
763f299d47fSmrg		if (++i >= argc) usage ();
764f299d47fSmrg		displayname = argv[i];
765f299d47fSmrg		continue;
766f299d47fSmrg	      case 'g':			/* -geometry geom */
767f299d47fSmrg		if (++i >= argc) usage ();
768f299d47fSmrg		geom = argv[i];
769f299d47fSmrg		continue;
770f299d47fSmrg	      case 'b':
771f299d47fSmrg		switch (arg[2]) {
772f299d47fSmrg		  case 'w':		/* -bw pixels */
773f299d47fSmrg		    if (++i >= argc) usage ();
774f299d47fSmrg		    borderwidth = atoi (argv[i]);
775f299d47fSmrg		    continue;
776f299d47fSmrg		  case 's':		/* -bs type */
777f299d47fSmrg		    if (++i >= argc) usage ();
778f299d47fSmrg		    attr.backing_store = parse_backing_store (argv[i]);
779f299d47fSmrg		    mask |= CWBackingStore;
780f299d47fSmrg		    continue;
781f299d47fSmrg		  default:
782f299d47fSmrg		    usage ();
783f299d47fSmrg		}
784f299d47fSmrg	      case 'i':			/* -id */
785f299d47fSmrg		if (++i >= argc) usage ();
786f299d47fSmrg		sscanf(argv[i], "0x%lx", &w);
787f299d47fSmrg		if (!w)
788f299d47fSmrg		    sscanf(argv[i], "%lu", &w);
789f299d47fSmrg		if (!w)
790f299d47fSmrg		    usage ();
791f299d47fSmrg		continue;
792f299d47fSmrg	      case 'n':			/* -name */
793f299d47fSmrg		if (++i >= argc) usage ();
794f299d47fSmrg		name = argv[i];
795f299d47fSmrg		continue;
796625f88beSmrg	      case 'r':
797625f88beSmrg		switch (arg[2]) {
798625f88beSmrg		  case 'o':		/* -root */
799625f88beSmrg		    use_root = True;
800625f88beSmrg		    continue;
801625f88beSmrg		  case 'v':		/* -rv */
802625f88beSmrg		    reverse = True;
803625f88beSmrg		    continue;
804625f88beSmrg		  default:
805625f88beSmrg		    usage ();
806625f88beSmrg		}
807f299d47fSmrg		continue;
808f299d47fSmrg	      case 's':			/* -s */
809f299d47fSmrg		attr.save_under = True;
810f299d47fSmrg		mask |= CWSaveUnder;
811f299d47fSmrg		continue;
812f299d47fSmrg	      default:
813f299d47fSmrg		usage ();
814f299d47fSmrg	    }				/* end switch on - */
815f299d47fSmrg	} else
816f299d47fSmrg	  usage ();
817f299d47fSmrg    }					/* end for over argc */
818f299d47fSmrg
819f299d47fSmrg    dpy = XOpenDisplay (displayname);
820f299d47fSmrg    if (!dpy) {
821f299d47fSmrg	fprintf (stderr, "%s:  unable to open display '%s'\n",
822f299d47fSmrg		 ProgramName, XDisplayName (displayname));
823f299d47fSmrg	exit (1);
824f299d47fSmrg    }
825f299d47fSmrg
826f299d47fSmrg    /* we're testing the default input method */
827f299d47fSmrg    modifiers = XSetLocaleModifiers ("@im=none");
828f299d47fSmrg    if (modifiers == NULL) {
829f299d47fSmrg        fprintf (stderr, "%s:  XSetLocaleModifiers failed\n", ProgramName);
830f299d47fSmrg    }
831f299d47fSmrg
832f299d47fSmrg    xim = XOpenIM (dpy, NULL, NULL, NULL);
833f299d47fSmrg    if (xim == NULL) {
834f299d47fSmrg        fprintf (stderr, "%s:  XOpenIM failed\n", ProgramName);
835f299d47fSmrg    }
836f299d47fSmrg
837f299d47fSmrg    if (xim) {
838f299d47fSmrg        imvalret = XGetIMValues (xim, XNQueryInputStyle, &xim_styles, NULL);
839f299d47fSmrg        if (imvalret != NULL || xim_styles == NULL) {
840f299d47fSmrg            fprintf (stderr, "%s:  input method doesn't support any styles\n", ProgramName);
841f299d47fSmrg        }
842f299d47fSmrg
843f299d47fSmrg        if (xim_styles) {
844f299d47fSmrg            xim_style = 0;
845f299d47fSmrg            for (i = 0;  i < xim_styles->count_styles;  i++) {
846f299d47fSmrg                if (xim_styles->supported_styles[i] ==
847f299d47fSmrg                    (XIMPreeditNothing | XIMStatusNothing)) {
848f299d47fSmrg                    xim_style = xim_styles->supported_styles[i];
849f299d47fSmrg                    break;
850f299d47fSmrg                }
851f299d47fSmrg            }
852f299d47fSmrg
853f299d47fSmrg            if (xim_style == 0) {
854f299d47fSmrg                fprintf (stderr, "%s: input method doesn't support the style we support\n",
855f299d47fSmrg                         ProgramName);
856f299d47fSmrg            }
857f299d47fSmrg            XFree (xim_styles);
858f299d47fSmrg        }
859f299d47fSmrg    }
860f299d47fSmrg
861f299d47fSmrg    screen = DefaultScreen (dpy);
862f299d47fSmrg
863f299d47fSmrg    /* select for all events */
864f299d47fSmrg    attr.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
865f299d47fSmrg			   ButtonReleaseMask | EnterWindowMask |
866f299d47fSmrg			   LeaveWindowMask | PointerMotionMask |
867f299d47fSmrg			   Button1MotionMask |
868f299d47fSmrg			   Button2MotionMask | Button3MotionMask |
869f299d47fSmrg			   Button4MotionMask | Button5MotionMask |
870f299d47fSmrg			   ButtonMotionMask | KeymapStateMask |
871f299d47fSmrg			   ExposureMask | VisibilityChangeMask |
872f299d47fSmrg			   StructureNotifyMask | /* ResizeRedirectMask | */
873f299d47fSmrg			   SubstructureNotifyMask | SubstructureRedirectMask |
874f299d47fSmrg			   FocusChangeMask | PropertyChangeMask |
875f299d47fSmrg			   ColormapChangeMask | OwnerGrabButtonMask;
876f299d47fSmrg
877625f88beSmrg    if (use_root)
878625f88beSmrg	w = RootWindow(dpy, screen);
879625f88beSmrg
880f299d47fSmrg    if (w) {
881f299d47fSmrg	XGetWindowAttributes(dpy, w, &wattr);
882f299d47fSmrg	if (wattr.all_event_masks & ButtonPressMask)
883f299d47fSmrg	    attr.event_mask &= ~ButtonPressMask;
884f299d47fSmrg	attr.event_mask &= ~SubstructureRedirectMask;
885f299d47fSmrg	XSelectInput(dpy, w, attr.event_mask);
886f299d47fSmrg    } else {
887f299d47fSmrg	set_sizehints (&hints, OUTER_WINDOW_MIN_WIDTH, OUTER_WINDOW_MIN_HEIGHT,
888f299d47fSmrg		       OUTER_WINDOW_DEF_WIDTH, OUTER_WINDOW_DEF_HEIGHT,
889f299d47fSmrg		       OUTER_WINDOW_DEF_X, OUTER_WINDOW_DEF_Y, geom);
890f299d47fSmrg
891f299d47fSmrg	if (reverse) {
892f299d47fSmrg	    back = BlackPixel(dpy,screen);
893f299d47fSmrg	    fore = WhitePixel(dpy,screen);
894f299d47fSmrg	} else {
895f299d47fSmrg	    back = WhitePixel(dpy,screen);
896f299d47fSmrg	    fore = BlackPixel(dpy,screen);
897f299d47fSmrg	}
898f299d47fSmrg
899f299d47fSmrg	attr.background_pixel = back;
900f299d47fSmrg	attr.border_pixel = fore;
901f299d47fSmrg	mask |= (CWBackPixel | CWBorderPixel | CWEventMask);
902f299d47fSmrg
903f299d47fSmrg	w = XCreateWindow (dpy, RootWindow (dpy, screen), hints.x, hints.y,
904f299d47fSmrg			   hints.width, hints.height, borderwidth, 0,
905f299d47fSmrg			   InputOutput, (Visual *)CopyFromParent,
906f299d47fSmrg			   mask, &attr);
907f299d47fSmrg
908f299d47fSmrg	XSetStandardProperties (dpy, w, name, NULL, (Pixmap) 0,
909f299d47fSmrg				argv, argc, &hints);
910f299d47fSmrg
911f299d47fSmrg	subw = XCreateSimpleWindow (dpy, w, INNER_WINDOW_X, INNER_WINDOW_Y,
912f299d47fSmrg				    INNER_WINDOW_WIDTH, INNER_WINDOW_HEIGHT,
913f299d47fSmrg				    INNER_WINDOW_BORDER,
914f299d47fSmrg				    attr.border_pixel, attr.background_pixel);
915f299d47fSmrg
916f299d47fSmrg        wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
917f299d47fSmrg        wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
918f299d47fSmrg        XSetWMProtocols(dpy, w, &wm_delete_window, 1);
919f299d47fSmrg
920f299d47fSmrg	XMapWindow (dpy, subw);		/* map before w so that it appears */
921f299d47fSmrg	XMapWindow (dpy, w);
922f299d47fSmrg
923f299d47fSmrg	printf ("Outer window is 0x%lx, inner window is 0x%lx\n", w, subw);
924f299d47fSmrg    }
925f299d47fSmrg
926f299d47fSmrg    if (xim && xim_style) {
927f299d47fSmrg        xic = XCreateIC (xim,
928f299d47fSmrg                         XNInputStyle, xim_style,
929f299d47fSmrg                         XNClientWindow, w,
930f299d47fSmrg                         XNFocusWindow, w,
931f299d47fSmrg                         NULL);
932f299d47fSmrg
933f299d47fSmrg        if (xic == NULL) {
934f299d47fSmrg            fprintf (stderr, "XCreateIC failed\n");
935f299d47fSmrg        }
936f299d47fSmrg    }
937f299d47fSmrg
938f299d47fSmrg    for (done = 0; !done; ) {
939f299d47fSmrg	XEvent event;
940f299d47fSmrg
941f299d47fSmrg	XNextEvent (dpy, &event);
942f299d47fSmrg
943f299d47fSmrg	switch (event.type) {
944f299d47fSmrg	  case KeyPress:
945f299d47fSmrg	    prologue (&event, "KeyPress");
946f299d47fSmrg	    do_KeyPress (&event);
947f299d47fSmrg	    break;
948f299d47fSmrg	  case KeyRelease:
949f299d47fSmrg	    prologue (&event, "KeyRelease");
950f299d47fSmrg	    do_KeyRelease (&event);
951f299d47fSmrg	    break;
952f299d47fSmrg	  case ButtonPress:
953f299d47fSmrg	    prologue (&event, "ButtonPress");
954f299d47fSmrg	    do_ButtonPress (&event);
955f299d47fSmrg	    break;
956f299d47fSmrg	  case ButtonRelease:
957f299d47fSmrg	    prologue (&event, "ButtonRelease");
958f299d47fSmrg	    do_ButtonRelease (&event);
959f299d47fSmrg	    break;
960f299d47fSmrg	  case MotionNotify:
961f299d47fSmrg	    prologue (&event, "MotionNotify");
962f299d47fSmrg	    do_MotionNotify (&event);
963f299d47fSmrg	    break;
964f299d47fSmrg	  case EnterNotify:
965f299d47fSmrg	    prologue (&event, "EnterNotify");
966f299d47fSmrg	    do_EnterNotify (&event);
967f299d47fSmrg	    break;
968f299d47fSmrg	  case LeaveNotify:
969f299d47fSmrg	    prologue (&event, "LeaveNotify");
970f299d47fSmrg	    do_LeaveNotify (&event);
971f299d47fSmrg	    break;
972f299d47fSmrg	  case FocusIn:
973f299d47fSmrg	    prologue (&event, "FocusIn");
974f299d47fSmrg	    do_FocusIn (&event);
975f299d47fSmrg	    break;
976f299d47fSmrg	  case FocusOut:
977f299d47fSmrg	    prologue (&event, "FocusOut");
978f299d47fSmrg	    do_FocusOut (&event);
979f299d47fSmrg	    break;
980f299d47fSmrg	  case KeymapNotify:
981f299d47fSmrg	    prologue (&event, "KeymapNotify");
982f299d47fSmrg	    do_KeymapNotify (&event);
983f299d47fSmrg	    break;
984f299d47fSmrg	  case Expose:
985f299d47fSmrg	    prologue (&event, "Expose");
986f299d47fSmrg	    do_Expose (&event);
987f299d47fSmrg	    break;
988f299d47fSmrg	  case GraphicsExpose:
989f299d47fSmrg	    prologue (&event, "GraphicsExpose");
990f299d47fSmrg	    do_GraphicsExpose (&event);
991f299d47fSmrg	    break;
992f299d47fSmrg	  case NoExpose:
993f299d47fSmrg	    prologue (&event, "NoExpose");
994f299d47fSmrg	    do_NoExpose (&event);
995f299d47fSmrg	    break;
996f299d47fSmrg	  case VisibilityNotify:
997f299d47fSmrg	    prologue (&event, "VisibilityNotify");
998f299d47fSmrg	    do_VisibilityNotify (&event);
999f299d47fSmrg	    break;
1000f299d47fSmrg	  case CreateNotify:
1001f299d47fSmrg	    prologue (&event, "CreateNotify");
1002f299d47fSmrg	    do_CreateNotify (&event);
1003f299d47fSmrg	    break;
1004f299d47fSmrg	  case DestroyNotify:
1005f299d47fSmrg	    prologue (&event, "DestroyNotify");
1006f299d47fSmrg	    do_DestroyNotify (&event);
1007f299d47fSmrg	    break;
1008f299d47fSmrg	  case UnmapNotify:
1009f299d47fSmrg	    prologue (&event, "UnmapNotify");
1010f299d47fSmrg	    do_UnmapNotify (&event);
1011f299d47fSmrg	    break;
1012f299d47fSmrg	  case MapNotify:
1013f299d47fSmrg	    prologue (&event, "MapNotify");
1014f299d47fSmrg	    do_MapNotify (&event);
1015f299d47fSmrg	    break;
1016f299d47fSmrg	  case MapRequest:
1017f299d47fSmrg	    prologue (&event, "MapRequest");
1018f299d47fSmrg	    do_MapRequest (&event);
1019f299d47fSmrg	    break;
1020f299d47fSmrg	  case ReparentNotify:
1021f299d47fSmrg	    prologue (&event, "ReparentNotify");
1022f299d47fSmrg	    do_ReparentNotify (&event);
1023f299d47fSmrg	    break;
1024f299d47fSmrg	  case ConfigureNotify:
1025f299d47fSmrg	    prologue (&event, "ConfigureNotify");
1026f299d47fSmrg	    do_ConfigureNotify (&event);
1027f299d47fSmrg	    break;
1028f299d47fSmrg	  case ConfigureRequest:
1029f299d47fSmrg	    prologue (&event, "ConfigureRequest");
1030f299d47fSmrg	    do_ConfigureRequest (&event);
1031f299d47fSmrg	    break;
1032f299d47fSmrg	  case GravityNotify:
1033f299d47fSmrg	    prologue (&event, "GravityNotify");
1034f299d47fSmrg	    do_GravityNotify (&event);
1035f299d47fSmrg	    break;
1036f299d47fSmrg	  case ResizeRequest:
1037f299d47fSmrg	    prologue (&event, "ResizeRequest");
1038f299d47fSmrg	    do_ResizeRequest (&event);
1039f299d47fSmrg	    break;
1040f299d47fSmrg	  case CirculateNotify:
1041f299d47fSmrg	    prologue (&event, "CirculateNotify");
1042f299d47fSmrg	    do_CirculateNotify (&event);
1043f299d47fSmrg	    break;
1044f299d47fSmrg	  case CirculateRequest:
1045f299d47fSmrg	    prologue (&event, "CirculateRequest");
1046f299d47fSmrg	    do_CirculateRequest (&event);
1047f299d47fSmrg	    break;
1048f299d47fSmrg	  case PropertyNotify:
1049f299d47fSmrg	    prologue (&event, "PropertyNotify");
1050f299d47fSmrg	    do_PropertyNotify (&event);
1051f299d47fSmrg	    break;
1052f299d47fSmrg	  case SelectionClear:
1053f299d47fSmrg	    prologue (&event, "SelectionClear");
1054f299d47fSmrg	    do_SelectionClear (&event);
1055f299d47fSmrg	    break;
1056f299d47fSmrg	  case SelectionRequest:
1057f299d47fSmrg	    prologue (&event, "SelectionRequest");
1058f299d47fSmrg	    do_SelectionRequest (&event);
1059f299d47fSmrg	    break;
1060f299d47fSmrg	  case SelectionNotify:
1061f299d47fSmrg	    prologue (&event, "SelectionNotify");
1062f299d47fSmrg	    do_SelectionNotify (&event);
1063f299d47fSmrg	    break;
1064f299d47fSmrg	  case ColormapNotify:
1065f299d47fSmrg	    prologue (&event, "ColormapNotify");
1066f299d47fSmrg	    do_ColormapNotify (&event);
1067f299d47fSmrg	    break;
1068f299d47fSmrg	  case ClientMessage:
1069f299d47fSmrg	    prologue (&event, "ClientMessage");
1070f299d47fSmrg	    do_ClientMessage (&event);
1071f299d47fSmrg	    break;
1072f299d47fSmrg	  case MappingNotify:
1073f299d47fSmrg	    prologue (&event, "MappingNotify");
1074f299d47fSmrg	    do_MappingNotify (&event);
1075f299d47fSmrg	    break;
1076f299d47fSmrg	  default:
1077f299d47fSmrg	    printf ("Unknown event type %d\n", event.type);
1078f299d47fSmrg	    break;
1079f299d47fSmrg	}
1080aa98702cSmrg	fflush(stdout);
1081f299d47fSmrg    }
1082f299d47fSmrg
1083f299d47fSmrg    XCloseDisplay (dpy);
1084f299d47fSmrg    return 0;
1085f299d47fSmrg}
1086