Xrandr.c revision 8c4a8e55
1b042e37fSmrg/* 2b042e37fSmrg * Copyright © 2000 Compaq Computer Corporation, Inc. 3b042e37fSmrg * Copyright © 2002 Hewlett Packard Company, Inc. 4b042e37fSmrg * 5b042e37fSmrg * Permission to use, copy, modify, distribute, and sell this software and its 6b042e37fSmrg * documentation for any purpose is hereby granted without fee, provided that 7b042e37fSmrg * the above copyright notice appear in all copies and that both that 8b042e37fSmrg * copyright notice and this permission notice appear in supporting 9b042e37fSmrg * documentation, and that the name of Compaq or HP not be used in advertising 10b042e37fSmrg * or publicity pertaining to distribution of the software without specific, 11b042e37fSmrg * written prior permission. HP makes no representations about the 12b042e37fSmrg * suitability of this software for any purpose. It is provided "as is" 13b042e37fSmrg * without express or implied warranty. 14b042e37fSmrg * 15b042e37fSmrg * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16b042e37fSmrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ 17b042e37fSmrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18b042e37fSmrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19b042e37fSmrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20b042e37fSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21b042e37fSmrg * 22b042e37fSmrg * Author: Jim Gettys, HP Labs, HP. 23b042e37fSmrg */ 24b042e37fSmrg 25b042e37fSmrg#ifdef HAVE_CONFIG_H 26b042e37fSmrg#include <config.h> 27b042e37fSmrg#endif 28b042e37fSmrg 29b042e37fSmrg#include <stdio.h> 30b042e37fSmrg#include <X11/Xlib.h> 31b042e37fSmrg/* we need to be able to manipulate the Display structure on events */ 32b042e37fSmrg#include <X11/Xlibint.h> 33b042e37fSmrg#include <X11/extensions/render.h> 34b042e37fSmrg#include <X11/extensions/Xrender.h> 35b042e37fSmrg#include "Xrandrint.h" 36b042e37fSmrg 378c4a8e55Smrgstatic XExtensionInfo XRRExtensionInfo; 388c4a8e55Smrg_X_HIDDEN char XRRExtensionName[] = RANDR_NAME; 39b042e37fSmrg 40b042e37fSmrgstatic Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire); 41b042e37fSmrgstatic Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire); 42b042e37fSmrg 43b042e37fSmrgstatic int 44b042e37fSmrgXRRCloseDisplay (Display *dpy, XExtCodes *codes); 45b042e37fSmrg 46b042e37fSmrgstatic /* const */ XExtensionHooks rr_extension_hooks = { 47b042e37fSmrg NULL, /* create_gc */ 48b042e37fSmrg NULL, /* copy_gc */ 49b042e37fSmrg NULL, /* flush_gc */ 50b042e37fSmrg NULL, /* free_gc */ 51b042e37fSmrg NULL, /* create_font */ 52b042e37fSmrg NULL, /* free_font */ 53b042e37fSmrg XRRCloseDisplay, /* close_display */ 54b042e37fSmrg XRRWireToEvent, /* wire_to_event */ 55b042e37fSmrg XRREventToWire, /* event_to_wire */ 56b042e37fSmrg NULL, /* error */ 57b042e37fSmrg NULL, /* error_string */ 58b042e37fSmrg}; 59b042e37fSmrg 60b042e37fSmrgstatic Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire) 61b042e37fSmrg{ 62b042e37fSmrg XExtDisplayInfo *info = XRRFindDisplay(dpy); 63b042e37fSmrg 64b042e37fSmrg RRCheckExtension(dpy, info, False); 65b042e37fSmrg 66b042e37fSmrg switch ((wire->u.u.type & 0x7F) - info->codes->first_event) 67b042e37fSmrg { 68b042e37fSmrg case RRScreenChangeNotify: { 69b042e37fSmrg XRRScreenChangeNotifyEvent *aevent= (XRRScreenChangeNotifyEvent *) event; 70b042e37fSmrg xRRScreenChangeNotifyEvent *awire = (xRRScreenChangeNotifyEvent *) wire; 71b042e37fSmrg aevent->type = awire->type & 0x7F; 72b042e37fSmrg aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); 73b042e37fSmrg aevent->send_event = (awire->type & 0x80) != 0; 74b042e37fSmrg aevent->display = dpy; 75b042e37fSmrg aevent->window = awire->window; 76b042e37fSmrg aevent->root = awire->root; 77b042e37fSmrg aevent->timestamp = awire->timestamp; 78b042e37fSmrg aevent->config_timestamp = awire->configTimestamp; 79b042e37fSmrg aevent->size_index = awire->sizeID; 80b042e37fSmrg aevent->subpixel_order = awire->subpixelOrder; 81b042e37fSmrg aevent->rotation = awire->rotation; 82b042e37fSmrg aevent->width = awire->widthInPixels; 83b042e37fSmrg aevent->height = awire->heightInPixels; 84b042e37fSmrg aevent->mwidth = awire->widthInMillimeters; 85b042e37fSmrg aevent->mheight = awire->heightInMillimeters; 86b042e37fSmrg return True; 87b042e37fSmrg } 88b042e37fSmrg case RRNotify: { 898c4a8e55Smrg switch (wire->u.u.detail) { 90b042e37fSmrg case RRNotify_OutputChange: { 91b042e37fSmrg XRROutputChangeNotifyEvent *aevent = (XRROutputChangeNotifyEvent *) event; 92b042e37fSmrg xRROutputChangeNotifyEvent *awire = (xRROutputChangeNotifyEvent *) wire; 938c4a8e55Smrg aevent->type = awire->type & 0x7F; 948c4a8e55Smrg aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); 958c4a8e55Smrg aevent->send_event = (awire->type & 0x80) != 0; 968c4a8e55Smrg aevent->display = dpy; 978c4a8e55Smrg aevent->window = awire->window; 988c4a8e55Smrg aevent->subtype = awire->subCode; 99b042e37fSmrg aevent->output = awire->output; 100b042e37fSmrg aevent->crtc = awire->crtc; 101b042e37fSmrg aevent->mode = awire->mode; 102b042e37fSmrg aevent->rotation = awire->rotation; 103b042e37fSmrg aevent->connection = awire->connection; 104b042e37fSmrg aevent->subpixel_order = awire->subpixelOrder; 105b042e37fSmrg return True; 106b042e37fSmrg } 107b042e37fSmrg case RRNotify_CrtcChange: { 108b042e37fSmrg XRRCrtcChangeNotifyEvent *aevent = (XRRCrtcChangeNotifyEvent *) event; 109b042e37fSmrg xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire; 1108c4a8e55Smrg aevent->type = awire->type & 0x7F; 1118c4a8e55Smrg aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); 1128c4a8e55Smrg aevent->send_event = (awire->type & 0x80) != 0; 1138c4a8e55Smrg aevent->display = dpy; 1148c4a8e55Smrg aevent->window = awire->window; 1158c4a8e55Smrg aevent->subtype = awire->subCode; 116b042e37fSmrg aevent->crtc = awire->crtc; 117b042e37fSmrg aevent->mode = awire->mode; 118b042e37fSmrg aevent->rotation = awire->rotation; 119b042e37fSmrg aevent->x = awire->x; 120b042e37fSmrg aevent->y = awire->y; 121b042e37fSmrg aevent->width = awire->width; 122b042e37fSmrg aevent->height = awire->height; 123b042e37fSmrg return True; 124b042e37fSmrg } 125b042e37fSmrg case RRNotify_OutputProperty: { 126b042e37fSmrg XRROutputPropertyNotifyEvent *aevent = (XRROutputPropertyNotifyEvent *) event; 127b042e37fSmrg xRROutputPropertyNotifyEvent *awire = (xRROutputPropertyNotifyEvent *) wire; 1288c4a8e55Smrg aevent->type = awire->type & 0x7F; 1298c4a8e55Smrg aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); 1308c4a8e55Smrg aevent->send_event = (awire->type & 0x80) != 0; 1318c4a8e55Smrg aevent->display = dpy; 1328c4a8e55Smrg aevent->window = awire->window; 1338c4a8e55Smrg aevent->subtype = awire->subCode; 134b042e37fSmrg aevent->output = awire->output; 135b042e37fSmrg aevent->property = awire->atom; 136b042e37fSmrg aevent->timestamp = awire->timestamp; 137b042e37fSmrg aevent->state = awire->state; 138b042e37fSmrg return True; 139b042e37fSmrg } 140b042e37fSmrg 141b042e37fSmrg break; 142b042e37fSmrg } 143b042e37fSmrg } 144b042e37fSmrg } 145b042e37fSmrg 146b042e37fSmrg return False; 147b042e37fSmrg} 148b042e37fSmrg 149b042e37fSmrgstatic Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire) 150b042e37fSmrg{ 151b042e37fSmrg XExtDisplayInfo *info = XRRFindDisplay(dpy); 152b042e37fSmrg 153b042e37fSmrg RRCheckExtension(dpy, info, False); 154b042e37fSmrg 155b042e37fSmrg switch ((event->type & 0x7F) - info->codes->first_event) 156b042e37fSmrg { 157b042e37fSmrg case RRScreenChangeNotify: { 158b042e37fSmrg xRRScreenChangeNotifyEvent *awire = (xRRScreenChangeNotifyEvent *) wire; 159b042e37fSmrg XRRScreenChangeNotifyEvent *aevent = (XRRScreenChangeNotifyEvent *) event; 160b042e37fSmrg awire->type = aevent->type | (aevent->send_event ? 0x80 : 0); 161b042e37fSmrg awire->rotation = (CARD8) aevent->rotation; 162b042e37fSmrg awire->sequenceNumber = aevent->serial & 0xFFFF; 163b042e37fSmrg awire->timestamp = aevent->timestamp; 164b042e37fSmrg awire->configTimestamp = aevent->config_timestamp; 165b042e37fSmrg awire->root = aevent->root; 166b042e37fSmrg awire->window = aevent->window; 167b042e37fSmrg awire->sizeID = aevent->size_index; 168b042e37fSmrg awire->subpixelOrder = aevent->subpixel_order; 169b042e37fSmrg awire->widthInPixels = aevent->width; 170b042e37fSmrg awire->heightInPixels = aevent->height; 171b042e37fSmrg awire->widthInMillimeters = aevent->mwidth; 172b042e37fSmrg awire->heightInMillimeters = aevent->mheight; 173b042e37fSmrg return True; 174b042e37fSmrg } 175b042e37fSmrg case RRNotify: { 176b042e37fSmrg xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire; 177b042e37fSmrg XRRNotifyEvent *aevent = (XRRNotifyEvent *) event; 178b042e37fSmrg awire->type = aevent->type | (aevent->send_event ? 0x80 : 0); 179b042e37fSmrg awire->sequenceNumber = aevent->serial & 0xFFFF; 180b042e37fSmrg awire->subCode = aevent->subtype; 181b042e37fSmrg switch (aevent->subtype) { 182b042e37fSmrg case RRNotify_OutputChange: { 183b042e37fSmrg xRROutputChangeNotifyEvent *awire = (xRROutputChangeNotifyEvent *) wire; 184b042e37fSmrg XRROutputChangeNotifyEvent *aevent = (XRROutputChangeNotifyEvent *) event; 1858c4a8e55Smrg awire->window = aevent->window; 186b042e37fSmrg awire->output = aevent->output; 187b042e37fSmrg awire->crtc = aevent->crtc; 188b042e37fSmrg awire->mode = aevent->mode; 189b042e37fSmrg awire->rotation = aevent->rotation; 190b042e37fSmrg awire->connection = aevent->connection; 191b042e37fSmrg awire->subpixelOrder = aevent->subpixel_order; 192b042e37fSmrg return True; 193b042e37fSmrg } 194b042e37fSmrg case RRNotify_CrtcChange: { 195b042e37fSmrg xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire; 196b042e37fSmrg XRRCrtcChangeNotifyEvent *aevent = (XRRCrtcChangeNotifyEvent *) event; 1978c4a8e55Smrg awire->window = aevent->window; 198b042e37fSmrg awire->crtc = aevent->crtc; 199b042e37fSmrg awire->mode = aevent->mode; 200b042e37fSmrg awire->rotation = aevent->rotation; 201b042e37fSmrg awire->x = aevent->x; 202b042e37fSmrg awire->y = aevent->y; 203b042e37fSmrg awire->width = aevent->width; 204b042e37fSmrg awire->height = aevent->height; 205b042e37fSmrg return True; 206b042e37fSmrg } 207b042e37fSmrg case RRNotify_OutputProperty: { 208b042e37fSmrg xRROutputPropertyNotifyEvent *awire = (xRROutputPropertyNotifyEvent *) wire; 209b042e37fSmrg XRROutputPropertyNotifyEvent *aevent = (XRROutputPropertyNotifyEvent *) event; 2108c4a8e55Smrg awire->window = aevent->window; 211b042e37fSmrg awire->output = aevent->output; 212b042e37fSmrg awire->atom = aevent->property; 213b042e37fSmrg awire->timestamp = aevent->timestamp; 214b042e37fSmrg awire->state = aevent->state; 215b042e37fSmrg return True; 216b042e37fSmrg } 217b042e37fSmrg } 218b042e37fSmrg } 219b042e37fSmrg } 220b042e37fSmrg return False; 221b042e37fSmrg} 222b042e37fSmrg 2238c4a8e55Smrg_X_HIDDEN XExtDisplayInfo * 224b042e37fSmrgXRRFindDisplay (Display *dpy) 225b042e37fSmrg{ 226b042e37fSmrg XExtDisplayInfo *dpyinfo; 227b042e37fSmrg XRandRInfo *xrri; 228b042e37fSmrg int i, numscreens; 229b042e37fSmrg 230b042e37fSmrg dpyinfo = XextFindDisplay (&XRRExtensionInfo, dpy); 231b042e37fSmrg if (!dpyinfo) { 232b042e37fSmrg dpyinfo = XextAddDisplay (&XRRExtensionInfo, dpy, 233b042e37fSmrg XRRExtensionName, 234b042e37fSmrg &rr_extension_hooks, 2358c4a8e55Smrg RRNumberEvents, NULL); 236b042e37fSmrg numscreens = ScreenCount(dpy); 237b042e37fSmrg xrri = Xmalloc (sizeof(XRandRInfo) + 238b042e37fSmrg sizeof(char *) * numscreens); 239b042e37fSmrg xrri->config = (XRRScreenConfiguration **)(xrri + 1); 240b042e37fSmrg for(i = 0; i < numscreens; i++) 241b042e37fSmrg xrri->config[i] = NULL; 242b042e37fSmrg xrri->major_version = -1; 243b042e37fSmrg dpyinfo->data = (char *) xrri; 244b042e37fSmrg } 245b042e37fSmrg return dpyinfo; 246b042e37fSmrg} 247b042e37fSmrg 248b042e37fSmrgstatic int 249b042e37fSmrgXRRCloseDisplay (Display *dpy, XExtCodes *codes) 250b042e37fSmrg{ 251b042e37fSmrg int i; 252b042e37fSmrg XRRScreenConfiguration **configs; 253b042e37fSmrg XExtDisplayInfo *info = XRRFindDisplay (dpy); 254b042e37fSmrg XRandRInfo *xrri; 255b042e37fSmrg 256b042e37fSmrg LockDisplay(dpy); 257b042e37fSmrg /* 258b042e37fSmrg * free cached data 259b042e37fSmrg */ 260b042e37fSmrg if (XextHasExtension(info)) { 261b042e37fSmrg xrri = (XRandRInfo *) info->data; 262b042e37fSmrg if (xrri) { 263b042e37fSmrg configs = xrri->config; 264b042e37fSmrg 265b042e37fSmrg for (i = 0; i < ScreenCount(dpy); i++) { 266b042e37fSmrg if (configs[i] != NULL) XFree (configs[i]); 267b042e37fSmrg } 268b042e37fSmrg XFree (xrri); 269b042e37fSmrg } 270b042e37fSmrg } 271b042e37fSmrg UnlockDisplay(dpy); 272b042e37fSmrg return XextRemoveDisplay (&XRRExtensionInfo, dpy); 273b042e37fSmrg} 274b042e37fSmrg 275b042e37fSmrgint XRRRootToScreen(Display *dpy, Window root) 276b042e37fSmrg{ 277b042e37fSmrg int snum; 278b042e37fSmrg for (snum = 0; snum < ScreenCount(dpy); snum++) { 279b042e37fSmrg if (RootWindow(dpy, snum) == root) return snum; 280b042e37fSmrg } 281b042e37fSmrg return -1; 282b042e37fSmrg} 283b042e37fSmrg 284b042e37fSmrg 2858c4a8e55SmrgBool XRRQueryExtension (Display *dpy, 2868c4a8e55Smrg int *event_base_return, 2878c4a8e55Smrg int *error_base_return) 288b042e37fSmrg{ 289b042e37fSmrg XExtDisplayInfo *info = XRRFindDisplay (dpy); 290b042e37fSmrg 291b042e37fSmrg if (XextHasExtension(info)) { 2928c4a8e55Smrg *event_base_return = info->codes->first_event; 2938c4a8e55Smrg *error_base_return = info->codes->first_error; 294b042e37fSmrg return True; 295b042e37fSmrg } else { 296b042e37fSmrg return False; 297b042e37fSmrg } 298b042e37fSmrg} 299b042e37fSmrg 3008c4a8e55Smrg_X_HIDDEN Bool 301b042e37fSmrg_XRRHasRates (int major, int minor) 302b042e37fSmrg{ 303b042e37fSmrg return major > 1 || (major == 1 && minor >= 1); 304b042e37fSmrg} 305b042e37fSmrg 306b042e37fSmrgStatus XRRQueryVersion (Display *dpy, 307b042e37fSmrg int *major_versionp, 308b042e37fSmrg int *minor_versionp) 309b042e37fSmrg{ 310b042e37fSmrg XExtDisplayInfo *info = XRRFindDisplay (dpy); 311b042e37fSmrg xRRQueryVersionReply rep; 312b042e37fSmrg xRRQueryVersionReq *req; 313b042e37fSmrg XRandRInfo *xrri; 314b042e37fSmrg 315b042e37fSmrg RRCheckExtension (dpy, info, 0); 316b042e37fSmrg 317b042e37fSmrg xrri = (XRandRInfo *) info->data; 318b042e37fSmrg 319b042e37fSmrg /* 320b042e37fSmrg * only get the version information from the server if we don't have it already 321b042e37fSmrg */ 322b042e37fSmrg if (xrri->major_version == -1) { 323b042e37fSmrg LockDisplay (dpy); 324b042e37fSmrg GetReq (RRQueryVersion, req); 325b042e37fSmrg req->reqType = info->codes->major_opcode; 326b042e37fSmrg req->randrReqType = X_RRQueryVersion; 327b042e37fSmrg req->majorVersion = RANDR_MAJOR; 328b042e37fSmrg req->minorVersion = RANDR_MINOR; 329b042e37fSmrg if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 330b042e37fSmrg UnlockDisplay (dpy); 331b042e37fSmrg SyncHandle (); 332b042e37fSmrg return 0; 333b042e37fSmrg } 334b042e37fSmrg xrri->major_version = rep.majorVersion; 335b042e37fSmrg xrri->minor_version = rep.minorVersion; 336b042e37fSmrg xrri->has_rates = _XRRHasRates (xrri->major_version, xrri->minor_version); 337b042e37fSmrg UnlockDisplay (dpy); 338b042e37fSmrg SyncHandle (); 339b042e37fSmrg } 340b042e37fSmrg *major_versionp = xrri->major_version; 341b042e37fSmrg *minor_versionp = xrri->minor_version; 342b042e37fSmrg return 1; 343b042e37fSmrg} 344b042e37fSmrg 3458c4a8e55Smrg_X_HIDDEN Bool 346b042e37fSmrg_XRRVersionHandler (Display *dpy, 347b042e37fSmrg xReply *rep, 348b042e37fSmrg char *buf, 349b042e37fSmrg int len, 350b042e37fSmrg XPointer data) 351b042e37fSmrg{ 352b042e37fSmrg xRRQueryVersionReply replbuf; 353b042e37fSmrg xRRQueryVersionReply *repl; 354b042e37fSmrg _XRRVersionState *state = (_XRRVersionState *) data; 355b042e37fSmrg 356b042e37fSmrg if (dpy->last_request_read != state->version_seq) 357b042e37fSmrg return False; 358b042e37fSmrg if (rep->generic.type == X_Error) 359b042e37fSmrg { 360b042e37fSmrg state->error = True; 361b042e37fSmrg return False; 362b042e37fSmrg } 363b042e37fSmrg repl = (xRRQueryVersionReply *) 364b042e37fSmrg _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, 365b042e37fSmrg (SIZEOF(xRRQueryVersionReply) - SIZEOF(xReply)) >> 2, 366b042e37fSmrg True); 367b042e37fSmrg state->major_version = repl->majorVersion; 368b042e37fSmrg state->minor_version = repl->minorVersion; 369b042e37fSmrg return True; 370b042e37fSmrg} 371b042e37fSmrg 372b042e37fSmrg/* 373b042e37fSmrg * in protocol version 0.1, routine added to allow selecting for new events. 374b042e37fSmrg */ 375b042e37fSmrg 376b042e37fSmrgvoid XRRSelectInput (Display *dpy, Window window, int mask) 377b042e37fSmrg{ 378b042e37fSmrg XExtDisplayInfo *info = XRRFindDisplay (dpy); 379b042e37fSmrg xRRSelectInputReq *req; 380b042e37fSmrg 381b042e37fSmrg RRSimpleCheckExtension (dpy, info); 382b042e37fSmrg 383b042e37fSmrg LockDisplay (dpy); 384b042e37fSmrg GetReq (RRSelectInput, req); 385b042e37fSmrg req->reqType = info->codes->major_opcode; 386b042e37fSmrg req->randrReqType = X_RRSelectInput; 387b042e37fSmrg req->window = window; 388b042e37fSmrg req->enable = 0; 389b042e37fSmrg if (mask) req->enable = mask; 390b042e37fSmrg UnlockDisplay (dpy); 391b042e37fSmrg SyncHandle (); 392b042e37fSmrg return; 393b042e37fSmrg} 394b042e37fSmrg 395b042e37fSmrgint XRRUpdateConfiguration(XEvent *event) 396b042e37fSmrg{ 397b042e37fSmrg XRRScreenChangeNotifyEvent *scevent; 398b042e37fSmrg XConfigureEvent *rcevent; 399b042e37fSmrg Display *dpy = event->xany.display; 400b042e37fSmrg XExtDisplayInfo *info; 401b042e37fSmrg XRandRInfo *xrri; 402b042e37fSmrg int snum; 403b042e37fSmrg 404b042e37fSmrg /* first, see if it is a vanilla configure notify event */ 405b042e37fSmrg if (event->type == ConfigureNotify) { 406b042e37fSmrg rcevent = (XConfigureEvent *) event; 407b042e37fSmrg snum = XRRRootToScreen(dpy, rcevent->window); 4088c4a8e55Smrg if (snum != -1) { 4098c4a8e55Smrg dpy->screens[snum].width = rcevent->width; 4108c4a8e55Smrg dpy->screens[snum].height = rcevent->height; 4118c4a8e55Smrg return 1; 4128c4a8e55Smrg } 413b042e37fSmrg } 414b042e37fSmrg 415b042e37fSmrg info = XRRFindDisplay(dpy); 416b042e37fSmrg RRCheckExtension (dpy, info, 0); 417b042e37fSmrg 418b042e37fSmrg switch (event->type - info->codes->first_event) { 419b042e37fSmrg case RRScreenChangeNotify: 420b042e37fSmrg scevent = (XRRScreenChangeNotifyEvent *) event; 421b042e37fSmrg snum = XRRRootToScreen(dpy, 422b042e37fSmrg ((XRRScreenChangeNotifyEvent *) event)->root); 423b042e37fSmrg if (scevent->rotation & (RR_Rotate_90 | RR_Rotate_270)) { 424b042e37fSmrg dpy->screens[snum].width = scevent->height; 425b042e37fSmrg dpy->screens[snum].height = scevent->width; 426b042e37fSmrg dpy->screens[snum].mwidth = scevent->mheight; 427b042e37fSmrg dpy->screens[snum].mheight = scevent->mwidth; 428b042e37fSmrg } else { 429b042e37fSmrg dpy->screens[snum].width = scevent->width; 430b042e37fSmrg dpy->screens[snum].height = scevent->height; 431b042e37fSmrg dpy->screens[snum].mwidth = scevent->mwidth; 432b042e37fSmrg dpy->screens[snum].mheight = scevent->mheight; 433b042e37fSmrg } 434b042e37fSmrg XRenderSetSubpixelOrder (dpy, snum, scevent->subpixel_order); 435b042e37fSmrg break; 436b042e37fSmrg default: 437b042e37fSmrg return 0; 438b042e37fSmrg } 439b042e37fSmrg xrri = (XRandRInfo *) info->data; 440b042e37fSmrg /* 441b042e37fSmrg * so the next time someone wants some data, it will be fetched; 442b042e37fSmrg * it might be better to force the round trip immediately, but 443b042e37fSmrg * I dislike pounding the server simultaneously when not necessary 444b042e37fSmrg */ 445b042e37fSmrg if (xrri->config[snum] != NULL) { 446b042e37fSmrg XFree (xrri->config[snum]); 447b042e37fSmrg xrri->config[snum] = NULL; 448b042e37fSmrg } 449b042e37fSmrg return 1; 450b042e37fSmrg} 451