XF86VMode.c revision d9dcd5ae
1191cded7Smrg/* 2191cded7Smrg 3191cded7SmrgCopyright (c) 1995 Kaleb S. KEITHLEY 4191cded7Smrg 5191cded7SmrgPermission is hereby granted, free of charge, to any person obtaining 6191cded7Smrga copy of this software and associated documentation files (the 7191cded7Smrg"Software"), to deal in the Software without restriction, including 8191cded7Smrgwithout limitation the rights to use, copy, modify, merge, publish, 9191cded7Smrgdistribute, sublicense, and/or sell copies of the Software, and to 10191cded7Smrgpermit persons to whom the Software is furnished to do so, subject to 11191cded7Smrgthe following conditions: 12191cded7Smrg 13191cded7SmrgThe above copyright notice and this permission notice shall be 14191cded7Smrgincluded in all copies or substantial portions of the Software. 15191cded7Smrg 16191cded7SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17191cded7SmrgEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18191cded7SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19d9dcd5aeSmrgIN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES 20191cded7SmrgOR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21191cded7SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22191cded7SmrgOTHER DEALINGS IN THE SOFTWARE. 23191cded7Smrg 24d9dcd5aeSmrgExcept as contained in this notice, the name of Kaleb S. KEITHLEY 25d9dcd5aeSmrgshall not be used in advertising or otherwise to promote the sale, use 26191cded7Smrgor other dealings in this Software without prior written authorization 27191cded7Smrgfrom Kaleb S. KEITHLEY. 28191cded7Smrg 29191cded7Smrg*/ 30191cded7Smrg 31191cded7Smrg/* THIS IS NOT AN X CONSORTIUM STANDARD */ 32191cded7Smrg 33d9dcd5aeSmrg#ifdef HAVE_CONFIG_H 34d9dcd5aeSmrg#include <config.h> 35d9dcd5aeSmrg#endif 36d9dcd5aeSmrg 37191cded7Smrg#include <X11/Xlibint.h> 38b290cf36Smrg#include <X11/extensions/xf86vmproto.h> 39b290cf36Smrg#include <X11/extensions/xf86vmode.h> 40191cded7Smrg#include <X11/extensions/Xext.h> 41191cded7Smrg#include <X11/extensions/extutil.h> 42d9dcd5aeSmrg#include <limits.h> 43d9dcd5aeSmrg 44d9dcd5aeSmrg#ifndef HAVE__XEATDATAWORDS 45d9dcd5aeSmrgstatic inline void _XEatDataWords(Display *dpy, unsigned long n) 46d9dcd5aeSmrg{ 47d9dcd5aeSmrg# ifndef LONG64 48d9dcd5aeSmrg if (n >= (ULONG_MAX >> 2)) 49d9dcd5aeSmrg _XIOError(dpy); 50d9dcd5aeSmrg# endif 51d9dcd5aeSmrg _XEatData (dpy, n << 2); 52d9dcd5aeSmrg} 53d9dcd5aeSmrg#endif 54191cded7Smrg 55191cded7Smrg#ifdef DEBUG 56191cded7Smrg#include <stdio.h> 57191cded7Smrg#endif 58191cded7Smrg 59191cded7Smrg#ifndef MODE_BAD 60191cded7Smrg#define MODE_BAD 255 61191cded7Smrg#endif 62191cded7Smrg 63191cded7Smrgstatic XExtensionInfo _xf86vidmode_info_data; 64191cded7Smrgstatic XExtensionInfo *xf86vidmode_info = &_xf86vidmode_info_data; 65d9dcd5aeSmrgstatic const char *xf86vidmode_extension_name = XF86VIDMODENAME; 66191cded7Smrg 67191cded7Smrg#define XF86VidModeCheckExtension(dpy,i,val) \ 68191cded7Smrg XextCheckExtension (dpy, i, xf86vidmode_extension_name, val) 69191cded7Smrg 70191cded7Smrg/***************************************************************************** 71191cded7Smrg * * 72191cded7Smrg * private utility routines * 73191cded7Smrg * * 74191cded7Smrg *****************************************************************************/ 75191cded7Smrg 76191cded7Smrgstatic XEXT_CLOSE_DISPLAY_PROTO(close_display); 77191cded7Smrgstatic /* const */ XExtensionHooks xf86vidmode_extension_hooks = { 78191cded7Smrg NULL, /* create_gc */ 79191cded7Smrg NULL, /* copy_gc */ 80191cded7Smrg NULL, /* flush_gc */ 81191cded7Smrg NULL, /* free_gc */ 82191cded7Smrg NULL, /* create_font */ 83191cded7Smrg NULL, /* free_font */ 84191cded7Smrg close_display, /* close_display */ 85191cded7Smrg NULL, /* wire_to_event */ 86191cded7Smrg NULL, /* event_to_wire */ 87191cded7Smrg NULL, /* error */ 88191cded7Smrg NULL, /* error_string */ 89191cded7Smrg}; 90191cded7Smrg 91d9dcd5aeSmrgstatic XEXT_GENERATE_FIND_DISPLAY (find_display, xf86vidmode_info, 92d9dcd5aeSmrg xf86vidmode_extension_name, 93d9dcd5aeSmrg &xf86vidmode_extension_hooks, 94191cded7Smrg 0, NULL) 95191cded7Smrg 96191cded7Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86vidmode_info) 97191cded7Smrg 98191cded7Smrg 99191cded7Smrg/***************************************************************************** 100191cded7Smrg * * 101191cded7Smrg * public XFree86-VidMode Extension routines * 102191cded7Smrg * * 103191cded7Smrg *****************************************************************************/ 104191cded7Smrg 105191cded7SmrgBool 106b290cf36SmrgXF86VidModeQueryExtension(Display *dpy, int *event_basep, int *error_basep) 107191cded7Smrg{ 108191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 109191cded7Smrg 110191cded7Smrg if (XextHasExtension(info)) { 111191cded7Smrg *event_basep = info->codes->first_event; 112191cded7Smrg *error_basep = info->codes->first_error; 113191cded7Smrg return True; 114191cded7Smrg } else { 115191cded7Smrg return False; 116191cded7Smrg } 117191cded7Smrg} 118191cded7Smrg 119191cded7SmrgBool 120b290cf36SmrgXF86VidModeQueryVersion(Display* dpy, int* majorVersion, int* minorVersion) 121191cded7Smrg{ 122191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 123191cded7Smrg xXF86VidModeQueryVersionReply rep; 124191cded7Smrg xXF86VidModeQueryVersionReq *req; 125191cded7Smrg 126191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 127191cded7Smrg 128191cded7Smrg LockDisplay(dpy); 129191cded7Smrg GetReq(XF86VidModeQueryVersion, req); 130191cded7Smrg req->reqType = info->codes->major_opcode; 131191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeQueryVersion; 132191cded7Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 133191cded7Smrg UnlockDisplay(dpy); 134191cded7Smrg SyncHandle(); 135191cded7Smrg return False; 136191cded7Smrg } 137191cded7Smrg *majorVersion = rep.majorVersion; 138191cded7Smrg *minorVersion = rep.minorVersion; 139191cded7Smrg UnlockDisplay(dpy); 140191cded7Smrg SyncHandle(); 141191cded7Smrg if (*majorVersion >= 2) 142191cded7Smrg XF86VidModeSetClientVersion(dpy); 143191cded7Smrg return True; 144191cded7Smrg} 145191cded7Smrg 146191cded7SmrgBool 147191cded7SmrgXF86VidModeSetClientVersion(Display *dpy) 148191cded7Smrg{ 149191cded7Smrg XExtDisplayInfo *info = find_display(dpy); 150191cded7Smrg xXF86VidModeSetClientVersionReq *req; 151191cded7Smrg 152191cded7Smrg XF86VidModeCheckExtension(dpy, info, False); 153191cded7Smrg 154191cded7Smrg LockDisplay(dpy); 155191cded7Smrg GetReq(XF86VidModeSetClientVersion, req); 156191cded7Smrg req->reqType = info->codes->major_opcode; 157191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeSetClientVersion; 158191cded7Smrg req->major = XF86VIDMODE_MAJOR_VERSION; 159191cded7Smrg req->minor = XF86VIDMODE_MINOR_VERSION; 160191cded7Smrg UnlockDisplay(dpy); 161191cded7Smrg SyncHandle(); 162191cded7Smrg return True; 163191cded7Smrg} 164191cded7Smrg 165191cded7SmrgBool 166191cded7SmrgXF86VidModeSetGamma(Display *dpy, int screen, XF86VidModeGamma *Gamma) 167191cded7Smrg{ 168191cded7Smrg XExtDisplayInfo *info = find_display(dpy); 169191cded7Smrg xXF86VidModeSetGammaReq *req; 170191cded7Smrg 171191cded7Smrg XF86VidModeCheckExtension(dpy, info, False); 172191cded7Smrg 173191cded7Smrg LockDisplay(dpy); 174191cded7Smrg GetReq(XF86VidModeSetGamma, req); 175191cded7Smrg req->reqType = info->codes->major_opcode; 176191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeSetGamma; 177191cded7Smrg req->screen = screen; 178191cded7Smrg req->red = (CARD32)(Gamma->red * 10000.); 179191cded7Smrg req->green = (CARD32)(Gamma->green * 10000.); 180191cded7Smrg req->blue = (CARD32)(Gamma->blue * 10000.); 181191cded7Smrg UnlockDisplay(dpy); 182191cded7Smrg SyncHandle(); 183191cded7Smrg return True; 184191cded7Smrg} 185191cded7Smrg 186191cded7SmrgBool 187191cded7SmrgXF86VidModeGetGamma(Display *dpy, int screen, XF86VidModeGamma *Gamma) 188191cded7Smrg{ 189191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 190191cded7Smrg xXF86VidModeGetGammaReply rep; 191191cded7Smrg xXF86VidModeGetGammaReq *req; 192191cded7Smrg 193191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 194191cded7Smrg 195191cded7Smrg LockDisplay(dpy); 196191cded7Smrg GetReq(XF86VidModeGetGamma, req); 197191cded7Smrg req->reqType = info->codes->major_opcode; 198191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetGamma; 199191cded7Smrg req->screen = screen; 200191cded7Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 201191cded7Smrg UnlockDisplay(dpy); 202191cded7Smrg SyncHandle(); 203191cded7Smrg return False; 204191cded7Smrg } 205191cded7Smrg Gamma->red = ((float)rep.red) / 10000.; 206191cded7Smrg Gamma->green = ((float)rep.green) / 10000.; 207191cded7Smrg Gamma->blue = ((float)rep.blue) / 10000.; 208191cded7Smrg UnlockDisplay(dpy); 209191cded7Smrg SyncHandle(); 210191cded7Smrg return True; 211191cded7Smrg} 212191cded7Smrg 213191cded7SmrgBool 214b290cf36SmrgXF86VidModeGetModeLine(Display* dpy, int screen, int* dotclock, 215b290cf36Smrg XF86VidModeModeLine* modeline) 216191cded7Smrg{ 217191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 218191cded7Smrg xXF86VidModeGetModeLineReply rep; 219191cded7Smrg xXF86OldVidModeGetModeLineReply oldrep; 220191cded7Smrg xXF86VidModeGetModeLineReq *req; 221191cded7Smrg int majorVersion, minorVersion; 222d9dcd5aeSmrg Bool result = True; 223191cded7Smrg 224191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 225191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 226191cded7Smrg 227191cded7Smrg LockDisplay(dpy); 228191cded7Smrg GetReq(XF86VidModeGetModeLine, req); 229191cded7Smrg req->reqType = info->codes->major_opcode; 230191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetModeLine; 231191cded7Smrg req->screen = screen; 232d9dcd5aeSmrg 233191cded7Smrg if (majorVersion < 2) { 234d9dcd5aeSmrg if (!_XReply(dpy, (xReply *)&oldrep, 235191cded7Smrg (SIZEOF(xXF86OldVidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) { 236191cded7Smrg UnlockDisplay(dpy); 237191cded7Smrg SyncHandle(); 238191cded7Smrg return False; 239191cded7Smrg } 240191cded7Smrg *dotclock = oldrep.dotclock; 241191cded7Smrg modeline->hdisplay = oldrep.hdisplay; 242191cded7Smrg modeline->hsyncstart = oldrep.hsyncstart; 243191cded7Smrg modeline->hsyncend = oldrep.hsyncend; 244191cded7Smrg modeline->htotal = oldrep.htotal; 245191cded7Smrg modeline->hskew = 0; 246191cded7Smrg modeline->vdisplay = oldrep.vdisplay; 247191cded7Smrg modeline->vsyncstart = oldrep.vsyncstart; 248191cded7Smrg modeline->vsyncend = oldrep.vsyncend; 249191cded7Smrg modeline->vtotal = oldrep.vtotal; 250191cded7Smrg modeline->flags = oldrep.flags; 251191cded7Smrg modeline->privsize = oldrep.privsize; 252191cded7Smrg } else { 253d9dcd5aeSmrg if (!_XReply(dpy, (xReply *)&rep, 254191cded7Smrg (SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) { 255191cded7Smrg UnlockDisplay(dpy); 256191cded7Smrg SyncHandle(); 257191cded7Smrg return False; 258191cded7Smrg } 259191cded7Smrg *dotclock = rep.dotclock; 260191cded7Smrg modeline->hdisplay = rep.hdisplay; 261191cded7Smrg modeline->hsyncstart = rep.hsyncstart; 262191cded7Smrg modeline->hsyncend = rep.hsyncend; 263191cded7Smrg modeline->htotal = rep.htotal; 264191cded7Smrg modeline->hskew = rep.hskew; 265191cded7Smrg modeline->vdisplay = rep.vdisplay; 266191cded7Smrg modeline->vsyncstart = rep.vsyncstart; 267191cded7Smrg modeline->vsyncend = rep.vsyncend; 268191cded7Smrg modeline->vtotal = rep.vtotal; 269191cded7Smrg modeline->flags = rep.flags; 270191cded7Smrg modeline->privsize = rep.privsize; 271191cded7Smrg } 272d9dcd5aeSmrg 273191cded7Smrg if (modeline->privsize > 0) { 274d9dcd5aeSmrg if (modeline->privsize < (INT_MAX / sizeof(INT32))) 275d9dcd5aeSmrg modeline->private = Xcalloc(modeline->privsize, sizeof(INT32)); 276d9dcd5aeSmrg else 277d9dcd5aeSmrg modeline->private = NULL; 278d9dcd5aeSmrg if (modeline->private == NULL) { 279d9dcd5aeSmrg _XEatDataWords(dpy, rep.length - 280d9dcd5aeSmrg ((SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xReply)) >> 2)); 281d9dcd5aeSmrg result = False; 282d9dcd5aeSmrg } else 283d9dcd5aeSmrg _XRead(dpy, (char*)modeline->private, modeline->privsize * sizeof(INT32)); 284191cded7Smrg } else { 285191cded7Smrg modeline->private = NULL; 286191cded7Smrg } 287191cded7Smrg UnlockDisplay(dpy); 288191cded7Smrg SyncHandle(); 289d9dcd5aeSmrg return result; 290191cded7Smrg} 291191cded7Smrg 292191cded7SmrgBool 293b290cf36SmrgXF86VidModeGetAllModeLines(Display* dpy, int screen, int* modecount, 294b290cf36Smrg XF86VidModeModeInfo ***modelinesPtr) 295191cded7Smrg{ 296191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 297191cded7Smrg xXF86VidModeGetAllModeLinesReply rep; 298191cded7Smrg xXF86VidModeGetAllModeLinesReq *req; 299191cded7Smrg XF86VidModeModeInfo *mdinfptr, **modelines; 300191cded7Smrg xXF86VidModeModeInfo xmdline; 301191cded7Smrg xXF86OldVidModeModeInfo oldxmdline; 302191cded7Smrg int i; 303191cded7Smrg int majorVersion, minorVersion; 304191cded7Smrg Bool protocolBug = False; 305191cded7Smrg 306191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 307191cded7Smrg 308191cded7Smrg /* 309191cded7Smrg * Note: There was a bug in the protocol implementation in versions 310191cded7Smrg * 0.x with x < 8 (the .private field wasn't being passed over the wire). 311191cded7Smrg * Check the server's version, and accept the old format if appropriate. 312191cded7Smrg */ 313191cded7Smrg 314191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 315191cded7Smrg if (majorVersion == 0 && minorVersion < 8) { 316191cded7Smrg protocolBug = True; 317191cded7Smrg#ifdef DEBUG 318191cded7Smrg fprintf(stderr, "XF86VidModeGetAllModeLines: Warning: Xserver is" 319191cded7Smrg "running an old version (%d.%d)\n", majorVersion, 320191cded7Smrg minorVersion); 321191cded7Smrg#endif 322191cded7Smrg } 323d9dcd5aeSmrg 324191cded7Smrg LockDisplay(dpy); 325191cded7Smrg GetReq(XF86VidModeGetAllModeLines, req); 326191cded7Smrg req->reqType = info->codes->major_opcode; 327191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetAllModeLines; 328191cded7Smrg req->screen = screen; 329d9dcd5aeSmrg if (!_XReply(dpy, (xReply *)&rep, 330191cded7Smrg (SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xReply)) >> 2, xFalse)) { 331191cded7Smrg UnlockDisplay(dpy); 332191cded7Smrg SyncHandle(); 333191cded7Smrg return False; 334191cded7Smrg } 335191cded7Smrg 336191cded7Smrg *modecount = rep.modecount; 337191cded7Smrg 338191cded7Smrg if (!(modelines = (XF86VidModeModeInfo **) Xcalloc(rep.modecount, 339191cded7Smrg sizeof(XF86VidModeModeInfo *) 340191cded7Smrg +sizeof(XF86VidModeModeInfo)))) { 341d9dcd5aeSmrg _XEatDataWords(dpy, rep.length - 342d9dcd5aeSmrg ((SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xReply)) >> 2)); 343d9dcd5aeSmrg UnlockDisplay(dpy); 344d9dcd5aeSmrg SyncHandle(); 345191cded7Smrg return False; 346191cded7Smrg } 347191cded7Smrg mdinfptr = (XF86VidModeModeInfo *) ( 348191cded7Smrg (char *) modelines 349191cded7Smrg + rep.modecount*sizeof(XF86VidModeModeInfo *) 350191cded7Smrg ); 351191cded7Smrg 352191cded7Smrg for (i = 0; i < rep.modecount; i++) { 353191cded7Smrg modelines[i] = mdinfptr++; 354191cded7Smrg if (majorVersion < 2) { 355191cded7Smrg _XRead(dpy, (char*)&oldxmdline, sizeof(xXF86OldVidModeModeInfo)); 356191cded7Smrg modelines[i]->dotclock = oldxmdline.dotclock; 357191cded7Smrg modelines[i]->hdisplay = oldxmdline.hdisplay; 358191cded7Smrg modelines[i]->hsyncstart = oldxmdline.hsyncstart; 359191cded7Smrg modelines[i]->hsyncend = oldxmdline.hsyncend; 360191cded7Smrg modelines[i]->htotal = oldxmdline.htotal; 361191cded7Smrg modelines[i]->hskew = 0; 362191cded7Smrg modelines[i]->vdisplay = oldxmdline.vdisplay; 363191cded7Smrg modelines[i]->vsyncstart = oldxmdline.vsyncstart; 364191cded7Smrg modelines[i]->vsyncend = oldxmdline.vsyncend; 365191cded7Smrg modelines[i]->vtotal = oldxmdline.vtotal; 366191cded7Smrg modelines[i]->flags = oldxmdline.flags; 367191cded7Smrg if (protocolBug) { 368191cded7Smrg modelines[i]->privsize = 0; 369191cded7Smrg modelines[i]->private = NULL; 370191cded7Smrg } else { 371191cded7Smrg modelines[i]->privsize = oldxmdline.privsize; 372191cded7Smrg if (oldxmdline.privsize > 0) { 373191cded7Smrg if (!(modelines[i]->private = 374191cded7Smrg Xcalloc(oldxmdline.privsize, sizeof(INT32)))) { 375d9dcd5aeSmrg _XEatDataWords(dpy, oldxmdline.privsize); 376191cded7Smrg } else { 377191cded7Smrg _XRead(dpy, (char*)modelines[i]->private, 378191cded7Smrg oldxmdline.privsize * sizeof(INT32)); 379191cded7Smrg } 380191cded7Smrg } else { 381191cded7Smrg modelines[i]->private = NULL; 382191cded7Smrg } 383191cded7Smrg } 384191cded7Smrg } else { 385191cded7Smrg _XRead(dpy, (char*)&xmdline, sizeof(xXF86VidModeModeInfo)); 386191cded7Smrg modelines[i]->dotclock = xmdline.dotclock; 387191cded7Smrg modelines[i]->hdisplay = xmdline.hdisplay; 388191cded7Smrg modelines[i]->hsyncstart = xmdline.hsyncstart; 389191cded7Smrg modelines[i]->hsyncend = xmdline.hsyncend; 390191cded7Smrg modelines[i]->htotal = xmdline.htotal; 391191cded7Smrg modelines[i]->hskew = xmdline.hskew; 392191cded7Smrg modelines[i]->vdisplay = xmdline.vdisplay; 393191cded7Smrg modelines[i]->vsyncstart = xmdline.vsyncstart; 394191cded7Smrg modelines[i]->vsyncend = xmdline.vsyncend; 395191cded7Smrg modelines[i]->vtotal = xmdline.vtotal; 396191cded7Smrg modelines[i]->flags = xmdline.flags; 397191cded7Smrg if (protocolBug) { 398191cded7Smrg modelines[i]->privsize = 0; 399191cded7Smrg modelines[i]->private = NULL; 400191cded7Smrg } else { 401191cded7Smrg modelines[i]->privsize = xmdline.privsize; 402191cded7Smrg if (xmdline.privsize > 0) { 403191cded7Smrg if (!(modelines[i]->private = 404191cded7Smrg Xcalloc(xmdline.privsize, sizeof(INT32)))) { 405d9dcd5aeSmrg _XEatDataWords(dpy, xmdline.privsize); 406191cded7Smrg } else { 407191cded7Smrg _XRead(dpy, (char*)modelines[i]->private, 408191cded7Smrg xmdline.privsize * sizeof(INT32)); 409191cded7Smrg } 410191cded7Smrg } else { 411191cded7Smrg modelines[i]->private = NULL; 412191cded7Smrg } 413191cded7Smrg } 414191cded7Smrg } 415191cded7Smrg } 416191cded7Smrg *modelinesPtr = modelines; 417191cded7Smrg UnlockDisplay(dpy); 418191cded7Smrg SyncHandle(); 419191cded7Smrg return True; 420191cded7Smrg} 421191cded7Smrg 422191cded7Smrg/* 423191cded7Smrg * GetReq replacement for use with VidMode protocols earlier than 2.0 424191cded7Smrg */ 425191cded7Smrg#if !defined(UNIXCPP) || defined(ANSICPP) 426191cded7Smrg#define GetOldReq(name, oldname, req) \ 427191cded7Smrg WORD64ALIGN\ 428191cded7Smrg if ((dpy->bufptr + SIZEOF(x##oldname##Req)) > dpy->bufmax)\ 429191cded7Smrg _XFlush(dpy);\ 430191cded7Smrg req = (x##oldname##Req *)(dpy->last_req = dpy->bufptr);\ 431191cded7Smrg req->reqType = X_##name;\ 432191cded7Smrg req->length = (SIZEOF(x##oldname##Req))>>2;\ 433191cded7Smrg dpy->bufptr += SIZEOF(x##oldname##Req);\ 434191cded7Smrg dpy->request++ 435191cded7Smrg 436191cded7Smrg#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ 437191cded7Smrg#define GetOldReq(name, oldname, req) \ 438191cded7Smrg WORD64ALIGN\ 439191cded7Smrg if ((dpy->bufptr + SIZEOF(x/**/oldname/**/Req)) > dpy->bufmax)\ 440191cded7Smrg _XFlush(dpy);\ 441191cded7Smrg req = (x/**/oldname/**/Req *)(dpy->last_req = dpy->bufptr);\ 442191cded7Smrg req->reqType = X_/**/name;\ 443191cded7Smrg req->length = (SIZEOF(x/**/oldname/**/Req))>>2;\ 444191cded7Smrg dpy->bufptr += SIZEOF(x/**/oldname/**/Req);\ 445191cded7Smrg dpy->request++ 446191cded7Smrg#endif 447191cded7Smrg 448191cded7SmrgBool 449b290cf36SmrgXF86VidModeAddModeLine(Display *dpy, int screen, 450b290cf36Smrg XF86VidModeModeInfo* newmodeline, 451b290cf36Smrg XF86VidModeModeInfo* aftermodeline) 452191cded7Smrg{ 453191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 454191cded7Smrg xXF86VidModeAddModeLineReq *req; 455191cded7Smrg xXF86OldVidModeAddModeLineReq *oldreq; 456191cded7Smrg int majorVersion, minorVersion; 457191cded7Smrg 458191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 459191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 460191cded7Smrg 461191cded7Smrg LockDisplay(dpy); 462191cded7Smrg if (majorVersion < 2) { 463191cded7Smrg GetOldReq(XF86VidModeAddModeLine, XF86OldVidModeAddModeLine, oldreq); 464191cded7Smrg oldreq->reqType = info->codes->major_opcode; 465191cded7Smrg oldreq->xf86vidmodeReqType = X_XF86VidModeAddModeLine; 466191cded7Smrg oldreq->screen = screen; 467191cded7Smrg oldreq->dotclock = newmodeline->dotclock; 468191cded7Smrg oldreq->hdisplay = newmodeline->hdisplay; 469191cded7Smrg oldreq->hsyncstart = newmodeline->hsyncstart; 470191cded7Smrg oldreq->hsyncend = newmodeline->hsyncend; 471191cded7Smrg oldreq->htotal = newmodeline->htotal; 472191cded7Smrg oldreq->vdisplay = newmodeline->vdisplay; 473191cded7Smrg oldreq->vsyncstart = newmodeline->vsyncstart; 474191cded7Smrg oldreq->vsyncend = newmodeline->vsyncend; 475191cded7Smrg oldreq->vtotal = newmodeline->vtotal; 476191cded7Smrg oldreq->flags = newmodeline->flags; 477191cded7Smrg oldreq->privsize = newmodeline->privsize; 478191cded7Smrg if (aftermodeline != NULL) { 479191cded7Smrg oldreq->after_dotclock = aftermodeline->dotclock; 480191cded7Smrg oldreq->after_hdisplay = aftermodeline->hdisplay; 481191cded7Smrg oldreq->after_hsyncstart = aftermodeline->hsyncstart; 482191cded7Smrg oldreq->after_hsyncend = aftermodeline->hsyncend; 483191cded7Smrg oldreq->after_htotal = aftermodeline->htotal; 484191cded7Smrg oldreq->after_vdisplay = aftermodeline->vdisplay; 485191cded7Smrg oldreq->after_vsyncstart = aftermodeline->vsyncstart; 486191cded7Smrg oldreq->after_vsyncend = aftermodeline->vsyncend; 487191cded7Smrg oldreq->after_vtotal = aftermodeline->vtotal; 488191cded7Smrg oldreq->after_flags = aftermodeline->flags; 489191cded7Smrg } else { 490191cded7Smrg oldreq->after_dotclock = 0; 491191cded7Smrg oldreq->after_hdisplay = 0; 492191cded7Smrg oldreq->after_hsyncstart = 0; 493191cded7Smrg oldreq->after_hsyncend = 0; 494191cded7Smrg oldreq->after_htotal = 0; 495191cded7Smrg oldreq->after_vdisplay = 0; 496191cded7Smrg oldreq->after_vsyncstart = 0; 497191cded7Smrg oldreq->after_vsyncend = 0; 498191cded7Smrg oldreq->after_vtotal = 0; 499191cded7Smrg oldreq->after_flags = 0; 500191cded7Smrg } 501191cded7Smrg if (newmodeline->privsize) { 502191cded7Smrg oldreq->length += newmodeline->privsize; 503191cded7Smrg Data32(dpy, (long *) newmodeline->private, 504191cded7Smrg newmodeline->privsize * sizeof(INT32)); 505191cded7Smrg } 506191cded7Smrg } else { 507191cded7Smrg GetReq(XF86VidModeAddModeLine, req); 508191cded7Smrg req->reqType = info->codes->major_opcode; 509191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeAddModeLine; 510191cded7Smrg req->screen = screen; 511191cded7Smrg req->dotclock = newmodeline->dotclock; 512191cded7Smrg req->hdisplay = newmodeline->hdisplay; 513191cded7Smrg req->hsyncstart = newmodeline->hsyncstart; 514191cded7Smrg req->hsyncend = newmodeline->hsyncend; 515191cded7Smrg req->htotal = newmodeline->htotal; 516191cded7Smrg req->hskew = newmodeline->hskew; 517191cded7Smrg req->vdisplay = newmodeline->vdisplay; 518191cded7Smrg req->vsyncstart = newmodeline->vsyncstart; 519191cded7Smrg req->vsyncend = newmodeline->vsyncend; 520191cded7Smrg req->vtotal = newmodeline->vtotal; 521191cded7Smrg req->flags = newmodeline->flags; 522191cded7Smrg req->privsize = newmodeline->privsize; 523191cded7Smrg if (aftermodeline != NULL) { 524191cded7Smrg req->after_dotclock = aftermodeline->dotclock; 525191cded7Smrg req->after_hdisplay = aftermodeline->hdisplay; 526191cded7Smrg req->after_hsyncstart = aftermodeline->hsyncstart; 527191cded7Smrg req->after_hsyncend = aftermodeline->hsyncend; 528191cded7Smrg req->after_htotal = aftermodeline->htotal; 529191cded7Smrg req->after_hskew = aftermodeline->hskew; 530191cded7Smrg req->after_vdisplay = aftermodeline->vdisplay; 531191cded7Smrg req->after_vsyncstart = aftermodeline->vsyncstart; 532191cded7Smrg req->after_vsyncend = aftermodeline->vsyncend; 533191cded7Smrg req->after_vtotal = aftermodeline->vtotal; 534191cded7Smrg req->after_flags = aftermodeline->flags; 535191cded7Smrg } else { 536191cded7Smrg req->after_dotclock = 0; 537191cded7Smrg req->after_hdisplay = 0; 538191cded7Smrg req->after_hsyncstart = 0; 539191cded7Smrg req->after_hsyncend = 0; 540191cded7Smrg req->after_htotal = 0; 541191cded7Smrg req->after_hskew = 0; 542191cded7Smrg req->after_vdisplay = 0; 543191cded7Smrg req->after_vsyncstart = 0; 544191cded7Smrg req->after_vsyncend = 0; 545191cded7Smrg req->after_vtotal = 0; 546191cded7Smrg req->after_flags = 0; 547191cded7Smrg } 548191cded7Smrg if (newmodeline->privsize) { 549191cded7Smrg req->length += newmodeline->privsize; 550191cded7Smrg Data32(dpy, (long *) newmodeline->private, 551191cded7Smrg newmodeline->privsize * sizeof(INT32)); 552191cded7Smrg } 553191cded7Smrg } 554191cded7Smrg UnlockDisplay(dpy); 555191cded7Smrg SyncHandle(); 556191cded7Smrg return True; 557191cded7Smrg} 558191cded7Smrg 559191cded7SmrgBool 560b290cf36SmrgXF86VidModeDeleteModeLine(Display *dpy, int screen, 561b290cf36Smrg XF86VidModeModeInfo* modeline) 562191cded7Smrg{ 563191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 564191cded7Smrg xXF86VidModeDeleteModeLineReq *req; 565191cded7Smrg xXF86OldVidModeDeleteModeLineReq *oldreq; 566191cded7Smrg int majorVersion, minorVersion; 567191cded7Smrg 568191cded7Smrg XF86VidModeCheckExtension (dpy, info, 0); 569191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 570191cded7Smrg 571191cded7Smrg LockDisplay(dpy); 572191cded7Smrg if (majorVersion < 2) { 573191cded7Smrg GetOldReq(XF86VidModeDeleteModeLine, XF86OldVidModeDeleteModeLine, oldreq); 574191cded7Smrg oldreq->reqType = info->codes->major_opcode; 575191cded7Smrg oldreq->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine; 576191cded7Smrg oldreq->screen = screen; 577191cded7Smrg oldreq->dotclock = modeline->dotclock; 578191cded7Smrg oldreq->hdisplay = modeline->hdisplay; 579191cded7Smrg oldreq->hsyncstart = modeline->hsyncstart; 580191cded7Smrg oldreq->hsyncend = modeline->hsyncend; 581191cded7Smrg oldreq->htotal = modeline->htotal; 582191cded7Smrg oldreq->vdisplay = modeline->vdisplay; 583191cded7Smrg oldreq->vsyncstart = modeline->vsyncstart; 584191cded7Smrg oldreq->vsyncend = modeline->vsyncend; 585191cded7Smrg oldreq->vtotal = modeline->vtotal; 586191cded7Smrg oldreq->flags = modeline->flags; 587191cded7Smrg oldreq->privsize = modeline->privsize; 588191cded7Smrg if (modeline->privsize) { 589191cded7Smrg oldreq->length += modeline->privsize; 590191cded7Smrg Data32(dpy, (long *) modeline->private, 591191cded7Smrg modeline->privsize * sizeof(INT32)); 592191cded7Smrg } 593191cded7Smrg } else { 594191cded7Smrg GetReq(XF86VidModeDeleteModeLine, req); 595191cded7Smrg req->reqType = info->codes->major_opcode; 596191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine; 597191cded7Smrg req->screen = screen; 598191cded7Smrg req->dotclock = modeline->dotclock; 599191cded7Smrg req->hdisplay = modeline->hdisplay; 600191cded7Smrg req->hsyncstart = modeline->hsyncstart; 601191cded7Smrg req->hsyncend = modeline->hsyncend; 602191cded7Smrg req->htotal = modeline->htotal; 603191cded7Smrg req->hskew = modeline->hskew; 604191cded7Smrg req->vdisplay = modeline->vdisplay; 605191cded7Smrg req->vsyncstart = modeline->vsyncstart; 606191cded7Smrg req->vsyncend = modeline->vsyncend; 607191cded7Smrg req->vtotal = modeline->vtotal; 608191cded7Smrg req->flags = modeline->flags; 609191cded7Smrg req->privsize = modeline->privsize; 610191cded7Smrg if (modeline->privsize) { 611191cded7Smrg req->length += modeline->privsize; 612191cded7Smrg Data32(dpy, (long *) modeline->private, 613191cded7Smrg modeline->privsize * sizeof(INT32)); 614191cded7Smrg } 615191cded7Smrg } 616191cded7Smrg UnlockDisplay(dpy); 617191cded7Smrg SyncHandle(); 618191cded7Smrg return True; 619191cded7Smrg} 620191cded7Smrg 621191cded7SmrgBool 622b290cf36SmrgXF86VidModeModModeLine(Display *dpy, int screen, XF86VidModeModeLine* modeline) 623191cded7Smrg{ 624191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 625191cded7Smrg xXF86VidModeModModeLineReq *req; 626191cded7Smrg xXF86OldVidModeModModeLineReq *oldreq; 627191cded7Smrg int majorVersion, minorVersion; 628191cded7Smrg 629191cded7Smrg XF86VidModeCheckExtension (dpy, info, 0); 630191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 631191cded7Smrg 632191cded7Smrg LockDisplay(dpy); 633191cded7Smrg if (majorVersion < 2) { 634191cded7Smrg GetOldReq(XF86VidModeModModeLine, XF86OldVidModeModModeLine, oldreq); 635191cded7Smrg oldreq->reqType = info->codes->major_opcode; 636191cded7Smrg oldreq->xf86vidmodeReqType = X_XF86VidModeModModeLine; 637191cded7Smrg oldreq->screen = screen; 638191cded7Smrg oldreq->hdisplay = modeline->hdisplay; 639191cded7Smrg oldreq->hsyncstart = modeline->hsyncstart; 640191cded7Smrg oldreq->hsyncend = modeline->hsyncend; 641191cded7Smrg oldreq->htotal = modeline->htotal; 642191cded7Smrg oldreq->vdisplay = modeline->vdisplay; 643191cded7Smrg oldreq->vsyncstart = modeline->vsyncstart; 644191cded7Smrg oldreq->vsyncend = modeline->vsyncend; 645191cded7Smrg oldreq->vtotal = modeline->vtotal; 646191cded7Smrg oldreq->flags = modeline->flags; 647191cded7Smrg oldreq->privsize = modeline->privsize; 648191cded7Smrg if (modeline->privsize) { 649191cded7Smrg oldreq->length += modeline->privsize; 650191cded7Smrg Data32(dpy, (long *) modeline->private, 651191cded7Smrg modeline->privsize * sizeof(INT32)); 652191cded7Smrg } 653191cded7Smrg } else { 654191cded7Smrg GetReq(XF86VidModeModModeLine, req); 655191cded7Smrg req->reqType = info->codes->major_opcode; 656191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeModModeLine; 657191cded7Smrg req->screen = screen; 658191cded7Smrg req->hdisplay = modeline->hdisplay; 659191cded7Smrg req->hsyncstart = modeline->hsyncstart; 660191cded7Smrg req->hsyncend = modeline->hsyncend; 661191cded7Smrg req->htotal = modeline->htotal; 662191cded7Smrg req->hskew = modeline->hskew; 663191cded7Smrg req->vdisplay = modeline->vdisplay; 664191cded7Smrg req->vsyncstart = modeline->vsyncstart; 665191cded7Smrg req->vsyncend = modeline->vsyncend; 666191cded7Smrg req->vtotal = modeline->vtotal; 667191cded7Smrg req->flags = modeline->flags; 668191cded7Smrg req->privsize = modeline->privsize; 669191cded7Smrg if (modeline->privsize) { 670191cded7Smrg req->length += modeline->privsize; 671191cded7Smrg Data32(dpy, (long *) modeline->private, 672191cded7Smrg modeline->privsize * sizeof(INT32)); 673191cded7Smrg } 674191cded7Smrg } 675191cded7Smrg UnlockDisplay(dpy); 676191cded7Smrg SyncHandle(); 677191cded7Smrg return True; 678191cded7Smrg} 679191cded7Smrg 680191cded7SmrgStatus 681b290cf36SmrgXF86VidModeValidateModeLine(Display *dpy, int screen, 682b290cf36Smrg XF86VidModeModeInfo* modeline) 683191cded7Smrg{ 684191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 685191cded7Smrg xXF86VidModeValidateModeLineReq *req; 686191cded7Smrg xXF86OldVidModeValidateModeLineReq *oldreq; 687191cded7Smrg xXF86VidModeValidateModeLineReply rep; 688191cded7Smrg int majorVersion, minorVersion; 689191cded7Smrg 690191cded7Smrg XF86VidModeCheckExtension (dpy, info, 0); 691191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 692191cded7Smrg 693191cded7Smrg LockDisplay(dpy); 694191cded7Smrg 695191cded7Smrg if (majorVersion < 2) { 696191cded7Smrg GetOldReq(XF86VidModeValidateModeLine, XF86OldVidModeValidateModeLine, oldreq); 697191cded7Smrg oldreq->reqType = info->codes->major_opcode; 698191cded7Smrg oldreq->xf86vidmodeReqType = X_XF86VidModeValidateModeLine; 699191cded7Smrg oldreq->screen = screen; 700191cded7Smrg oldreq->dotclock = modeline->dotclock; 701191cded7Smrg oldreq->hdisplay = modeline->hdisplay; 702191cded7Smrg oldreq->hsyncstart = modeline->hsyncstart; 703191cded7Smrg oldreq->hsyncend = modeline->hsyncend; 704191cded7Smrg oldreq->htotal = modeline->htotal; 705191cded7Smrg oldreq->vdisplay = modeline->vdisplay; 706191cded7Smrg oldreq->vsyncstart = modeline->vsyncstart; 707191cded7Smrg oldreq->vsyncend = modeline->vsyncend; 708191cded7Smrg oldreq->vtotal = modeline->vtotal; 709191cded7Smrg oldreq->flags = modeline->flags; 710191cded7Smrg oldreq->privsize = modeline->privsize; 711191cded7Smrg if (modeline->privsize) { 712191cded7Smrg oldreq->length += modeline->privsize; 713191cded7Smrg Data32(dpy, (long *) modeline->private, 714191cded7Smrg modeline->privsize * sizeof(INT32)); 715191cded7Smrg } 716191cded7Smrg } else { 717191cded7Smrg GetReq(XF86VidModeValidateModeLine, req); 718191cded7Smrg req->reqType = info->codes->major_opcode; 719191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeValidateModeLine; 720191cded7Smrg req->screen = screen; 721191cded7Smrg req->dotclock = modeline->dotclock; 722191cded7Smrg req->hdisplay = modeline->hdisplay; 723191cded7Smrg req->hsyncstart = modeline->hsyncstart; 724191cded7Smrg req->hsyncend = modeline->hsyncend; 725191cded7Smrg req->htotal = modeline->htotal; 726191cded7Smrg req->hskew = modeline->hskew; 727191cded7Smrg req->vdisplay = modeline->vdisplay; 728191cded7Smrg req->vsyncstart = modeline->vsyncstart; 729191cded7Smrg req->vsyncend = modeline->vsyncend; 730191cded7Smrg req->vtotal = modeline->vtotal; 731191cded7Smrg req->flags = modeline->flags; 732191cded7Smrg req->privsize = modeline->privsize; 733191cded7Smrg if (modeline->privsize) { 734191cded7Smrg req->length += modeline->privsize; 735191cded7Smrg Data32(dpy, (long *) modeline->private, 736191cded7Smrg modeline->privsize * sizeof(INT32)); 737191cded7Smrg } 738191cded7Smrg } 739191cded7Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 740191cded7Smrg UnlockDisplay(dpy); 741191cded7Smrg SyncHandle(); 742191cded7Smrg return MODE_BAD; 743191cded7Smrg } 744191cded7Smrg UnlockDisplay(dpy); 745191cded7Smrg SyncHandle(); 746191cded7Smrg return rep.status; 747191cded7Smrg} 748191cded7Smrg 749191cded7SmrgBool 750b290cf36SmrgXF86VidModeSwitchMode(Display* dpy, int screen, int zoom) 751191cded7Smrg{ 752191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 753191cded7Smrg xXF86VidModeSwitchModeReq *req; 754191cded7Smrg 755191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 756191cded7Smrg 757191cded7Smrg LockDisplay(dpy); 758191cded7Smrg GetReq(XF86VidModeSwitchMode, req); 759191cded7Smrg req->reqType = info->codes->major_opcode; 760191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeSwitchMode; 761191cded7Smrg req->screen = screen; 762191cded7Smrg req->zoom = zoom; 763191cded7Smrg UnlockDisplay(dpy); 764191cded7Smrg SyncHandle(); 765191cded7Smrg return True; 766191cded7Smrg} 767d9dcd5aeSmrg 768191cded7SmrgBool 769b290cf36SmrgXF86VidModeSwitchToMode(Display* dpy, int screen, XF86VidModeModeInfo* modeline) 770191cded7Smrg{ 771191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 772191cded7Smrg xXF86VidModeSwitchToModeReq *req; 773191cded7Smrg xXF86OldVidModeSwitchToModeReq *oldreq; 774191cded7Smrg int majorVersion, minorVersion; 775191cded7Smrg Bool protocolBug = False; 776191cded7Smrg 777191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 778191cded7Smrg 779191cded7Smrg /* 780191cded7Smrg * Note: There was a bug in the protocol implementation in versions 781191cded7Smrg * 0.x with x < 8 (the .private field wasn't expected to be sent over 782191cded7Smrg * the wire). Check the server's version, and accept the old format 783191cded7Smrg * if appropriate. 784191cded7Smrg */ 785191cded7Smrg 786191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 787191cded7Smrg if (majorVersion == 0 && minorVersion < 8) { 788191cded7Smrg protocolBug = True; 789191cded7Smrg#ifdef DEBUG 790191cded7Smrg fprintf(stderr, "XF86VidModeSwitchToMode: Warning: Xserver is" 791191cded7Smrg "running an old version (%d.%d)\n", majorVersion, 792191cded7Smrg minorVersion); 793191cded7Smrg#endif 794191cded7Smrg } 795d9dcd5aeSmrg 796191cded7Smrg LockDisplay(dpy); 797191cded7Smrg if (majorVersion < 2) { 798191cded7Smrg GetOldReq(XF86VidModeSwitchToMode, XF86OldVidModeSwitchToMode, oldreq); 799191cded7Smrg oldreq->reqType = info->codes->major_opcode; 800191cded7Smrg oldreq->xf86vidmodeReqType = X_XF86VidModeSwitchToMode; 801191cded7Smrg oldreq->screen = screen; 802191cded7Smrg oldreq->dotclock = modeline->dotclock; 803191cded7Smrg oldreq->hdisplay = modeline->hdisplay; 804191cded7Smrg oldreq->hsyncstart = modeline->hsyncstart; 805191cded7Smrg oldreq->hsyncend = modeline->hsyncend; 806191cded7Smrg oldreq->htotal = modeline->htotal; 807191cded7Smrg oldreq->vdisplay = modeline->vdisplay; 808191cded7Smrg oldreq->vsyncstart = modeline->vsyncstart; 809191cded7Smrg oldreq->vsyncend = modeline->vsyncend; 810191cded7Smrg oldreq->vtotal = modeline->vtotal; 811191cded7Smrg oldreq->flags = modeline->flags; 812191cded7Smrg if (protocolBug) { 813191cded7Smrg oldreq->privsize = 0; 814191cded7Smrg } else { 815191cded7Smrg oldreq->privsize = modeline->privsize; 816191cded7Smrg if (modeline->privsize) { 817191cded7Smrg oldreq->length += modeline->privsize; 818191cded7Smrg Data32(dpy, (long *) modeline->private, 819191cded7Smrg modeline->privsize * sizeof(INT32)); 820191cded7Smrg } 821191cded7Smrg } 822191cded7Smrg } else { 823191cded7Smrg GetReq(XF86VidModeSwitchToMode, req); 824191cded7Smrg req->reqType = info->codes->major_opcode; 825191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeSwitchToMode; 826191cded7Smrg req->screen = screen; 827191cded7Smrg req->dotclock = modeline->dotclock; 828191cded7Smrg req->hdisplay = modeline->hdisplay; 829191cded7Smrg req->hsyncstart = modeline->hsyncstart; 830191cded7Smrg req->hsyncend = modeline->hsyncend; 831191cded7Smrg req->htotal = modeline->htotal; 832191cded7Smrg req->hskew = modeline->hskew; 833191cded7Smrg req->vdisplay = modeline->vdisplay; 834191cded7Smrg req->vsyncstart = modeline->vsyncstart; 835191cded7Smrg req->vsyncend = modeline->vsyncend; 836191cded7Smrg req->vtotal = modeline->vtotal; 837191cded7Smrg req->flags = modeline->flags; 838191cded7Smrg if (protocolBug) { 839191cded7Smrg req->privsize = 0; 840191cded7Smrg } else { 841191cded7Smrg req->privsize = modeline->privsize; 842191cded7Smrg if (modeline->privsize) { 843191cded7Smrg req->length += modeline->privsize; 844191cded7Smrg Data32(dpy, (long *) modeline->private, 845191cded7Smrg modeline->privsize * sizeof(INT32)); 846191cded7Smrg } 847191cded7Smrg } 848191cded7Smrg } 849191cded7Smrg UnlockDisplay(dpy); 850191cded7Smrg SyncHandle(); 851191cded7Smrg return True; 852191cded7Smrg} 853d9dcd5aeSmrg 854191cded7SmrgBool 855b290cf36SmrgXF86VidModeLockModeSwitch(Display* dpy, int screen, int lock) 856191cded7Smrg{ 857191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 858191cded7Smrg xXF86VidModeLockModeSwitchReq *req; 859191cded7Smrg 860191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 861191cded7Smrg 862191cded7Smrg LockDisplay(dpy); 863191cded7Smrg GetReq(XF86VidModeLockModeSwitch, req); 864191cded7Smrg req->reqType = info->codes->major_opcode; 865191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeLockModeSwitch; 866191cded7Smrg req->screen = screen; 867191cded7Smrg req->lock = lock; 868191cded7Smrg UnlockDisplay(dpy); 869191cded7Smrg SyncHandle(); 870191cded7Smrg return True; 871191cded7Smrg} 872d9dcd5aeSmrg 873191cded7SmrgBool 874b290cf36SmrgXF86VidModeGetMonitor(Display* dpy, int screen, XF86VidModeMonitor* monitor) 875191cded7Smrg{ 876191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 877191cded7Smrg xXF86VidModeGetMonitorReply rep; 878191cded7Smrg xXF86VidModeGetMonitorReq *req; 879191cded7Smrg CARD32 syncrange; 880191cded7Smrg int i; 881d9dcd5aeSmrg Bool result = True; 882191cded7Smrg 883191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 884191cded7Smrg 885191cded7Smrg LockDisplay(dpy); 886191cded7Smrg GetReq(XF86VidModeGetMonitor, req); 887191cded7Smrg req->reqType = info->codes->major_opcode; 888191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetMonitor; 889191cded7Smrg req->screen = screen; 890191cded7Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 891191cded7Smrg UnlockDisplay(dpy); 892191cded7Smrg SyncHandle(); 893191cded7Smrg return False; 894191cded7Smrg } 895191cded7Smrg monitor->nhsync = rep.nhsync; 896191cded7Smrg monitor->nvsync = rep.nvsync; 897191cded7Smrg#if 0 898191cded7Smrg monitor->bandwidth = (float)rep.bandwidth / 1e6; 899191cded7Smrg#endif 900191cded7Smrg if (rep.vendorLength) { 901d9dcd5aeSmrg monitor->vendor = Xcalloc(rep.vendorLength + 1, 1); 902d9dcd5aeSmrg if (monitor->vendor == NULL) 903d9dcd5aeSmrg result = False; 904191cded7Smrg } else { 905191cded7Smrg monitor->vendor = NULL; 906191cded7Smrg } 907d9dcd5aeSmrg if (result && rep.modelLength) { 908d9dcd5aeSmrg monitor->model = Xcalloc(rep.modelLength + 1, 1); 909d9dcd5aeSmrg if (monitor->model == NULL) 910d9dcd5aeSmrg result = False; 911191cded7Smrg } else { 912191cded7Smrg monitor->model = NULL; 913191cded7Smrg } 914d9dcd5aeSmrg if (result) { 915d9dcd5aeSmrg monitor->hsync = Xcalloc(rep.nhsync, sizeof(XF86VidModeSyncRange)); 916d9dcd5aeSmrg monitor->vsync = Xcalloc(rep.nvsync, sizeof(XF86VidModeSyncRange)); 917d9dcd5aeSmrg if ((monitor->hsync == NULL) || (monitor->vsync == NULL)) 918d9dcd5aeSmrg result = False; 919d9dcd5aeSmrg } else { 920d9dcd5aeSmrg monitor->hsync = monitor->vsync = NULL; 921191cded7Smrg } 922d9dcd5aeSmrg if (result == False) { 923d9dcd5aeSmrg _XEatDataWords(dpy, rep.length); 924d9dcd5aeSmrg Xfree(monitor->vendor); 925d9dcd5aeSmrg monitor->vendor = NULL; 926d9dcd5aeSmrg Xfree(monitor->model); 927d9dcd5aeSmrg monitor->model = NULL; 928191cded7Smrg Xfree(monitor->hsync); 929d9dcd5aeSmrg monitor->hsync = NULL; 930d9dcd5aeSmrg Xfree(monitor->vsync); 931d9dcd5aeSmrg monitor->vsync = NULL; 932191cded7Smrg } 933d9dcd5aeSmrg else { 934d9dcd5aeSmrg for (i = 0; i < rep.nhsync; i++) { 935d9dcd5aeSmrg _XRead(dpy, (char *)&syncrange, 4); 936d9dcd5aeSmrg monitor->hsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0; 937d9dcd5aeSmrg monitor->hsync[i].hi = (float)(syncrange >> 16) / 100.0; 938d9dcd5aeSmrg } 939d9dcd5aeSmrg for (i = 0; i < rep.nvsync; i++) { 940d9dcd5aeSmrg _XRead(dpy, (char *)&syncrange, 4); 941d9dcd5aeSmrg monitor->vsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0; 942d9dcd5aeSmrg monitor->vsync[i].hi = (float)(syncrange >> 16) / 100.0; 943d9dcd5aeSmrg } 944d9dcd5aeSmrg if (rep.vendorLength) 945d9dcd5aeSmrg _XReadPad(dpy, monitor->vendor, rep.vendorLength); 946d9dcd5aeSmrg if (rep.modelLength) 947d9dcd5aeSmrg _XReadPad(dpy, monitor->model, rep.modelLength); 948191cded7Smrg } 949191cded7Smrg UnlockDisplay(dpy); 950191cded7Smrg SyncHandle(); 951d9dcd5aeSmrg return result; 952191cded7Smrg} 953191cded7Smrg 954191cded7SmrgBool 955b290cf36SmrgXF86VidModeGetViewPort(Display* dpy, int screen, int *x, int *y) 956191cded7Smrg{ 957191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 958191cded7Smrg xXF86VidModeGetViewPortReply rep; 959191cded7Smrg xXF86VidModeGetViewPortReq *req; 960191cded7Smrg int majorVersion, minorVersion; 961191cded7Smrg Bool protocolBug = False; 962191cded7Smrg 963191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 964191cded7Smrg 965191cded7Smrg /* 966191cded7Smrg * Note: There was a bug in the protocol implementation in versions 967191cded7Smrg * 0.x with x < 8 (no reply was sent, so the client would hang) 968191cded7Smrg * Check the server's version, and don't wait for a reply with older 969191cded7Smrg * versions. 970191cded7Smrg */ 971191cded7Smrg 972191cded7Smrg XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 973191cded7Smrg if (majorVersion == 0 && minorVersion < 8) { 974191cded7Smrg protocolBug = True; 975191cded7Smrg#ifdef DEBUG 976191cded7Smrg fprintf(stderr, "XF86VidModeGetViewPort: Warning: Xserver is" 977191cded7Smrg "running an old version (%d.%d)\n", majorVersion, 978191cded7Smrg minorVersion); 979191cded7Smrg#endif 980191cded7Smrg } 981191cded7Smrg LockDisplay(dpy); 982191cded7Smrg GetReq(XF86VidModeGetViewPort, req); 983191cded7Smrg req->reqType = info->codes->major_opcode; 984191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetViewPort; 985191cded7Smrg req->screen = screen; 986191cded7Smrg if (protocolBug) { 987191cded7Smrg *x = 0; 988191cded7Smrg *y = 0; 989191cded7Smrg } else { 990191cded7Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 991191cded7Smrg UnlockDisplay(dpy); 992191cded7Smrg SyncHandle(); 993191cded7Smrg return False; 994191cded7Smrg } 995191cded7Smrg *x = rep.x; 996191cded7Smrg *y = rep.y; 997191cded7Smrg } 998191cded7Smrg 999191cded7Smrg UnlockDisplay(dpy); 1000191cded7Smrg SyncHandle(); 1001191cded7Smrg return True; 1002191cded7Smrg} 1003191cded7Smrg 1004191cded7SmrgBool 1005b290cf36SmrgXF86VidModeSetViewPort(Display* dpy, int screen, int x, int y) 1006191cded7Smrg{ 1007191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 1008191cded7Smrg xXF86VidModeSetViewPortReq *req; 1009191cded7Smrg 1010191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 1011191cded7Smrg 1012191cded7Smrg LockDisplay(dpy); 1013191cded7Smrg GetReq(XF86VidModeSetViewPort, req); 1014191cded7Smrg req->reqType = info->codes->major_opcode; 1015191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeSetViewPort; 1016191cded7Smrg req->screen = screen; 1017191cded7Smrg req->x = x; 1018191cded7Smrg req->y = y; 1019191cded7Smrg 1020191cded7Smrg UnlockDisplay(dpy); 1021191cded7Smrg SyncHandle(); 1022191cded7Smrg return True; 1023191cded7Smrg} 1024191cded7Smrg 1025191cded7SmrgBool 1026b290cf36SmrgXF86VidModeGetDotClocks(Display* dpy, int screen, int *flagsPtr, 1027b290cf36Smrg int *numclocksPtr, int *maxclocksPtr, int *clocksPtr[]) 1028191cded7Smrg{ 1029191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 1030191cded7Smrg xXF86VidModeGetDotClocksReply rep; 1031191cded7Smrg xXF86VidModeGetDotClocksReq *req; 1032191cded7Smrg int i, *dotclocks; 1033191cded7Smrg CARD32 dotclk; 1034d9dcd5aeSmrg Bool result = True; 1035191cded7Smrg 1036191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 1037191cded7Smrg 1038191cded7Smrg LockDisplay(dpy); 1039191cded7Smrg GetReq(XF86VidModeGetDotClocks, req); 1040191cded7Smrg req->reqType = info->codes->major_opcode; 1041191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetDotClocks; 1042191cded7Smrg req->screen = screen; 1043d9dcd5aeSmrg if (!_XReply(dpy, (xReply *)&rep, 1044191cded7Smrg (SIZEOF(xXF86VidModeGetDotClocksReply) - SIZEOF(xReply)) >> 2, xFalse)) 1045191cded7Smrg { 1046191cded7Smrg UnlockDisplay(dpy); 1047191cded7Smrg SyncHandle(); 1048191cded7Smrg return False; 1049191cded7Smrg } 1050191cded7Smrg *numclocksPtr = rep.clocks; 1051191cded7Smrg *maxclocksPtr = rep.maxclocks; 1052191cded7Smrg *flagsPtr = rep.flags; 1053191cded7Smrg 1054d9dcd5aeSmrg dotclocks = Xcalloc(rep.clocks, sizeof(int)); 1055d9dcd5aeSmrg if (dotclocks == NULL) { 1056d9dcd5aeSmrg _XEatDataWords(dpy, rep.length - 1057d9dcd5aeSmrg ((SIZEOF(xXF86VidModeGetDotClocksReply) - SIZEOF(xReply)) >> 2)); 1058d9dcd5aeSmrg result = False; 1059191cded7Smrg } 1060d9dcd5aeSmrg else { 1061d9dcd5aeSmrg for (i = 0; i < rep.clocks; i++) { 1062d9dcd5aeSmrg _XRead(dpy, (char*)&dotclk, 4); 1063d9dcd5aeSmrg dotclocks[i] = dotclk; 1064d9dcd5aeSmrg } 1065191cded7Smrg } 1066191cded7Smrg *clocksPtr = dotclocks; 1067191cded7Smrg UnlockDisplay(dpy); 1068191cded7Smrg SyncHandle(); 1069d9dcd5aeSmrg return result; 1070191cded7Smrg} 1071191cded7Smrg 1072191cded7SmrgBool 1073191cded7SmrgXF86VidModeSetGammaRamp ( 1074191cded7Smrg Display *dpy, 1075191cded7Smrg int screen, 1076191cded7Smrg int size, 1077191cded7Smrg unsigned short *red, 1078191cded7Smrg unsigned short *green, 1079191cded7Smrg unsigned short *blue 1080191cded7Smrg) 1081191cded7Smrg{ 1082191cded7Smrg int length = (size + 1) & ~1; 1083191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 1084191cded7Smrg xXF86VidModeSetGammaRampReq *req; 1085191cded7Smrg 1086191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 1087191cded7Smrg LockDisplay(dpy); 1088191cded7Smrg GetReq(XF86VidModeSetGammaRamp, req); 1089191cded7Smrg req->reqType = info->codes->major_opcode; 1090191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeSetGammaRamp; 1091191cded7Smrg req->screen = screen; 1092191cded7Smrg req->length += (length >> 1) * 3; 1093191cded7Smrg req->size = size; 1094191cded7Smrg _XSend(dpy, (char*)red, size * 2); 1095191cded7Smrg _XSend(dpy, (char*)green, size * 2); 1096191cded7Smrg _XSend(dpy, (char*)blue, size * 2); 1097191cded7Smrg UnlockDisplay(dpy); 1098191cded7Smrg SyncHandle(); 1099191cded7Smrg return True; 1100191cded7Smrg} 1101191cded7Smrg 1102191cded7Smrg 1103191cded7SmrgBool 1104191cded7SmrgXF86VidModeGetGammaRamp ( 1105191cded7Smrg Display *dpy, 1106191cded7Smrg int screen, 1107191cded7Smrg int size, 1108191cded7Smrg unsigned short *red, 1109191cded7Smrg unsigned short *green, 1110191cded7Smrg unsigned short *blue 1111191cded7Smrg) 1112191cded7Smrg{ 1113191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 1114191cded7Smrg xXF86VidModeGetGammaRampReq *req; 1115191cded7Smrg xXF86VidModeGetGammaRampReply rep; 1116d9dcd5aeSmrg Bool result = True; 1117d9dcd5aeSmrg 1118191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 1119191cded7Smrg 1120191cded7Smrg LockDisplay(dpy); 1121191cded7Smrg GetReq(XF86VidModeGetGammaRamp, req); 1122191cded7Smrg req->reqType = info->codes->major_opcode; 1123191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetGammaRamp; 1124191cded7Smrg req->screen = screen; 1125191cded7Smrg req->size = size; 1126191cded7Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 1127d9dcd5aeSmrg result = False; 1128191cded7Smrg } 1129d9dcd5aeSmrg else if (rep.size) { 1130d9dcd5aeSmrg if (rep.size <= size) { 1131d9dcd5aeSmrg _XRead(dpy, (char*)red, rep.size << 1); 1132d9dcd5aeSmrg _XRead(dpy, (char*)green, rep.size << 1); 1133d9dcd5aeSmrg _XRead(dpy, (char*)blue, rep.size << 1); 1134d9dcd5aeSmrg } 1135d9dcd5aeSmrg else { 1136d9dcd5aeSmrg _XEatDataWords(dpy, rep.length); 1137d9dcd5aeSmrg result = False; 1138d9dcd5aeSmrg } 1139191cded7Smrg } 1140191cded7Smrg 1141191cded7Smrg UnlockDisplay(dpy); 1142191cded7Smrg SyncHandle(); 1143d9dcd5aeSmrg return result; 1144191cded7Smrg} 1145191cded7Smrg 1146191cded7SmrgBool XF86VidModeGetGammaRampSize( 1147191cded7Smrg Display *dpy, 1148191cded7Smrg int screen, 1149191cded7Smrg int *size 1150191cded7Smrg) 1151191cded7Smrg{ 1152191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 1153191cded7Smrg xXF86VidModeGetGammaRampSizeReq *req; 1154191cded7Smrg xXF86VidModeGetGammaRampSizeReply rep; 1155d9dcd5aeSmrg 1156191cded7Smrg *size = 0; 1157191cded7Smrg 1158191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 1159191cded7Smrg 1160191cded7Smrg LockDisplay(dpy); 1161191cded7Smrg GetReq(XF86VidModeGetGammaRampSize, req); 1162191cded7Smrg req->reqType = info->codes->major_opcode; 1163191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetGammaRampSize; 1164191cded7Smrg req->screen = screen; 1165191cded7Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 1166191cded7Smrg UnlockDisplay (dpy); 1167191cded7Smrg SyncHandle (); 1168d9dcd5aeSmrg return False; 1169191cded7Smrg } 1170191cded7Smrg *size = rep.size; 1171191cded7Smrg UnlockDisplay(dpy); 1172191cded7Smrg SyncHandle(); 1173191cded7Smrg return True; 1174191cded7Smrg} 1175191cded7Smrg 1176191cded7SmrgBool XF86VidModeGetPermissions( 1177191cded7Smrg Display *dpy, 1178191cded7Smrg int screen, 1179191cded7Smrg int *permissions 1180191cded7Smrg) 1181191cded7Smrg{ 1182191cded7Smrg XExtDisplayInfo *info = find_display (dpy); 1183191cded7Smrg xXF86VidModeGetPermissionsReq *req; 1184191cded7Smrg xXF86VidModeGetPermissionsReply rep; 1185d9dcd5aeSmrg 1186191cded7Smrg *permissions = 0; 1187191cded7Smrg 1188191cded7Smrg XF86VidModeCheckExtension (dpy, info, False); 1189191cded7Smrg 1190191cded7Smrg LockDisplay(dpy); 1191191cded7Smrg GetReq(XF86VidModeGetPermissions, req); 1192191cded7Smrg req->reqType = info->codes->major_opcode; 1193191cded7Smrg req->xf86vidmodeReqType = X_XF86VidModeGetPermissions; 1194191cded7Smrg req->screen = screen; 1195191cded7Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 1196191cded7Smrg UnlockDisplay (dpy); 1197191cded7Smrg SyncHandle (); 1198d9dcd5aeSmrg return False; 1199191cded7Smrg } 1200191cded7Smrg *permissions = rep.permissions; 1201191cded7Smrg UnlockDisplay(dpy); 1202191cded7Smrg SyncHandle(); 1203191cded7Smrg return True; 1204191cded7Smrg} 1205191cded7Smrg 1206