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