upload tizen1.0 source
[framework/uifw/xorg/lib/libxrandr.git] / src / XrrProperty.c
1 /*
2  * Copyright © 2006 Keith Packard
3  *
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.
13  *
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
20  * OF THIS SOFTWARE.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <X11/Xlib.h>
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"
34
35 Atom *
36 XRRListOutputProperties (Display *dpy, RROutput output, int *nprop)
37 {
38     XExtDisplayInfo             *info = XRRFindDisplay(dpy);
39     xRRListOutputPropertiesReply rep;
40     xRRListOutputPropertiesReq  *req;
41     int                         nbytes, rbytes;
42     Atom                        *props = NULL;
43
44     RRCheckExtension (dpy, info, NULL);
45
46     LockDisplay (dpy);
47     GetReq (RRListOutputProperties, req);
48     req->reqType = info->codes->major_opcode;
49     req->randrReqType = X_RRListOutputProperties;
50     req->output = output;
51
52     if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
53         UnlockDisplay (dpy);
54         SyncHandle ();
55         *nprop = 0;
56         return NULL;
57     }
58
59     if (rep.nAtoms) {
60         rbytes = rep.nAtoms * sizeof (Atom);
61         nbytes = rep.nAtoms << 2;
62
63         props = (Atom *) Xmalloc (rbytes);
64         if (props == NULL) {
65             _XEatData (dpy, nbytes);
66             UnlockDisplay (dpy);
67             SyncHandle ();
68             *nprop = 0;
69             return NULL;
70         }
71
72         _XRead32 (dpy, props, nbytes);
73     }
74
75     *nprop = rep.nAtoms;
76     UnlockDisplay (dpy);
77     SyncHandle ();
78     return props;
79 }
80
81 XRRPropertyInfo *
82 XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property)
83 {
84     XExtDisplayInfo             *info = XRRFindDisplay(dpy);
85     xRRQueryOutputPropertyReply rep;
86     xRRQueryOutputPropertyReq   *req;
87     int                         rbytes, nbytes;
88     XRRPropertyInfo             *prop_info;
89
90     RRCheckExtension (dpy, info, NULL);
91
92     LockDisplay (dpy);
93     GetReq (RRQueryOutputProperty, req);
94     req->reqType = info->codes->major_opcode;
95     req->randrReqType = X_RRQueryOutputProperty;
96     req->output = output;
97     req->property = property;
98
99     if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
100         UnlockDisplay (dpy);
101         SyncHandle ();
102         return NULL;
103     }
104
105     rbytes = sizeof (XRRPropertyInfo) + rep.length * sizeof (long);
106     nbytes = rep.length << 2;
107
108     prop_info = (XRRPropertyInfo *) Xmalloc (rbytes);
109     if (prop_info == NULL) {
110         _XEatData (dpy, nbytes);
111         UnlockDisplay (dpy);
112         SyncHandle ();
113         return NULL;
114     }
115
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);
123     } else {
124         prop_info->values = NULL;
125     }
126
127     UnlockDisplay (dpy);
128     SyncHandle ();
129     return prop_info;
130 }
131
132 void
133 XRRConfigureOutputProperty (Display *dpy, RROutput output, Atom property,
134                             Bool pending, Bool range, int num_values,
135                             long *values)
136 {
137     XExtDisplayInfo                 *info = XRRFindDisplay(dpy);
138     xRRConfigureOutputPropertyReq   *req;
139     long len;
140
141     RRSimpleCheckExtension (dpy, info);
142
143     LockDisplay(dpy);
144     GetReq (RRConfigureOutputProperty, req);
145     req->reqType = info->codes->major_opcode;
146     req->randrReqType = X_RRConfigureOutputProperty;
147     req->output = output;
148     req->property = property;
149     req->pending = pending;
150     req->range = range;
151
152     len = num_values;
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 */
158
159     UnlockDisplay(dpy);
160     SyncHandle();
161 }
162                         
163 void
164 XRRChangeOutputProperty (Display *dpy, RROutput output,
165                          Atom property, Atom type,
166                          int format, int mode,
167                          _Xconst unsigned char *data, int nelements)
168 {
169     XExtDisplayInfo             *info = XRRFindDisplay(dpy);
170     xRRChangeOutputPropertyReq  *req;
171     long len;
172
173     RRSimpleCheckExtension (dpy, info);
174
175     LockDisplay(dpy);
176     GetReq (RRChangeOutputProperty, req);
177     req->reqType = info->codes->major_opcode;
178     req->randrReqType = X_RRChangeOutputProperty;
179     req->output = output;
180     req->property = property;
181     req->type = type;
182     req->mode = mode;
183     if (nelements < 0) {
184         req->nUnits = 0;
185         req->format = 0; /* ask for garbage, get garbage */
186     } else {
187         req->nUnits = nelements;
188         req->format = format;
189     }
190
191     switch (req->format) {
192     case 8:
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 */
198         break;
199
200     case 16:
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 */
207         break;
208
209     case 32:
210         len = nelements;
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 */
216         break;
217
218     default:
219         /* BadValue will be generated */ ;
220     }
221
222     UnlockDisplay(dpy);
223     SyncHandle();
224 }
225
226 void
227 XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property)
228 {
229     XExtDisplayInfo             *info = XRRFindDisplay(dpy);
230     xRRDeleteOutputPropertyReq *req;
231
232     RRSimpleCheckExtension (dpy, info);
233
234     LockDisplay(dpy);
235     GetReq(RRDeleteOutputProperty, req);
236     req->reqType = info->codes->major_opcode;
237     req->randrReqType = X_RRDeleteOutputProperty;
238     req->output = output;
239     req->property = property;
240     UnlockDisplay(dpy);
241     SyncHandle();
242 }
243
244 int
245 XRRGetOutputProperty (Display *dpy, RROutput output,
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)
251 {
252     XExtDisplayInfo             *info = XRRFindDisplay(dpy);
253     xRRGetOutputPropertyReply   rep;
254     xRRGetOutputPropertyReq     *req;
255     long                        nbytes, rbytes;
256
257     RRCheckExtension (dpy, info, 1);
258
259     LockDisplay (dpy);
260     GetReq (RRGetOutputProperty, req);
261     req->reqType = info->codes->major_opcode;
262     req->randrReqType = X_RRGetOutputProperty;
263     req->output = output;
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;
270
271     if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
272     {
273         UnlockDisplay (dpy);
274         SyncHandle ();
275         return ((xError *)&rep)->errorCode;
276     }
277
278     *prop = (unsigned char *) NULL;
279     if (rep.propertyType != None) {
280         /*
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.
285          */
286         switch (rep.format) {
287         case 8:
288             nbytes = rep.nItems;
289             rbytes = rep.nItems + 1;
290             if (rbytes > 0 &&
291                 (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
292                 _XReadPad (dpy, (char *) *prop, nbytes);
293             break;
294
295         case 16:
296             nbytes = rep.nItems << 1;
297             rbytes = rep.nItems * sizeof (short) + 1;
298             if (rbytes > 0 &&
299                 (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
300                 _XRead16Pad (dpy, (short *) *prop, nbytes);
301             break;
302
303         case 32:
304             nbytes = rep.nItems << 2;
305             rbytes = rep.nItems * sizeof (long) + 1;
306             if (rbytes > 0 &&
307                 (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
308                 _XRead32 (dpy, (long *) *prop, nbytes);
309             break;
310
311         default:
312             /*
313              * This part of the code should never be reached.  If it is,
314              * the server sent back a property with an invalid format.
315              */
316             nbytes = rep.length << 2;
317             _XEatData(dpy, (unsigned long) nbytes);
318             UnlockDisplay(dpy);
319             SyncHandle();
320             return(BadImplementation);
321         }
322         if (! *prop) {
323             _XEatData(dpy, (unsigned long) nbytes);
324             UnlockDisplay(dpy);
325             SyncHandle();
326             return(BadAlloc);
327         }
328         (*prop)[rbytes - 1] = '\0';
329     }
330
331     *actual_type = rep.propertyType;
332     *actual_format = rep.format;
333     *nitems = rep.nItems;
334     *bytes_after = rep.bytesAfter;
335     UnlockDisplay (dpy);
336     SyncHandle ();
337
338     return Success;
339 }