]> diplodocus.org Git - xorg-xinput/blob - src/test_xi2.c
d5a89850260545c7b7a38a9001f3849241aad248
[xorg-xinput] / src / test_xi2.c
1 /*
2 * Copyright © 2009 Red Hat, Inc.
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 *
23 */
24
25
26 #include "xinput.h"
27 #include <string.h>
28
29 extern void print_classes_xi2(Display*, XIAnyClassInfo **classes,
30 int num_classes);
31
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)))
34
35 static Window create_win(Display *dpy)
36 {
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,
40 BlackPixel(dpy, 0));
41
42 XMapWindow(dpy, subwindow);
43 XMapWindow(dpy, win);
44 XFlush(dpy);
45 return win;
46 }
47
48 static void print_deviceevent(XIDeviceEvent* event)
49 {
50 double *val;
51 int i;
52
53 printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
54 printf(" detail: %d\n", event->detail);
55 printf(" buttons:");
56 for (i = 0; i < event->buttons->mask_len * 8; i++)
57 if (BitIsOn(event->buttons->mask, i))
58 printf(" %d", i);
59 printf("\n");
60
61 printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n",
62 event->mods->locked, event->mods->latched,
63 event->mods->base);
64 printf(" group: locked 0x%x latched 0x%x base 0x%x\n",
65 event->group->locked, event->group->latched,
66 event->group->base);
67 printf(" valuators:");
68
69 val = event->valuators->values;
70 for (i = 0; i < event->valuators->mask_len * 8; i++)
71 if (BitIsOn(event->valuators->mask, i))
72 printf(" %.2f", *val++);
73 printf("\n");
74
75 printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
76 event->root, event->event, event->child);
77 }
78
79 static void print_devicechangedevent(Display *dpy, XIDeviceChangedEvent *event)
80 {
81 printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
82 printf(" reason: %s\n", (event->reason == SlaveSwitch) ? "SlaveSwitch" :
83 "DeviceChanged");
84 print_classes_xi2(dpy, event->classes, event->num_classes);
85 }
86
87 static void print_hierarchychangedevent(XIDeviceHierarchyEvent *event)
88 {
89 int i;
90 printf(" Changes happened: %s %s %s %s %s %s %s\n",
91 (event->flags & HF_MasterAdded) ? "[new master]" : "",
92 (event->flags & HF_MasterRemoved) ? "[master removed]" : "",
93 (event->flags & HF_SlaveAdded) ? "[new slave]" : "",
94 (event->flags & HF_SlaveRemoved) ? "[slave removed]" : "",
95 (event->flags & HF_SlaveAttached) ? "[slave attached]" : "",
96 (event->flags & HF_DeviceEnabled) ? "[device enabled]" : "",
97 (event->flags & HF_DeviceDisabled) ? "[device disabled]" : "");
98
99 for (i = 0; i < event->num_devices; i++)
100 {
101 char *use;
102 switch(event->info[i].use)
103 {
104 case MasterPointer: use = "master pointer";
105 case MasterKeyboard: use = "master keyboard"; break;
106 case SlavePointer: use = "slave pointer";
107 case SlaveKeyboard: use = "slave keyboard"; break;
108 case FloatingSlave: use = "floating slave"; break;
109 break;
110 }
111
112 printf(" device %d [%s (%d)] is %s\n",
113 event->info[i].deviceid,
114 use,
115 event->info[i].attachment,
116 (event->info[i].enabled) ? "enabled" : "disabled");
117 }
118 }
119
120 static void print_rawevent(XIRawDeviceEvent *event)
121 {
122 int i;
123 double *val, *raw_val;
124
125 printf(" device: %d\n", event->deviceid);
126 printf(" detail: %d\n", event->detail);
127 printf(" valuators:\n");
128
129 val = event->valuators->values;
130 raw_val = event->raw_values;
131 for (i = 0; i < event->valuators->mask_len * 8; i++)
132 if (BitIsOn(event->valuators->mask, i))
133 printf(" %2d: %.2f (%.2f)\n", i, *val++, *raw_val++);
134 printf("\n");
135 }
136
137 static void print_enterleave(XILeaveEvent* event)
138 {
139 char *mode, *detail;
140 int i;
141
142 printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
143 event->root, event->event, event->child);
144 switch(event->mode)
145 {
146 case NotifyNormal: mode = "NotifyNormal"; break;
147 case NotifyGrab: mode = "NotifyGrab"; break;
148 case NotifyUngrab: mode = "NotifyUngrab"; break;
149 case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break;
150 }
151 switch (event->detail)
152 {
153 case NotifyAncestor: detail = "NotifyAncestor"; break;
154 case NotifyVirtual: detail = "NotifyVirtual"; break;
155 case NotifyInferior: detail = "NotifyInferior"; break;
156 case NotifyNonlinear: detail = "NotifyNonlinear"; break;
157 case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break;
158 case NotifyPointer: detail = "NotifyPointer"; break;
159 case NotifyPointerRoot: detail = "NotifyPointerRoot"; break;
160 case NotifyDetailNone: detail = "NotifyDetailNone"; break;
161 }
162 printf(" mode: %s (detail %s)\n", mode, detail);
163 printf(" flags: %s %s\n", event->focus ? "[focus]" : "",
164 event->same_screen ? "[same screen]" : "");
165 printf(" buttons:");
166 for (i = 0; i < event->buttons->mask_len * 8; i++)
167 if (BitIsOn(event->buttons->mask, i))
168 printf(" %d", i);
169 printf("\n");
170
171 printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n",
172 event->mods->locked, event->mods->latched,
173 event->mods->base);
174 printf(" group: locked 0x%x latched 0x%x base 0x%x\n",
175 event->group->locked, event->group->latched,
176 event->group->base);
177
178 printf(" root x/y: %.2f / %.2f\n", event->root_x, event->root_y);
179 printf(" event x/y: %.2f / %.2f\n", event->event_x, event->event_x);
180
181 }
182
183 int
184 test_xi2(Display *display,
185 int argc,
186 char *argv[],
187 char *name,
188 char *desc)
189 {
190 XIDeviceEventMask mask;
191 Window win;
192
193 list(display, argc, argv, name, desc);
194 win = create_win(display);
195
196 /* Select for motion events */
197 mask.deviceid = AllDevices;
198 mask.mask_len = 2;
199 mask.mask = calloc(2, sizeof(char));
200 SetBit(mask.mask, XI_ButtonPress);
201 SetBit(mask.mask, XI_ButtonRelease);
202 SetBit(mask.mask, XI_Motion);
203 SetBit(mask.mask, XI_KeyPress);
204 SetBit(mask.mask, XI_KeyPress);
205 SetBit(mask.mask, XI_DeviceChanged);
206 SetBit(mask.mask, XI_Enter);
207 SetBit(mask.mask, XI_Leave);
208 SetBit(mask.mask, XI_FocusIn);
209 SetBit(mask.mask, XI_FocusOut);
210 SetBit(mask.mask, XI_HierarchyChanged);
211 XISelectEvent(display, win, &mask, 1);
212
213 mask.deviceid = AllMasterDevices;
214 memset(mask.mask, 0, 2);
215 SetBit(mask.mask, XI_RawEvent);
216 XISelectEvent(display, DefaultRootWindow(display), &mask, 1);
217
218 free(mask.mask);
219
220 while(1)
221 {
222 XIEvent ev;
223 XNextEvent(display, (XEvent*)&ev);
224 if (ev.type == GenericEvent)
225 {
226 XIDeviceEvent *event = (XIDeviceEvent*)&ev;
227
228 printf("EVENT type %d\n", event->evtype);
229 switch (event->evtype)
230 {
231 case XI_DeviceChanged:
232 print_devicechangedevent(display,
233 (XIDeviceChangedEvent*)event);
234 break;
235 case XI_HierarchyChanged:
236 print_hierarchychangedevent((XIDeviceHierarchyEvent*)event);
237 break;
238 case XI_RawEvent:
239 print_rawevent((XIRawDeviceEvent*)event);
240 break;
241 case XI_Enter:
242 case XI_Leave:
243 case XI_FocusIn:
244 case XI_FocusOut:
245 print_enterleave((XILeaveEvent*)event);
246 break;
247 default:
248 print_deviceevent(event);
249 break;
250 }
251 }
252
253 XIFreeEventData(&ev);
254 }
255
256 return EXIT_SUCCESS;
257 }