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