XrrProvider.c revision f1c62215
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 = (XRRProviderResources *) 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 107#define ProviderInfoExtra (SIZEOF(xRRGetProviderInfoReply) - 32) 108XRRProviderInfo * 109XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider) 110{ 111 XExtDisplayInfo *info = XRRFindDisplay(dpy); 112 xRRGetProviderInfoReply rep; 113 xRRGetProviderInfoReq *req; 114 int nbytes, nbytesRead, rbytes; 115 XRRProviderInfo *xpi; 116 117 RRCheckExtension (dpy, info, NULL); 118 119 LockDisplay (dpy); 120 GetReq (RRGetProviderInfo, req); 121 req->reqType = info->codes->major_opcode; 122 req->randrReqType = X_RRGetProviderInfo; 123 req->provider = provider; 124 req->configTimestamp = resources->configTimestamp; 125 126 if (!_XReply (dpy, (xReply *) &rep, ProviderInfoExtra >> 2, xFalse)) 127 { 128 UnlockDisplay (dpy); 129 SyncHandle (); 130 return NULL; 131 } 132 133 if (rep.length > INT_MAX >> 2 || rep.length < ProviderInfoExtra >> 2) 134 { 135 if (rep.length < ProviderInfoExtra >> 2) 136 _XEatDataWords (dpy, rep.length); 137 else 138 _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2)); 139 UnlockDisplay (dpy); 140 SyncHandle (); 141 return NULL; 142 } 143 144 nbytes = ((long) rep.length << 2) - ProviderInfoExtra; 145 146 nbytesRead = (long)(rep.nCrtcs * 4 + 147 rep.nOutputs * 4 + 148 rep.nAssociatedProviders * 8 + 149 ((rep.nameLength + 3) & ~3)); 150 151 rbytes = (sizeof(XRRProviderInfo) + 152 rep.nCrtcs * sizeof(RRCrtc) + 153 rep.nOutputs * sizeof(RROutput) + 154 rep.nAssociatedProviders * (sizeof(RRProvider) + sizeof(unsigned int))+ 155 rep.nameLength + 1); 156 157 xpi = (XRRProviderInfo *)Xmalloc(rbytes); 158 if (xpi == NULL) { 159 _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2)); 160 UnlockDisplay (dpy); 161 SyncHandle (); 162 return NULL; 163 } 164 165 xpi->capabilities = rep.capabilities; 166 xpi->ncrtcs = rep.nCrtcs; 167 xpi->noutputs = rep.nOutputs; 168 xpi->nassociatedproviders = rep.nAssociatedProviders; 169 xpi->crtcs = (RRCrtc *)(xpi + 1); 170 xpi->outputs = (RROutput *)(xpi->crtcs + rep.nCrtcs); 171 xpi->associated_providers = (RRProvider *)(xpi->outputs + rep.nOutputs); 172 xpi->associated_capability = (unsigned int *)(xpi->associated_providers + rep.nAssociatedProviders); 173 xpi->name = (char *)(xpi->associated_capability + rep.nAssociatedProviders); 174 175 _XRead32(dpy, (long *) xpi->crtcs, rep.nCrtcs << 2); 176 _XRead32(dpy, (long *) xpi->outputs, rep.nOutputs << 2); 177 178 _XRead32(dpy, (long *) xpi->associated_providers, rep.nAssociatedProviders << 2); 179 180 /* 181 * _XRead32 reads a series of 32-bit values from the protocol and writes 182 * them out as a series of "long int" values, but associated_capability 183 * is defined as unsigned int *, so that won't work for this array. 184 * Instead we assume for now that "unsigned int" is also 32-bits, so 185 * the values can be read without any conversion. 186 */ 187 _XRead(dpy, (char *) xpi->associated_capability, 188 rep.nAssociatedProviders << 2); 189 190 _XReadPad(dpy, xpi->name, rep.nameLength); 191 xpi->name[rep.nameLength] = '\0'; 192 193 /* 194 * Skip any extra data 195 */ 196 if (nbytes > nbytesRead) 197 _XEatData (dpy, (unsigned long) (nbytes - nbytesRead)); 198 199 UnlockDisplay (dpy); 200 SyncHandle (); 201 return (XRRProviderInfo *) xpi; 202} 203 204void 205XRRFreeProviderInfo(XRRProviderInfo *provider) 206{ 207 free(provider); 208} 209 210int 211XRRSetProviderOutputSource(Display *dpy, XID provider, 212 XID source_provider) 213{ 214 XExtDisplayInfo *info = XRRFindDisplay(dpy); 215 xRRSetProviderOutputSourceReq *req; 216 217 RRCheckExtension (dpy, info, 0); 218 LockDisplay (dpy); 219 GetReq (RRSetProviderOutputSource, req); 220 req->reqType = info->codes->major_opcode; 221 req->randrReqType = X_RRSetProviderOutputSource; 222 req->provider = provider; 223 req->source_provider = source_provider; 224 UnlockDisplay (dpy); 225 SyncHandle (); 226 return 0; 227} 228 229int 230XRRSetProviderOffloadSink(Display *dpy, XID provider, 231 XID sink_provider) 232{ 233 XExtDisplayInfo *info = XRRFindDisplay(dpy); 234 xRRSetProviderOffloadSinkReq *req; 235 236 RRCheckExtension (dpy, info, 0); 237 LockDisplay (dpy); 238 GetReq (RRSetProviderOffloadSink, req); 239 req->reqType = info->codes->major_opcode; 240 req->randrReqType = X_RRSetProviderOffloadSink; 241 req->provider = provider; 242 req->sink_provider = sink_provider; 243 UnlockDisplay (dpy); 244 SyncHandle (); 245 return 0; 246} 247