2 * Copyright © 2006 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
29 /* we need to be able to manipulate the Display structure on events */
30 #include <X11/Xlibint.h>
31 #include <X11/extensions/render.h>
32 #include <X11/extensions/Xrender.h>
33 #include "Xrandrint.h"
37 XRRListProviderProperties (Display *dpy, RRProvider provider, int *nprop)
39 XExtDisplayInfo *info = XRRFindDisplay(dpy);
40 xRRListProviderPropertiesReply rep;
41 xRRListProviderPropertiesReq *req;
45 RRCheckExtension (dpy, info, NULL);
48 GetReq (RRListProviderProperties, req);
49 req->reqType = info->codes->major_opcode;
50 req->randrReqType = X_RRListProviderProperties;
51 req->provider = provider;
53 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
61 rbytes = rep.nAtoms * sizeof (Atom);
62 nbytes = rep.nAtoms << 2;
64 props = (Atom *) Xmalloc (rbytes);
66 _XEatDataWords (dpy, rep.length);
73 _XRead32 (dpy, props, nbytes);
83 XRRQueryProviderProperty (Display *dpy, RRProvider provider, Atom property)
85 XExtDisplayInfo *info = XRRFindDisplay(dpy);
86 xRRQueryProviderPropertyReply rep;
87 xRRQueryProviderPropertyReq *req;
88 unsigned int rbytes, nbytes;
89 XRRPropertyInfo *prop_info;
91 RRCheckExtension (dpy, info, NULL);
94 GetReq (RRQueryProviderProperty, req);
95 req->reqType = info->codes->major_opcode;
96 req->randrReqType = X_RRQueryProviderProperty;
97 req->provider = provider;
98 req->property = property;
100 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
106 if (rep.length < ((INT_MAX / sizeof(long)) - sizeof (XRRPropertyInfo))) {
107 rbytes = sizeof (XRRPropertyInfo) + (rep.length * sizeof (long));
108 nbytes = rep.length << 2;
110 prop_info = Xmalloc (rbytes);
114 if (prop_info == NULL) {
115 _XEatDataWords (dpy, rep.length);
121 prop_info->pending = rep.pending;
122 prop_info->range = rep.range;
123 prop_info->immutable = rep.immutable;
124 prop_info->num_values = rep.length;
125 if (rep.length != 0) {
126 prop_info->values = (long *) (prop_info + 1);
127 _XRead32 (dpy, prop_info->values, nbytes);
129 prop_info->values = NULL;
138 XRRConfigureProviderProperty (Display *dpy, RRProvider provider, Atom property,
139 Bool pending, Bool range, int num_values,
142 XExtDisplayInfo *info = XRRFindDisplay(dpy);
143 xRRConfigureProviderPropertyReq *req;
146 RRSimpleCheckExtension (dpy, info);
149 GetReq (RRConfigureProviderProperty, req);
150 req->reqType = info->codes->major_opcode;
151 req->randrReqType = X_RRConfigureProviderProperty;
152 req->provider = provider;
153 req->property = property;
154 req->pending = pending;
158 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
159 SetReqLen(req, len, len);
160 len = (long)num_values << 2;
161 Data32 (dpy, values, len);
162 } /* else force BadLength */
169 XRRChangeProviderProperty (Display *dpy, RRProvider provider,
170 Atom property, Atom type,
171 int format, int mode,
172 _Xconst unsigned char *data, int nelements)
174 XExtDisplayInfo *info = XRRFindDisplay(dpy);
175 xRRChangeProviderPropertyReq *req;
178 RRSimpleCheckExtension (dpy, info);
181 GetReq (RRChangeProviderProperty, req);
182 req->reqType = info->codes->major_opcode;
183 req->randrReqType = X_RRChangeProviderProperty;
184 req->provider = provider;
185 req->property = property;
190 req->format = 0; /* ask for garbage, get garbage */
192 req->nUnits = nelements;
193 req->format = format;
196 switch (req->format) {
198 len = ((long)nelements + 3) >> 2;
199 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
200 SetReqLen(req, len, len);
201 Data (dpy, (char *)data, nelements);
202 } /* else force BadLength */
206 len = ((long)nelements + 1) >> 1;
207 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
208 SetReqLen(req, len, len);
209 len = (long)nelements << 1;
210 Data16 (dpy, (short *) data, len);
211 } /* else force BadLength */
216 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
217 SetReqLen(req, len, len);
218 len = (long)nelements << 2;
219 Data32 (dpy, (long *) data, len);
220 } /* else force BadLength */
224 /* BadValue will be generated */ ;
232 XRRDeleteProviderProperty (Display *dpy, RRProvider provider, Atom property)
234 XExtDisplayInfo *info = XRRFindDisplay(dpy);
235 xRRDeleteProviderPropertyReq *req;
237 RRSimpleCheckExtension (dpy, info);
240 GetReq(RRDeleteProviderProperty, req);
241 req->reqType = info->codes->major_opcode;
242 req->randrReqType = X_RRDeleteProviderProperty;
243 req->provider = provider;
244 req->property = property;
250 XRRGetProviderProperty (Display *dpy, RRProvider provider,
251 Atom property, long offset, long length,
252 Bool delete, Bool pending, Atom req_type,
253 Atom *actual_type, int *actual_format,
254 unsigned long *nitems, unsigned long *bytes_after,
255 unsigned char **prop)
257 XExtDisplayInfo *info = XRRFindDisplay(dpy);
258 xRRGetProviderPropertyReply rep;
259 xRRGetProviderPropertyReq *req;
260 unsigned long nbytes, rbytes;
262 /* Always initialize return values, in case callers fail to initialize
263 them and fail to check the return code for an error. */
266 *nitems = *bytes_after = 0L;
267 *prop = (unsigned char *) NULL;
269 RRCheckExtension (dpy, info, 1);
272 GetReq (RRGetProviderProperty, req);
273 req->reqType = info->codes->major_opcode;
274 req->randrReqType = X_RRGetProviderProperty;
275 req->provider = provider;
276 req->property = property;
277 req->type = req_type;
278 req->longOffset = offset;
279 req->longLength = length;
280 req->delete = delete;
281 req->pending = pending;
283 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
287 return ((xError *)&rep)->errorCode;
290 if (rep.propertyType != None) {
291 int format = rep.format;
294 * Protect against both integer overflow and just plain oversized
295 * memory allocation - no server should ever return this many props.
297 if (rep.nItems >= (INT_MAX >> 4))
298 format = -1; /* fall through to default error case */
301 * One extra byte is malloced than is needed to contain the property
302 * data, but this last byte is null terminated and convenient for
303 * returning string properties, so the client doesn't then have to
304 * recopy the string to make it null terminated.
309 rbytes = rep.nItems + 1;
310 if (rbytes > 0 && (*prop = Xmalloc (rbytes)))
311 _XReadPad (dpy, (char *) *prop, nbytes);
315 nbytes = rep.nItems << 1;
316 rbytes = rep.nItems * sizeof (short) + 1;
317 if (rbytes > 0 && (*prop = Xmalloc (rbytes)))
318 _XRead16Pad (dpy, (short *) *prop, nbytes);
322 nbytes = rep.nItems << 2;
323 rbytes = rep.nItems * sizeof (long) + 1;
324 if (rbytes > 0 && (*prop = Xmalloc (rbytes)))
325 _XRead32 (dpy, (long *) *prop, nbytes);
330 * This part of the code should never be reached. If it is,
331 * the server sent back a property with an invalid format.
333 _XEatDataWords(dpy, rep.length);
336 return(BadImplementation);
339 _XEatDataWords(dpy, rep.length);
344 (*prop)[rbytes - 1] = '\0';
347 *actual_type = rep.propertyType;
348 *actual_format = rep.format;
349 *nitems = rep.nItems;
350 *bytes_after = rep.bytesAfter;