xev.c 40 KB

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