XF86VMode.c revision d9dcd5ae
1/* 2 3Copyright (c) 1995 Kaleb S. KEITHLEY 4 5Permission is hereby granted, free of charge, to any person obtaining 6a copy of this software and associated documentation files (the 7"Software"), to deal in the Software without restriction, including 8without limitation the rights to use, copy, modify, merge, publish, 9distribute, sublicense, and/or sell copies of the Software, and to 10permit persons to whom the Software is furnished to do so, subject to 11the following conditions: 12 13The above copyright notice and this permission notice shall be 14included in all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES 20OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22OTHER DEALINGS IN THE SOFTWARE. 23 24Except as contained in this notice, the name of Kaleb S. KEITHLEY 25shall not be used in advertising or otherwise to promote the sale, use 26or other dealings in this Software without prior written authorization 27from Kaleb S. KEITHLEY. 28 29*/ 30 31/* THIS IS NOT AN X CONSORTIUM STANDARD */ 32 33#ifdef HAVE_CONFIG_H 34#include <config.h> 35#endif 36 37#include <X11/Xlibint.h> 38#include <X11/extensions/xf86vmproto.h> 39#include <X11/extensions/xf86vmode.h> 40#include <X11/extensions/Xext.h> 41#include <X11/extensions/extutil.h> 42#include <limits.h> 43 44#ifndef HAVE__XEATDATAWORDS 45static inline void _XEatDataWords(Display *dpy, unsigned long n) 46{ 47# ifndef LONG64 48 if (n >= (ULONG_MAX >> 2)) 49 _XIOError(dpy); 50# endif 51 _XEatData (dpy, n << 2); 52} 53#endif 54 55#ifdef DEBUG 56#include <stdio.h> 57#endif 58 59#ifndef MODE_BAD 60#define MODE_BAD 255 61#endif 62 63static XExtensionInfo _xf86vidmode_info_data; 64static XExtensionInfo *xf86vidmode_info = &_xf86vidmode_info_data; 65static const char *xf86vidmode_extension_name = XF86VIDMODENAME; 66 67#define XF86VidModeCheckExtension(dpy,i,val) \ 68 XextCheckExtension (dpy, i, xf86vidmode_extension_name, val) 69 70/***************************************************************************** 71 * * 72 * private utility routines * 73 * * 74 *****************************************************************************/ 75 76static XEXT_CLOSE_DISPLAY_PROTO(close_display); 77static /* const */ XExtensionHooks xf86vidmode_extension_hooks = { 78 NULL, /* create_gc */ 79 NULL, /* copy_gc */ 80 NULL, /* flush_gc */ 81 NULL, /* free_gc */ 82 NULL, /* create_font */ 83 NULL, /* free_font */ 84 close_display, /* close_display */ 85 NULL, /* wire_to_event */ 86 NULL, /* event_to_wire */ 87 NULL, /* error */ 88 NULL, /* error_string */ 89}; 90 91static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86vidmode_info, 92 xf86vidmode_extension_name, 93 &xf86vidmode_extension_hooks, 94 0, NULL) 95 96static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86vidmode_info) 97 98 99/***************************************************************************** 100 * * 101 * public XFree86-VidMode Extension routines * 102 * * 103 *****************************************************************************/ 104 105Bool 106XF86VidModeQueryExtension(Display *dpy, int *event_basep, int *error_basep) 107{ 108 XExtDisplayInfo *info = find_display (dpy); 109 110 if (XextHasExtension(info)) { 111 *event_basep = info->codes->first_event; 112 *error_basep = info->codes->first_error; 113 return True; 114 } else { 115 return False; 116 } 117} 118 119Bool 120XF86VidModeQueryVersion(Display* dpy, int* majorVersion, int* minorVersion) 121{ 122 XExtDisplayInfo *info = find_display (dpy); 123 xXF86VidModeQueryVersionReply rep; 124 xXF86VidModeQueryVersionReq *req; 125 126 XF86VidModeCheckExtension (dpy, info, False); 127 128 LockDisplay(dpy); 129 GetReq(XF86VidModeQueryVersion, req); 130 req->reqType = info->codes->major_opcode; 131 req->xf86vidmodeReqType = X_XF86VidModeQueryVersion; 132 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 133 UnlockDisplay(dpy); 134 SyncHandle(); 135 return False; 136 } 137 *majorVersion = rep.majorVersion; 138 *minorVersion = rep.minorVersion; 139 UnlockDisplay(dpy); 140 SyncHandle(); 141 if (*majorVersion >= 2) 142 XF86VidModeSetClientVersion(dpy); 143 return True; 144} 145 146Bool 147XF86VidModeSetClientVersion(Display *dpy) 148{ 149 XExtDisplayInfo *info = find_display(dpy); 150 xXF86VidModeSetClientVersionReq *req; 151 152 XF86VidModeCheckExtension(dpy, info, False); 153 154 LockDisplay(dpy); 155 GetReq(XF86VidModeSetClientVersion, req); 156 req->reqType = info->codes->major_opcode; 157 req->xf86vidmodeReqType = X_XF86VidModeSetClientVersion; 158 req->major = XF86VIDMODE_MAJOR_VERSION; 159 req->minor = XF86VIDMODE_MINOR_VERSION; 160 UnlockDisplay(dpy); 161 SyncHandle(); 162 return True; 163} 164 165Bool 166XF86VidModeSetGamma(Display *dpy, int screen, XF86VidModeGamma *Gamma) 167{ 168 XExtDisplayInfo *info = find_display(dpy); 169 xXF86VidModeSetGammaReq *req; 170 171 XF86VidModeCheckExtension(dpy, info, False); 172 173 LockDisplay(dpy); 174 GetReq(XF86VidModeSetGamma, req); 175 req->reqType = info->codes->major_opcode; 176 req->xf86vidmodeReqType = X_XF86VidModeSetGamma; 177 req->screen = screen; 178 req->red = (CARD32)(Gamma->red * 10000.); 179 req->green = (CARD32)(Gamma->green * 10000.); 180 req->blue = (CARD32)(Gamma->blue * 10000.); 181 UnlockDisplay(dpy); 182 SyncHandle(); 183 return True; 184} 185 186Bool 187XF86VidModeGetGamma(Display *dpy, int screen, XF86VidModeGamma *Gamma) 188{ 189 XExtDisplayInfo *info = find_display (dpy); 190 xXF86VidModeGetGammaReply rep; 191 xXF86VidModeGetGammaReq *req; 192 193 XF86VidModeCheckExtension (dpy, info, False); 194 195 LockDisplay(dpy); 196 GetReq(XF86VidModeGetGamma, req); 197 req->reqType = info->codes->major_opcode; 198 req->xf86vidmodeReqType = X_XF86VidModeGetGamma; 199 req->screen = screen; 200 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 201 UnlockDisplay(dpy); 202 SyncHandle(); 203 return False; 204 } 205 Gamma->red = ((float)rep.red) / 10000.; 206 Gamma->green = ((float)rep.green) / 10000.; 207 Gamma->blue = ((float)rep.blue) / 10000.; 208 UnlockDisplay(dpy); 209 SyncHandle(); 210 return True; 211} 212 213Bool 214XF86VidModeGetModeLine(Display* dpy, int screen, int* dotclock, 215 XF86VidModeModeLine* modeline) 216{ 217 XExtDisplayInfo *info = find_display (dpy); 218 xXF86VidModeGetModeLineReply rep; 219 xXF86OldVidModeGetModeLineReply oldrep; 220 xXF86VidModeGetModeLineReq *req; 221 int majorVersion, minorVersion; 222 Bool result = True; 223 224 XF86VidModeCheckExtension (dpy, info, False); 225 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 226 227 LockDisplay(dpy); 228 GetReq(XF86VidModeGetModeLine, req); 229 req->reqType = info->codes->major_opcode; 230 req->xf86vidmodeReqType = X_XF86VidModeGetModeLine; 231 req->screen = screen; 232 233 if (majorVersion < 2) { 234 if (!_XReply(dpy, (xReply *)&oldrep, 235 (SIZEOF(xXF86OldVidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) { 236 UnlockDisplay(dpy); 237 SyncHandle(); 238 return False; 239 } 240 *dotclock = oldrep.dotclock; 241 modeline->hdisplay = oldrep.hdisplay; 242 modeline->hsyncstart = oldrep.hsyncstart; 243 modeline->hsyncend = oldrep.hsyncend; 244 modeline->htotal = oldrep.htotal; 245 modeline->hskew = 0; 246 modeline->vdisplay = oldrep.vdisplay; 247 modeline->vsyncstart = oldrep.vsyncstart; 248 modeline->vsyncend = oldrep.vsyncend; 249 modeline->vtotal = oldrep.vtotal; 250 modeline->flags = oldrep.flags; 251 modeline->privsize = oldrep.privsize; 252 } else { 253 if (!_XReply(dpy, (xReply *)&rep, 254 (SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) { 255 UnlockDisplay(dpy); 256 SyncHandle(); 257 return False; 258 } 259 *dotclock = rep.dotclock; 260 modeline->hdisplay = rep.hdisplay; 261 modeline->hsyncstart = rep.hsyncstart; 262 modeline->hsyncend = rep.hsyncend; 263 modeline->htotal = rep.htotal; 264 modeline->hskew = rep.hskew; 265 modeline->vdisplay = rep.vdisplay; 266 modeline->vsyncstart = rep.vsyncstart; 267 modeline->vsyncend = rep.vsyncend; 268 modeline->vtotal = rep.vtotal; 269 modeline->flags = rep.flags; 270 modeline->privsize = rep.privsize; 271 } 272 273 if (modeline->privsize > 0) { 274 if (modeline->privsize < (INT_MAX / sizeof(INT32))) 275 modeline->private = Xcalloc(modeline->privsize, sizeof(INT32)); 276 else 277 modeline->private = NULL; 278 if (modeline->private == NULL) { 279 _XEatDataWords(dpy, rep.length - 280 ((SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xReply)) >> 2)); 281 result = False; 282 } else 283 _XRead(dpy, (char*)modeline->private, modeline->privsize * sizeof(INT32)); 284 } else { 285 modeline->private = NULL; 286 } 287 UnlockDisplay(dpy); 288 SyncHandle(); 289 return result; 290} 291 292Bool 293XF86VidModeGetAllModeLines(Display* dpy, int screen, int* modecount, 294 XF86VidModeModeInfo ***modelinesPtr) 295{ 296 XExtDisplayInfo *info = find_display (dpy); 297 xXF86VidModeGetAllModeLinesReply rep; 298 xXF86VidModeGetAllModeLinesReq *req; 299 XF86VidModeModeInfo *mdinfptr, **modelines; 300 xXF86VidModeModeInfo xmdline; 301 xXF86OldVidModeModeInfo oldxmdline; 302 int i; 303 int majorVersion, minorVersion; 304 Bool protocolBug = False; 305 306 XF86VidModeCheckExtension (dpy, info, False); 307 308 /* 309 * Note: There was a bug in the protocol implementation in versions 310 * 0.x with x < 8 (the .private field wasn't being passed over the wire). 311 * Check the server's version, and accept the old format if appropriate. 312 */ 313 314 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 315 if (majorVersion == 0 && minorVersion < 8) { 316 protocolBug = True; 317#ifdef DEBUG 318 fprintf(stderr, "XF86VidModeGetAllModeLines: Warning: Xserver is" 319 "running an old version (%d.%d)\n", majorVersion, 320 minorVersion); 321#endif 322 } 323 324 LockDisplay(dpy); 325 GetReq(XF86VidModeGetAllModeLines, req); 326 req->reqType = info->codes->major_opcode; 327 req->xf86vidmodeReqType = X_XF86VidModeGetAllModeLines; 328 req->screen = screen; 329 if (!_XReply(dpy, (xReply *)&rep, 330 (SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xReply)) >> 2, xFalse)) { 331 UnlockDisplay(dpy); 332 SyncHandle(); 333 return False; 334 } 335 336 *modecount = rep.modecount; 337 338 if (!(modelines = (XF86VidModeModeInfo **) Xcalloc(rep.modecount, 339 sizeof(XF86VidModeModeInfo *) 340 +sizeof(XF86VidModeModeInfo)))) { 341 _XEatDataWords(dpy, rep.length - 342 ((SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xReply)) >> 2)); 343 UnlockDisplay(dpy); 344 SyncHandle(); 345 return False; 346 } 347 mdinfptr = (XF86VidModeModeInfo *) ( 348 (char *) modelines 349 + rep.modecount*sizeof(XF86VidModeModeInfo *) 350 ); 351 352 for (i = 0; i < rep.modecount; i++) { 353 modelines[i] = mdinfptr++; 354 if (majorVersion < 2) { 355 _XRead(dpy, (char*)&oldxmdline, sizeof(xXF86OldVidModeModeInfo)); 356 modelines[i]->dotclock = oldxmdline.dotclock; 357 modelines[i]->hdisplay = oldxmdline.hdisplay; 358 modelines[i]->hsyncstart = oldxmdline.hsyncstart; 359 modelines[i]->hsyncend = oldxmdline.hsyncend; 360 modelines[i]->htotal = oldxmdline.htotal; 361 modelines[i]->hskew = 0; 362 modelines[i]->vdisplay = oldxmdline.vdisplay; 363 modelines[i]->vsyncstart = oldxmdline.vsyncstart; 364 modelines[i]->vsyncend = oldxmdline.vsyncend; 365 modelines[i]->vtotal = oldxmdline.vtotal; 366 modelines[i]->flags = oldxmdline.flags; 367 if (protocolBug) { 368 modelines[i]->privsize = 0; 369 modelines[i]->private = NULL; 370 } else { 371 modelines[i]->privsize = oldxmdline.privsize; 372 if (oldxmdline.privsize > 0) { 373 if (!(modelines[i]->private = 374 Xcalloc(oldxmdline.privsize, sizeof(INT32)))) { 375 _XEatDataWords(dpy, oldxmdline.privsize); 376 } else { 377 _XRead(dpy, (char*)modelines[i]->private, 378 oldxmdline.privsize * sizeof(INT32)); 379 } 380 } else { 381 modelines[i]->private = NULL; 382 } 383 } 384 } else { 385 _XRead(dpy, (char*)&xmdline, sizeof(xXF86VidModeModeInfo)); 386 modelines[i]->dotclock = xmdline.dotclock; 387 modelines[i]->hdisplay = xmdline.hdisplay; 388 modelines[i]->hsyncstart = xmdline.hsyncstart; 389 modelines[i]->hsyncend = xmdline.hsyncend; 390 modelines[i]->htotal = xmdline.htotal; 391 modelines[i]->hskew = xmdline.hskew; 392 modelines[i]->vdisplay = xmdline.vdisplay; 393 modelines[i]->vsyncstart = xmdline.vsyncstart; 394 modelines[i]->vsyncend = xmdline.vsyncend; 395 modelines[i]->vtotal = xmdline.vtotal; 396 modelines[i]->flags = xmdline.flags; 397 if (protocolBug) { 398 modelines[i]->privsize = 0; 399 modelines[i]->private = NULL; 400 } else { 401 modelines[i]->privsize = xmdline.privsize; 402 if (xmdline.privsize > 0) { 403 if (!(modelines[i]->private = 404 Xcalloc(xmdline.privsize, sizeof(INT32)))) { 405 _XEatDataWords(dpy, xmdline.privsize); 406 } else { 407 _XRead(dpy, (char*)modelines[i]->private, 408 xmdline.privsize * sizeof(INT32)); 409 } 410 } else { 411 modelines[i]->private = NULL; 412 } 413 } 414 } 415 } 416 *modelinesPtr = modelines; 417 UnlockDisplay(dpy); 418 SyncHandle(); 419 return True; 420} 421 422/* 423 * GetReq replacement for use with VidMode protocols earlier than 2.0 424 */ 425#if !defined(UNIXCPP) || defined(ANSICPP) 426#define GetOldReq(name, oldname, req) \ 427 WORD64ALIGN\ 428 if ((dpy->bufptr + SIZEOF(x##oldname##Req)) > dpy->bufmax)\ 429 _XFlush(dpy);\ 430 req = (x##oldname##Req *)(dpy->last_req = dpy->bufptr);\ 431 req->reqType = X_##name;\ 432 req->length = (SIZEOF(x##oldname##Req))>>2;\ 433 dpy->bufptr += SIZEOF(x##oldname##Req);\ 434 dpy->request++ 435 436#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ 437#define GetOldReq(name, oldname, req) \ 438 WORD64ALIGN\ 439 if ((dpy->bufptr + SIZEOF(x/**/oldname/**/Req)) > dpy->bufmax)\ 440 _XFlush(dpy);\ 441 req = (x/**/oldname/**/Req *)(dpy->last_req = dpy->bufptr);\ 442 req->reqType = X_/**/name;\ 443 req->length = (SIZEOF(x/**/oldname/**/Req))>>2;\ 444 dpy->bufptr += SIZEOF(x/**/oldname/**/Req);\ 445 dpy->request++ 446#endif 447 448Bool 449XF86VidModeAddModeLine(Display *dpy, int screen, 450 XF86VidModeModeInfo* newmodeline, 451 XF86VidModeModeInfo* aftermodeline) 452{ 453 XExtDisplayInfo *info = find_display (dpy); 454 xXF86VidModeAddModeLineReq *req; 455 xXF86OldVidModeAddModeLineReq *oldreq; 456 int majorVersion, minorVersion; 457 458 XF86VidModeCheckExtension (dpy, info, False); 459 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 460 461 LockDisplay(dpy); 462 if (majorVersion < 2) { 463 GetOldReq(XF86VidModeAddModeLine, XF86OldVidModeAddModeLine, oldreq); 464 oldreq->reqType = info->codes->major_opcode; 465 oldreq->xf86vidmodeReqType = X_XF86VidModeAddModeLine; 466 oldreq->screen = screen; 467 oldreq->dotclock = newmodeline->dotclock; 468 oldreq->hdisplay = newmodeline->hdisplay; 469 oldreq->hsyncstart = newmodeline->hsyncstart; 470 oldreq->hsyncend = newmodeline->hsyncend; 471 oldreq->htotal = newmodeline->htotal; 472 oldreq->vdisplay = newmodeline->vdisplay; 473 oldreq->vsyncstart = newmodeline->vsyncstart; 474 oldreq->vsyncend = newmodeline->vsyncend; 475 oldreq->vtotal = newmodeline->vtotal; 476 oldreq->flags = newmodeline->flags; 477 oldreq->privsize = newmodeline->privsize; 478 if (aftermodeline != NULL) { 479 oldreq->after_dotclock = aftermodeline->dotclock; 480 oldreq->after_hdisplay = aftermodeline->hdisplay; 481 oldreq->after_hsyncstart = aftermodeline->hsyncstart; 482 oldreq->after_hsyncend = aftermodeline->hsyncend; 483 oldreq->after_htotal = aftermodeline->htotal; 484 oldreq->after_vdisplay = aftermodeline->vdisplay; 485 oldreq->after_vsyncstart = aftermodeline->vsyncstart; 486 oldreq->after_vsyncend = aftermodeline->vsyncend; 487 oldreq->after_vtotal = aftermodeline->vtotal; 488 oldreq->after_flags = aftermodeline->flags; 489 } else { 490 oldreq->after_dotclock = 0; 491 oldreq->after_hdisplay = 0; 492 oldreq->after_hsyncstart = 0; 493 oldreq->after_hsyncend = 0; 494 oldreq->after_htotal = 0; 495 oldreq->after_vdisplay = 0; 496 oldreq->after_vsyncstart = 0; 497 oldreq->after_vsyncend = 0; 498 oldreq->after_vtotal = 0; 499 oldreq->after_flags = 0; 500 } 501 if (newmodeline->privsize) { 502 oldreq->length += newmodeline->privsize; 503 Data32(dpy, (long *) newmodeline->private, 504 newmodeline->privsize * sizeof(INT32)); 505 } 506 } else { 507 GetReq(XF86VidModeAddModeLine, req); 508 req->reqType = info->codes->major_opcode; 509 req->xf86vidmodeReqType = X_XF86VidModeAddModeLine; 510 req->screen = screen; 511 req->dotclock = newmodeline->dotclock; 512 req->hdisplay = newmodeline->hdisplay; 513 req->hsyncstart = newmodeline->hsyncstart; 514 req->hsyncend = newmodeline->hsyncend; 515 req->htotal = newmodeline->htotal; 516 req->hskew = newmodeline->hskew; 517 req->vdisplay = newmodeline->vdisplay; 518 req->vsyncstart = newmodeline->vsyncstart; 519 req->vsyncend = newmodeline->vsyncend; 520 req->vtotal = newmodeline->vtotal; 521 req->flags = newmodeline->flags; 522 req->privsize = newmodeline->privsize; 523 if (aftermodeline != NULL) { 524 req->after_dotclock = aftermodeline->dotclock; 525 req->after_hdisplay = aftermodeline->hdisplay; 526 req->after_hsyncstart = aftermodeline->hsyncstart; 527 req->after_hsyncend = aftermodeline->hsyncend; 528 req->after_htotal = aftermodeline->htotal; 529 req->after_hskew = aftermodeline->hskew; 530 req->after_vdisplay = aftermodeline->vdisplay; 531 req->after_vsyncstart = aftermodeline->vsyncstart; 532 req->after_vsyncend = aftermodeline->vsyncend; 533 req->after_vtotal = aftermodeline->vtotal; 534 req->after_flags = aftermodeline->flags; 535 } else { 536 req->after_dotclock = 0; 537 req->after_hdisplay = 0; 538 req->after_hsyncstart = 0; 539 req->after_hsyncend = 0; 540 req->after_htotal = 0; 541 req->after_hskew = 0; 542 req->after_vdisplay = 0; 543 req->after_vsyncstart = 0; 544 req->after_vsyncend = 0; 545 req->after_vtotal = 0; 546 req->after_flags = 0; 547 } 548 if (newmodeline->privsize) { 549 req->length += newmodeline->privsize; 550 Data32(dpy, (long *) newmodeline->private, 551 newmodeline->privsize * sizeof(INT32)); 552 } 553 } 554 UnlockDisplay(dpy); 555 SyncHandle(); 556 return True; 557} 558 559Bool 560XF86VidModeDeleteModeLine(Display *dpy, int screen, 561 XF86VidModeModeInfo* modeline) 562{ 563 XExtDisplayInfo *info = find_display (dpy); 564 xXF86VidModeDeleteModeLineReq *req; 565 xXF86OldVidModeDeleteModeLineReq *oldreq; 566 int majorVersion, minorVersion; 567 568 XF86VidModeCheckExtension (dpy, info, 0); 569 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 570 571 LockDisplay(dpy); 572 if (majorVersion < 2) { 573 GetOldReq(XF86VidModeDeleteModeLine, XF86OldVidModeDeleteModeLine, oldreq); 574 oldreq->reqType = info->codes->major_opcode; 575 oldreq->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine; 576 oldreq->screen = screen; 577 oldreq->dotclock = modeline->dotclock; 578 oldreq->hdisplay = modeline->hdisplay; 579 oldreq->hsyncstart = modeline->hsyncstart; 580 oldreq->hsyncend = modeline->hsyncend; 581 oldreq->htotal = modeline->htotal; 582 oldreq->vdisplay = modeline->vdisplay; 583 oldreq->vsyncstart = modeline->vsyncstart; 584 oldreq->vsyncend = modeline->vsyncend; 585 oldreq->vtotal = modeline->vtotal; 586 oldreq->flags = modeline->flags; 587 oldreq->privsize = modeline->privsize; 588 if (modeline->privsize) { 589 oldreq->length += modeline->privsize; 590 Data32(dpy, (long *) modeline->private, 591 modeline->privsize * sizeof(INT32)); 592 } 593 } else { 594 GetReq(XF86VidModeDeleteModeLine, req); 595 req->reqType = info->codes->major_opcode; 596 req->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine; 597 req->screen = screen; 598 req->dotclock = modeline->dotclock; 599 req->hdisplay = modeline->hdisplay; 600 req->hsyncstart = modeline->hsyncstart; 601 req->hsyncend = modeline->hsyncend; 602 req->htotal = modeline->htotal; 603 req->hskew = modeline->hskew; 604 req->vdisplay = modeline->vdisplay; 605 req->vsyncstart = modeline->vsyncstart; 606 req->vsyncend = modeline->vsyncend; 607 req->vtotal = modeline->vtotal; 608 req->flags = modeline->flags; 609 req->privsize = modeline->privsize; 610 if (modeline->privsize) { 611 req->length += modeline->privsize; 612 Data32(dpy, (long *) modeline->private, 613 modeline->privsize * sizeof(INT32)); 614 } 615 } 616 UnlockDisplay(dpy); 617 SyncHandle(); 618 return True; 619} 620 621Bool 622XF86VidModeModModeLine(Display *dpy, int screen, XF86VidModeModeLine* modeline) 623{ 624 XExtDisplayInfo *info = find_display (dpy); 625 xXF86VidModeModModeLineReq *req; 626 xXF86OldVidModeModModeLineReq *oldreq; 627 int majorVersion, minorVersion; 628 629 XF86VidModeCheckExtension (dpy, info, 0); 630 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 631 632 LockDisplay(dpy); 633 if (majorVersion < 2) { 634 GetOldReq(XF86VidModeModModeLine, XF86OldVidModeModModeLine, oldreq); 635 oldreq->reqType = info->codes->major_opcode; 636 oldreq->xf86vidmodeReqType = X_XF86VidModeModModeLine; 637 oldreq->screen = screen; 638 oldreq->hdisplay = modeline->hdisplay; 639 oldreq->hsyncstart = modeline->hsyncstart; 640 oldreq->hsyncend = modeline->hsyncend; 641 oldreq->htotal = modeline->htotal; 642 oldreq->vdisplay = modeline->vdisplay; 643 oldreq->vsyncstart = modeline->vsyncstart; 644 oldreq->vsyncend = modeline->vsyncend; 645 oldreq->vtotal = modeline->vtotal; 646 oldreq->flags = modeline->flags; 647 oldreq->privsize = modeline->privsize; 648 if (modeline->privsize) { 649 oldreq->length += modeline->privsize; 650 Data32(dpy, (long *) modeline->private, 651 modeline->privsize * sizeof(INT32)); 652 } 653 } else { 654 GetReq(XF86VidModeModModeLine, req); 655 req->reqType = info->codes->major_opcode; 656 req->xf86vidmodeReqType = X_XF86VidModeModModeLine; 657 req->screen = screen; 658 req->hdisplay = modeline->hdisplay; 659 req->hsyncstart = modeline->hsyncstart; 660 req->hsyncend = modeline->hsyncend; 661 req->htotal = modeline->htotal; 662 req->hskew = modeline->hskew; 663 req->vdisplay = modeline->vdisplay; 664 req->vsyncstart = modeline->vsyncstart; 665 req->vsyncend = modeline->vsyncend; 666 req->vtotal = modeline->vtotal; 667 req->flags = modeline->flags; 668 req->privsize = modeline->privsize; 669 if (modeline->privsize) { 670 req->length += modeline->privsize; 671 Data32(dpy, (long *) modeline->private, 672 modeline->privsize * sizeof(INT32)); 673 } 674 } 675 UnlockDisplay(dpy); 676 SyncHandle(); 677 return True; 678} 679 680Status 681XF86VidModeValidateModeLine(Display *dpy, int screen, 682 XF86VidModeModeInfo* modeline) 683{ 684 XExtDisplayInfo *info = find_display (dpy); 685 xXF86VidModeValidateModeLineReq *req; 686 xXF86OldVidModeValidateModeLineReq *oldreq; 687 xXF86VidModeValidateModeLineReply rep; 688 int majorVersion, minorVersion; 689 690 XF86VidModeCheckExtension (dpy, info, 0); 691 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 692 693 LockDisplay(dpy); 694 695 if (majorVersion < 2) { 696 GetOldReq(XF86VidModeValidateModeLine, XF86OldVidModeValidateModeLine, oldreq); 697 oldreq->reqType = info->codes->major_opcode; 698 oldreq->xf86vidmodeReqType = X_XF86VidModeValidateModeLine; 699 oldreq->screen = screen; 700 oldreq->dotclock = modeline->dotclock; 701 oldreq->hdisplay = modeline->hdisplay; 702 oldreq->hsyncstart = modeline->hsyncstart; 703 oldreq->hsyncend = modeline->hsyncend; 704 oldreq->htotal = modeline->htotal; 705 oldreq->vdisplay = modeline->vdisplay; 706 oldreq->vsyncstart = modeline->vsyncstart; 707 oldreq->vsyncend = modeline->vsyncend; 708 oldreq->vtotal = modeline->vtotal; 709 oldreq->flags = modeline->flags; 710 oldreq->privsize = modeline->privsize; 711 if (modeline->privsize) { 712 oldreq->length += modeline->privsize; 713 Data32(dpy, (long *) modeline->private, 714 modeline->privsize * sizeof(INT32)); 715 } 716 } else { 717 GetReq(XF86VidModeValidateModeLine, req); 718 req->reqType = info->codes->major_opcode; 719 req->xf86vidmodeReqType = X_XF86VidModeValidateModeLine; 720 req->screen = screen; 721 req->dotclock = modeline->dotclock; 722 req->hdisplay = modeline->hdisplay; 723 req->hsyncstart = modeline->hsyncstart; 724 req->hsyncend = modeline->hsyncend; 725 req->htotal = modeline->htotal; 726 req->hskew = modeline->hskew; 727 req->vdisplay = modeline->vdisplay; 728 req->vsyncstart = modeline->vsyncstart; 729 req->vsyncend = modeline->vsyncend; 730 req->vtotal = modeline->vtotal; 731 req->flags = modeline->flags; 732 req->privsize = modeline->privsize; 733 if (modeline->privsize) { 734 req->length += modeline->privsize; 735 Data32(dpy, (long *) modeline->private, 736 modeline->privsize * sizeof(INT32)); 737 } 738 } 739 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 740 UnlockDisplay(dpy); 741 SyncHandle(); 742 return MODE_BAD; 743 } 744 UnlockDisplay(dpy); 745 SyncHandle(); 746 return rep.status; 747} 748 749Bool 750XF86VidModeSwitchMode(Display* dpy, int screen, int zoom) 751{ 752 XExtDisplayInfo *info = find_display (dpy); 753 xXF86VidModeSwitchModeReq *req; 754 755 XF86VidModeCheckExtension (dpy, info, False); 756 757 LockDisplay(dpy); 758 GetReq(XF86VidModeSwitchMode, req); 759 req->reqType = info->codes->major_opcode; 760 req->xf86vidmodeReqType = X_XF86VidModeSwitchMode; 761 req->screen = screen; 762 req->zoom = zoom; 763 UnlockDisplay(dpy); 764 SyncHandle(); 765 return True; 766} 767 768Bool 769XF86VidModeSwitchToMode(Display* dpy, int screen, XF86VidModeModeInfo* modeline) 770{ 771 XExtDisplayInfo *info = find_display (dpy); 772 xXF86VidModeSwitchToModeReq *req; 773 xXF86OldVidModeSwitchToModeReq *oldreq; 774 int majorVersion, minorVersion; 775 Bool protocolBug = False; 776 777 XF86VidModeCheckExtension (dpy, info, False); 778 779 /* 780 * Note: There was a bug in the protocol implementation in versions 781 * 0.x with x < 8 (the .private field wasn't expected to be sent over 782 * the wire). Check the server's version, and accept the old format 783 * if appropriate. 784 */ 785 786 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 787 if (majorVersion == 0 && minorVersion < 8) { 788 protocolBug = True; 789#ifdef DEBUG 790 fprintf(stderr, "XF86VidModeSwitchToMode: Warning: Xserver is" 791 "running an old version (%d.%d)\n", majorVersion, 792 minorVersion); 793#endif 794 } 795 796 LockDisplay(dpy); 797 if (majorVersion < 2) { 798 GetOldReq(XF86VidModeSwitchToMode, XF86OldVidModeSwitchToMode, oldreq); 799 oldreq->reqType = info->codes->major_opcode; 800 oldreq->xf86vidmodeReqType = X_XF86VidModeSwitchToMode; 801 oldreq->screen = screen; 802 oldreq->dotclock = modeline->dotclock; 803 oldreq->hdisplay = modeline->hdisplay; 804 oldreq->hsyncstart = modeline->hsyncstart; 805 oldreq->hsyncend = modeline->hsyncend; 806 oldreq->htotal = modeline->htotal; 807 oldreq->vdisplay = modeline->vdisplay; 808 oldreq->vsyncstart = modeline->vsyncstart; 809 oldreq->vsyncend = modeline->vsyncend; 810 oldreq->vtotal = modeline->vtotal; 811 oldreq->flags = modeline->flags; 812 if (protocolBug) { 813 oldreq->privsize = 0; 814 } else { 815 oldreq->privsize = modeline->privsize; 816 if (modeline->privsize) { 817 oldreq->length += modeline->privsize; 818 Data32(dpy, (long *) modeline->private, 819 modeline->privsize * sizeof(INT32)); 820 } 821 } 822 } else { 823 GetReq(XF86VidModeSwitchToMode, req); 824 req->reqType = info->codes->major_opcode; 825 req->xf86vidmodeReqType = X_XF86VidModeSwitchToMode; 826 req->screen = screen; 827 req->dotclock = modeline->dotclock; 828 req->hdisplay = modeline->hdisplay; 829 req->hsyncstart = modeline->hsyncstart; 830 req->hsyncend = modeline->hsyncend; 831 req->htotal = modeline->htotal; 832 req->hskew = modeline->hskew; 833 req->vdisplay = modeline->vdisplay; 834 req->vsyncstart = modeline->vsyncstart; 835 req->vsyncend = modeline->vsyncend; 836 req->vtotal = modeline->vtotal; 837 req->flags = modeline->flags; 838 if (protocolBug) { 839 req->privsize = 0; 840 } else { 841 req->privsize = modeline->privsize; 842 if (modeline->privsize) { 843 req->length += modeline->privsize; 844 Data32(dpy, (long *) modeline->private, 845 modeline->privsize * sizeof(INT32)); 846 } 847 } 848 } 849 UnlockDisplay(dpy); 850 SyncHandle(); 851 return True; 852} 853 854Bool 855XF86VidModeLockModeSwitch(Display* dpy, int screen, int lock) 856{ 857 XExtDisplayInfo *info = find_display (dpy); 858 xXF86VidModeLockModeSwitchReq *req; 859 860 XF86VidModeCheckExtension (dpy, info, False); 861 862 LockDisplay(dpy); 863 GetReq(XF86VidModeLockModeSwitch, req); 864 req->reqType = info->codes->major_opcode; 865 req->xf86vidmodeReqType = X_XF86VidModeLockModeSwitch; 866 req->screen = screen; 867 req->lock = lock; 868 UnlockDisplay(dpy); 869 SyncHandle(); 870 return True; 871} 872 873Bool 874XF86VidModeGetMonitor(Display* dpy, int screen, XF86VidModeMonitor* monitor) 875{ 876 XExtDisplayInfo *info = find_display (dpy); 877 xXF86VidModeGetMonitorReply rep; 878 xXF86VidModeGetMonitorReq *req; 879 CARD32 syncrange; 880 int i; 881 Bool result = True; 882 883 XF86VidModeCheckExtension (dpy, info, False); 884 885 LockDisplay(dpy); 886 GetReq(XF86VidModeGetMonitor, req); 887 req->reqType = info->codes->major_opcode; 888 req->xf86vidmodeReqType = X_XF86VidModeGetMonitor; 889 req->screen = screen; 890 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 891 UnlockDisplay(dpy); 892 SyncHandle(); 893 return False; 894 } 895 monitor->nhsync = rep.nhsync; 896 monitor->nvsync = rep.nvsync; 897#if 0 898 monitor->bandwidth = (float)rep.bandwidth / 1e6; 899#endif 900 if (rep.vendorLength) { 901 monitor->vendor = Xcalloc(rep.vendorLength + 1, 1); 902 if (monitor->vendor == NULL) 903 result = False; 904 } else { 905 monitor->vendor = NULL; 906 } 907 if (result && rep.modelLength) { 908 monitor->model = Xcalloc(rep.modelLength + 1, 1); 909 if (monitor->model == NULL) 910 result = False; 911 } else { 912 monitor->model = NULL; 913 } 914 if (result) { 915 monitor->hsync = Xcalloc(rep.nhsync, sizeof(XF86VidModeSyncRange)); 916 monitor->vsync = Xcalloc(rep.nvsync, sizeof(XF86VidModeSyncRange)); 917 if ((monitor->hsync == NULL) || (monitor->vsync == NULL)) 918 result = False; 919 } else { 920 monitor->hsync = monitor->vsync = NULL; 921 } 922 if (result == False) { 923 _XEatDataWords(dpy, rep.length); 924 Xfree(monitor->vendor); 925 monitor->vendor = NULL; 926 Xfree(monitor->model); 927 monitor->model = NULL; 928 Xfree(monitor->hsync); 929 monitor->hsync = NULL; 930 Xfree(monitor->vsync); 931 monitor->vsync = NULL; 932 } 933 else { 934 for (i = 0; i < rep.nhsync; i++) { 935 _XRead(dpy, (char *)&syncrange, 4); 936 monitor->hsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0; 937 monitor->hsync[i].hi = (float)(syncrange >> 16) / 100.0; 938 } 939 for (i = 0; i < rep.nvsync; i++) { 940 _XRead(dpy, (char *)&syncrange, 4); 941 monitor->vsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0; 942 monitor->vsync[i].hi = (float)(syncrange >> 16) / 100.0; 943 } 944 if (rep.vendorLength) 945 _XReadPad(dpy, monitor->vendor, rep.vendorLength); 946 if (rep.modelLength) 947 _XReadPad(dpy, monitor->model, rep.modelLength); 948 } 949 UnlockDisplay(dpy); 950 SyncHandle(); 951 return result; 952} 953 954Bool 955XF86VidModeGetViewPort(Display* dpy, int screen, int *x, int *y) 956{ 957 XExtDisplayInfo *info = find_display (dpy); 958 xXF86VidModeGetViewPortReply rep; 959 xXF86VidModeGetViewPortReq *req; 960 int majorVersion, minorVersion; 961 Bool protocolBug = False; 962 963 XF86VidModeCheckExtension (dpy, info, False); 964 965 /* 966 * Note: There was a bug in the protocol implementation in versions 967 * 0.x with x < 8 (no reply was sent, so the client would hang) 968 * Check the server's version, and don't wait for a reply with older 969 * versions. 970 */ 971 972 XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion); 973 if (majorVersion == 0 && minorVersion < 8) { 974 protocolBug = True; 975#ifdef DEBUG 976 fprintf(stderr, "XF86VidModeGetViewPort: Warning: Xserver is" 977 "running an old version (%d.%d)\n", majorVersion, 978 minorVersion); 979#endif 980 } 981 LockDisplay(dpy); 982 GetReq(XF86VidModeGetViewPort, req); 983 req->reqType = info->codes->major_opcode; 984 req->xf86vidmodeReqType = X_XF86VidModeGetViewPort; 985 req->screen = screen; 986 if (protocolBug) { 987 *x = 0; 988 *y = 0; 989 } else { 990 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 991 UnlockDisplay(dpy); 992 SyncHandle(); 993 return False; 994 } 995 *x = rep.x; 996 *y = rep.y; 997 } 998 999 UnlockDisplay(dpy); 1000 SyncHandle(); 1001 return True; 1002} 1003 1004Bool 1005XF86VidModeSetViewPort(Display* dpy, int screen, int x, int y) 1006{ 1007 XExtDisplayInfo *info = find_display (dpy); 1008 xXF86VidModeSetViewPortReq *req; 1009 1010 XF86VidModeCheckExtension (dpy, info, False); 1011 1012 LockDisplay(dpy); 1013 GetReq(XF86VidModeSetViewPort, req); 1014 req->reqType = info->codes->major_opcode; 1015 req->xf86vidmodeReqType = X_XF86VidModeSetViewPort; 1016 req->screen = screen; 1017 req->x = x; 1018 req->y = y; 1019 1020 UnlockDisplay(dpy); 1021 SyncHandle(); 1022 return True; 1023} 1024 1025Bool 1026XF86VidModeGetDotClocks(Display* dpy, int screen, int *flagsPtr, 1027 int *numclocksPtr, int *maxclocksPtr, int *clocksPtr[]) 1028{ 1029 XExtDisplayInfo *info = find_display (dpy); 1030 xXF86VidModeGetDotClocksReply rep; 1031 xXF86VidModeGetDotClocksReq *req; 1032 int i, *dotclocks; 1033 CARD32 dotclk; 1034 Bool result = True; 1035 1036 XF86VidModeCheckExtension (dpy, info, False); 1037 1038 LockDisplay(dpy); 1039 GetReq(XF86VidModeGetDotClocks, req); 1040 req->reqType = info->codes->major_opcode; 1041 req->xf86vidmodeReqType = X_XF86VidModeGetDotClocks; 1042 req->screen = screen; 1043 if (!_XReply(dpy, (xReply *)&rep, 1044 (SIZEOF(xXF86VidModeGetDotClocksReply) - SIZEOF(xReply)) >> 2, xFalse)) 1045 { 1046 UnlockDisplay(dpy); 1047 SyncHandle(); 1048 return False; 1049 } 1050 *numclocksPtr = rep.clocks; 1051 *maxclocksPtr = rep.maxclocks; 1052 *flagsPtr = rep.flags; 1053 1054 dotclocks = Xcalloc(rep.clocks, sizeof(int)); 1055 if (dotclocks == NULL) { 1056 _XEatDataWords(dpy, rep.length - 1057 ((SIZEOF(xXF86VidModeGetDotClocksReply) - SIZEOF(xReply)) >> 2)); 1058 result = False; 1059 } 1060 else { 1061 for (i = 0; i < rep.clocks; i++) { 1062 _XRead(dpy, (char*)&dotclk, 4); 1063 dotclocks[i] = dotclk; 1064 } 1065 } 1066 *clocksPtr = dotclocks; 1067 UnlockDisplay(dpy); 1068 SyncHandle(); 1069 return result; 1070} 1071 1072Bool 1073XF86VidModeSetGammaRamp ( 1074 Display *dpy, 1075 int screen, 1076 int size, 1077 unsigned short *red, 1078 unsigned short *green, 1079 unsigned short *blue 1080) 1081{ 1082 int length = (size + 1) & ~1; 1083 XExtDisplayInfo *info = find_display (dpy); 1084 xXF86VidModeSetGammaRampReq *req; 1085 1086 XF86VidModeCheckExtension (dpy, info, False); 1087 LockDisplay(dpy); 1088 GetReq(XF86VidModeSetGammaRamp, req); 1089 req->reqType = info->codes->major_opcode; 1090 req->xf86vidmodeReqType = X_XF86VidModeSetGammaRamp; 1091 req->screen = screen; 1092 req->length += (length >> 1) * 3; 1093 req->size = size; 1094 _XSend(dpy, (char*)red, size * 2); 1095 _XSend(dpy, (char*)green, size * 2); 1096 _XSend(dpy, (char*)blue, size * 2); 1097 UnlockDisplay(dpy); 1098 SyncHandle(); 1099 return True; 1100} 1101 1102 1103Bool 1104XF86VidModeGetGammaRamp ( 1105 Display *dpy, 1106 int screen, 1107 int size, 1108 unsigned short *red, 1109 unsigned short *green, 1110 unsigned short *blue 1111) 1112{ 1113 XExtDisplayInfo *info = find_display (dpy); 1114 xXF86VidModeGetGammaRampReq *req; 1115 xXF86VidModeGetGammaRampReply rep; 1116 Bool result = True; 1117 1118 XF86VidModeCheckExtension (dpy, info, False); 1119 1120 LockDisplay(dpy); 1121 GetReq(XF86VidModeGetGammaRamp, req); 1122 req->reqType = info->codes->major_opcode; 1123 req->xf86vidmodeReqType = X_XF86VidModeGetGammaRamp; 1124 req->screen = screen; 1125 req->size = size; 1126 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 1127 result = False; 1128 } 1129 else if (rep.size) { 1130 if (rep.size <= size) { 1131 _XRead(dpy, (char*)red, rep.size << 1); 1132 _XRead(dpy, (char*)green, rep.size << 1); 1133 _XRead(dpy, (char*)blue, rep.size << 1); 1134 } 1135 else { 1136 _XEatDataWords(dpy, rep.length); 1137 result = False; 1138 } 1139 } 1140 1141 UnlockDisplay(dpy); 1142 SyncHandle(); 1143 return result; 1144} 1145 1146Bool XF86VidModeGetGammaRampSize( 1147 Display *dpy, 1148 int screen, 1149 int *size 1150) 1151{ 1152 XExtDisplayInfo *info = find_display (dpy); 1153 xXF86VidModeGetGammaRampSizeReq *req; 1154 xXF86VidModeGetGammaRampSizeReply rep; 1155 1156 *size = 0; 1157 1158 XF86VidModeCheckExtension (dpy, info, False); 1159 1160 LockDisplay(dpy); 1161 GetReq(XF86VidModeGetGammaRampSize, req); 1162 req->reqType = info->codes->major_opcode; 1163 req->xf86vidmodeReqType = X_XF86VidModeGetGammaRampSize; 1164 req->screen = screen; 1165 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 1166 UnlockDisplay (dpy); 1167 SyncHandle (); 1168 return False; 1169 } 1170 *size = rep.size; 1171 UnlockDisplay(dpy); 1172 SyncHandle(); 1173 return True; 1174} 1175 1176Bool XF86VidModeGetPermissions( 1177 Display *dpy, 1178 int screen, 1179 int *permissions 1180) 1181{ 1182 XExtDisplayInfo *info = find_display (dpy); 1183 xXF86VidModeGetPermissionsReq *req; 1184 xXF86VidModeGetPermissionsReply rep; 1185 1186 *permissions = 0; 1187 1188 XF86VidModeCheckExtension (dpy, info, False); 1189 1190 LockDisplay(dpy); 1191 GetReq(XF86VidModeGetPermissions, req); 1192 req->reqType = info->codes->major_opcode; 1193 req->xf86vidmodeReqType = X_XF86VidModeGetPermissions; 1194 req->screen = screen; 1195 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 1196 UnlockDisplay (dpy); 1197 SyncHandle (); 1198 return False; 1199 } 1200 *permissions = rep.permissions; 1201 UnlockDisplay(dpy); 1202 SyncHandle(); 1203 return True; 1204} 1205 1206