Bug Summary

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