Bug Summary

File:Xi/xiproperty.c
Location:line 901, column 5
Description:Value stored to 'rc' is never read

Annotated Source Code

1/*
2 * Copyright © 2006 Keith Packard
3 * Copyright © 2008 Peter Hutterer
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WAXIANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WAXIANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26/* This code is a modified version of randr/rrproperty.c */
27
28#ifdef HAVE_DIX_CONFIG_H1
29#include <dix-config.h>
30#endif
31
32#include "dix.h"
33#include "inputstr.h"
34#include <X11/extensions/XI.h>
35#include <X11/Xatom.h>
36#include <X11/extensions/XIproto.h>
37#include <X11/extensions/XI2proto.h>
38#include "exglobals.h"
39#include "exevents.h"
40#include "swaprep.h"
41
42#include "xiproperty.h"
43#include "xserver-properties.h"
44
45/**
46 * Properties used or alloced from inside the server.
47 */
48static struct dev_properties {
49 Atom type;
50 const char *name;
51} dev_properties[] = {
52 {0, XI_PROP_ENABLED"Device Enabled"},
53 {0, XI_PROP_XTEST_DEVICE"XTEST Device"},
54 {0, XATOM_FLOAT"FLOAT"},
55 {0, ACCEL_PROP_PROFILE_NUMBER"Device Accel Profile"},
56 {0, ACCEL_PROP_CONSTANT_DECELERATION"Device Accel Constant Deceleration"},
57 {0, ACCEL_PROP_ADAPTIVE_DECELERATION"Device Accel Adaptive Deceleration"},
58 {0, ACCEL_PROP_VELOCITY_SCALING"Device Accel Velocity Scaling"},
59 {0, AXIS_LABEL_PROP"Axis Labels"},
60 {0, AXIS_LABEL_PROP_REL_X"Rel X"},
61 {0, AXIS_LABEL_PROP_REL_Y"Rel Y"},
62 {0, AXIS_LABEL_PROP_REL_Z"Rel Z"},
63 {0, AXIS_LABEL_PROP_REL_RX"Rel Rotary X"},
64 {0, AXIS_LABEL_PROP_REL_RY"Rel Rotary Y"},
65 {0, AXIS_LABEL_PROP_REL_RZ"Rel Rotary Z"},
66 {0, AXIS_LABEL_PROP_REL_HWHEEL"Rel Horiz Wheel"},
67 {0, AXIS_LABEL_PROP_REL_DIAL"Rel Dial"},
68 {0, AXIS_LABEL_PROP_REL_WHEEL"Rel Vert Wheel"},
69 {0, AXIS_LABEL_PROP_REL_MISC"Rel Misc"},
70 {0, AXIS_LABEL_PROP_REL_VSCROLL"Rel Vert Scroll"},
71 {0, AXIS_LABEL_PROP_REL_HSCROLL"Rel Horiz Scroll"},
72 {0, AXIS_LABEL_PROP_ABS_X"Abs X"},
73 {0, AXIS_LABEL_PROP_ABS_Y"Abs Y"},
74 {0, AXIS_LABEL_PROP_ABS_Z"Abs Z"},
75 {0, AXIS_LABEL_PROP_ABS_RX"Abs Rotary X"},
76 {0, AXIS_LABEL_PROP_ABS_RY"Abs Rotary Y"},
77 {0, AXIS_LABEL_PROP_ABS_RZ"Abs Rotary Z"},
78 {0, AXIS_LABEL_PROP_ABS_THROTTLE"Abs Throttle"},
79 {0, AXIS_LABEL_PROP_ABS_RUDDER"Abs Rudder"},
80 {0, AXIS_LABEL_PROP_ABS_WHEEL"Abs Wheel"},
81 {0, AXIS_LABEL_PROP_ABS_GAS"Abs Gas"},
82 {0, AXIS_LABEL_PROP_ABS_BRAKE"Abs Brake"},
83 {0, AXIS_LABEL_PROP_ABS_HAT0X"Abs Hat 0 X"},
84 {0, AXIS_LABEL_PROP_ABS_HAT0Y"Abs Hat 0 Y"},
85 {0, AXIS_LABEL_PROP_ABS_HAT1X"Abs Hat 1 X"},
86 {0, AXIS_LABEL_PROP_ABS_HAT1Y"Abs Hat 1 Y"},
87 {0, AXIS_LABEL_PROP_ABS_HAT2X"Abs Hat 2 X"},
88 {0, AXIS_LABEL_PROP_ABS_HAT2Y"Abs Hat 2 Y"},
89 {0, AXIS_LABEL_PROP_ABS_HAT3X"Abs Hat 3 X"},
90 {0, AXIS_LABEL_PROP_ABS_HAT3Y"Abs Hat 3 Y"},
91 {0, AXIS_LABEL_PROP_ABS_PRESSURE"Abs Pressure"},
92 {0, AXIS_LABEL_PROP_ABS_DISTANCE"Abs Distance"},
93 {0, AXIS_LABEL_PROP_ABS_TILT_X"Abs Tilt X"},
94 {0, AXIS_LABEL_PROP_ABS_TILT_Y"Abs Tilt Y"},
95 {0, AXIS_LABEL_PROP_ABS_TOOL_WIDTH"Abs Tool Width"},
96 {0, AXIS_LABEL_PROP_ABS_VOLUME"Abs Volume"},
97 {0, AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR"Abs MT Touch Major"},
98 {0, AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR"Abs MT Touch Minor"},
99 {0, AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR"Abs MT Width Major"},
100 {0, AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR"Abs MT Width Minor"},
101 {0, AXIS_LABEL_PROP_ABS_MT_ORIENTATION"Abs MT Orientation"},
102 {0, AXIS_LABEL_PROP_ABS_MT_POSITION_X"Abs MT Position X"},
103 {0, AXIS_LABEL_PROP_ABS_MT_POSITION_Y"Abs MT Position Y"},
104 {0, AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE"Abs MT Tool Type"},
105 {0, AXIS_LABEL_PROP_ABS_MT_BLOB_ID"Abs MT Blob ID"},
106 {0, AXIS_LABEL_PROP_ABS_MT_TRACKING_ID"Abs MT Tracking ID"},
107 {0, AXIS_LABEL_PROP_ABS_MT_PRESSURE"Abs MT Pressure"},
108 {0, AXIS_LABEL_PROP_ABS_MT_DISTANCE"Abs MT Distance"},
109 {0, AXIS_LABEL_PROP_ABS_MT_TOOL_X"Abs MT Tool X"},
110 {0, AXIS_LABEL_PROP_ABS_MT_TOOL_Y"Abs MT Tool Y"},
111 {0, AXIS_LABEL_PROP_ABS_MISC"Abs Misc"},
112 {0, BTN_LABEL_PROP"Button Labels"},
113 {0, BTN_LABEL_PROP_BTN_UNKNOWN"Button Unknown"},
114 {0, BTN_LABEL_PROP_BTN_WHEEL_UP"Button Wheel Up"},
115 {0, BTN_LABEL_PROP_BTN_WHEEL_DOWN"Button Wheel Down"},
116 {0, BTN_LABEL_PROP_BTN_HWHEEL_LEFT"Button Horiz Wheel Left"},
117 {0, BTN_LABEL_PROP_BTN_HWHEEL_RIGHT"Button Horiz Wheel Right"},
118 {0, BTN_LABEL_PROP_BTN_0"Button 0"},
119 {0, BTN_LABEL_PROP_BTN_1"Button 1"},
120 {0, BTN_LABEL_PROP_BTN_2"Button 2"},
121 {0, BTN_LABEL_PROP_BTN_3"Button 3"},
122 {0, BTN_LABEL_PROP_BTN_4"Button 4"},
123 {0, BTN_LABEL_PROP_BTN_5"Button 5"},
124 {0, BTN_LABEL_PROP_BTN_6"Button 6"},
125 {0, BTN_LABEL_PROP_BTN_7"Button 7"},
126 {0, BTN_LABEL_PROP_BTN_8"Button 8"},
127 {0, BTN_LABEL_PROP_BTN_9"Button 9"},
128 {0, BTN_LABEL_PROP_BTN_LEFT"Button Left"},
129 {0, BTN_LABEL_PROP_BTN_RIGHT"Button Right"},
130 {0, BTN_LABEL_PROP_BTN_MIDDLE"Button Middle"},
131 {0, BTN_LABEL_PROP_BTN_SIDE"Button Side"},
132 {0, BTN_LABEL_PROP_BTN_EXTRA"Button Extra"},
133 {0, BTN_LABEL_PROP_BTN_FORWARD"Button Forward"},
134 {0, BTN_LABEL_PROP_BTN_BACK"Button Back"},
135 {0, BTN_LABEL_PROP_BTN_TASK"Button Task"},
136 {0, BTN_LABEL_PROP_BTN_TRIGGER"Button Trigger"},
137 {0, BTN_LABEL_PROP_BTN_THUMB"Button Thumb"},
138 {0, BTN_LABEL_PROP_BTN_THUMB2"Button Thumb2"},
139 {0, BTN_LABEL_PROP_BTN_TOP"Button Top"},
140 {0, BTN_LABEL_PROP_BTN_TOP2"Button Top2"},
141 {0, BTN_LABEL_PROP_BTN_PINKIE"Button Pinkie"},
142 {0, BTN_LABEL_PROP_BTN_BASE"Button Base"},
143 {0, BTN_LABEL_PROP_BTN_BASE2"Button Base2"},
144 {0, BTN_LABEL_PROP_BTN_BASE3"Button Base3"},
145 {0, BTN_LABEL_PROP_BTN_BASE4"Button Base4"},
146 {0, BTN_LABEL_PROP_BTN_BASE5"Button Base5"},
147 {0, BTN_LABEL_PROP_BTN_BASE6"Button Base6"},
148 {0, BTN_LABEL_PROP_BTN_DEAD"Button Dead"},
149 {0, BTN_LABEL_PROP_BTN_A"Button A"},
150 {0, BTN_LABEL_PROP_BTN_B"Button B"},
151 {0, BTN_LABEL_PROP_BTN_C"Button C"},
152 {0, BTN_LABEL_PROP_BTN_X"Button X"},
153 {0, BTN_LABEL_PROP_BTN_Y"Button Y"},
154 {0, BTN_LABEL_PROP_BTN_Z"Button Z"},
155 {0, BTN_LABEL_PROP_BTN_TL"Button T Left"},
156 {0, BTN_LABEL_PROP_BTN_TR"Button T Right"},
157 {0, BTN_LABEL_PROP_BTN_TL2"Button T Left2"},
158 {0, BTN_LABEL_PROP_BTN_TR2"Button T Right2"},
159 {0, BTN_LABEL_PROP_BTN_SELECT"Button Select"},
160 {0, BTN_LABEL_PROP_BTN_START"Button Start"},
161 {0, BTN_LABEL_PROP_BTN_MODE"Button Mode"},
162 {0, BTN_LABEL_PROP_BTN_THUMBL"Button Thumb Left"},
163 {0, BTN_LABEL_PROP_BTN_THUMBR"Button Thumb Right"},
164 {0, BTN_LABEL_PROP_BTN_TOOL_PEN"Button Tool Pen"},
165 {0, BTN_LABEL_PROP_BTN_TOOL_RUBBER"Button Tool Rubber"},
166 {0, BTN_LABEL_PROP_BTN_TOOL_BRUSH"Button Tool Brush"},
167 {0, BTN_LABEL_PROP_BTN_TOOL_PENCIL"Button Tool Pencil"},
168 {0, BTN_LABEL_PROP_BTN_TOOL_AIRBRUSH"Button Tool Airbrush"},
169 {0, BTN_LABEL_PROP_BTN_TOOL_FINGER"Button Tool Finger"},
170 {0, BTN_LABEL_PROP_BTN_TOOL_MOUSE"Button Tool Mouse"},
171 {0, BTN_LABEL_PROP_BTN_TOOL_LENS"Button Tool Lens"},
172 {0, BTN_LABEL_PROP_BTN_TOUCH"Button Touch"},
173 {0, BTN_LABEL_PROP_BTN_STYLUS"Button Stylus"},
174 {0, BTN_LABEL_PROP_BTN_STYLUS2"Button Stylus2"},
175 {0, BTN_LABEL_PROP_BTN_TOOL_DOUBLETAP"Button Tool Doubletap"},
176 {0, BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP"Button Tool Tripletap"},
177 {0, BTN_LABEL_PROP_BTN_GEAR_DOWN"Button Gear down"},
178 {0, BTN_LABEL_PROP_BTN_GEAR_UP"Button Gear up"},
179 {0, XI_PROP_TRANSFORM"Coordinate Transformation Matrix"}
180};
181
182static long XIPropHandlerID = 1;
183
184static void
185send_property_event(DeviceIntPtr dev, Atom property, int what)
186{
187 int state = (what == XIPropertyDeleted0) ? PropertyDelete1 : PropertyNewValue0;
188 devicePropertyNotify event = {
189 .type = DevicePropertyNotify,
190 .deviceid = dev->id,
191 .state = state,
192 .atom = property,
193 .time = currentTime.milliseconds
194 };
195 xXIPropertyEvent xi2 = {
196 .type = GenericEvent35,
197 .extension = IReqCode,
198 .length = 0,
199 .evtype = XI_PropertyEvent12,
200 .deviceid = dev->id,
201 .time = currentTime.milliseconds,
202 .property = property,
203 .what = what
204 };
205
206 SendEventToAllWindows(dev, DevicePropertyNotifyMask, (xEvent *) &event, 1);
207
208 SendEventToAllWindows(dev, GetEventFilter(dev, (xEvent *) &xi2),
209 (xEvent *) &xi2, 1);
210}
211
212static int
213list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return)
214{
215 XIPropertyPtr prop;
216 Atom *atoms = NULL((void*)0);
217 int nprops = 0;
218
219 for (prop = dev->properties.properties; prop; prop = prop->next)
220 nprops++;
221 if (nprops) {
222 Atom *a;
223
224 atoms = malloc(nprops * sizeof(Atom));
225 if (!atoms)
226 return BadAlloc11;
227 a = atoms;
228 for (prop = dev->properties.properties; prop; prop = prop->next, a++)
229 *a = prop->propertyName;
230 }
231
232 *natoms = nprops;
233 *atoms_return = atoms;
234 return Success0;
235}
236
237static int
238get_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
239 BOOL delete, int offset, int length,
240 int *bytes_after, Atom *type_return, int *format, int *nitems,
241 int *length_return, char **data)
242{
243 unsigned long n, len, ind;
244 int rc;
245 XIPropertyPtr prop;
246 XIPropertyValuePtr prop_value;
247
248 if (!ValidAtom(property)) {
249 client->errorValue = property;
250 return BadAtom5;
251 }
252 if ((delete != xTrue1) && (delete != xFalse0)) {
253 client->errorValue = delete;
254 return BadValue2;
255 }
256
257 if ((type != AnyPropertyType0L) && !ValidAtom(type)) {
258 client->errorValue = type;
259 return BadAtom5;
260 }
261
262 for (prop = dev->properties.properties; prop; prop = prop->next)
263 if (prop->propertyName == property)
264 break;
265
266 if (!prop) {
267 *bytes_after = 0;
268 *type_return = None0L;
269 *format = 0;
270 *nitems = 0;
271 *length_return = 0;
272 return Success0;
273 }
274
275 rc = XIGetDeviceProperty(dev, property, &prop_value);
276 if (rc != Success0) {
277 client->errorValue = property;
278 return rc;
279 }
280
281 /* If the request type and actual type don't match. Return the
282 property information, but not the data. */
283
284 if (((type != prop_value->type) && (type != AnyPropertyType0L))) {
285 *bytes_after = prop_value->size;
286 *format = prop_value->format;
287 *length_return = 0;
288 *nitems = 0;
289 *type_return = prop_value->type;
290 return Success0;
291 }
292
293 /* Return type, format, value to client */
294 n = (prop_value->format / 8) * prop_value->size; /* size (bytes) of prop */
295 ind = offset << 2;
296
297 /* If offset is invalid such that it causes "len" to
298 be negative, it's a value error. */
299
300 if (n < ind) {
301 client->errorValue = offset;
302 return BadValue2;
303 }
304
305 len = min(n - ind, 4 * length)(((n - ind) < (4 * length)) ? (n - ind) : (4 * length));
306
307 *bytes_after = n - (ind + len);
308 *format = prop_value->format;
309 *length_return = len;
310 if (prop_value->format)
311 *nitems = len / (prop_value->format / 8);
312 else
313 *nitems = 0;
314 *type_return = prop_value->type;
315
316 *data = (char *) prop_value->data + ind;
317
318 return Success0;
319}
320
321static int
322check_change_property(ClientPtr client, Atom property, Atom type, int format,
323 int mode, int nitems)
324{
325 if ((mode != PropModeReplace0) && (mode != PropModeAppend2) &&
326 (mode != PropModePrepend1)) {
327 client->errorValue = mode;
328 return BadValue2;
329 }
330 if ((format != 8) && (format != 16) && (format != 32)) {
331 client->errorValue = format;
332 return BadValue2;
333 }
334
335 if (!ValidAtom(property)) {
336 client->errorValue = property;
337 return BadAtom5;
338 }
339 if (!ValidAtom(type)) {
340 client->errorValue = type;
341 return BadAtom5;
342 }
343
344 return Success0;
345}
346
347static int
348change_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
349 int format, int mode, int len, void *data)
350{
351 int rc = Success0;
352
353 rc = XIChangeDeviceProperty(dev, property, type, format, mode, len, data,
354 TRUE1);
355 if (rc != Success0)
356 client->errorValue = property;
357
358 return rc;
359}
360
361/**
362 * Return the atom assigned to the specified string or 0 if the atom isn't known
363 * to the DIX.
364 *
365 * If name is NULL, None is returned.
366 */
367Atom
368XIGetKnownProperty(const char *name)
369{
370 int i;
371
372 if (!name)
373 return None0L;
374
375 for (i = 0; i < (sizeof(dev_properties) / sizeof(struct dev_properties));
376 i++) {
377 if (strcmp(name, dev_properties[i].name) == 0) {
378 if (dev_properties[i].type == None0L) {
379 dev_properties[i].type =
380 MakeAtom(dev_properties[i].name,
381 strlen(dev_properties[i].name), TRUE1);
382 }
383
384 return dev_properties[i].type;
385 }
386 }
387
388 return 0;
389}
390
391void
392XIResetProperties(void)
393{
394 int i;
395
396 for (i = 0; i < (sizeof(dev_properties) / sizeof(struct dev_properties));
397 i++)
398 dev_properties[i].type = None0L;
399}
400
401/**
402 * Convert the given property's value(s) into @nelem_return integer values and
403 * store them in @buf_return. If @nelem_return is larger than the number of
404 * values in the property, @nelem_return is set to the number of values in the
405 * property.
406 *
407 * If *@buf_return is NULL and @nelem_return is 0, memory is allocated
408 * automatically and must be freed by the caller.
409 *
410 * Possible return codes.
411 * Success ... No error.
412 * BadMatch ... Wrong atom type, atom is not XA_INTEGER
413 * BadAlloc ... NULL passed as buffer and allocation failed.
414 * BadLength ... @buff is NULL but @nelem_return is non-zero.
415 *
416 * @param val The property value
417 * @param nelem_return The maximum number of elements to return.
418 * @param buf_return Pointer to an array of at least @nelem_return values.
419 * @return Success or the error code if an error occured.
420 */
421_X_EXPORT__attribute__((visibility("default"))) int
422XIPropToInt(XIPropertyValuePtr val, int *nelem_return, int **buf_return)
423{
424 int i;
425 int *buf;
426
427 if (val->type != XA_INTEGER((Atom) 19))
428 return BadMatch8;
429 if (!*buf_return && *nelem_return)
430 return BadLength16;
431
432 switch (val->format) {
433 case 8:
434 case 16:
435 case 32:
436 break;
437 default:
438 return BadValue2;
439 }
440
441 buf = *buf_return;
442
443 if (!buf && !(*nelem_return)) {
444 buf = calloc(val->size, sizeof(int));
445 if (!buf)
446 return BadAlloc11;
447 *buf_return = buf;
448 *nelem_return = val->size;
449 }
450 else if (val->size < *nelem_return)
451 *nelem_return = val->size;
452
453 for (i = 0; i < val->size && i < *nelem_return; i++) {
454 switch (val->format) {
455 case 8:
456 buf[i] = ((CARD8 *) val->data)[i];
457 break;
458 case 16:
459 buf[i] = ((CARD16 *) val->data)[i];
460 break;
461 case 32:
462 buf[i] = ((CARD32 *) val->data)[i];
463 break;
464 }
465 }
466
467 return Success0;
468}
469
470/**
471 * Convert the given property's value(s) into @nelem_return float values and
472 * store them in @buf_return. If @nelem_return is larger than the number of
473 * values in the property, @nelem_return is set to the number of values in the
474 * property.
475 *
476 * If *@buf_return is NULL and @nelem_return is 0, memory is allocated
477 * automatically and must be freed by the caller.
478 *
479 * Possible errors returned:
480 * Success
481 * BadMatch ... Wrong atom type, atom is not XA_FLOAT
482 * BadValue ... Wrong format, format is not 32
483 * BadAlloc ... NULL passed as buffer and allocation failed.
484 * BadLength ... @buff is NULL but @nelem_return is non-zero.
485 *
486 * @param val The property value
487 * @param nelem_return The maximum number of elements to return.
488 * @param buf_return Pointer to an array of at least @nelem_return values.
489 * @return Success or the error code if an error occured.
490 */
491_X_EXPORT__attribute__((visibility("default"))) int
492XIPropToFloat(XIPropertyValuePtr val, int *nelem_return, float **buf_return)
493{
494 int i;
495 float *buf;
496
497 if (!val->type || val->type != XIGetKnownProperty(XATOM_FLOAT"FLOAT"))
498 return BadMatch8;
499
500 if (val->format != 32)
501 return BadValue2;
502 if (!*buf_return && *nelem_return)
503 return BadLength16;
504
505 buf = *buf_return;
506
507 if (!buf && !(*nelem_return)) {
508 buf = calloc(val->size, sizeof(float));
509 if (!buf)
510 return BadAlloc11;
511 *buf_return = buf;
512 *nelem_return = val->size;
513 }
514 else if (val->size < *nelem_return)
515 *nelem_return = val->size;
516
517 for (i = 0; i < val->size && i < *nelem_return; i++)
518 buf[i] = ((float *) val->data)[i];
519
520 return Success0;
521}
522
523/* Registers a new property handler on the given device and returns a unique
524 * identifier for this handler. This identifier is required to unregister the
525 * property handler again.
526 * @return The handler's identifier or 0 if an error occured.
527 */
528long
529XIRegisterPropertyHandler(DeviceIntPtr dev,
530 int (*SetProperty) (DeviceIntPtr dev,
531 Atom property,
532 XIPropertyValuePtr prop,
533 BOOL checkonly),
534 int (*GetProperty) (DeviceIntPtr dev,
535 Atom property),
536 int (*DeleteProperty) (DeviceIntPtr dev,
537 Atom property))
538{
539 XIPropertyHandlerPtr new_handler;
540
541 new_handler = calloc(1, sizeof(XIPropertyHandler));
542 if (!new_handler)
543 return 0;
544
545 new_handler->id = XIPropHandlerID++;
546 new_handler->SetProperty = SetProperty;
547 new_handler->GetProperty = GetProperty;
548 new_handler->DeleteProperty = DeleteProperty;
549 new_handler->next = dev->properties.handlers;
550 dev->properties.handlers = new_handler;
551
552 return new_handler->id;
553}
554
555void
556XIUnregisterPropertyHandler(DeviceIntPtr dev, long id)
557{
558 XIPropertyHandlerPtr curr, prev = NULL((void*)0);
559
560 curr = dev->properties.handlers;
561 while (curr && curr->id != id) {
562 prev = curr;
563 curr = curr->next;
564 }
565
566 if (!curr)
567 return;
568
569 if (!prev) /* first one */
570 dev->properties.handlers = curr->next;
571 else
572 prev->next = curr->next;
573
574 free(curr);
575}
576
577static XIPropertyPtr
578XICreateDeviceProperty(Atom property)
579{
580 XIPropertyPtr prop;
581
582 prop = (XIPropertyPtr) malloc(sizeof(XIPropertyRec));
583 if (!prop)
584 return NULL((void*)0);
585
586 prop->next = NULL((void*)0);
587 prop->propertyName = property;
588 prop->value.type = None0L;
589 prop->value.format = 0;
590 prop->value.size = 0;
591 prop->value.data = NULL((void*)0);
592 prop->deletable = TRUE1;
593
594 return prop;
595}
596
597static XIPropertyPtr
598XIFetchDeviceProperty(DeviceIntPtr dev, Atom property)
599{
600 XIPropertyPtr prop;
601
602 for (prop = dev->properties.properties; prop; prop = prop->next)
603 if (prop->propertyName == property)
604 return prop;
605 return NULL((void*)0);
606}
607
608static void
609XIDestroyDeviceProperty(XIPropertyPtr prop)
610{
611 free(prop->value.data);
612 free(prop);
613}
614
615/* This function destroys all of the device's property-related stuff,
616 * including removing all device handlers.
617 * DO NOT CALL FROM THE DRIVER.
618 */
619void
620XIDeleteAllDeviceProperties(DeviceIntPtr device)
621{
622 XIPropertyPtr prop, next;
623 XIPropertyHandlerPtr curr_handler, next_handler;
624
625 for (prop = device->properties.properties; prop; prop = next) {
626 next = prop->next;
627 send_property_event(device, prop->propertyName, XIPropertyDeleted0);
628 XIDestroyDeviceProperty(prop);
629 }
630
631 device->properties.properties = NULL((void*)0);
632
633 /* Now free all handlers */
634 curr_handler = device->properties.handlers;
635 while (curr_handler) {
636 next_handler = curr_handler->next;
637 free(curr_handler);
638 curr_handler = next_handler;
639 }
640
641 device->properties.handlers = NULL((void*)0);
642}
643
644int
645XIDeleteDeviceProperty(DeviceIntPtr device, Atom property, Bool fromClient)
646{
647 XIPropertyPtr prop, *prev;
648 int rc = Success0;
649
650 for (prev = &device->properties.properties; (prop = *prev);
651 prev = &(prop->next))
652 if (prop->propertyName == property)
653 break;
654
655 if (!prop)
656 return Success0;
657
658 if (fromClient && !prop->deletable)
659 return BadAccess10;
660
661 /* Ask handlers if we may delete the property */
662 if (device->properties.handlers) {
663 XIPropertyHandlerPtr handler = device->properties.handlers;
664
665 while (handler) {
666 if (handler->DeleteProperty)
667 rc = handler->DeleteProperty(device, prop->propertyName);
668 if (rc != Success0)
669 return rc;
670 handler = handler->next;
671 }
672 }
673
674 if (prop) {
675 *prev = prop->next;
676 send_property_event(device, prop->propertyName, XIPropertyDeleted0);
677 XIDestroyDeviceProperty(prop);
678 }
679
680 return Success0;
681}
682
683int
684XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
685 int format, int mode, unsigned long len,
686 const void *value, Bool sendevent)
687{
688 XIPropertyPtr prop;
689 int size_in_bytes;
690 int total_size;
691 unsigned long total_len;
692 XIPropertyValuePtr prop_value;
693 XIPropertyValueRec new_value;
694 Bool add = FALSE0;
695 int rc;
696
697 size_in_bytes = format >> 3;
698
699 /* first see if property already exists */
700 prop = XIFetchDeviceProperty(dev, property);
701 if (!prop) { /* just add to list */
702 prop = XICreateDeviceProperty(property);
703 if (!prop)
704 return BadAlloc11;
705 add = TRUE1;
706 mode = PropModeReplace0;
707 }
708 prop_value = &prop->value;
709
710 /* To append or prepend to a property the request format and type
711 must match those of the already defined property. The
712 existing format and type are irrelevant when using the mode
713 "PropModeReplace" since they will be written over. */
714
715 if ((format != prop_value->format) && (mode != PropModeReplace0))
716 return BadMatch8;
717 if ((prop_value->type != type) && (mode != PropModeReplace0))
718 return BadMatch8;
719 new_value = *prop_value;
720 if (mode == PropModeReplace0)
721 total_len = len;
722 else
723 total_len = prop_value->size + len;
724
725 if (mode == PropModeReplace0 || len > 0) {
726 void *new_data = NULL((void*)0), *old_data = NULL((void*)0);
727
728 total_size = total_len * size_in_bytes;
729 new_value.data = (void *) malloc(total_size);
730 if (!new_value.data && total_size) {
731 if (add)
732 XIDestroyDeviceProperty(prop);
733 return BadAlloc11;
734 }
735 new_value.size = len;
736 new_value.type = type;
737 new_value.format = format;
738
739 switch (mode) {
740 case PropModeReplace0:
741 new_data = new_value.data;
742 old_data = NULL((void*)0);
743 break;
744 case PropModeAppend2:
745 new_data = (void *) (((char *) new_value.data) +
746 (prop_value->size * size_in_bytes));
747 old_data = new_value.data;
748 break;
749 case PropModePrepend1:
750 new_data = new_value.data;
751 old_data = (void *) (((char *) new_value.data) +
752 (prop_value->size * size_in_bytes));
753 break;
754 }
755 if (new_data)
756 memcpy((char *) new_data, value, len * size_in_bytes)__builtin___memcpy_chk ((char *) new_data, value, len * size_in_bytes
, __builtin_object_size ((char *) new_data, 0))
;
757 if (old_data)
758 memcpy((char *) old_data, (char *) prop_value->data,__builtin___memcpy_chk ((char *) old_data, (char *) prop_value
->data, prop_value->size * size_in_bytes, __builtin_object_size
((char *) old_data, 0))
759 prop_value->size * size_in_bytes)__builtin___memcpy_chk ((char *) old_data, (char *) prop_value
->data, prop_value->size * size_in_bytes, __builtin_object_size
((char *) old_data, 0))
;
760
761 if (dev->properties.handlers) {
762 XIPropertyHandlerPtr handler;
763 BOOL checkonly = TRUE1;
764
765 /* run through all handlers with checkonly TRUE, then again with
766 * checkonly FALSE. Handlers MUST return error codes on the
767 * checkonly run, errors on the second run are ignored */
768 do {
769 handler = dev->properties.handlers;
770 while (handler) {
771 if (handler->SetProperty) {
772 rc = handler->SetProperty(dev, prop->propertyName,
773 &new_value, checkonly);
774 if (checkonly && rc != Success0) {
775 free(new_value.data);
776 if (add)
777 XIDestroyDeviceProperty(prop);
778 return rc;
779 }
780 }
781 handler = handler->next;
782 }
783 checkonly = !checkonly;
784 } while (!checkonly);
785 }
786 free(prop_value->data);
787 *prop_value = new_value;
788 }
789 else if (len == 0) {
790 /* do nothing */
791 }
792
793 if (add) {
794 prop->next = dev->properties.properties;
795 dev->properties.properties = prop;
796 }
797
798 if (sendevent)
799 send_property_event(dev, prop->propertyName,
800 (add) ? XIPropertyCreated1 : XIPropertyModified2);
801
802 return Success0;
803}
804
805int
806XIGetDeviceProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr *value)
807{
808 XIPropertyPtr prop = XIFetchDeviceProperty(dev, property);
809 int rc;
810
811 if (!prop) {
812 *value = NULL((void*)0);
813 return BadAtom5;
814 }
815
816 /* If we can, try to update the property value first */
817 if (dev->properties.handlers) {
818 XIPropertyHandlerPtr handler = dev->properties.handlers;
819
820 while (handler) {
821 if (handler->GetProperty) {
822 rc = handler->GetProperty(dev, prop->propertyName);
823 if (rc != Success0) {
824 *value = NULL((void*)0);
825 return rc;
826 }
827 }
828 handler = handler->next;
829 }
830 }
831
832 *value = &prop->value;
833 return Success0;
834}
835
836int
837XISetDevicePropertyDeletable(DeviceIntPtr dev, Atom property, Bool deletable)
838{
839 XIPropertyPtr prop = XIFetchDeviceProperty(dev, property);
840
841 if (!prop)
842 return BadAtom5;
843
844 prop->deletable = deletable;
845 return Success0;
846}
847
848int
849ProcXListDeviceProperties(ClientPtr client)
850{
851 Atom *atoms;
852 xListDevicePropertiesReply rep;
853 int natoms;
854 DeviceIntPtr dev;
855 int rc = Success0;
856
857 REQUEST(xListDevicePropertiesReq)xListDevicePropertiesReq *stuff = (xListDevicePropertiesReq *
)client->requestBuffer
;
858 REQUEST_SIZE_MATCH(xListDevicePropertiesReq)if ((sizeof(xListDevicePropertiesReq) >> 2) != client->
req_len) return(16)
;
859
860 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixListPropAccess(1<<6));
861 if (rc != Success0)
862 return rc;
863
864 rc = list_atoms(dev, &natoms, &atoms);
865 if (rc != Success0)
866 return rc;
867
868 rep = (xListDevicePropertiesReply) {
869 .repType = X_Reply1,
870 .RepType = X_ListDeviceProperties36,
871 .sequenceNumber = client->sequence,
872 .length = natoms,
873 .nAtoms = natoms
874 };
875
876 WriteReplyToClient(client, sizeof(xListDevicePropertiesReply), &rep){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xListDevicePropertiesReply
)), &rep); else WriteToClient(client, (int)(sizeof(xListDevicePropertiesReply
)), (&rep)); }
;
877 if (natoms) {
878 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
879 WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(natoms * sizeof(Atom)), atoms); else WriteToClient(client
, (int)(natoms * sizeof(Atom)), (atoms));
;
880 free(atoms);
881 }
882 return rc;
883}
884
885int
886ProcXChangeDeviceProperty(ClientPtr client)
887{
888 REQUEST(xChangeDevicePropertyReq)xChangeDevicePropertyReq *stuff = (xChangeDevicePropertyReq *
)client->requestBuffer
;
889 DeviceIntPtr dev;
890 unsigned long len;
891 int totalSize;
892 int rc;
893
894 REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq)if ((sizeof(xChangeDevicePropertyReq) >> 2) > client
->req_len ) return(16)
;
895 UpdateCurrentTime();
896
897 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
898 if (rc != Success0)
899 return rc;
900
901 rc = check_change_property(client, stuff->property, stuff->type,
Value stored to 'rc' is never read
902 stuff->format, stuff->mode, stuff->nUnits);
903
904 len = stuff->nUnits;
905 if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq))))
906 return BadLength16;
907
908 totalSize = len * (stuff->format / 8);
909 REQUEST_FIXED_SIZE(xChangeDevicePropertyReq, totalSize)if (((sizeof(xChangeDevicePropertyReq) >> 2) > client
->req_len) || (((totalSize) >> 2) >= client->req_len
) || ((((uint64_t) sizeof(xChangeDevicePropertyReq) + (totalSize
) + 3) >> 2) != (uint64_t) client->req_len)) return(
16)
;
910
911 rc = change_property(client, dev, stuff->property, stuff->type,
912 stuff->format, stuff->mode, len, (void *) &stuff[1]);
913 return rc;
914}
915
916int
917ProcXDeleteDeviceProperty(ClientPtr client)
918{
919 REQUEST(xDeleteDevicePropertyReq)xDeleteDevicePropertyReq *stuff = (xDeleteDevicePropertyReq *
)client->requestBuffer
;
920 DeviceIntPtr dev;
921 int rc;
922
923 REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq)if ((sizeof(xDeleteDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
924 UpdateCurrentTime();
925 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
926 if (rc != Success0)
927 return rc;
928
929 if (!ValidAtom(stuff->property)) {
930 client->errorValue = stuff->property;
931 return BadAtom5;
932 }
933
934 rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE1);
935 return rc;
936}
937
938int
939ProcXGetDeviceProperty(ClientPtr client)
940{
941 REQUEST(xGetDevicePropertyReq)xGetDevicePropertyReq *stuff = (xGetDevicePropertyReq *)client
->requestBuffer
;
942 DeviceIntPtr dev;
943 int length;
944 int rc, format, nitems, bytes_after;
945 char *data;
946 Atom type;
947 xGetDevicePropertyReply reply;
948
949 REQUEST_SIZE_MATCH(xGetDevicePropertyReq)if ((sizeof(xGetDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
950 if (stuff->delete)
951 UpdateCurrentTime();
952 rc = dixLookupDevice(&dev, stuff->deviceid, client,
953 stuff->delete ? DixSetPropAccess(1<<8) : DixGetPropAccess(1<<7));
954 if (rc != Success0)
955 return rc;
956
957 rc = get_property(client, dev, stuff->property, stuff->type,
958 stuff->delete, stuff->longOffset, stuff->longLength,
959 &bytes_after, &type, &format, &nitems, &length, &data);
960
961 if (rc != Success0)
962 return rc;
963
964 reply = (xGetDevicePropertyReply) {
965 .repType = X_Reply1,
966 .RepType = X_GetDeviceProperty39,
967 .sequenceNumber = client->sequence,
968 .length = bytes_to_int32(length),
969 .propertyType = type,
970 .bytesAfter = bytes_after,
971 .nItems = nitems,
972 .format = format,
973 .deviceid = dev->id
974 };
975
976 if (stuff->delete && (reply.bytesAfter == 0))
977 send_property_event(dev, stuff->property, XIPropertyDeleted0);
978
979 WriteReplyToClient(client, sizeof(xGenericReply), &reply){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xGenericReply
)), &reply); else WriteToClient(client, (int)(sizeof(xGenericReply
)), (&reply)); }
;
980
981 if (length) {
982 switch (reply.format) {
983 case 32:
984 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
985 break;
986 case 16:
987 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
988 break;
989 default:
990 client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
991 break;
992 }
993 WriteSwappedDataToClient(client, length, data)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(length), data); else WriteToClient(client, (int)(length
), (data));
;
994 }
995
996 /* delete the Property */
997 if (stuff->delete && (reply.bytesAfter == 0)) {
998 XIPropertyPtr prop, *prev;
999
1000 for (prev = &dev->properties.properties; (prop = *prev);
1001 prev = &prop->next) {
1002 if (prop->propertyName == stuff->property) {
1003 *prev = prop->next;
1004 XIDestroyDeviceProperty(prop);
1005 break;
1006 }
1007 }
1008 }
1009 return Success0;
1010}
1011
1012int
1013SProcXListDeviceProperties(ClientPtr client)
1014{
1015 REQUEST(xListDevicePropertiesReq)xListDevicePropertiesReq *stuff = (xListDevicePropertiesReq *
)client->requestBuffer
;
1016 REQUEST_SIZE_MATCH(xListDevicePropertiesReq)if ((sizeof(xListDevicePropertiesReq) >> 2) != client->
req_len) return(16)
;
1017
1018 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)
;
1019 return (ProcXListDeviceProperties(client));
1020}
1021
1022int
1023SProcXChangeDeviceProperty(ClientPtr client)
1024{
1025 REQUEST(xChangeDevicePropertyReq)xChangeDevicePropertyReq *stuff = (xChangeDevicePropertyReq *
)client->requestBuffer
;
1026
1027 REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq)if ((sizeof(xChangeDevicePropertyReq) >> 2) > client
->req_len ) return(16)
;
1028 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)
;
1029 swapl(&stuff->property)do { if (sizeof(*(&stuff->property)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->property
) & 3) && ((uintptr_t)(&stuff->property) &
3) == 0) *(&stuff->property) = lswapl(*(&stuff->
property)); else swap_uint32((uint32_t *)(&stuff->property
)); } while (0)
;
1030 swapl(&stuff->type)do { if (sizeof(*(&stuff->type)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->type) &
3) && ((uintptr_t)(&stuff->type) & 3) == 0
) *(&stuff->type) = lswapl(*(&stuff->type)); else
swap_uint32((uint32_t *)(&stuff->type)); } while (0)
;
1031 swapl(&stuff->nUnits)do { if (sizeof(*(&stuff->nUnits)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->nUnits) &
3) && ((uintptr_t)(&stuff->nUnits) & 3) ==
0) *(&stuff->nUnits) = lswapl(*(&stuff->nUnits
)); else swap_uint32((uint32_t *)(&stuff->nUnits)); } while
(0)
;
1032 return (ProcXChangeDeviceProperty(client));
1033}
1034
1035int
1036SProcXDeleteDeviceProperty(ClientPtr client)
1037{
1038 REQUEST(xDeleteDevicePropertyReq)xDeleteDevicePropertyReq *stuff = (xDeleteDevicePropertyReq *
)client->requestBuffer
;
1039 REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq)if ((sizeof(xDeleteDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
1040
1041 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)
;
1042 swapl(&stuff->property)do { if (sizeof(*(&stuff->property)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->property
) & 3) && ((uintptr_t)(&stuff->property) &
3) == 0) *(&stuff->property) = lswapl(*(&stuff->
property)); else swap_uint32((uint32_t *)(&stuff->property
)); } while (0)
;
1043 return (ProcXDeleteDeviceProperty(client));
1044}
1045
1046int
1047SProcXGetDeviceProperty(ClientPtr client)
1048{
1049 REQUEST(xGetDevicePropertyReq)xGetDevicePropertyReq *stuff = (xGetDevicePropertyReq *)client
->requestBuffer
;
1050 REQUEST_SIZE_MATCH(xGetDevicePropertyReq)if ((sizeof(xGetDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
1051
1052 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)
;
1053 swapl(&stuff->property)do { if (sizeof(*(&stuff->property)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->property
) & 3) && ((uintptr_t)(&stuff->property) &
3) == 0) *(&stuff->property) = lswapl(*(&stuff->
property)); else swap_uint32((uint32_t *)(&stuff->property
)); } while (0)
;
1054 swapl(&stuff->type)do { if (sizeof(*(&stuff->type)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->type) &
3) && ((uintptr_t)(&stuff->type) & 3) == 0
) *(&stuff->type) = lswapl(*(&stuff->type)); else
swap_uint32((uint32_t *)(&stuff->type)); } while (0)
;
1055 swapl(&stuff->longOffset)do { if (sizeof(*(&stuff->longOffset)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->longOffset
) & 3) && ((uintptr_t)(&stuff->longOffset)
& 3) == 0) *(&stuff->longOffset) = lswapl(*(&
stuff->longOffset)); else swap_uint32((uint32_t *)(&stuff
->longOffset)); } while (0)
;
1056 swapl(&stuff->longLength)do { if (sizeof(*(&stuff->longLength)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->longLength
) & 3) && ((uintptr_t)(&stuff->longLength)
& 3) == 0) *(&stuff->longLength) = lswapl(*(&
stuff->longLength)); else swap_uint32((uint32_t *)(&stuff
->longLength)); } while (0)
;
1057 return (ProcXGetDeviceProperty(client));
1058}
1059
1060/* Reply swapping */
1061
1062void
1063SRepXListDeviceProperties(ClientPtr client, int size,
1064 xListDevicePropertiesReply * rep)
1065{
1066 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)
;
1067 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)
;
1068 swaps(&rep->nAtoms)do { if (sizeof(*(&rep->nAtoms)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep->nAtoms) &
1) && ((uintptr_t)(&rep->nAtoms) & 1) == 0
) *(&rep->nAtoms) = lswaps(*(&rep->nAtoms)); else
swap_uint16((uint16_t *)(&rep->nAtoms)); } while (0)
;
1069 /* properties will be swapped later, see ProcXListDeviceProperties */
1070 WriteToClient(client, size, rep);
1071}
1072
1073void
1074SRepXGetDeviceProperty(ClientPtr client, int size,
1075 xGetDevicePropertyReply * rep)
1076{
1077 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)
;
1078 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)
;
1079 swapl(&rep->propertyType)do { if (sizeof(*(&rep->propertyType)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&rep->propertyType
) & 3) && ((uintptr_t)(&rep->propertyType)
& 3) == 0) *(&rep->propertyType) = lswapl(*(&
rep->propertyType)); else swap_uint32((uint32_t *)(&rep
->propertyType)); } while (0)
;
1080 swapl(&rep->bytesAfter)do { if (sizeof(*(&rep->bytesAfter)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep->bytesAfter
) & 3) && ((uintptr_t)(&rep->bytesAfter) &
3) == 0) *(&rep->bytesAfter) = lswapl(*(&rep->
bytesAfter)); else swap_uint32((uint32_t *)(&rep->bytesAfter
)); } while (0)
;
1081 swapl(&rep->nItems)do { if (sizeof(*(&rep->nItems)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&rep->nItems) &
3) && ((uintptr_t)(&rep->nItems) & 3) == 0
) *(&rep->nItems) = lswapl(*(&rep->nItems)); else
swap_uint32((uint32_t *)(&rep->nItems)); } while (0)
;
1082 /* data will be swapped, see ProcXGetDeviceProperty */
1083 WriteToClient(client, size, rep);
1084}
1085
1086/* XI2 Request/reply handling */
1087int
1088ProcXIListProperties(ClientPtr client)
1089{
1090 Atom *atoms;
1091 xXIListPropertiesReply rep;
1092 int natoms;
1093 DeviceIntPtr dev;
1094 int rc = Success0;
1095
1096 REQUEST(xXIListPropertiesReq)xXIListPropertiesReq *stuff = (xXIListPropertiesReq *)client->
requestBuffer
;
1097 REQUEST_SIZE_MATCH(xXIListPropertiesReq)if ((sizeof(xXIListPropertiesReq) >> 2) != client->req_len
) return(16)
;
1098
1099 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixListPropAccess(1<<6));
1100 if (rc != Success0)
1101 return rc;
1102
1103 rc = list_atoms(dev, &natoms, &atoms);
1104 if (rc != Success0)
1105 return rc;
1106
1107 rep = (xXIListPropertiesReply) {
1108 .repType = X_Reply1,
1109 .RepType = X_XIListProperties56,
1110 .sequenceNumber = client->sequence,
1111 .length = natoms,
1112 .num_properties = natoms
1113 };
1114
1115 WriteReplyToClient(client, sizeof(xXIListPropertiesReply), &rep){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xXIListPropertiesReply
)), &rep); else WriteToClient(client, (int)(sizeof(xXIListPropertiesReply
)), (&rep)); }
;
1116 if (natoms) {
1117 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
1118 WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(natoms * sizeof(Atom)), atoms); else WriteToClient(client
, (int)(natoms * sizeof(Atom)), (atoms));
;
1119 free(atoms);
1120 }
1121 return rc;
1122}
1123
1124int
1125ProcXIChangeProperty(ClientPtr client)
1126{
1127 int rc;
1128 DeviceIntPtr dev;
1129 int totalSize;
1130 unsigned long len;
1131
1132 REQUEST(xXIChangePropertyReq)xXIChangePropertyReq *stuff = (xXIChangePropertyReq *)client->
requestBuffer
;
1133 REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq)if ((sizeof(xXIChangePropertyReq) >> 2) > client->
req_len ) return(16)
;
1134 UpdateCurrentTime();
1135
1136 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
1137 if (rc != Success0)
1138 return rc;
1139
1140 rc = check_change_property(client, stuff->property, stuff->type,
1141 stuff->format, stuff->mode, stuff->num_items);
1142 len = stuff->num_items;
1143 if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq)))
1144 return BadLength16;
1145
1146 totalSize = len * (stuff->format / 8);
1147 REQUEST_FIXED_SIZE(xXIChangePropertyReq, totalSize)if (((sizeof(xXIChangePropertyReq) >> 2) > client->
req_len) || (((totalSize) >> 2) >= client->req_len
) || ((((uint64_t) sizeof(xXIChangePropertyReq) + (totalSize)
+ 3) >> 2) != (uint64_t) client->req_len)) return(16
)
;
1148
1149 rc = change_property(client, dev, stuff->property, stuff->type,
1150 stuff->format, stuff->mode, len, (void *) &stuff[1]);
1151 return rc;
1152}
1153
1154int
1155ProcXIDeleteProperty(ClientPtr client)
1156{
1157 DeviceIntPtr dev;
1158 int rc;
1159
1160 REQUEST(xXIDeletePropertyReq)xXIDeletePropertyReq *stuff = (xXIDeletePropertyReq *)client->
requestBuffer
;
1161
1162 REQUEST_SIZE_MATCH(xXIDeletePropertyReq)if ((sizeof(xXIDeletePropertyReq) >> 2) != client->req_len
) return(16)
;
1163 UpdateCurrentTime();
1164 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
1165 if (rc != Success0)
1166 return rc;
1167
1168 if (!ValidAtom(stuff->property)) {
1169 client->errorValue = stuff->property;
1170 return BadAtom5;
1171 }
1172
1173 rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE1);
1174 return rc;
1175}
1176
1177int
1178ProcXIGetProperty(ClientPtr client)
1179{
1180 REQUEST(xXIGetPropertyReq)xXIGetPropertyReq *stuff = (xXIGetPropertyReq *)client->requestBuffer;
1181 DeviceIntPtr dev;
1182 xXIGetPropertyReply reply;
1183 int length;
1184 int rc, format, nitems, bytes_after;
1185 char *data;
1186 Atom type;
1187
1188 REQUEST_SIZE_MATCH(xXIGetPropertyReq)if ((sizeof(xXIGetPropertyReq) >> 2) != client->req_len
) return(16)
;
1189 if (stuff->delete)
1190 UpdateCurrentTime();
1191 rc = dixLookupDevice(&dev, stuff->deviceid, client,
1192 stuff->delete ? DixSetPropAccess(1<<8) : DixGetPropAccess(1<<7));
1193 if (rc != Success0)
1194 return rc;
1195
1196 rc = get_property(client, dev, stuff->property, stuff->type,
1197 stuff->delete, stuff->offset, stuff->len,
1198 &bytes_after, &type, &format, &nitems, &length, &data);
1199
1200 if (rc != Success0)
1201 return rc;
1202
1203 reply = (xXIGetPropertyReply) {
1204 .repType = X_Reply1,
1205 .RepType = X_XIGetProperty59,
1206 .sequenceNumber = client->sequence,
1207 .length = bytes_to_int32(length),
1208 .type = type,
1209 .bytes_after = bytes_after,
1210 .num_items = nitems,
1211 .format = format
1212 };
1213
1214 if (length && stuff->delete && (reply.bytes_after == 0))
1215 send_property_event(dev, stuff->property, XIPropertyDeleted0);
1216
1217 WriteReplyToClient(client, sizeof(xXIGetPropertyReply), &reply){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xXIGetPropertyReply
)), &reply); else WriteToClient(client, (int)(sizeof(xXIGetPropertyReply
)), (&reply)); }
;
1218
1219 if (length) {
1220 switch (reply.format) {
1221 case 32:
1222 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
1223 break;
1224 case 16:
1225 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
1226 break;
1227 default:
1228 client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
1229 break;
1230 }
1231 WriteSwappedDataToClient(client, length, data)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(length), data); else WriteToClient(client, (int)(length
), (data));
;
1232 }
1233
1234 /* delete the Property */
1235 if (stuff->delete && (reply.bytes_after == 0)) {
1236 XIPropertyPtr prop, *prev;
1237
1238 for (prev = &dev->properties.properties; (prop = *prev);
1239 prev = &prop->next) {
1240 if (prop->propertyName == stuff->property) {
1241 *prev = prop->next;
1242 XIDestroyDeviceProperty(prop);
1243 break;
1244 }
1245 }
1246 }
1247
1248 return Success0;
1249}
1250
1251int
1252SProcXIListProperties(ClientPtr client)
1253{
1254 REQUEST(xXIListPropertiesReq)xXIListPropertiesReq *stuff = (xXIListPropertiesReq *)client->
requestBuffer
;
1255 REQUEST_SIZE_MATCH(xXIListPropertiesReq)if ((sizeof(xXIListPropertiesReq) >> 2) != client->req_len
) return(16)
;
1256
1257 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)
;
1258 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)
;
1259 return (ProcXIListProperties(client));
1260}
1261
1262int
1263SProcXIChangeProperty(ClientPtr client)
1264{
1265 REQUEST(xXIChangePropertyReq)xXIChangePropertyReq *stuff = (xXIChangePropertyReq *)client->
requestBuffer
;
1266
1267 REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq)if ((sizeof(xXIChangePropertyReq) >> 2) > client->
req_len ) return(16)
;
1268 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)
;
1269 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)
;
1270 swapl(&stuff->property)do { if (sizeof(*(&stuff->property)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->property
) & 3) && ((uintptr_t)(&stuff->property) &
3) == 0) *(&stuff->property) = lswapl(*(&stuff->
property)); else swap_uint32((uint32_t *)(&stuff->property
)); } while (0)
;
1271 swapl(&stuff->type)do { if (sizeof(*(&stuff->type)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->type) &
3) && ((uintptr_t)(&stuff->type) & 3) == 0
) *(&stuff->type) = lswapl(*(&stuff->type)); else
swap_uint32((uint32_t *)(&stuff->type)); } while (0)
;
1272 swapl(&stuff->num_items)do { if (sizeof(*(&stuff->num_items)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->num_items
) & 3) && ((uintptr_t)(&stuff->num_items) &
3) == 0) *(&stuff->num_items) = lswapl(*(&stuff->
num_items)); else swap_uint32((uint32_t *)(&stuff->num_items
)); } while (0)
;
1273 return (ProcXIChangeProperty(client));
1274}
1275
1276int
1277SProcXIDeleteProperty(ClientPtr client)
1278{
1279 REQUEST(xXIDeletePropertyReq)xXIDeletePropertyReq *stuff = (xXIDeletePropertyReq *)client->
requestBuffer
;
1280 REQUEST_SIZE_MATCH(xXIDeletePropertyReq)if ((sizeof(xXIDeletePropertyReq) >> 2) != client->req_len
) return(16)
;
1281
1282 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)
;
1283 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)
;
1284 swapl(&stuff->property)do { if (sizeof(*(&stuff->property)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->property
) & 3) && ((uintptr_t)(&stuff->property) &
3) == 0) *(&stuff->property) = lswapl(*(&stuff->
property)); else swap_uint32((uint32_t *)(&stuff->property
)); } while (0)
;
1285 return (ProcXIDeleteProperty(client));
1286}
1287
1288int
1289SProcXIGetProperty(ClientPtr client)
1290{
1291 REQUEST(xXIGetPropertyReq)xXIGetPropertyReq *stuff = (xXIGetPropertyReq *)client->requestBuffer;
1292 REQUEST_SIZE_MATCH(xXIGetPropertyReq)if ((sizeof(xXIGetPropertyReq) >> 2) != client->req_len
) return(16)
;
1293
1294 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)
;
1295 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)
;
1296 swapl(&stuff->property)do { if (sizeof(*(&stuff->property)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->property
) & 3) && ((uintptr_t)(&stuff->property) &
3) == 0) *(&stuff->property) = lswapl(*(&stuff->
property)); else swap_uint32((uint32_t *)(&stuff->property
)); } while (0)
;
1297 swapl(&stuff->type)do { if (sizeof(*(&stuff->type)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->type) &
3) && ((uintptr_t)(&stuff->type) & 3) == 0
) *(&stuff->type) = lswapl(*(&stuff->type)); else
swap_uint32((uint32_t *)(&stuff->type)); } while (0)
;
1298 swapl(&stuff->offset)do { if (sizeof(*(&stuff->offset)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->offset) &
3) && ((uintptr_t)(&stuff->offset) & 3) ==
0) *(&stuff->offset) = lswapl(*(&stuff->offset
)); else swap_uint32((uint32_t *)(&stuff->offset)); } while
(0)
;
1299 swapl(&stuff->len)do { if (sizeof(*(&stuff->len)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->len) & 3
) && ((uintptr_t)(&stuff->len) & 3) == 0) *
(&stuff->len) = lswapl(*(&stuff->len)); else swap_uint32
((uint32_t *)(&stuff->len)); } while (0)
;
1300 return (ProcXIGetProperty(client));
1301}
1302
1303void
1304SRepXIListProperties(ClientPtr client, int size, xXIListPropertiesReply * rep)
1305{
1306 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)
;
1307 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)
;
1308 swaps(&rep->num_properties)do { if (sizeof(*(&rep->num_properties)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&rep->num_properties
) & 1) && ((uintptr_t)(&rep->num_properties
) & 1) == 0) *(&rep->num_properties) = lswaps(*(&
rep->num_properties)); else swap_uint16((uint16_t *)(&
rep->num_properties)); } while (0)
;
1309 /* properties will be swapped later, see ProcXIListProperties */
1310 WriteToClient(client, size, rep);
1311}
1312
1313void
1314SRepXIGetProperty(ClientPtr client, int size, xXIGetPropertyReply * rep)
1315{
1316 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)
;
1317 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)
;
1318 swapl(&rep->type)do { if (sizeof(*(&rep->type)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&rep->type) & 3) &&
((uintptr_t)(&rep->type) & 3) == 0) *(&rep->
type) = lswapl(*(&rep->type)); else swap_uint32((uint32_t
*)(&rep->type)); } while (0)
;
1319 swapl(&rep->bytes_after)do { if (sizeof(*(&rep->bytes_after)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&rep->bytes_after
) & 3) && ((uintptr_t)(&rep->bytes_after) &
3) == 0) *(&rep->bytes_after) = lswapl(*(&rep->
bytes_after)); else swap_uint32((uint32_t *)(&rep->bytes_after
)); } while (0)
;
1320 swapl(&rep->num_items)do { if (sizeof(*(&rep->num_items)) != 4) wrong_size()
; if (__builtin_constant_p((uintptr_t)(&rep->num_items
) & 3) && ((uintptr_t)(&rep->num_items) &
3) == 0) *(&rep->num_items) = lswapl(*(&rep->num_items
)); else swap_uint32((uint32_t *)(&rep->num_items)); }
while (0)
;
1321 /* data will be swapped, see ProcXIGetProperty */
1322 WriteToClient(client, size, rep);
1323}