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