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