2 * Copyright © 2009 Red Hat, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
29 extern void print_classes_xi2(Display
*, XIAnyClassInfo
**classes
,
32 #define BitIsOn(ptr, bit) (((unsigned char *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
33 #define SetBit(ptr, bit) (((unsigned char *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7)))
35 static Window
create_win(Display
*dpy
)
37 Window win
= XCreateSimpleWindow(dpy
, DefaultRootWindow(dpy
), 0, 0, 200,
38 200, 0, 0, WhitePixel(dpy
, 0));
39 Window subwindow
= XCreateSimpleWindow(dpy
, win
, 50, 50, 50, 50, 0, 0,
42 XSelectInput(dpy
, win
, ExposureMask
);
43 XMapWindow(dpy
, subwindow
);
49 static void print_deviceevent(XIDeviceEvent
* event
)
54 printf(" device: %d (%d)\n", event
->deviceid
, event
->sourceid
);
55 printf(" detail: %d\n", event
->detail
);
57 printf(" root: %.2f/%.2f\n", event
->root_x
, event
->root_y
);
58 printf(" event: %.2f/%.2f\n", event
->event_x
, event
->event_x
);
61 for (i
= 0; i
< event
->buttons
->mask_len
* 8; i
++)
62 if (BitIsOn(event
->buttons
->mask
, i
))
66 printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n",
67 event
->mods
->locked
, event
->mods
->latched
,
69 printf(" group: locked 0x%x latched 0x%x base 0x%x\n",
70 event
->group
->locked
, event
->group
->latched
,
72 printf(" valuators:");
74 val
= event
->valuators
->values
;
75 for (i
= 0; i
< event
->valuators
->mask_len
* 8; i
++)
76 if (BitIsOn(event
->valuators
->mask
, i
))
77 printf(" %.2f", *val
++);
80 printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
81 event
->root
, event
->event
, event
->child
);
84 static void print_devicechangedevent(Display
*dpy
, XIDeviceChangedEvent
*event
)
86 printf(" device: %d (%d)\n", event
->deviceid
, event
->sourceid
);
87 printf(" reason: %s\n", (event
->reason
== XISlaveSwitch
) ? "SlaveSwitch" :
89 print_classes_xi2(dpy
, event
->classes
, event
->num_classes
);
92 static void print_hierarchychangedevent(XIHierarchyEvent
*event
)
95 printf(" Changes happened: %s %s %s %s %s %s %s %s\n",
96 (event
->flags
& XIMasterAdded
) ? "[new master]" : "",
97 (event
->flags
& XIMasterRemoved
) ? "[master removed]" : "",
98 (event
->flags
& XISlaveAdded
) ? "[new slave]" : "",
99 (event
->flags
& XISlaveRemoved
) ? "[slave removed]" : "",
100 (event
->flags
& XISlaveAttached
) ? "[slave attached]" : "",
101 (event
->flags
& XISlaveDetached
) ? "[slave detached]" : "",
102 (event
->flags
& XIDeviceEnabled
) ? "[device enabled]" : "",
103 (event
->flags
& XIDeviceDisabled
) ? "[device disabled]" : "");
105 for (i
= 0; i
< event
->num_devices
; i
++)
108 switch(event
->info
[i
].use
)
110 case XIMasterPointer
: use
= "master pointer";
111 case XIMasterKeyboard
: use
= "master keyboard"; break;
112 case XISlavePointer
: use
= "slave pointer";
113 case XISlaveKeyboard
: use
= "slave keyboard"; break;
114 case XIFloatingSlave
: use
= "floating slave"; break;
118 printf(" device %d [%s (%d)] is %s\n",
119 event
->info
[i
].deviceid
,
121 event
->info
[i
].attachment
,
122 (event
->info
[i
].enabled
) ? "enabled" : "disabled");
123 if (event
->info
[i
].flags
)
125 printf(" changes: %s %s %s %s %s %s %s %s\n",
126 (event
->info
[i
].flags
& XIMasterAdded
) ? "[new master]" : "",
127 (event
->info
[i
].flags
& XIMasterRemoved
) ? "[master removed]" : "",
128 (event
->info
[i
].flags
& XISlaveAdded
) ? "[new slave]" : "",
129 (event
->info
[i
].flags
& XISlaveRemoved
) ? "[slave removed]" : "",
130 (event
->info
[i
].flags
& XISlaveAttached
) ? "[slave attached]" : "",
131 (event
->info
[i
].flags
& XISlaveDetached
) ? "[slave detached]" : "",
132 (event
->info
[i
].flags
& XIDeviceEnabled
) ? "[device enabled]" : "",
133 (event
->info
[i
].flags
& XIDeviceDisabled
) ? "[device disabled]" : "");
138 static void print_rawevent(XIRawEvent
*event
)
141 double *val
, *raw_val
;
143 printf(" device: %d\n", event
->deviceid
);
144 printf(" detail: %d\n", event
->detail
);
145 printf(" valuators:\n");
147 val
= event
->valuators
->values
;
148 raw_val
= event
->raw_values
;
149 for (i
= 0; i
< event
->valuators
->mask_len
* 8; i
++)
150 if (BitIsOn(event
->valuators
->mask
, i
))
151 printf(" %2d: %.2f (%.2f)\n", i
, *val
++, *raw_val
++);
155 static void print_enterleave(XILeaveEvent
* event
)
160 printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
161 event
->root
, event
->event
, event
->child
);
164 case NotifyNormal
: mode
= "NotifyNormal"; break;
165 case NotifyGrab
: mode
= "NotifyGrab"; break;
166 case NotifyUngrab
: mode
= "NotifyUngrab"; break;
167 case NotifyWhileGrabbed
: mode
= "NotifyWhileGrabbed"; break;
169 switch (event
->detail
)
171 case NotifyAncestor
: detail
= "NotifyAncestor"; break;
172 case NotifyVirtual
: detail
= "NotifyVirtual"; break;
173 case NotifyInferior
: detail
= "NotifyInferior"; break;
174 case NotifyNonlinear
: detail
= "NotifyNonlinear"; break;
175 case NotifyNonlinearVirtual
: detail
= "NotifyNonlinearVirtual"; break;
176 case NotifyPointer
: detail
= "NotifyPointer"; break;
177 case NotifyPointerRoot
: detail
= "NotifyPointerRoot"; break;
178 case NotifyDetailNone
: detail
= "NotifyDetailNone"; break;
180 printf(" mode: %s (detail %s)\n", mode
, detail
);
181 printf(" flags: %s %s\n", event
->focus
? "[focus]" : "",
182 event
->same_screen
? "[same screen]" : "");
184 for (i
= 0; i
< event
->buttons
->mask_len
* 8; i
++)
185 if (BitIsOn(event
->buttons
->mask
, i
))
189 printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n",
190 event
->mods
->locked
, event
->mods
->latched
,
192 printf(" group: locked 0x%x latched 0x%x base 0x%x\n",
193 event
->group
->locked
, event
->group
->latched
,
196 printf(" root x/y: %.2f / %.2f\n", event
->root_x
, event
->root_y
);
197 printf(" event x/y: %.2f / %.2f\n", event
->event_x
, event
->event_y
);
201 static void print_propertyevent(Display
*display
, XIPropertyEvent
* event
)
205 if (event
->what
== XIPropertyDeleted
)
207 else if (event
->what
== XIPropertyCreated
)
210 changed
= "modified";
212 printf(" property: %ld '%s'\n", event
->property
, XGetAtomName(display
, event
->property
));
213 printf(" changed: %s\n", changed
);
217 test_sync_grab(Display
*display
, Window win
)
223 /* Select for motion events */
224 mask
.deviceid
= XIAllDevices
;
226 mask
.mask
= calloc(2, sizeof(char));
227 SetBit(mask
.mask
, XI_ButtonPress
);
229 if ((rc
= XIGrabDevice(display
, 2, win
, CurrentTime
, None
, GrabModeSync
,
230 GrabModeAsync
, False
, &mask
)) != GrabSuccess
)
232 fprintf(stderr
, "Grab failed with %d\n", rc
);
237 XSync(display
, True
);
238 XIAllowEvents(display
, 2, SyncPointer
, CurrentTime
);
241 printf("Holding sync grab for %d button presses.\n", loop
);
247 XNextEvent(display
, (XEvent
*)&ev
);
248 if (ev
.type
== GenericEvent
)
250 XIDeviceEvent
*event
= (XIDeviceEvent
*)&ev
;
251 print_deviceevent(event
);
252 XIAllowEvents(display
, 2, SyncPointer
, CurrentTime
);
253 XIFreeEventData(&ev
);
257 XIUngrabDevice(display
, 2, CurrentTime
);
262 test_xi2(Display
*display
,
271 list(display
, argc
, argv
, name
, desc
);
272 win
= create_win(display
);
274 XSync(display
, False
);
276 /* Select for motion events */
277 mask
.deviceid
= XIAllDevices
;
279 mask
.mask
= calloc(mask
.mask_len
, sizeof(char));
280 SetBit(mask
.mask
, XI_ButtonPress
);
281 SetBit(mask
.mask
, XI_ButtonRelease
);
282 SetBit(mask
.mask
, XI_KeyPress
);
283 SetBit(mask
.mask
, XI_KeyRelease
);
284 SetBit(mask
.mask
, XI_Motion
);
285 SetBit(mask
.mask
, XI_DeviceChanged
);
286 SetBit(mask
.mask
, XI_Enter
);
287 SetBit(mask
.mask
, XI_Leave
);
288 SetBit(mask
.mask
, XI_FocusIn
);
289 SetBit(mask
.mask
, XI_FocusOut
);
290 SetBit(mask
.mask
, XI_HierarchyChanged
);
291 SetBit(mask
.mask
, XI_PropertyEvent
);
292 XISelectEvents(display
, win
, &mask
, 1);
293 XSync(display
, False
);
296 XIGrabModifiers modifiers
[] = {{0, 0}, {0, 0x10}, {0, 0x1}, {0, 0x11}};
297 int nmods
= sizeof(modifiers
)/sizeof(modifiers
[0]);
300 memset(mask
.mask
, 0, 2);
301 SetBit(mask
.mask
, XI_KeyPress
);
302 SetBit(mask
.mask
, XI_KeyRelease
);
303 SetBit(mask
.mask
, XI_ButtonPress
);
304 SetBit(mask
.mask
, XI_Motion
);
305 XIGrabButton(display
, 2, 1, win
, None
, GrabModeAsync
, GrabModeAsync
,
306 False
, &mask
, nmods
, modifiers
);
307 XIGrabKeysym(display
, 3, 0x71, win
, GrabModeAsync
, GrabModeAsync
,
308 False
, &mask
, nmods
, modifiers
);
309 XIUngrabButton(display
, 3, 1, win
, nmods
- 2, &modifiers
[2]);
310 XIUngrabKeysym(display
, 3, 0x71, win
, nmods
- 2, &modifiers
[2]);
313 mask
.deviceid
= XIAllMasterDevices
;
314 memset(mask
.mask
, 0, 2);
315 SetBit(mask
.mask
, XI_RawEvent
);
316 XISelectEvents(display
, DefaultRootWindow(display
), &mask
, 1);
322 XMaskEvent(display
, ExposureMask
, &event
);
323 XSelectInput(display
, win
, 0);
327 test_sync_grab(display, win);
333 XNextEvent(display
, (XEvent
*)&ev
);
334 if (ev
.type
== GenericEvent
)
336 XIDeviceEvent
*event
= (XIDeviceEvent
*)&ev
;
338 printf("EVENT type %d\n", event
->evtype
);
339 switch (event
->evtype
)
341 case XI_DeviceChanged
:
342 print_devicechangedevent(display
,
343 (XIDeviceChangedEvent
*)event
);
345 case XI_HierarchyChanged
:
346 print_hierarchychangedevent((XIHierarchyEvent
*)event
);
349 print_rawevent((XIRawEvent
*)event
);
355 print_enterleave((XILeaveEvent
*)event
);
357 case XI_PropertyEvent
:
358 print_propertyevent(display
, (XIPropertyEvent
*)event
);
361 print_deviceevent(event
);
366 XIFreeEventData(&ev
);
369 XDestroyWindow(display
, win
);