Bug Summary

File:Xi/xiproperty.c
Location:line 899, 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 = xallocarray(nprops, sizeof(Atom))xreallocarray(((void*)0), (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 unsigned long total_len;
691 XIPropertyValuePtr prop_value;
692 XIPropertyValueRec new_value;
693 Bool add = FALSE0;
694 int rc;
695
696 size_in_bytes = format >> 3;
697
698 /* first see if property already exists */
699 prop = XIFetchDeviceProperty(dev, property);
700 if (!prop) { /* just add to list */
701 prop = XICreateDeviceProperty(property);
702 if (!prop)
703 return BadAlloc11;
704 add = TRUE1;
705 mode = PropModeReplace0;
706 }
707 prop_value = &prop->value;
708
709 /* To append or prepend to a property the request format and type
710 must match those of the already defined property. The
711 existing format and type are irrelevant when using the mode
712 "PropModeReplace" since they will be written over. */
713
714 if ((format != prop_value->format) && (mode != PropModeReplace0))
715 return BadMatch8;
716 if ((prop_value->type != type) && (mode != PropModeReplace0))
717 return BadMatch8;
718 new_value = *prop_value;
719 if (mode == PropModeReplace0)
720 total_len = len;
721 else
722 total_len = prop_value->size + len;
723
724 if (mode == PropModeReplace0 || len > 0) {
725 void *new_data = NULL((void*)0), *old_data = NULL((void*)0);
726
727 new_value.data = xallocarray(total_len, size_in_bytes)xreallocarray(((void*)0), (total_len), (size_in_bytes));
728 if (!new_value.data && total_len && size_in_bytes) {
729 if (add)
730 XIDestroyDeviceProperty(prop);
731 return BadAlloc11;
732 }
733 new_value.size = len;
734 new_value.type = type;
735 new_value.format = format;
736
737 switch (mode) {
738 case PropModeReplace0:
739 new_data = new_value.data;
740 old_data = NULL((void*)0);
741 break;
742 case PropModeAppend2:
743 new_data = (void *) (((char *) new_value.data) +
744 (prop_value->size * size_in_bytes));
745 old_data = new_value.data;
746 break;
747 case PropModePrepend1:
748 new_data = new_value.data;
749 old_data = (void *) (((char *) new_value.data) +
750 (prop_value->size * size_in_bytes));
751 break;
752 }
753 if (new_data)
754 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))
;
755 if (old_data)
756 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))
757 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))
;
758
759 if (dev->properties.handlers) {
760 XIPropertyHandlerPtr handler;
761 BOOL checkonly = TRUE1;
762
763 /* run through all handlers with checkonly TRUE, then again with
764 * checkonly FALSE. Handlers MUST return error codes on the
765 * checkonly run, errors on the second run are ignored */
766 do {
767 handler = dev->properties.handlers;
768 while (handler) {
769 if (handler->SetProperty) {
770 rc = handler->SetProperty(dev, prop->propertyName,
771 &new_value, checkonly);
772 if (checkonly && rc != Success0) {
773 free(new_value.data);
774 if (add)
775 XIDestroyDeviceProperty(prop);
776 return rc;
777 }
778 }
779 handler = handler->next;
780 }
781 checkonly = !checkonly;
782 } while (!checkonly);
783 }
784 free(prop_value->data);
785 *prop_value = new_value;
786 }
787 else if (len == 0) {
788 /* do nothing */
789 }
790
791 if (add) {
792 prop->next = dev->properties.properties;
793 dev->properties.properties = prop;
794 }
795
796 if (sendevent)
797 send_property_event(dev, prop->propertyName,
798 (add) ? XIPropertyCreated1 : XIPropertyModified2);
799
800 return Success0;
801}
802
803int
804XIGetDeviceProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr *value)
805{
806 XIPropertyPtr prop = XIFetchDeviceProperty(dev, property);
807 int rc;
808
809 if (!prop) {
810 *value = NULL((void*)0);
811 return BadAtom5;
812 }
813
814 /* If we can, try to update the property value first */
815 if (dev->properties.handlers) {
816 XIPropertyHandlerPtr handler = dev->properties.handlers;
817
818 while (handler) {
819 if (handler->GetProperty) {
820 rc = handler->GetProperty(dev, prop->propertyName);
821 if (rc != Success0) {
822 *value = NULL((void*)0);
823 return rc;
824 }
825 }
826 handler = handler->next;
827 }
828 }
829
830 *value = &prop->value;
831 return Success0;
832}
833
834int
835XISetDevicePropertyDeletable(DeviceIntPtr dev, Atom property, Bool deletable)
836{
837 XIPropertyPtr prop = XIFetchDeviceProperty(dev, property);
838
839 if (!prop)
840 return BadAtom5;
841
842 prop->deletable = deletable;
843 return Success0;
844}
845
846int
847ProcXListDeviceProperties(ClientPtr client)
848{
849 Atom *atoms;
850 xListDevicePropertiesReply rep;
851 int natoms;
852 DeviceIntPtr dev;
853 int rc = Success0;
854
855 REQUEST(xListDevicePropertiesReq)xListDevicePropertiesReq *stuff = (xListDevicePropertiesReq *
)client->requestBuffer
;
856 REQUEST_SIZE_MATCH(xListDevicePropertiesReq)if ((sizeof(xListDevicePropertiesReq) >> 2) != client->
req_len) return(16)
;
857
858 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixListPropAccess(1<<6));
859 if (rc != Success0)
860 return rc;
861
862 rc = list_atoms(dev, &natoms, &atoms);
863 if (rc != Success0)
864 return rc;
865
866 rep = (xListDevicePropertiesReply) {
867 .repType = X_Reply1,
868 .RepType = X_ListDeviceProperties36,
869 .sequenceNumber = client->sequence,
870 .length = natoms,
871 .nAtoms = natoms
872 };
873
874 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)); }
;
875 if (natoms) {
876 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
877 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));
;
878 free(atoms);
879 }
880 return rc;
881}
882
883int
884ProcXChangeDeviceProperty(ClientPtr client)
885{
886 REQUEST(xChangeDevicePropertyReq)xChangeDevicePropertyReq *stuff = (xChangeDevicePropertyReq *
)client->requestBuffer
;
887 DeviceIntPtr dev;
888 unsigned long len;
889 int totalSize;
890 int rc;
891
892 REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq)if ((sizeof(xChangeDevicePropertyReq) >> 2) > client
->req_len ) return(16)
;
893 UpdateCurrentTime();
894
895 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
896 if (rc != Success0)
897 return rc;
898
899 rc = check_change_property(client, stuff->property, stuff->type,
Value stored to 'rc' is never read
900 stuff->format, stuff->mode, stuff->nUnits);
901
902 len = stuff->nUnits;
903 if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq))))
904 return BadLength16;
905
906 totalSize = len * (stuff->format / 8);
907 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)
;
908
909 rc = change_property(client, dev, stuff->property, stuff->type,
910 stuff->format, stuff->mode, len, (void *) &stuff[1]);
911 return rc;
912}
913
914int
915ProcXDeleteDeviceProperty(ClientPtr client)
916{
917 REQUEST(xDeleteDevicePropertyReq)xDeleteDevicePropertyReq *stuff = (xDeleteDevicePropertyReq *
)client->requestBuffer
;
918 DeviceIntPtr dev;
919 int rc;
920
921 REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq)if ((sizeof(xDeleteDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
922 UpdateCurrentTime();
923 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
924 if (rc != Success0)
925 return rc;
926
927 if (!ValidAtom(stuff->property)) {
928 client->errorValue = stuff->property;
929 return BadAtom5;
930 }
931
932 rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE1);
933 return rc;
934}
935
936int
937ProcXGetDeviceProperty(ClientPtr client)
938{
939 REQUEST(xGetDevicePropertyReq)xGetDevicePropertyReq *stuff = (xGetDevicePropertyReq *)client
->requestBuffer
;
940 DeviceIntPtr dev;
941 int length;
942 int rc, format, nitems, bytes_after;
943 char *data;
944 Atom type;
945 xGetDevicePropertyReply reply;
946
947 REQUEST_SIZE_MATCH(xGetDevicePropertyReq)if ((sizeof(xGetDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
948 if (stuff->delete)
949 UpdateCurrentTime();
950 rc = dixLookupDevice(&dev, stuff->deviceid, client,
951 stuff->delete ? DixSetPropAccess(1<<8) : DixGetPropAccess(1<<7));
952 if (rc != Success0)
953 return rc;
954
955 rc = get_property(client, dev, stuff->property, stuff->type,
956 stuff->delete, stuff->longOffset, stuff->longLength,
957 &bytes_after, &type, &format, &nitems, &length, &data);
958
959 if (rc != Success0)
960 return rc;
961
962 reply = (xGetDevicePropertyReply) {
963 .repType = X_Reply1,
964 .RepType = X_GetDeviceProperty39,
965 .sequenceNumber = client->sequence,
966 .length = bytes_to_int32(length),
967 .propertyType = type,
968 .bytesAfter = bytes_after,
969 .nItems = nitems,
970 .format = format,
971 .deviceid = dev->id
972 };
973
974 if (stuff->delete && (reply.bytesAfter == 0))
975 send_property_event(dev, stuff->property, XIPropertyDeleted0);
976
977 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)); }
;
978
979 if (length) {
980 switch (reply.format) {
981 case 32:
982 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
983 break;
984 case 16:
985 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
986 break;
987 default:
988 client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
989 break;
990 }
991 WriteSwappedDataToClient(client, length, data)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(length), data); else WriteToClient(client, (int)(length
), (data));
;
992 }
993
994 /* delete the Property */
995 if (stuff->delete && (reply.bytesAfter == 0)) {
996 XIPropertyPtr prop, *prev;
997
998 for (prev = &dev->properties.properties; (prop = *prev);
999 prev = &prop->next) {
1000 if (prop->propertyName == stuff->property) {
1001 *prev = prop->next;
1002 XIDestroyDeviceProperty(prop);
1003 break;
1004 }
1005 }
1006 }
1007 return Success0;
1008}
1009
1010int
1011SProcXListDeviceProperties(ClientPtr client)
1012{
1013 REQUEST(xListDevicePropertiesReq)xListDevicePropertiesReq *stuff = (xListDevicePropertiesReq *
)client->requestBuffer
;
1014 REQUEST_SIZE_MATCH(xListDevicePropertiesReq)if ((sizeof(xListDevicePropertiesReq) >> 2) != client->
req_len) return(16)
;
1015
1016 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)
;
1017 return (ProcXListDeviceProperties(client));
1018}
1019
1020int
1021SProcXChangeDeviceProperty(ClientPtr client)
1022{
1023 REQUEST(xChangeDevicePropertyReq)xChangeDevicePropertyReq *stuff = (xChangeDevicePropertyReq *
)client->requestBuffer
;
1024
1025 REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq)if ((sizeof(xChangeDevicePropertyReq) >> 2) > client
->req_len ) return(16)
;
1026 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)
;
1027 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)
;
1028 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)
;
1029 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)
;
1030 return (ProcXChangeDeviceProperty(client));
1031}
1032
1033int
1034SProcXDeleteDeviceProperty(ClientPtr client)
1035{
1036 REQUEST(xDeleteDevicePropertyReq)xDeleteDevicePropertyReq *stuff = (xDeleteDevicePropertyReq *
)client->requestBuffer
;
1037 REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq)if ((sizeof(xDeleteDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
1038
1039 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)
;
1040 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)
;
1041 return (ProcXDeleteDeviceProperty(client));
1042}
1043
1044int
1045SProcXGetDeviceProperty(ClientPtr client)
1046{
1047 REQUEST(xGetDevicePropertyReq)xGetDevicePropertyReq *stuff = (xGetDevicePropertyReq *)client
->requestBuffer
;
1048 REQUEST_SIZE_MATCH(xGetDevicePropertyReq)if ((sizeof(xGetDevicePropertyReq) >> 2) != client->
req_len) return(16)
;
1049
1050 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)
;
1051 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)
;
1052 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)
;
1053 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)
;
1054 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)
;
1055 return (ProcXGetDeviceProperty(client));
1056}
1057
1058/* Reply swapping */
1059
1060void
1061SRepXListDeviceProperties(ClientPtr client, int size,
1062 xListDevicePropertiesReply * rep)
1063{
1064 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)
;
1065 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)
;
1066 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)
;
1067 /* properties will be swapped later, see ProcXListDeviceProperties */
1068 WriteToClient(client, size, rep);
1069}
1070
1071void
1072SRepXGetDeviceProperty(ClientPtr client, int size,
1073 xGetDevicePropertyReply * rep)
1074{
1075 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)
;
1076 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)
;
1077 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)
;
1078 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)
;
1079 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)
;
1080 /* data will be swapped, see ProcXGetDeviceProperty */
1081 WriteToClient(client, size, rep);
1082}
1083
1084/* XI2 Request/reply handling */
1085int
1086ProcXIListProperties(ClientPtr client)
1087{
1088 Atom *atoms;
1089 xXIListPropertiesReply rep;
1090 int natoms;
1091 DeviceIntPtr dev;
1092 int rc = Success0;
1093
1094 REQUEST(xXIListPropertiesReq)xXIListPropertiesReq *stuff = (xXIListPropertiesReq *)client->
requestBuffer
;
1095 REQUEST_SIZE_MATCH(xXIListPropertiesReq)if ((sizeof(xXIListPropertiesReq) >> 2) != client->req_len
) return(16)
;
1096
1097 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixListPropAccess(1<<6));
1098 if (rc != Success0)
1099 return rc;
1100
1101 rc = list_atoms(dev, &natoms, &atoms);
1102 if (rc != Success0)
1103 return rc;
1104
1105 rep = (xXIListPropertiesReply) {
1106 .repType = X_Reply1,
1107 .RepType = X_XIListProperties56,
1108 .sequenceNumber = client->sequence,
1109 .length = natoms,
1110 .num_properties = natoms
1111 };
1112
1113 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)); }
;
1114 if (natoms) {
1115 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
1116 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));
;
1117 free(atoms);
1118 }
1119 return rc;
1120}
1121
1122int
1123ProcXIChangeProperty(ClientPtr client)
1124{
1125 int rc;
1126 DeviceIntPtr dev;
1127 int totalSize;
1128 unsigned long len;
1129
1130 REQUEST(xXIChangePropertyReq)xXIChangePropertyReq *stuff = (xXIChangePropertyReq *)client->
requestBuffer
;
1131 REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq)if ((sizeof(xXIChangePropertyReq) >> 2) > client->
req_len ) return(16)
;
1132 UpdateCurrentTime();
1133
1134 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
1135 if (rc != Success0)
1136 return rc;
1137
1138 rc = check_change_property(client, stuff->property, stuff->type,
1139 stuff->format, stuff->mode, stuff->num_items);
1140 len = stuff->num_items;
1141 if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq)))
1142 return BadLength16;
1143
1144 totalSize = len * (stuff->format / 8);
1145 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
)
;
1146
1147 rc = change_property(client, dev, stuff->property, stuff->type,
1148 stuff->format, stuff->mode, len, (void *) &stuff[1]);
1149 return rc;
1150}
1151
1152int
1153ProcXIDeleteProperty(ClientPtr client)
1154{
1155 DeviceIntPtr dev;
1156 int rc;
1157
1158 REQUEST(xXIDeletePropertyReq)xXIDeletePropertyReq *stuff = (xXIDeletePropertyReq *)client->
requestBuffer
;
1159
1160 REQUEST_SIZE_MATCH(xXIDeletePropertyReq)if ((sizeof(xXIDeletePropertyReq) >> 2) != client->req_len
) return(16)
;
1161 UpdateCurrentTime();
1162 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixSetPropAccess(1<<8));
1163 if (rc != Success0)
1164 return rc;
1165
1166 if (!ValidAtom(stuff->property)) {
1167 client->errorValue = stuff->property;
1168 return BadAtom5;
1169 }
1170
1171 rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE1);
1172 return rc;
1173}
1174
1175int
1176ProcXIGetProperty(ClientPtr client)
1177{
1178 REQUEST(xXIGetPropertyReq)xXIGetPropertyReq *stuff = (xXIGetPropertyReq *)client->requestBuffer;
1179 DeviceIntPtr dev;
1180 xXIGetPropertyReply reply;
1181 int length;
1182 int rc, format, nitems, bytes_after;
1183 char *data;
1184 Atom type;
1185
1186 REQUEST_SIZE_MATCH(xXIGetPropertyReq)if ((sizeof(xXIGetPropertyReq) >> 2) != client->req_len
) return(16)
;
1187 if (stuff->delete)
1188 UpdateCurrentTime();
1189 rc = dixLookupDevice(&dev, stuff->deviceid, client,
1190 stuff->delete ? DixSetPropAccess(1<<8) : DixGetPropAccess(1<<7));
1191 if (rc != Success0)
1192 return rc;
1193
1194 rc = get_property(client, dev, stuff->property, stuff->type,
1195 stuff->delete, stuff->offset, stuff->len,
1196 &bytes_after, &type, &format, &nitems, &length, &data);
1197
1198 if (rc != Success0)
1199 return rc;
1200
1201 reply = (xXIGetPropertyReply) {
1202 .repType = X_Reply1,
1203 .RepType = X_XIGetProperty59,
1204 .sequenceNumber = client->sequence,
1205 .length = bytes_to_int32(length),
1206 .type = type,
1207 .bytes_after = bytes_after,
1208 .num_items = nitems,
1209 .format = format
1210 };
1211
1212 if (length && stuff->delete && (reply.bytes_after == 0))
1213 send_property_event(dev, stuff->property, XIPropertyDeleted0);
1214
1215 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)); }
;
1216
1217 if (length) {
1218 switch (reply.format) {
1219 case 32:
1220 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
1221 break;
1222 case 16:
1223 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
1224 break;
1225 default:
1226 client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
1227 break;
1228 }
1229 WriteSwappedDataToClient(client, length, data)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(length), data); else WriteToClient(client, (int)(length
), (data));
;
1230 }
1231
1232 /* delete the Property */
1233 if (stuff->delete && (reply.bytes_after == 0)) {
1234 XIPropertyPtr prop, *prev;
1235
1236 for (prev = &dev->properties.properties; (prop = *prev);
1237 prev = &prop->next) {
1238 if (prop->propertyName == stuff->property) {
1239 *prev = prop->next;
1240 XIDestroyDeviceProperty(prop);
1241 break;
1242 }
1243 }
1244 }
1245
1246 return Success0;
1247}
1248
1249int
1250SProcXIListProperties(ClientPtr client)
1251{
1252 REQUEST(xXIListPropertiesReq)xXIListPropertiesReq *stuff = (xXIListPropertiesReq *)client->
requestBuffer
;
1253 REQUEST_SIZE_MATCH(xXIListPropertiesReq)if ((sizeof(xXIListPropertiesReq) >> 2) != client->req_len
) return(16)
;
1254
1255 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)
;
1256 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)
;
1257 return (ProcXIListProperties(client));
1258}
1259
1260int
1261SProcXIChangeProperty(ClientPtr client)
1262{
1263 REQUEST(xXIChangePropertyReq)xXIChangePropertyReq *stuff = (xXIChangePropertyReq *)client->
requestBuffer
;
1264
1265 REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq)if ((sizeof(xXIChangePropertyReq) >> 2) > client->
req_len ) return(16)
;
1266 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)
;
1267 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)
;
1268 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)
;
1269 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)
;
1270 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)
;
1271 return (ProcXIChangeProperty(client));
1272}
1273
1274int
1275SProcXIDeleteProperty(ClientPtr client)
1276{
1277 REQUEST(xXIDeletePropertyReq)xXIDeletePropertyReq *stuff = (xXIDeletePropertyReq *)client->
requestBuffer
;
1278 REQUEST_SIZE_MATCH(xXIDeletePropertyReq)if ((sizeof(xXIDeletePropertyReq) >> 2) != client->req_len
) return(16)
;
1279
1280 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)
;
1281 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)
;
1282 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)
;
1283 return (ProcXIDeleteProperty(client));
1284}
1285
1286int
1287SProcXIGetProperty(ClientPtr client)
1288{
1289 REQUEST(xXIGetPropertyReq)xXIGetPropertyReq *stuff = (xXIGetPropertyReq *)client->requestBuffer;
1290 REQUEST_SIZE_MATCH(xXIGetPropertyReq)if ((sizeof(xXIGetPropertyReq) >> 2) != client->req_len
) return(16)
;
1291
1292 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)
;
1293 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)
;
1294 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)
;
1295 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)
;
1296 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)
;
1297 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)
;
1298 return (ProcXIGetProperty(client));
1299}
1300
1301void
1302SRepXIListProperties(ClientPtr client, int size, xXIListPropertiesReply * rep)
1303{
1304 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)
;
1305 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)
;
1306 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)
;
1307 /* properties will be swapped later, see ProcXIListProperties */
1308 WriteToClient(client, size, rep);
1309}
1310
1311void
1312SRepXIGetProperty(ClientPtr client, int size, xXIGetPropertyReply * rep)
1313{
1314 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)
;
1315 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)
;
1316 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)
;
1317 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)
;
1318 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)
;
1319 /* data will be swapped, see ProcXIGetProperty */
1320 WriteToClient(client, size, rep);
1321}