XrrProvider.c revision a0b5b4fa
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
36XRRProviderResources *
37XRRGetProviderResources(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, (RRProvider *)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
92void
93XRRFreeProviderResources(XRRProviderResources *provider_resources)
94{
95    free(provider_resources);
96}
97
98#define ProviderInfoExtra	(SIZEOF(xRRGetProviderInfoReply) - 32)
99XRRProviderInfo *
100XRRGetProviderInfo(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    _XRead32(dpy, (RRProvider *)xpi->associated_capability, rep.nAssociatedProviders << 2);
160
161    _XReadPad(dpy, xpi->name, rep.nameLength);
162    xpi->name[rep.nameLength] = '\0';
163
164    /*
165     * Skip any extra data
166     */
167    if (nbytes > nbytesRead)
168	_XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
169
170    UnlockDisplay (dpy);
171    SyncHandle ();
172    return (XRRProviderInfo *) xpi;
173}
174
175void
176XRRFreeProviderInfo(XRRProviderInfo *provider)
177{
178    free(provider);
179}
180
181int
182XRRSetProviderOutputSource(Display *dpy, XID provider,
183			   XID source_provider)
184{
185    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
186    xRRSetProviderOutputSourceReq *req;
187
188    RRCheckExtension (dpy, info, 0);
189    LockDisplay (dpy);
190    GetReq (RRSetProviderOutputSource, req);
191    req->reqType = info->codes->major_opcode;
192    req->randrReqType = X_RRSetProviderOutputSource;
193    req->provider = provider;
194    req->source_provider = source_provider;
195    UnlockDisplay (dpy);
196    SyncHandle ();
197    return 0;
198}
199
200int
201XRRSetProviderOffloadSink(Display *dpy, XID provider,
202			  XID sink_provider)
203{
204    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
205    xRRSetProviderOffloadSinkReq *req;
206
207    RRCheckExtension (dpy, info, 0);
208    LockDisplay (dpy);
209    GetReq (RRSetProviderOffloadSink, req);
210    req->reqType = info->codes->major_opcode;
211    req->randrReqType = X_RRSetProviderOffloadSink;
212    req->provider = provider;
213    req->sink_provider = sink_provider;
214    UnlockDisplay (dpy);
215    SyncHandle ();
216    return 0;
217}
218