Bug Summary

File:Xi/xiquerydevice.c
Location:line 105, column 12
Description:Call to 'calloc' has an allocation size of 0 bytes

Annotated Source Code

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
48static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d);
49static int
50 ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo * info);
51static int SizeDeviceInfo(DeviceIntPtr dev);
52static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo * info);
53int
54SProcXIQueryDevice(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);
1
Calling 'ProcXIQueryDevice'
63}
64
65int
66ProcXIQueryDevice(ClientPtr client)
67{
68 xXIQueryDeviceReply rep;
69 DeviceIntPtr dev = NULL((void*)0);
70 int rc = Success0;
71 int i = 0, len = 0;
2
'len' initialized to 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)
3
Assuming 'skip' is non-null
4
Taking false branch
90 return BadAlloc11;
91
92 for (dev = inputInfo.devices; dev; dev = dev->next, i++) {
5
Loop condition is false. Execution continues on line 98
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++) {
6
Loop condition is false. Execution continues on line 105
99 skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
100 if (!skip[i])
101 len += SizeDeviceInfo(dev);
102 }
103 }
104
105 info = calloc(1, len);
7
Call to 'calloc' has an allocation size of 0 bytes
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
158void
159SRepXIQueryDevice(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 */
173static Bool
174ShouldSkipDevice(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 */
190static int
191SizeDeviceInfo(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 */
205int
206SizeDeviceClasses(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 */
244int
245ListButtonInfo(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
276static void
277SwapButtonInfo(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 */
296int
297ListKeyInfo(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
315static void
316SwapKeyInfo(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 */
337int
338ListValuatorInfo(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
362static void
363SwapValuatorInfo(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
376int
377ListScrollInfo(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
413static void
414SwapScrollInfo(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 */
430int
431ListTouchInfo(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
442static void
443SwapTouchInfo(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
450int
451GetDeviceUse(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 */
477static int
478ListDeviceInfo(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 */
505int
506ListDeviceClasses(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
556static void
557SwapDeviceInfo(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}