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