File: | Xi/xiquerydevice.c |
Location: | line 105, column 12 |
Description: | Call to 'calloc' has an allocation size of 0 bytes |
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 | * Authors: Peter Hutterer | |||
24 | * | |||
25 | */ | |||
26 | ||||
27 | /** | |||
28 | * @file Protocol handling for the XIQueryDevice request/reply. | |||
29 | */ | |||
30 | ||||
31 | #ifdef HAVE_DIX_CONFIG_H1 | |||
32 | #include <dix-config.h> | |||
33 | #endif | |||
34 | ||||
35 | #include "inputstr.h" | |||
36 | #include <X11/X.h> | |||
37 | #include <X11/Xatom.h> | |||
38 | #include <X11/extensions/XI2proto.h> | |||
39 | #include "xkbstr.h" | |||
40 | #include "xkbsrv.h" | |||
41 | #include "xserver-properties.h" | |||
42 | #include "exevents.h" | |||
43 | #include "xace.h" | |||
44 | #include "inpututils.h" | |||
45 | ||||
46 | #include "xiquerydevice.h" | |||
47 | ||||
48 | static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d); | |||
49 | static int | |||
50 | ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo * info); | |||
51 | static int SizeDeviceInfo(DeviceIntPtr dev); | |||
52 | static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo * info); | |||
53 | int | |||
54 | SProcXIQueryDevice(ClientPtr client) | |||
55 | { | |||
56 | REQUEST(xXIQueryDeviceReq)xXIQueryDeviceReq *stuff = (xXIQueryDeviceReq *)client->requestBuffer; | |||
57 | REQUEST_SIZE_MATCH(xXIQueryDeviceReq)if ((sizeof(xXIQueryDeviceReq) >> 2) != client->req_len ) return(16); | |||
58 | ||||
59 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
60 | swaps(&stuff->deviceid)do { if (sizeof(*(&stuff->deviceid)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->deviceid ) & 1) && ((uintptr_t)(&stuff->deviceid) & 1) == 0) *(&stuff->deviceid) = lswaps(*(&stuff-> deviceid)); else swap_uint16((uint16_t *)(&stuff->deviceid )); } while (0); | |||
61 | ||||
62 | return ProcXIQueryDevice(client); | |||
| ||||
63 | } | |||
64 | ||||
65 | int | |||
66 | ProcXIQueryDevice(ClientPtr client) | |||
67 | { | |||
68 | xXIQueryDeviceReply rep; | |||
69 | DeviceIntPtr dev = NULL((void*)0); | |||
70 | int rc = Success0; | |||
71 | int i = 0, len = 0; | |||
72 | char *info, *ptr; | |||
73 | Bool *skip = NULL((void*)0); | |||
74 | ||||
75 | REQUEST(xXIQueryDeviceReq)xXIQueryDeviceReq *stuff = (xXIQueryDeviceReq *)client->requestBuffer; | |||
76 | REQUEST_SIZE_MATCH(xXIQueryDeviceReq)if ((sizeof(xXIQueryDeviceReq) >> 2) != client->req_len ) return(16); | |||
77 | ||||
78 | if (stuff->deviceid != XIAllDevices0 && | |||
79 | stuff->deviceid != XIAllMasterDevices1) { | |||
80 | rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess(1<<4)); | |||
81 | if (rc != Success0) { | |||
82 | client->errorValue = stuff->deviceid; | |||
83 | return rc; | |||
84 | } | |||
85 | len += SizeDeviceInfo(dev); | |||
86 | } | |||
87 | else { | |||
88 | skip = calloc(sizeof(Bool), inputInfo.numDevices); | |||
89 | if (!skip) | |||
90 | return BadAlloc11; | |||
91 | ||||
92 | for (dev = inputInfo.devices; dev; dev = dev->next, i++) { | |||
93 | skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); | |||
94 | if (!skip[i]) | |||
95 | len += SizeDeviceInfo(dev); | |||
96 | } | |||
97 | ||||
98 | for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) { | |||
99 | skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); | |||
100 | if (!skip[i]) | |||
101 | len += SizeDeviceInfo(dev); | |||
102 | } | |||
103 | } | |||
104 | ||||
105 | info = calloc(1, len); | |||
| ||||
106 | if (!info) { | |||
107 | free(skip); | |||
108 | return BadAlloc11; | |||
109 | } | |||
110 | ||||
111 | rep = (xXIQueryDeviceReply) { | |||
112 | .repType = X_Reply1, | |||
113 | .RepType = X_XIQueryDevice48, | |||
114 | .sequenceNumber = client->sequence, | |||
115 | .length = len / 4, | |||
116 | .num_devices = 0 | |||
117 | }; | |||
118 | ||||
119 | ptr = info; | |||
120 | if (dev) { | |||
121 | len = ListDeviceInfo(client, dev, (xXIDeviceInfo *) info); | |||
122 | if (client->swapped) | |||
123 | SwapDeviceInfo(dev, (xXIDeviceInfo *) info); | |||
124 | info += len; | |||
125 | rep.num_devices = 1; | |||
126 | } | |||
127 | else { | |||
128 | i = 0; | |||
129 | for (dev = inputInfo.devices; dev; dev = dev->next, i++) { | |||
130 | if (!skip[i]) { | |||
131 | len = ListDeviceInfo(client, dev, (xXIDeviceInfo *) info); | |||
132 | if (client->swapped) | |||
133 | SwapDeviceInfo(dev, (xXIDeviceInfo *) info); | |||
134 | info += len; | |||
135 | rep.num_devices++; | |||
136 | } | |||
137 | } | |||
138 | ||||
139 | for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) { | |||
140 | if (!skip[i]) { | |||
141 | len = ListDeviceInfo(client, dev, (xXIDeviceInfo *) info); | |||
142 | if (client->swapped) | |||
143 | SwapDeviceInfo(dev, (xXIDeviceInfo *) info); | |||
144 | info += len; | |||
145 | rep.num_devices++; | |||
146 | } | |||
147 | } | |||
148 | } | |||
149 | ||||
150 | len = rep.length * 4; | |||
151 | WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client )->requestBuffer)->reqType]) (client, (int)(sizeof(xXIQueryDeviceReply )), &rep); else WriteToClient(client, (int)(sizeof(xXIQueryDeviceReply )), (&rep)); }; | |||
152 | WriteToClient(client, len, ptr); | |||
153 | free(ptr); | |||
154 | free(skip); | |||
155 | return rc; | |||
156 | } | |||
157 | ||||
158 | void | |||
159 | SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply * rep) | |||
160 | { | |||
161 | swaps(&rep->sequenceNumber)do { if (sizeof(*(&rep->sequenceNumber)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&rep->sequenceNumber ) & 1) && ((uintptr_t)(&rep->sequenceNumber ) & 1) == 0) *(&rep->sequenceNumber) = lswaps(*(& rep->sequenceNumber)); else swap_uint16((uint16_t *)(& rep->sequenceNumber)); } while (0); | |||
162 | swapl(&rep->length)do { if (sizeof(*(&rep->length)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&rep->length) & 3) && ((uintptr_t)(&rep->length) & 3) == 0 ) *(&rep->length) = lswapl(*(&rep->length)); else swap_uint32((uint32_t *)(&rep->length)); } while (0); | |||
163 | swaps(&rep->num_devices)do { if (sizeof(*(&rep->num_devices)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&rep->num_devices ) & 1) && ((uintptr_t)(&rep->num_devices) & 1) == 0) *(&rep->num_devices) = lswaps(*(&rep-> num_devices)); else swap_uint16((uint16_t *)(&rep->num_devices )); } while (0); | |||
164 | ||||
165 | /* Device info is already swapped, see ProcXIQueryDevice */ | |||
166 | ||||
167 | WriteToClient(client, size, rep); | |||
168 | } | |||
169 | ||||
170 | /** | |||
171 | * @return Whether the device should be included in the returned list. | |||
172 | */ | |||
173 | static Bool | |||
174 | ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev) | |||
175 | { | |||
176 | /* if all devices are not being queried, only master devices are */ | |||
177 | if (deviceid == XIAllDevices0 || IsMaster(dev)) { | |||
178 | int rc = XaceHook(XACE_DEVICE_ACCESS3, client, dev, DixGetAttrAccess(1<<4)); | |||
179 | ||||
180 | if (rc == Success0) | |||
181 | return FALSE0; | |||
182 | } | |||
183 | return TRUE1; | |||
184 | } | |||
185 | ||||
186 | /** | |||
187 | * @return The number of bytes needed to store this device's xXIDeviceInfo | |||
188 | * (and its classes). | |||
189 | */ | |||
190 | static int | |||
191 | SizeDeviceInfo(DeviceIntPtr dev) | |||
192 | { | |||
193 | int len = sizeof(xXIDeviceInfo); | |||
194 | ||||
195 | /* 4-padded name */ | |||
196 | len += pad_to_int32(strlen(dev->name)); | |||
197 | ||||
198 | return len + SizeDeviceClasses(dev); | |||
199 | ||||
200 | } | |||
201 | ||||
202 | /* | |||
203 | * @return The number of bytes needed to store this device's classes. | |||
204 | */ | |||
205 | int | |||
206 | SizeDeviceClasses(DeviceIntPtr dev) | |||
207 | { | |||
208 | int len = 0; | |||
209 | ||||
210 | if (dev->button) { | |||
211 | len += sizeof(xXIButtonInfo); | |||
212 | len += dev->button->numButtons * sizeof(Atom); | |||
213 | len += pad_to_int32(bits_to_bytes(dev->button->numButtons)); | |||
214 | } | |||
215 | ||||
216 | if (dev->key) { | |||
217 | XkbDescPtr xkb = dev->key->xkbInfo->desc; | |||
218 | ||||
219 | len += sizeof(xXIKeyInfo); | |||
220 | len += (xkb->max_key_code - xkb->min_key_code + 1) * sizeof(uint32_t); | |||
221 | } | |||
222 | ||||
223 | if (dev->valuator) { | |||
224 | int i; | |||
225 | ||||
226 | len += (sizeof(xXIValuatorInfo)) * dev->valuator->numAxes; | |||
227 | ||||
228 | for (i = 0; i < dev->valuator->numAxes; i++) { | |||
229 | if (dev->valuator->axes[i].scroll.type != SCROLL_TYPE_NONE) | |||
230 | len += sizeof(xXIScrollInfo); | |||
231 | } | |||
232 | } | |||
233 | ||||
234 | if (dev->touch) | |||
235 | len += sizeof(xXITouchInfo); | |||
236 | ||||
237 | return len; | |||
238 | } | |||
239 | ||||
240 | /** | |||
241 | * Write button information into info. | |||
242 | * @return Number of bytes written into info. | |||
243 | */ | |||
244 | int | |||
245 | ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState) | |||
246 | { | |||
247 | unsigned char *bits; | |||
248 | int mask_len; | |||
249 | int i; | |||
250 | ||||
251 | if (!dev || !dev->button) | |||
252 | return 0; | |||
253 | ||||
254 | mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons)); | |||
255 | ||||
256 | info->type = ButtonClass1; | |||
257 | info->num_buttons = dev->button->numButtons; | |||
258 | info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + | |||
259 | info->num_buttons + mask_len; | |||
260 | info->sourceid = dev->button->sourceid; | |||
261 | ||||
262 | bits = (unsigned char *) &info[1]; | |||
263 | memset(bits, 0, mask_len * 4)__builtin___memset_chk (bits, 0, mask_len * 4, __builtin_object_size (bits, 0)); | |||
264 | ||||
265 | if (reportState) | |||
266 | for (i = 0; i < dev->button->numButtons; i++) | |||
267 | if (BitIsOn(dev->button->down, i)(!!(((const BYTE *) (dev->button->down))[(i)>>3] & (1 << ((i) & 7))))) | |||
268 | SetBit(bits, i)(((BYTE *) (bits))[(i)>>3] |= (1 << ((i) & 7) )); | |||
269 | ||||
270 | bits += mask_len * 4; | |||
271 | memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom))__builtin___memcpy_chk (bits, dev->button->labels, dev-> button->numButtons * sizeof(Atom), __builtin_object_size ( bits, 0)); | |||
272 | ||||
273 | return info->length * 4; | |||
274 | } | |||
275 | ||||
276 | static void | |||
277 | SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info) | |||
278 | { | |||
279 | Atom *btn; | |||
280 | int i; | |||
281 | ||||
282 | swaps(&info->type)do { if (sizeof(*(&info->type)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->type) & 1 ) && ((uintptr_t)(&info->type) & 1) == 0) * (&info->type) = lswaps(*(&info->type)); else swap_uint16 ((uint16_t *)(&info->type)); } while (0); | |||
283 | swaps(&info->length)do { if (sizeof(*(&info->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->length) & 1) && ((uintptr_t)(&info->length) & 1) == 0) *(&info->length) = lswaps(*(&info->length)) ; else swap_uint16((uint16_t *)(&info->length)); } while (0); | |||
284 | swaps(&info->sourceid)do { if (sizeof(*(&info->sourceid)) != 2) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->sourceid ) & 1) && ((uintptr_t)(&info->sourceid) & 1) == 0) *(&info->sourceid) = lswaps(*(&info-> sourceid)); else swap_uint16((uint16_t *)(&info->sourceid )); } while (0); | |||
285 | ||||
286 | for (i = 0, btn = (Atom *) &info[1]; i < info->num_buttons; i++, btn++) | |||
287 | swapl(btn)do { if (sizeof(*(btn)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(btn) & 3) && ((uintptr_t)(btn) & 3) == 0) *(btn) = lswapl(*(btn)); else swap_uint32((uint32_t *)(btn)); } while (0); | |||
288 | ||||
289 | swaps(&info->num_buttons)do { if (sizeof(*(&info->num_buttons)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->num_buttons ) & 1) && ((uintptr_t)(&info->num_buttons) & 1) == 0) *(&info->num_buttons) = lswaps(*(& info->num_buttons)); else swap_uint16((uint16_t *)(&info ->num_buttons)); } while (0); | |||
290 | } | |||
291 | ||||
292 | /** | |||
293 | * Write key information into info. | |||
294 | * @return Number of bytes written into info. | |||
295 | */ | |||
296 | int | |||
297 | ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo * info) | |||
298 | { | |||
299 | int i; | |||
300 | XkbDescPtr xkb = dev->key->xkbInfo->desc; | |||
301 | uint32_t *kc; | |||
302 | ||||
303 | info->type = KeyClass0; | |||
304 | info->num_keycodes = xkb->max_key_code - xkb->min_key_code + 1; | |||
305 | info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes; | |||
306 | info->sourceid = dev->key->sourceid; | |||
307 | ||||
308 | kc = (uint32_t *) &info[1]; | |||
309 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++) | |||
310 | *kc = i; | |||
311 | ||||
312 | return info->length * 4; | |||
313 | } | |||
314 | ||||
315 | static void | |||
316 | SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo * info) | |||
317 | { | |||
318 | uint32_t *key; | |||
319 | int i; | |||
320 | ||||
321 | swaps(&info->type)do { if (sizeof(*(&info->type)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->type) & 1 ) && ((uintptr_t)(&info->type) & 1) == 0) * (&info->type) = lswaps(*(&info->type)); else swap_uint16 ((uint16_t *)(&info->type)); } while (0); | |||
322 | swaps(&info->length)do { if (sizeof(*(&info->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->length) & 1) && ((uintptr_t)(&info->length) & 1) == 0) *(&info->length) = lswaps(*(&info->length)) ; else swap_uint16((uint16_t *)(&info->length)); } while (0); | |||
323 | swaps(&info->sourceid)do { if (sizeof(*(&info->sourceid)) != 2) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->sourceid ) & 1) && ((uintptr_t)(&info->sourceid) & 1) == 0) *(&info->sourceid) = lswaps(*(&info-> sourceid)); else swap_uint16((uint16_t *)(&info->sourceid )); } while (0); | |||
324 | ||||
325 | for (i = 0, key = (uint32_t *) &info[1]; i < info->num_keycodes; | |||
326 | i++, key++) | |||
327 | swapl(key)do { if (sizeof(*(key)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(key) & 3) && ((uintptr_t)(key) & 3) == 0) *(key) = lswapl(*(key)); else swap_uint32((uint32_t *)(key)); } while (0); | |||
328 | ||||
329 | swaps(&info->num_keycodes)do { if (sizeof(*(&info->num_keycodes)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->num_keycodes ) & 1) && ((uintptr_t)(&info->num_keycodes ) & 1) == 0) *(&info->num_keycodes) = lswaps(*(& info->num_keycodes)); else swap_uint16((uint16_t *)(&info ->num_keycodes)); } while (0); | |||
330 | } | |||
331 | ||||
332 | /** | |||
333 | * List axis information for the given axis. | |||
334 | * | |||
335 | * @return The number of bytes written into info. | |||
336 | */ | |||
337 | int | |||
338 | ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo * info, int axisnumber, | |||
339 | Bool reportState) | |||
340 | { | |||
341 | ValuatorClassPtr v = dev->valuator; | |||
342 | ||||
343 | info->type = ValuatorClass2; | |||
344 | info->length = sizeof(xXIValuatorInfo) / 4; | |||
345 | info->label = v->axes[axisnumber].label; | |||
346 | info->min.integral = v->axes[axisnumber].min_value; | |||
347 | info->min.frac = 0; | |||
348 | info->max.integral = v->axes[axisnumber].max_value; | |||
349 | info->max.frac = 0; | |||
350 | info->value = double_to_fp3232(v->axisVal[axisnumber]); | |||
351 | info->resolution = v->axes[axisnumber].resolution; | |||
352 | info->number = axisnumber; | |||
353 | info->mode = valuator_get_mode(dev, axisnumber); | |||
354 | info->sourceid = v->sourceid; | |||
355 | ||||
356 | if (!reportState) | |||
357 | info->value = info->min; | |||
358 | ||||
359 | return info->length * 4; | |||
360 | } | |||
361 | ||||
362 | static void | |||
363 | SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo * info) | |||
364 | { | |||
365 | swaps(&info->type)do { if (sizeof(*(&info->type)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->type) & 1 ) && ((uintptr_t)(&info->type) & 1) == 0) * (&info->type) = lswaps(*(&info->type)); else swap_uint16 ((uint16_t *)(&info->type)); } while (0); | |||
366 | swaps(&info->length)do { if (sizeof(*(&info->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->length) & 1) && ((uintptr_t)(&info->length) & 1) == 0) *(&info->length) = lswaps(*(&info->length)) ; else swap_uint16((uint16_t *)(&info->length)); } while (0); | |||
367 | swapl(&info->label)do { if (sizeof(*(&info->label)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->label) & 3) && ((uintptr_t)(&info->label) & 3) == 0 ) *(&info->label) = lswapl(*(&info->label)); else swap_uint32((uint32_t *)(&info->label)); } while (0); | |||
368 | swapl(&info->min.integral)do { if (sizeof(*(&info->min.integral)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->min.integral ) & 3) && ((uintptr_t)(&info->min.integral ) & 3) == 0) *(&info->min.integral) = lswapl(*(& info->min.integral)); else swap_uint32((uint32_t *)(&info ->min.integral)); } while (0); | |||
369 | swapl(&info->min.frac)do { if (sizeof(*(&info->min.frac)) != 4) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->min.frac ) & 3) && ((uintptr_t)(&info->min.frac) & 3) == 0) *(&info->min.frac) = lswapl(*(&info-> min.frac)); else swap_uint32((uint32_t *)(&info->min.frac )); } while (0); | |||
370 | swapl(&info->max.integral)do { if (sizeof(*(&info->max.integral)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->max.integral ) & 3) && ((uintptr_t)(&info->max.integral ) & 3) == 0) *(&info->max.integral) = lswapl(*(& info->max.integral)); else swap_uint32((uint32_t *)(&info ->max.integral)); } while (0); | |||
371 | swapl(&info->max.frac)do { if (sizeof(*(&info->max.frac)) != 4) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->max.frac ) & 3) && ((uintptr_t)(&info->max.frac) & 3) == 0) *(&info->max.frac) = lswapl(*(&info-> max.frac)); else swap_uint32((uint32_t *)(&info->max.frac )); } while (0); | |||
372 | swaps(&info->number)do { if (sizeof(*(&info->number)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->number) & 1) && ((uintptr_t)(&info->number) & 1) == 0) *(&info->number) = lswaps(*(&info->number)) ; else swap_uint16((uint16_t *)(&info->number)); } while (0); | |||
373 | swaps(&info->sourceid)do { if (sizeof(*(&info->sourceid)) != 2) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->sourceid ) & 1) && ((uintptr_t)(&info->sourceid) & 1) == 0) *(&info->sourceid) = lswaps(*(&info-> sourceid)); else swap_uint16((uint16_t *)(&info->sourceid )); } while (0); | |||
374 | } | |||
375 | ||||
376 | int | |||
377 | ListScrollInfo(DeviceIntPtr dev, xXIScrollInfo * info, int axisnumber) | |||
378 | { | |||
379 | ValuatorClassPtr v = dev->valuator; | |||
380 | AxisInfoPtr axis = &v->axes[axisnumber]; | |||
381 | ||||
382 | if (axis->scroll.type == SCROLL_TYPE_NONE) | |||
383 | return 0; | |||
384 | ||||
385 | info->type = XIScrollClass3; | |||
386 | info->length = sizeof(xXIScrollInfo) / 4; | |||
387 | info->number = axisnumber; | |||
388 | switch (axis->scroll.type) { | |||
389 | case SCROLL_TYPE_VERTICAL: | |||
390 | info->scroll_type = XIScrollTypeVertical1; | |||
391 | break; | |||
392 | case SCROLL_TYPE_HORIZONTAL: | |||
393 | info->scroll_type = XIScrollTypeHorizontal2; | |||
394 | break; | |||
395 | default: | |||
396 | ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n", | |||
397 | axis->scroll.type); | |||
398 | break; | |||
399 | } | |||
400 | info->increment = double_to_fp3232(axis->scroll.increment); | |||
401 | info->sourceid = v->sourceid; | |||
402 | ||||
403 | info->flags = 0; | |||
404 | ||||
405 | if (axis->scroll.flags & SCROLL_FLAG_DONT_EMULATE) | |||
406 | info->flags |= XIScrollFlagNoEmulation(1 << 0); | |||
407 | if (axis->scroll.flags & SCROLL_FLAG_PREFERRED) | |||
408 | info->flags |= XIScrollFlagPreferred(1 << 1); | |||
409 | ||||
410 | return info->length * 4; | |||
411 | } | |||
412 | ||||
413 | static void | |||
414 | SwapScrollInfo(DeviceIntPtr dev, xXIScrollInfo * info) | |||
415 | { | |||
416 | swaps(&info->type)do { if (sizeof(*(&info->type)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->type) & 1 ) && ((uintptr_t)(&info->type) & 1) == 0) * (&info->type) = lswaps(*(&info->type)); else swap_uint16 ((uint16_t *)(&info->type)); } while (0); | |||
417 | swaps(&info->length)do { if (sizeof(*(&info->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->length) & 1) && ((uintptr_t)(&info->length) & 1) == 0) *(&info->length) = lswaps(*(&info->length)) ; else swap_uint16((uint16_t *)(&info->length)); } while (0); | |||
418 | swaps(&info->number)do { if (sizeof(*(&info->number)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&info->number) & 1) && ((uintptr_t)(&info->number) & 1) == 0) *(&info->number) = lswaps(*(&info->number)) ; else swap_uint16((uint16_t *)(&info->number)); } while (0); | |||
419 | swaps(&info->sourceid)do { if (sizeof(*(&info->sourceid)) != 2) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->sourceid ) & 1) && ((uintptr_t)(&info->sourceid) & 1) == 0) *(&info->sourceid) = lswaps(*(&info-> sourceid)); else swap_uint16((uint16_t *)(&info->sourceid )); } while (0); | |||
420 | swaps(&info->scroll_type)do { if (sizeof(*(&info->scroll_type)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->scroll_type ) & 1) && ((uintptr_t)(&info->scroll_type) & 1) == 0) *(&info->scroll_type) = lswaps(*(& info->scroll_type)); else swap_uint16((uint16_t *)(&info ->scroll_type)); } while (0); | |||
421 | swapl(&info->increment.integral)do { if (sizeof(*(&info->increment.integral)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->increment .integral) & 3) && ((uintptr_t)(&info->increment .integral) & 3) == 0) *(&info->increment.integral) = lswapl(*(&info->increment.integral)); else swap_uint32 ((uint32_t *)(&info->increment.integral)); } while (0); | |||
422 | swapl(&info->increment.frac)do { if (sizeof(*(&info->increment.frac)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->increment .frac) & 3) && ((uintptr_t)(&info->increment .frac) & 3) == 0) *(&info->increment.frac) = lswapl (*(&info->increment.frac)); else swap_uint32((uint32_t *)(&info->increment.frac)); } while (0); | |||
423 | } | |||
424 | ||||
425 | /** | |||
426 | * List multitouch information | |||
427 | * | |||
428 | * @return The number of bytes written into info. | |||
429 | */ | |||
430 | int | |||
431 | ListTouchInfo(DeviceIntPtr dev, xXITouchInfo * touch) | |||
432 | { | |||
433 | touch->type = XITouchClass8; | |||
434 | touch->length = sizeof(xXITouchInfo) >> 2; | |||
435 | touch->sourceid = dev->touch->sourceid; | |||
436 | touch->mode = dev->touch->mode; | |||
437 | touch->num_touches = dev->touch->num_touches; | |||
438 | ||||
439 | return touch->length << 2; | |||
440 | } | |||
441 | ||||
442 | static void | |||
443 | SwapTouchInfo(DeviceIntPtr dev, xXITouchInfo * touch) | |||
444 | { | |||
445 | swaps(&touch->type)do { if (sizeof(*(&touch->type)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&touch->type) & 1) && ((uintptr_t)(&touch->type) & 1) == 0 ) *(&touch->type) = lswaps(*(&touch->type)); else swap_uint16((uint16_t *)(&touch->type)); } while (0); | |||
446 | swaps(&touch->length)do { if (sizeof(*(&touch->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&touch->length) & 1) && ((uintptr_t)(&touch->length) & 1) == 0) *(&touch->length) = lswaps(*(&touch->length )); else swap_uint16((uint16_t *)(&touch->length)); } while (0); | |||
447 | swaps(&touch->sourceid)do { if (sizeof(*(&touch->sourceid)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&touch->sourceid ) & 1) && ((uintptr_t)(&touch->sourceid) & 1) == 0) *(&touch->sourceid) = lswaps(*(&touch-> sourceid)); else swap_uint16((uint16_t *)(&touch->sourceid )); } while (0); | |||
448 | } | |||
449 | ||||
450 | int | |||
451 | GetDeviceUse(DeviceIntPtr dev, uint16_t * attachment) | |||
452 | { | |||
453 | DeviceIntPtr master = GetMaster(dev, MASTER_ATTACHED4); | |||
454 | int use; | |||
455 | ||||
456 | if (IsMaster(dev)) { | |||
457 | DeviceIntPtr paired = GetPairedDevice(dev); | |||
458 | ||||
459 | use = IsPointerDevice(dev) ? XIMasterPointer1 : XIMasterKeyboard2; | |||
460 | *attachment = (paired ? paired->id : 0); | |||
461 | } | |||
462 | else if (!IsFloating(dev)) { | |||
463 | use = IsPointerDevice(master) ? XISlavePointer3 : XISlaveKeyboard4; | |||
464 | *attachment = master->id; | |||
465 | } | |||
466 | else | |||
467 | use = XIFloatingSlave5; | |||
468 | ||||
469 | return use; | |||
470 | } | |||
471 | ||||
472 | /** | |||
473 | * Write the info for device dev into the buffer pointed to by info. | |||
474 | * | |||
475 | * @return The number of bytes used. | |||
476 | */ | |||
477 | static int | |||
478 | ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo * info) | |||
479 | { | |||
480 | char *any = (char *) &info[1]; | |||
481 | int len = 0, total_len = 0; | |||
482 | ||||
483 | info->deviceid = dev->id; | |||
484 | info->use = GetDeviceUse(dev, &info->attachment); | |||
485 | info->num_classes = 0; | |||
486 | info->name_len = strlen(dev->name); | |||
487 | info->enabled = dev->enabled; | |||
488 | total_len = sizeof(xXIDeviceInfo); | |||
489 | ||||
490 | len = pad_to_int32(info->name_len); | |||
491 | memset(any, 0, len)__builtin___memset_chk (any, 0, len, __builtin_object_size (any , 0)); | |||
492 | strncpy(any, dev->name, info->name_len)__builtin___strncpy_chk (any, dev->name, info->name_len , __builtin_object_size (any, 2 > 1 ? 1 : 0)); | |||
493 | any += len; | |||
494 | total_len += len; | |||
495 | ||||
496 | total_len += ListDeviceClasses(client, dev, any, &info->num_classes); | |||
497 | return total_len; | |||
498 | } | |||
499 | ||||
500 | /** | |||
501 | * Write the class info of the device into the memory pointed to by any, set | |||
502 | * nclasses to the number of classes in total and return the number of bytes | |||
503 | * written. | |||
504 | */ | |||
505 | int | |||
506 | ListDeviceClasses(ClientPtr client, DeviceIntPtr dev, | |||
507 | char *any, uint16_t * nclasses) | |||
508 | { | |||
509 | int total_len = 0; | |||
510 | int len; | |||
511 | int i; | |||
512 | int rc; | |||
513 | ||||
514 | /* Check if the current device state should be suppressed */ | |||
515 | rc = XaceHook(XACE_DEVICE_ACCESS3, client, dev, DixReadAccess(1<<0)); | |||
516 | ||||
517 | if (dev->button) { | |||
518 | (*nclasses)++; | |||
519 | len = ListButtonInfo(dev, (xXIButtonInfo *) any, rc == Success0); | |||
520 | any += len; | |||
521 | total_len += len; | |||
522 | } | |||
523 | ||||
524 | if (dev->key) { | |||
525 | (*nclasses)++; | |||
526 | len = ListKeyInfo(dev, (xXIKeyInfo *) any); | |||
527 | any += len; | |||
528 | total_len += len; | |||
529 | } | |||
530 | ||||
531 | for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++) { | |||
532 | (*nclasses)++; | |||
533 | len = ListValuatorInfo(dev, (xXIValuatorInfo *) any, i, rc == Success0); | |||
534 | any += len; | |||
535 | total_len += len; | |||
536 | } | |||
537 | ||||
538 | for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++) { | |||
539 | len = ListScrollInfo(dev, (xXIScrollInfo *) any, i); | |||
540 | if (len) | |||
541 | (*nclasses)++; | |||
542 | any += len; | |||
543 | total_len += len; | |||
544 | } | |||
545 | ||||
546 | if (dev->touch) { | |||
547 | (*nclasses)++; | |||
548 | len = ListTouchInfo(dev, (xXITouchInfo *) any); | |||
549 | any += len; | |||
550 | total_len += len; | |||
551 | } | |||
552 | ||||
553 | return total_len; | |||
554 | } | |||
555 | ||||
556 | static void | |||
557 | SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo * info) | |||
558 | { | |||
559 | char *any = (char *) &info[1]; | |||
560 | int i; | |||
561 | ||||
562 | /* Skip over name */ | |||
563 | any += pad_to_int32(info->name_len); | |||
564 | ||||
565 | for (i = 0; i < info->num_classes; i++) { | |||
566 | int len = ((xXIAnyInfo *) any)->length; | |||
567 | ||||
568 | switch (((xXIAnyInfo *) any)->type) { | |||
569 | case XIButtonClass1: | |||
570 | SwapButtonInfo(dev, (xXIButtonInfo *) any); | |||
571 | break; | |||
572 | case XIKeyClass0: | |||
573 | SwapKeyInfo(dev, (xXIKeyInfo *) any); | |||
574 | break; | |||
575 | case XIValuatorClass2: | |||
576 | SwapValuatorInfo(dev, (xXIValuatorInfo *) any); | |||
577 | break; | |||
578 | case XIScrollClass3: | |||
579 | SwapScrollInfo(dev, (xXIScrollInfo *) any); | |||
580 | break; | |||
581 | case XITouchClass8: | |||
582 | SwapTouchInfo(dev, (xXITouchInfo *) any); | |||
583 | break; | |||
584 | ||||
585 | } | |||
586 | ||||
587 | any += len * 4; | |||
588 | } | |||
589 | ||||
590 | swaps(&info->deviceid)do { if (sizeof(*(&info->deviceid)) != 2) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->deviceid ) & 1) && ((uintptr_t)(&info->deviceid) & 1) == 0) *(&info->deviceid) = lswaps(*(&info-> deviceid)); else swap_uint16((uint16_t *)(&info->deviceid )); } while (0); | |||
591 | swaps(&info->use)do { if (sizeof(*(&info->use)) != 2) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&info->use) & 1) && ((uintptr_t)(&info->use) & 1) == 0) *(&info-> use) = lswaps(*(&info->use)); else swap_uint16((uint16_t *)(&info->use)); } while (0); | |||
592 | swaps(&info->attachment)do { if (sizeof(*(&info->attachment)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->attachment ) & 1) && ((uintptr_t)(&info->attachment) & 1) == 0) *(&info->attachment) = lswaps(*(&info-> attachment)); else swap_uint16((uint16_t *)(&info->attachment )); } while (0); | |||
593 | swaps(&info->num_classes)do { if (sizeof(*(&info->num_classes)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&info->num_classes ) & 1) && ((uintptr_t)(&info->num_classes) & 1) == 0) *(&info->num_classes) = lswaps(*(& info->num_classes)); else swap_uint16((uint16_t *)(&info ->num_classes)); } while (0); | |||
594 | swaps(&info->name_len)do { if (sizeof(*(&info->name_len)) != 2) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&info->name_len ) & 1) && ((uintptr_t)(&info->name_len) & 1) == 0) *(&info->name_len) = lswaps(*(&info-> name_len)); else swap_uint16((uint16_t *)(&info->name_len )); } while (0); | |||
595 | ||||
596 | } |