XrrProvider.c revision 0597fb56
10597fb56Smrg/* 20597fb56Smrg * Copyright © 2011 Dave Airlie 30597fb56Smrg * 40597fb56Smrg * Permission to use, copy, modify, distribute, and sell this software and its 50597fb56Smrg * documentation for any purpose is hereby granted without fee, provided that 60597fb56Smrg * the above copyright notice appear in all copies and that both that copyright 70597fb56Smrg * notice and this permission notice appear in supporting documentation, and 80597fb56Smrg * that the name of the copyright holders not be used in advertising or 90597fb56Smrg * publicity pertaining to distribution of the software without specific, 100597fb56Smrg * written prior permission. The copyright holders make no representations 110597fb56Smrg * about the suitability of this software for any purpose. It is provided "as 120597fb56Smrg * is" without express or implied warranty. 130597fb56Smrg * 140597fb56Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 150597fb56Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 160597fb56Smrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 170597fb56Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 180597fb56Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 190597fb56Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 200597fb56Smrg * OF THIS SOFTWARE. 210597fb56Smrg */ 220597fb56Smrg 230597fb56Smrg 240597fb56Smrg#ifdef HAVE_CONFIG_H 250597fb56Smrg#include <config.h> 260597fb56Smrg#endif 270597fb56Smrg 280597fb56Smrg#include <stdio.h> 290597fb56Smrg#include <X11/Xlib.h> 300597fb56Smrg/* we need to be able to manipulate the Display structure on events */ 310597fb56Smrg#include <X11/Xlibint.h> 320597fb56Smrg#include <X11/extensions/render.h> 330597fb56Smrg#include <X11/extensions/Xrender.h> 340597fb56Smrg#include "Xrandrint.h" 350597fb56Smrg 360597fb56SmrgXRRProviderResources * 370597fb56SmrgXRRGetProviderResources(Display *dpy, Window window) 380597fb56Smrg{ 390597fb56Smrg XExtDisplayInfo *info = XRRFindDisplay(dpy); 400597fb56Smrg xRRGetProvidersReply rep; 410597fb56Smrg xRRGetProvidersReq *req; 420597fb56Smrg XRRProviderResources *xrpr; 430597fb56Smrg long nbytes, nbytesRead; 440597fb56Smrg int rbytes; 450597fb56Smrg 460597fb56Smrg RRCheckExtension (dpy, info, NULL); 470597fb56Smrg 480597fb56Smrg LockDisplay (dpy); 490597fb56Smrg 500597fb56Smrg GetReq(RRGetProviders, req); 510597fb56Smrg req->reqType = info->codes->major_opcode; 520597fb56Smrg req->randrReqType = X_RRGetProviders; 530597fb56Smrg req->window = window; 540597fb56Smrg 550597fb56Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 560597fb56Smrg { 570597fb56Smrg UnlockDisplay (dpy); 580597fb56Smrg SyncHandle (); 590597fb56Smrg return NULL; 600597fb56Smrg } 610597fb56Smrg 620597fb56Smrg nbytes = (long) rep.length << 2; 630597fb56Smrg 640597fb56Smrg nbytesRead = (long) (rep.nProviders * 4); 650597fb56Smrg 660597fb56Smrg rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider)); 670597fb56Smrg xrpr = (XRRProviderResources *) Xmalloc(rbytes); 680597fb56Smrg 690597fb56Smrg if (xrpr == NULL) { 700597fb56Smrg _XEatData (dpy, (unsigned long) nbytes); 710597fb56Smrg UnlockDisplay (dpy); 720597fb56Smrg SyncHandle (); 730597fb56Smrg return NULL; 740597fb56Smrg } 750597fb56Smrg 760597fb56Smrg xrpr->timestamp = rep.timestamp; 770597fb56Smrg xrpr->nproviders = rep.nProviders; 780597fb56Smrg xrpr->providers = (RRProvider *)(xrpr + 1); 790597fb56Smrg 800597fb56Smrg _XRead32(dpy, xrpr->providers, rep.nProviders << 2); 810597fb56Smrg 820597fb56Smrg if (nbytes > nbytesRead) 830597fb56Smrg _XEatData (dpy, (unsigned long) (nbytes - nbytesRead)); 840597fb56Smrg 850597fb56Smrg 860597fb56Smrg UnlockDisplay (dpy); 870597fb56Smrg SyncHandle(); 880597fb56Smrg 890597fb56Smrg return (XRRProviderResources *) xrpr; 900597fb56Smrg} 910597fb56Smrg 920597fb56Smrgvoid 930597fb56SmrgXRRFreeProviderResources(XRRProviderResources *provider_resources) 940597fb56Smrg{ 950597fb56Smrg free(provider_resources); 960597fb56Smrg} 970597fb56Smrg 980597fb56Smrg#define ProviderInfoExtra (SIZEOF(xRRGetProviderInfoReply) - 32) 990597fb56SmrgXRRProviderInfo * 1000597fb56SmrgXRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider) 1010597fb56Smrg{ 1020597fb56Smrg XExtDisplayInfo *info = XRRFindDisplay(dpy); 1030597fb56Smrg xRRGetProviderInfoReply rep; 1040597fb56Smrg xRRGetProviderInfoReq *req; 1050597fb56Smrg int nbytes, nbytesRead, rbytes; 1060597fb56Smrg XRRProviderInfo *xpi; 1070597fb56Smrg 1080597fb56Smrg RRCheckExtension (dpy, info, NULL); 1090597fb56Smrg 1100597fb56Smrg LockDisplay (dpy); 1110597fb56Smrg GetReq (RRGetProviderInfo, req); 1120597fb56Smrg req->reqType = info->codes->major_opcode; 1130597fb56Smrg req->randrReqType = X_RRGetProviderInfo; 1140597fb56Smrg req->provider = provider; 1150597fb56Smrg req->configTimestamp = resources->configTimestamp; 1160597fb56Smrg 1170597fb56Smrg if (!_XReply (dpy, (xReply *) &rep, ProviderInfoExtra >> 2, xFalse)) 1180597fb56Smrg { 1190597fb56Smrg UnlockDisplay (dpy); 1200597fb56Smrg SyncHandle (); 1210597fb56Smrg return NULL; 1220597fb56Smrg } 1230597fb56Smrg 1240597fb56Smrg nbytes = ((long) rep.length << 2) - ProviderInfoExtra; 1250597fb56Smrg 1260597fb56Smrg nbytesRead = (long)(rep.nCrtcs * 4 + 1270597fb56Smrg rep.nOutputs * 4 + 1280597fb56Smrg rep.nAssociatedProviders * 8 + 1290597fb56Smrg ((rep.nameLength + 3) & ~3)); 1300597fb56Smrg 1310597fb56Smrg rbytes = (sizeof(XRRProviderInfo) + 1320597fb56Smrg rep.nCrtcs * sizeof(RRCrtc) + 1330597fb56Smrg rep.nOutputs * sizeof(RROutput) + 1340597fb56Smrg rep.nAssociatedProviders * (sizeof(RRProvider) + sizeof(unsigned int))+ 1350597fb56Smrg rep.nameLength + 1); 1360597fb56Smrg 1370597fb56Smrg xpi = (XRRProviderInfo *)Xmalloc(rbytes); 1380597fb56Smrg if (xpi == NULL) { 1390597fb56Smrg _XEatData (dpy, (unsigned long) nbytes); 1400597fb56Smrg UnlockDisplay (dpy); 1410597fb56Smrg SyncHandle (); 1420597fb56Smrg return NULL; 1430597fb56Smrg } 1440597fb56Smrg 1450597fb56Smrg xpi->capabilities = rep.capabilities; 1460597fb56Smrg xpi->ncrtcs = rep.nCrtcs; 1470597fb56Smrg xpi->noutputs = rep.nOutputs; 1480597fb56Smrg xpi->nassociatedproviders = rep.nAssociatedProviders; 1490597fb56Smrg xpi->crtcs = (RRCrtc *)(xpi + 1); 1500597fb56Smrg xpi->outputs = (RROutput *)(xpi->crtcs + rep.nCrtcs); 1510597fb56Smrg xpi->associated_providers = (RRProvider *)(xpi->outputs + rep.nOutputs); 1520597fb56Smrg xpi->associated_capability = (unsigned int *)(xpi->associated_providers + rep.nAssociatedProviders); 1530597fb56Smrg xpi->name = (char *)(xpi->associated_capability + rep.nAssociatedProviders); 1540597fb56Smrg 1550597fb56Smrg _XRead32(dpy, xpi->crtcs, rep.nCrtcs << 2); 1560597fb56Smrg _XRead32(dpy, xpi->outputs, rep.nOutputs << 2); 1570597fb56Smrg 1580597fb56Smrg _XRead32(dpy, xpi->associated_providers, rep.nAssociatedProviders << 2); 1590597fb56Smrg _XRead32(dpy, xpi->associated_capability, rep.nAssociatedProviders << 2); 1600597fb56Smrg 1610597fb56Smrg _XReadPad(dpy, xpi->name, rep.nameLength); 1620597fb56Smrg xpi->name[rep.nameLength] = '\0'; 1630597fb56Smrg 1640597fb56Smrg /* 1650597fb56Smrg * Skip any extra data 1660597fb56Smrg */ 1670597fb56Smrg if (nbytes > nbytesRead) 1680597fb56Smrg _XEatData (dpy, (unsigned long) (nbytes - nbytesRead)); 1690597fb56Smrg 1700597fb56Smrg UnlockDisplay (dpy); 1710597fb56Smrg SyncHandle (); 1720597fb56Smrg return (XRRProviderInfo *) xpi; 1730597fb56Smrg} 1740597fb56Smrg 1750597fb56Smrgvoid 1760597fb56SmrgXRRFreeProviderInfo(XRRProviderInfo *provider) 1770597fb56Smrg{ 1780597fb56Smrg free(provider); 1790597fb56Smrg} 1800597fb56Smrg 1810597fb56Smrgint 1820597fb56SmrgXRRSetProviderOutputSource(Display *dpy, XID provider, 1830597fb56Smrg XID source_provider) 1840597fb56Smrg{ 1850597fb56Smrg XExtDisplayInfo *info = XRRFindDisplay(dpy); 1860597fb56Smrg xRRSetProviderOutputSourceReq *req; 1870597fb56Smrg 1880597fb56Smrg RRCheckExtension (dpy, info, 0); 1890597fb56Smrg LockDisplay (dpy); 1900597fb56Smrg GetReq (RRSetProviderOutputSource, req); 1910597fb56Smrg req->reqType = info->codes->major_opcode; 1920597fb56Smrg req->randrReqType = X_RRSetProviderOutputSource; 1930597fb56Smrg req->provider = provider; 1940597fb56Smrg req->source_provider = source_provider; 1950597fb56Smrg UnlockDisplay (dpy); 1960597fb56Smrg SyncHandle (); 1970597fb56Smrg return 0; 1980597fb56Smrg} 1990597fb56Smrg 2000597fb56Smrgint 2010597fb56SmrgXRRSetProviderOffloadSink(Display *dpy, XID provider, 2020597fb56Smrg XID sink_provider) 2030597fb56Smrg{ 2040597fb56Smrg XExtDisplayInfo *info = XRRFindDisplay(dpy); 2050597fb56Smrg xRRSetProviderOffloadSinkReq *req; 2060597fb56Smrg 2070597fb56Smrg RRCheckExtension (dpy, info, 0); 2080597fb56Smrg LockDisplay (dpy); 2090597fb56Smrg GetReq (RRSetProviderOffloadSink, req); 2100597fb56Smrg req->reqType = info->codes->major_opcode; 2110597fb56Smrg req->randrReqType = X_RRSetProviderOffloadSink; 2120597fb56Smrg req->provider = provider; 2130597fb56Smrg req->sink_provider = sink_provider; 2140597fb56Smrg UnlockDisplay (dpy); 2150597fb56Smrg SyncHandle (); 2160597fb56Smrg return 0; 2170597fb56Smrg} 218