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