package version up
[platform/upstream/libXrandr.git] / src / XrrProvider.c
1 /*
2  * Copyright © 2011 Dave Airlie
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
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <X11/Xlib.h>
30 /* we need to be able to manipulate the Display structure on events */
31 #include <X11/Xlibint.h>
32 #include <X11/extensions/render.h>
33 #include <X11/extensions/Xrender.h>
34 #include "Xrandrint.h"
35
36 XRRProviderResources *
37 XRRGetProviderResources(Display *dpy, Window window)
38 {
39     XExtDisplayInfo             *info = XRRFindDisplay(dpy);
40     xRRGetProvidersReply rep;
41     xRRGetProvidersReq *req;
42     XRRProviderResources *xrpr;
43     long nbytes, nbytesRead;
44     int rbytes;
45
46     RRCheckExtension (dpy, info, NULL);
47
48     LockDisplay (dpy);
49
50     GetReq(RRGetProviders, req);
51     req->reqType = info->codes->major_opcode;
52     req->randrReqType = X_RRGetProviders;
53     req->window = window;
54     
55     if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
56     {
57       UnlockDisplay (dpy);
58       SyncHandle ();
59       return NULL;
60     }
61
62     nbytes = (long) rep.length << 2;
63
64     nbytesRead = (long) (rep.nProviders * 4);
65
66     rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider));
67     xrpr = (XRRProviderResources *) Xmalloc(rbytes);
68
69     if (xrpr == NULL) {
70        _XEatDataWords (dpy, rep.length);
71        UnlockDisplay (dpy);
72        SyncHandle ();
73        return NULL;
74     }
75
76     xrpr->timestamp = rep.timestamp;
77     xrpr->nproviders = rep.nProviders;
78     xrpr->providers = (RRProvider *)(xrpr + 1);
79
80     _XRead32(dpy, xrpr->providers, rep.nProviders << 2);
81
82     if (nbytes > nbytesRead)
83       _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
84
85
86     UnlockDisplay (dpy);
87     SyncHandle();
88
89     return (XRRProviderResources *) xrpr;
90 }
91
92 void
93 XRRFreeProviderResources(XRRProviderResources *provider_resources)
94 {
95     free(provider_resources);
96 }
97
98 #define ProviderInfoExtra       (SIZEOF(xRRGetProviderInfoReply) - 32)  
99 XRRProviderInfo *
100 XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider)
101 {
102     XExtDisplayInfo         *info = XRRFindDisplay(dpy);
103     xRRGetProviderInfoReply rep;
104     xRRGetProviderInfoReq *req;
105     int nbytes, nbytesRead, rbytes;
106     XRRProviderInfo *xpi;
107
108     RRCheckExtension (dpy, info, NULL);
109
110     LockDisplay (dpy);
111     GetReq (RRGetProviderInfo, req);
112     req->reqType = info->codes->major_opcode;
113     req->randrReqType = X_RRGetProviderInfo;
114     req->provider = provider;
115     req->configTimestamp = resources->configTimestamp;
116
117     if (!_XReply (dpy, (xReply *) &rep, ProviderInfoExtra >> 2, xFalse))
118     {
119         UnlockDisplay (dpy);
120         SyncHandle ();
121         return NULL;
122     }
123
124     nbytes = ((long) rep.length << 2) - ProviderInfoExtra;
125
126     nbytesRead = (long)(rep.nCrtcs * 4 +
127                         rep.nOutputs * 4 +
128                         rep.nAssociatedProviders * 8 +
129                         ((rep.nameLength + 3) & ~3));
130
131     rbytes = (sizeof(XRRProviderInfo) +
132               rep.nCrtcs * sizeof(RRCrtc) +
133               rep.nOutputs * sizeof(RROutput) +
134               rep.nAssociatedProviders * (sizeof(RRProvider) + sizeof(unsigned int))+
135               rep.nameLength + 1);
136
137     xpi = (XRRProviderInfo *)Xmalloc(rbytes);
138     if (xpi == NULL) {
139         _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2));
140         UnlockDisplay (dpy);
141         SyncHandle ();
142         return NULL;
143     }
144
145     xpi->capabilities = rep.capabilities;
146     xpi->ncrtcs = rep.nCrtcs;
147     xpi->noutputs = rep.nOutputs;
148     xpi->nassociatedproviders = rep.nAssociatedProviders;
149     xpi->crtcs = (RRCrtc *)(xpi + 1);
150     xpi->outputs = (RROutput *)(xpi->crtcs + rep.nCrtcs);
151     xpi->associated_providers = (RRProvider *)(xpi->outputs + rep.nOutputs);
152     xpi->associated_capability = (unsigned int *)(xpi->associated_providers + rep.nAssociatedProviders);
153     xpi->name = (char *)(xpi->associated_capability + rep.nAssociatedProviders);
154
155     _XRead32(dpy, xpi->crtcs, rep.nCrtcs << 2);
156     _XRead32(dpy, xpi->outputs, rep.nOutputs << 2);
157
158     _XRead32(dpy, xpi->associated_providers, rep.nAssociatedProviders << 2);
159
160     /*
161      * _XRead32 reads a series of 32-bit values from the protocol and writes
162      * them out as a series of "long int" values, but associated_capability
163      * is defined as unsigned int *, so that won't work for this array.
164      * Instead we assume for now that "unsigned int" is also 32-bits, so
165      * the values can be read without any conversion.
166      */
167     _XRead(dpy, (char *) xpi->associated_capability,
168            rep.nAssociatedProviders << 2);
169
170     _XReadPad(dpy, xpi->name, rep.nameLength);
171     xpi->name[rep.nameLength] = '\0';
172
173     /*
174      * Skip any extra data
175      */
176     if (nbytes > nbytesRead)
177         _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
178
179     UnlockDisplay (dpy);
180     SyncHandle ();
181     return (XRRProviderInfo *) xpi;
182 }
183
184 void
185 XRRFreeProviderInfo(XRRProviderInfo *provider)
186 {
187     free(provider);
188 }
189
190 int
191 XRRSetProviderOutputSource(Display *dpy, XID provider,
192                            XID source_provider)
193 {
194     XExtDisplayInfo         *info = XRRFindDisplay(dpy);
195     xRRSetProviderOutputSourceReq *req;
196
197     RRCheckExtension (dpy, info, 0);
198     LockDisplay (dpy);
199     GetReq (RRSetProviderOutputSource, req);
200     req->reqType = info->codes->major_opcode;
201     req->randrReqType = X_RRSetProviderOutputSource;
202     req->provider = provider;
203     req->source_provider = source_provider;
204     UnlockDisplay (dpy);
205     SyncHandle ();
206     return 0;
207 }
208
209 int
210 XRRSetProviderOffloadSink(Display *dpy, XID provider,
211                           XID sink_provider)
212 {
213     XExtDisplayInfo         *info = XRRFindDisplay(dpy);
214     xRRSetProviderOffloadSinkReq *req;
215
216     RRCheckExtension (dpy, info, 0);
217     LockDisplay (dpy);
218     GetReq (RRSetProviderOffloadSink, req);
219     req->reqType = info->codes->major_opcode;
220     req->randrReqType = X_RRSetProviderOffloadSink;
221     req->provider = provider;
222     req->sink_provider = sink_provider;
223     UnlockDisplay (dpy);
224     SyncHandle ();
225     return 0;
226 }