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"
36 XRRListProviderProperties (Display *dpy, RRProvider provider, int *nprop)
38 XExtDisplayInfo *info = XRRFindDisplay(dpy);
39 xRRListProviderPropertiesReply rep;
40 xRRListProviderPropertiesReq *req;
44 RRCheckExtension (dpy, info, NULL);
47 GetReq (RRListProviderProperties, req);
48 req->reqType = info->codes->major_opcode;
49 req->randrReqType = X_RRListProviderProperties;
50 req->provider = provider;
52 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
60 rbytes = rep.nAtoms * sizeof (Atom);
61 nbytes = rep.nAtoms << 2;
63 props = (Atom *) Xmalloc (rbytes);
65 _XEatData (dpy, nbytes);
72 _XRead32 (dpy, props, nbytes);
82 XRRQueryProviderProperty (Display *dpy, RRProvider provider, Atom property)
84 XExtDisplayInfo *info = XRRFindDisplay(dpy);
85 xRRQueryProviderPropertyReply rep;
86 xRRQueryProviderPropertyReq *req;
88 XRRPropertyInfo *prop_info;
90 RRCheckExtension (dpy, info, NULL);
93 GetReq (RRQueryProviderProperty, req);
94 req->reqType = info->codes->major_opcode;
95 req->randrReqType = X_RRQueryProviderProperty;
96 req->provider = provider;
97 req->property = property;
99 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
105 rbytes = sizeof (XRRPropertyInfo) + rep.length * sizeof (long);
106 nbytes = rep.length << 2;
108 prop_info = (XRRPropertyInfo *) Xmalloc (rbytes);
109 if (prop_info == NULL) {
110 _XEatData (dpy, nbytes);
116 prop_info->pending = rep.pending;
117 prop_info->range = rep.range;
118 prop_info->immutable = rep.immutable;
119 prop_info->num_values = rep.length;
120 if (rep.length != 0) {
121 prop_info->values = (long *) (prop_info + 1);
122 _XRead32 (dpy, prop_info->values, nbytes);
124 prop_info->values = NULL;
133 XRRConfigureProviderProperty (Display *dpy, RRProvider provider, Atom property,
134 Bool pending, Bool range, int num_values,
137 XExtDisplayInfo *info = XRRFindDisplay(dpy);
138 xRRConfigureProviderPropertyReq *req;
141 RRSimpleCheckExtension (dpy, info);
144 GetReq (RRConfigureProviderProperty, req);
145 req->reqType = info->codes->major_opcode;
146 req->randrReqType = X_RRConfigureProviderProperty;
147 req->provider = provider;
148 req->property = property;
149 req->pending = pending;
153 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
154 SetReqLen(req, len, len);
155 len = (long)num_values << 2;
156 Data32 (dpy, values, len);
157 } /* else force BadLength */
164 XRRChangeProviderProperty (Display *dpy, RRProvider provider,
165 Atom property, Atom type,
166 int format, int mode,
167 _Xconst unsigned char *data, int nelements)
169 XExtDisplayInfo *info = XRRFindDisplay(dpy);
170 xRRChangeProviderPropertyReq *req;
173 RRSimpleCheckExtension (dpy, info);
176 GetReq (RRChangeProviderProperty, req);
177 req->reqType = info->codes->major_opcode;
178 req->randrReqType = X_RRChangeProviderProperty;
179 req->provider = provider;
180 req->property = property;
185 req->format = 0; /* ask for garbage, get garbage */
187 req->nUnits = nelements;
188 req->format = format;
191 switch (req->format) {
193 len = ((long)nelements + 3) >> 2;
194 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
195 SetReqLen(req, len, len);
196 Data (dpy, (char *)data, nelements);
197 } /* else force BadLength */
201 len = ((long)nelements + 1) >> 1;
202 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
203 SetReqLen(req, len, len);
204 len = (long)nelements << 1;
205 Data16 (dpy, (short *) data, len);
206 } /* else force BadLength */
211 if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
212 SetReqLen(req, len, len);
213 len = (long)nelements << 2;
214 Data32 (dpy, (long *) data, len);
215 } /* else force BadLength */
219 /* BadValue will be generated */ ;
227 XRRDeleteProviderProperty (Display *dpy, RRProvider provider, Atom property)
229 XExtDisplayInfo *info = XRRFindDisplay(dpy);
230 xRRDeleteProviderPropertyReq *req;
232 RRSimpleCheckExtension (dpy, info);
235 GetReq(RRDeleteProviderProperty, req);
236 req->reqType = info->codes->major_opcode;
237 req->randrReqType = X_RRDeleteProviderProperty;
238 req->provider = provider;
239 req->property = property;
245 XRRGetProviderProperty (Display *dpy, RRProvider provider,
246 Atom property, long offset, long length,
247 Bool delete, Bool pending, Atom req_type,
248 Atom *actual_type, int *actual_format,
249 unsigned long *nitems, unsigned long *bytes_after,
250 unsigned char **prop)
252 XExtDisplayInfo *info = XRRFindDisplay(dpy);
253 xRRGetProviderPropertyReply rep;
254 xRRGetProviderPropertyReq *req;
257 RRCheckExtension (dpy, info, 1);
260 GetReq (RRGetProviderProperty, req);
261 req->reqType = info->codes->major_opcode;
262 req->randrReqType = X_RRGetProviderProperty;
263 req->provider = provider;
264 req->property = property;
265 req->type = req_type;
266 req->longOffset = offset;
267 req->longLength = length;
268 req->delete = delete;
269 req->pending = pending;
271 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
275 return ((xError *)&rep)->errorCode;
278 *prop = (unsigned char *) NULL;
279 if (rep.propertyType != None) {
281 * One extra byte is malloced than is needed to contain the property
282 * data, but this last byte is null terminated and convenient for
283 * returning string properties, so the client doesn't then have to
284 * recopy the string to make it null terminated.
286 switch (rep.format) {
289 rbytes = rep.nItems + 1;
291 (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
292 _XReadPad (dpy, (char *) *prop, nbytes);
296 nbytes = rep.nItems << 1;
297 rbytes = rep.nItems * sizeof (short) + 1;
299 (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
300 _XRead16Pad (dpy, (short *) *prop, nbytes);
304 nbytes = rep.nItems << 2;
305 rbytes = rep.nItems * sizeof (long) + 1;
307 (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
308 _XRead32 (dpy, (long *) *prop, nbytes);
313 * This part of the code should never be reached. If it is,
314 * the server sent back a property with an invalid format.
316 nbytes = rep.length << 2;
317 _XEatData(dpy, (unsigned long) nbytes);
320 return(BadImplementation);
323 _XEatData(dpy, (unsigned long) nbytes);
328 (*prop)[rbytes - 1] = '\0';
331 *actual_type = rep.propertyType;
332 *actual_format = rep.format;
333 *nitems = rep.nItems;
334 *bytes_after = rep.bytesAfter;