2 * Copyright © 2009 Red Hat, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 /***********************************************************************
26 * XI2 property requests, list, change, delete and get properties.
35 #include <X11/Xlibint.h>
36 #include <X11/extensions/XI2.h>
37 #include <X11/extensions/XI2proto.h>
38 #include <X11/extensions/XInput2.h>
39 #include <X11/extensions/extutil.h>
43 XIListProperties(Display* dpy, int deviceid, int *num_props_return)
45 xXIListPropertiesReq *req;
46 xXIListPropertiesReply rep;
47 XExtDisplayInfo *info = XInput_find_display(dpy);
51 *num_props_return = 0;
52 if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1)
55 GetReq(XIListProperties, req);
56 req->reqType = info->codes->major_opcode;
57 req->ReqType = X_XIListProperties;
58 req->deviceid = deviceid;
60 if (!_XReply(dpy, (xReply*)&rep, 0, xFalse))
63 if (rep.num_properties) {
64 props = (Atom*)Xmalloc(rep.num_properties * sizeof(Atom));
67 _XEatData(dpy, rep.num_properties << 2);
71 _XRead32(dpy, (long*)props, rep.num_properties << 2);
74 *num_props_return = rep.num_properties;
84 XIDeleteProperty(Display* dpy, int deviceid, Atom property)
86 xXIDeletePropertyReq *req;
88 XExtDisplayInfo *info = XInput_find_display(dpy);
91 if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1)
94 GetReq(XIDeleteProperty, req);
95 req->reqType = info->codes->major_opcode;
96 req->ReqType = X_XIDeleteProperty;
97 req->deviceid = deviceid;
98 req->property = property;
105 XIChangeProperty(Display* dpy, int deviceid, Atom property, Atom type,
106 int format, int mode, unsigned char *data, int num_items)
108 xXIChangePropertyReq *req;
111 XExtDisplayInfo *info = XInput_find_display(dpy);
114 if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1)
117 GetReq(XIChangeProperty, req);
118 req->reqType = info->codes->major_opcode;
119 req->ReqType = X_XIChangeProperty;
120 req->deviceid = deviceid;
121 req->property = property;
126 req->format = 0; /* ask for garbage, get garbage */
128 req->num_items = num_items;
129 req->format = format;
132 switch (req->format) {
134 len = (num_items + 3)/4;
135 SetReqLen(req, len, len);
140 len = (num_items + 1)/2;
141 SetReqLen(req, len, len);
147 SetReqLen(req, len, len);
152 /* BadValue will be generated */ ;
156 /* we use data instead of Data32 and friends to avoid Xlib's braindead
159 Data(dpy, (const char*)data, len);
165 XIGetProperty(Display* dpy, int deviceid, Atom property, long offset,
166 long length, Bool delete_property, Atom type,
167 Atom *type_return, int *format_return,
168 unsigned long *num_items_return,unsigned long *bytes_after_return,
169 unsigned char **data)
171 xXIGetPropertyReq *req;
172 xXIGetPropertyReply rep;
175 XExtDisplayInfo *info = XInput_find_display(dpy);
178 if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1)
181 GetReq(XIGetProperty, req);
182 req->reqType = info->codes->major_opcode;
183 req->ReqType = X_XIGetProperty;
184 req->deviceid = deviceid;
185 req->property = property;
187 req->offset = offset;
189 req->delete = delete_property;
191 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
200 if (rep.type != None) {
201 if (rep.format != 8 && rep.format != 16 && rep.format != 32) {
203 * This part of the code should never be reached. If it is,
204 * the server sent back a property with an invalid format.
206 nbytes = rep.length << 2;
207 _XEatData(dpy, nbytes);
210 return(BadImplementation);
214 * One extra byte is malloced than is needed to contain the property
215 * data, but this last byte is null terminated and convenient for
216 * returning string properties, so the client doesn't then have to
217 * recopy the string to make it null terminated.
220 nbytes = rep.num_items * rep.format/8;
222 *data = Xmalloc(rbytes);
225 _XEatData(dpy, nbytes);
231 _XReadPad (dpy, (char *)*data, nbytes);
232 (*data)[rbytes - 1] = '\0';
235 *type_return = rep.type;
236 *format_return = rep.format;
237 *num_items_return = rep.num_items;
238 *bytes_after_return = rep.bytes_after;