vmwarexinerama.c revision 6df26cac
1/* 2 * Copyright 2006 by VMware, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the copyright holder(s) 23 * and author(s) shall not be used in advertising or otherwise to promote 24 * the sale, use or other dealings in this Software without prior written 25 * authorization from the copyright holder(s) and author(s). 26 */ 27 28/* 29 * vmwarexinerama.c -- 30 * 31 * The implementation of the Xinerama protocol extension. 32 */ 33 34 35#ifdef HAVE_CONFIG_H 36#include "config.h" 37#endif 38 39#define NEED_REPLIES 40#define NEED_EVENTS 41#include "dixstruct.h" 42#include "extnsionst.h" 43#include <X11/X.h> 44#include <X11/extensions/panoramiXproto.h> 45 46#include "vmware.h" 47 48 49/* 50 *---------------------------------------------------------------------------- 51 * 52 * VMwareXineramaQueryVersion -- 53 * 54 * Implementation of QueryVersion command handler. Initialises and 55 * sends a reply. 56 * 57 * Results: 58 * Standard response codes. 59 * 60 * Side effects: 61 * Writes reply to client. 62 * 63 *---------------------------------------------------------------------------- 64 */ 65 66static int 67VMwareXineramaQueryVersion(ClientPtr client) 68{ 69 xPanoramiXQueryVersionReply rep; 70 register int n; 71 72 REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); 73 rep.type = X_Reply; 74 rep.length = 0; 75 rep.sequenceNumber = client->sequence; 76 rep.majorVersion = 1; 77 rep.minorVersion = 0; 78 if(client->swapped) { 79 swaps(&rep.sequenceNumber, n); 80 swapl(&rep.length, n); 81 swaps(&rep.majorVersion, n); 82 swaps(&rep.minorVersion, n); 83 } 84 WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); 85 return (client->noClientException); 86} 87 88 89/* 90 *---------------------------------------------------------------------------- 91 * 92 * VMwareXineramaGetState -- 93 * 94 * Implementation of GetState command handler. Initialises and 95 * sends a reply. 96 * 97 * Results: 98 * Standard response codes. 99 * 100 * Side effects: 101 * Writes reply to client. 102 * 103 *---------------------------------------------------------------------------- 104 */ 105 106static int 107VMwareXineramaGetState(ClientPtr client) 108{ 109 REQUEST(xPanoramiXGetStateReq); 110 WindowPtr pWin; 111 xPanoramiXGetStateReply rep; 112 register int n; 113 ExtensionEntry *ext; 114 ScrnInfoPtr pScrn; 115 VMWAREPtr pVMWARE; 116 117 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); 118 pWin = LookupWindow(stuff->window, client); 119 if(!pWin) return BadWindow; 120 121 if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { 122 return BadMatch; 123 } 124 pScrn = ext->extPrivate; 125 pVMWARE = VMWAREPTR(pScrn); 126 127 rep.type = X_Reply; 128 rep.length = 0; 129 rep.sequenceNumber = client->sequence; 130 rep.state = pVMWARE->xinerama; 131 if(client->swapped) { 132 swaps (&rep.sequenceNumber, n); 133 swapl (&rep.length, n); 134 swaps (&rep.state, n); 135 } 136 WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep); 137 return client->noClientException; 138} 139 140 141/* 142 *---------------------------------------------------------------------------- 143 * 144 * VMwareXineramaGetScreenCount -- 145 * 146 * Implementation of GetScreenCount command handler. Initialises and 147 * sends a reply. 148 * 149 * Results: 150 * Standard response codes. 151 * 152 * Side effects: 153 * Writes reply to client. 154 * 155 *---------------------------------------------------------------------------- 156 */ 157 158static int 159VMwareXineramaGetScreenCount(ClientPtr client) 160{ 161 REQUEST(xPanoramiXGetScreenCountReq); 162 WindowPtr pWin; 163 xPanoramiXGetScreenCountReply rep; 164 register int n; 165 ExtensionEntry *ext; 166 ScrnInfoPtr pScrn; 167 VMWAREPtr pVMWARE; 168 169 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); 170 pWin = LookupWindow(stuff->window, client); 171 if(!pWin) return BadWindow; 172 173 if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { 174 return BadMatch; 175 } 176 pScrn = ext->extPrivate; 177 pVMWARE = VMWAREPTR(pScrn); 178 179 rep.type = X_Reply; 180 rep.length = 0; 181 rep.sequenceNumber = client->sequence; 182 rep.ScreenCount = pVMWARE->xineramaNumOutputs; 183 if(client->swapped) { 184 swaps(&rep.sequenceNumber, n); 185 swapl(&rep.length, n); 186 swaps(&rep.ScreenCount, n); 187 } 188 WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); 189 return client->noClientException; 190} 191 192 193/* 194 *---------------------------------------------------------------------------- 195 * 196 * VMwareXineramaGetScreenSize -- 197 * 198 * Implementation of GetScreenSize command handler. Initialises and 199 * sends a reply. 200 * 201 * Results: 202 * Standard response codes. 203 * 204 * Side effects: 205 * Writes reply to client. 206 * 207 *---------------------------------------------------------------------------- 208 */ 209 210static int 211VMwareXineramaGetScreenSize(ClientPtr client) 212{ 213 REQUEST(xPanoramiXGetScreenSizeReq); 214 WindowPtr pWin; 215 xPanoramiXGetScreenSizeReply rep; 216 register int n; 217 ExtensionEntry *ext; 218 ScrnInfoPtr pScrn; 219 VMWAREPtr pVMWARE; 220 221 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); 222 pWin = LookupWindow (stuff->window, client); 223 if(!pWin) return BadWindow; 224 225 if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { 226 return BadMatch; 227 } 228 pScrn = ext->extPrivate; 229 pVMWARE = VMWAREPTR(pScrn); 230 231 rep.type = X_Reply; 232 rep.length = 0; 233 rep.sequenceNumber = client->sequence; 234 rep.width = pVMWARE->xineramaState[stuff->screen].width; 235 rep.height = pVMWARE->xineramaState[stuff->screen].height; 236 if(client->swapped) { 237 swaps(&rep.sequenceNumber, n); 238 swapl(&rep.length, n); 239 swaps(&rep.width, n); 240 swaps(&rep.height, n); 241 } 242 WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); 243 return client->noClientException; 244} 245 246 247/* 248 *---------------------------------------------------------------------------- 249 * 250 * VMwareXineramaIsActive -- 251 * 252 * Implementation of IsActive command handler. Initialises and 253 * sends a reply. 254 * 255 * Results: 256 * Standard response codes. 257 * 258 * Side effects: 259 * Writes reply to client. 260 * 261 *---------------------------------------------------------------------------- 262 */ 263 264static int 265VMwareXineramaIsActive(ClientPtr client) 266{ 267 xXineramaIsActiveReply rep; 268 ExtensionEntry *ext; 269 ScrnInfoPtr pScrn; 270 VMWAREPtr pVMWARE; 271 272 REQUEST_SIZE_MATCH(xXineramaIsActiveReq); 273 274 if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { 275 return BadMatch; 276 } 277 pScrn = ext->extPrivate; 278 pVMWARE = VMWAREPTR(pScrn); 279 280 rep.type = X_Reply; 281 rep.length = 0; 282 rep.sequenceNumber = client->sequence; 283 rep.state = pVMWARE->xinerama; 284 if(client->swapped) { 285 register int n; 286 swaps(&rep.sequenceNumber, n); 287 swapl(&rep.length, n); 288 swapl(&rep.state, n); 289 } 290 WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep); 291 return client->noClientException; 292} 293 294 295/* 296 *---------------------------------------------------------------------------- 297 * 298 * VMwareXineramaQueryScreens -- 299 * 300 * Implementation of QueryScreens command handler. Initialises and 301 * sends a reply. 302 * 303 * Results: 304 * Standard response codes. 305 * 306 * Side effects: 307 * Writes reply to client. 308 * 309 *---------------------------------------------------------------------------- 310 */ 311 312static int 313VMwareXineramaQueryScreens(ClientPtr client) 314{ 315 xXineramaQueryScreensReply rep; 316 ExtensionEntry *ext; 317 ScrnInfoPtr pScrn; 318 VMWAREPtr pVMWARE; 319 320 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); 321 322 if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { 323 return BadMatch; 324 } 325 pScrn = ext->extPrivate; 326 pVMWARE = VMWAREPTR(pScrn); 327 328 rep.type = X_Reply; 329 rep.sequenceNumber = client->sequence; 330 rep.number = pVMWARE->xinerama ? pVMWARE->xineramaNumOutputs : 0; 331 rep.length = rep.number * sz_XineramaScreenInfo >> 2; 332 if(client->swapped) { 333 register int n; 334 swaps(&rep.sequenceNumber, n); 335 swapl(&rep.length, n); 336 swapl(&rep.number, n); 337 } 338 WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep); 339 340 if(pVMWARE->xinerama) { 341 xXineramaScreenInfo scratch; 342 int i; 343 344 for(i = 0; i < pVMWARE->xineramaNumOutputs; i++) { 345 scratch.x_org = pVMWARE->xineramaState[i].x_org; 346 scratch.y_org = pVMWARE->xineramaState[i].y_org; 347 scratch.width = pVMWARE->xineramaState[i].width; 348 scratch.height = pVMWARE->xineramaState[i].height; 349 if(client->swapped) { 350 register int n; 351 swaps(&scratch.x_org, n); 352 swaps(&scratch.y_org, n); 353 swaps(&scratch.width, n); 354 swaps(&scratch.height, n); 355 } 356 WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch); 357 } 358 } 359 360 return client->noClientException; 361} 362 363 364/* 365 *---------------------------------------------------------------------------- 366 * 367 * VMwareXineramaDispatch -- 368 * 369 * Dispatcher for Xinerama commands. Calls the correct handler for 370 * each command type. 371 * 372 * Results: 373 * Standard response codes. 374 * 375 * Side effects: 376 * Side effects of individual command handlers. 377 * 378 *---------------------------------------------------------------------------- 379 */ 380 381static int 382VMwareXineramaDispatch(ClientPtr client) 383{ 384 REQUEST(xReq); 385 switch (stuff->data) { 386 case X_PanoramiXQueryVersion: 387 return VMwareXineramaQueryVersion(client); 388 case X_PanoramiXGetState: 389 return VMwareXineramaGetState(client); 390 case X_PanoramiXGetScreenCount: 391 return VMwareXineramaGetScreenCount(client); 392 case X_PanoramiXGetScreenSize: 393 return VMwareXineramaGetScreenSize(client); 394 case X_XineramaIsActive: 395 return VMwareXineramaIsActive(client); 396 case X_XineramaQueryScreens: 397 return VMwareXineramaQueryScreens(client); 398 } 399 return BadRequest; 400} 401 402 403/* 404 *---------------------------------------------------------------------------- 405 * 406 * SVMwareXineramaQueryVersion -- 407 * 408 * Wrapper for QueryVersion handler that handles input from other-endian 409 * clients. 410 * 411 * Results: 412 * Standard response codes. 413 * 414 * Side effects: 415 * Side effects of unswapped implementation. 416 * 417 *---------------------------------------------------------------------------- 418 */ 419 420static int 421SVMwareXineramaQueryVersion (ClientPtr client) 422{ 423 REQUEST(xPanoramiXQueryVersionReq); 424 register int n; 425 swaps(&stuff->length,n); 426 REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); 427 return VMwareXineramaQueryVersion(client); 428} 429 430 431/* 432 *---------------------------------------------------------------------------- 433 * 434 * SVMwareXineramaGetState -- 435 * 436 * Wrapper for GetState handler that handles input from other-endian 437 * clients. 438 * 439 * Results: 440 * Standard response codes. 441 * 442 * Side effects: 443 * Side effects of unswapped implementation. 444 * 445 *---------------------------------------------------------------------------- 446 */ 447 448static int 449SVMwareXineramaGetState(ClientPtr client) 450{ 451 REQUEST(xPanoramiXGetStateReq); 452 register int n; 453 swaps (&stuff->length, n); 454 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); 455 return VMwareXineramaGetState(client); 456} 457 458 459/* 460 *---------------------------------------------------------------------------- 461 * 462 * SVMwareXineramaGetScreenCount -- 463 * 464 * Wrapper for GetScreenCount handler that handles input from other-endian 465 * clients. 466 * 467 * Results: 468 * Standard response codes. 469 * 470 * Side effects: 471 * Side effects of unswapped implementation. 472 * 473 *---------------------------------------------------------------------------- 474 */ 475 476static int 477SVMwareXineramaGetScreenCount(ClientPtr client) 478{ 479 REQUEST(xPanoramiXGetScreenCountReq); 480 register int n; 481 swaps (&stuff->length, n); 482 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); 483 return VMwareXineramaGetScreenCount(client); 484} 485 486 487/* 488 *---------------------------------------------------------------------------- 489 * 490 * SVMwareXineramaGetScreenSize -- 491 * 492 * Wrapper for GetScreenSize handler that handles input from other-endian 493 * clients. 494 * 495 * Results: 496 * Standard response codes. 497 * 498 * Side effects: 499 * Side effects of unswapped implementation. 500 * 501 *---------------------------------------------------------------------------- 502 */ 503 504static int 505SVMwareXineramaGetScreenSize(ClientPtr client) 506{ 507 REQUEST(xPanoramiXGetScreenSizeReq); 508 register int n; 509 swaps (&stuff->length, n); 510 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); 511 return VMwareXineramaGetScreenSize(client); 512} 513 514 515/* 516 *---------------------------------------------------------------------------- 517 * 518 * SVMwareXineramaIsActive -- 519 * 520 * Wrapper for IsActive handler that handles input from other-endian 521 * clients. 522 * 523 * Results: 524 * Standard response codes. 525 * 526 * Side effects: 527 * Side effects of unswapped implementation. 528 * 529 *---------------------------------------------------------------------------- 530 */ 531 532static int 533SVMwareXineramaIsActive(ClientPtr client) 534{ 535 REQUEST(xXineramaIsActiveReq); 536 register int n; 537 swaps (&stuff->length, n); 538 REQUEST_SIZE_MATCH(xXineramaIsActiveReq); 539 return VMwareXineramaIsActive(client); 540} 541 542 543/* 544 *---------------------------------------------------------------------------- 545 * 546 * SVMwareXineramaQueryScreens -- 547 * 548 * Wrapper for QueryScreens handler that handles input from other-endian 549 * clients. 550 * 551 * Results: 552 * Standard response codes. 553 * 554 * Side effects: 555 * Side effects of unswapped implementation. 556 * 557 *---------------------------------------------------------------------------- 558 */ 559 560static int 561SVMwareXineramaQueryScreens(ClientPtr client) 562{ 563 REQUEST(xXineramaQueryScreensReq); 564 register int n; 565 swaps (&stuff->length, n); 566 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); 567 return VMwareXineramaQueryScreens(client); 568} 569 570 571/* 572 *---------------------------------------------------------------------------- 573 * 574 * SVMwareXineramaDispatch -- 575 * 576 * Wrapper for dispatcher that handles input from other-endian clients. 577 * 578 * Results: 579 * Standard response codes. 580 * 581 * Side effects: 582 * Side effects of individual command handlers. 583 * 584 *---------------------------------------------------------------------------- 585 */ 586 587static int 588SVMwareXineramaDispatch(ClientPtr client) 589{ 590 REQUEST(xReq); 591 switch (stuff->data) { 592 case X_PanoramiXQueryVersion: 593 return SVMwareXineramaQueryVersion(client); 594 case X_PanoramiXGetState: 595 return SVMwareXineramaGetState(client); 596 case X_PanoramiXGetScreenCount: 597 return SVMwareXineramaGetScreenCount(client); 598 case X_PanoramiXGetScreenSize: 599 return SVMwareXineramaGetScreenSize(client); 600 case X_XineramaIsActive: 601 return SVMwareXineramaIsActive(client); 602 case X_XineramaQueryScreens: 603 return SVMwareXineramaQueryScreens(client); 604 } 605 return BadRequest; 606} 607 608 609/* 610 *---------------------------------------------------------------------------- 611 * 612 * VMwareXineramaResetProc -- 613 * 614 * Cleanup handler called when the extension is removed. 615 * 616 * Results: 617 * None 618 * 619 * Side effects: 620 * None 621 * 622 *---------------------------------------------------------------------------- 623 */ 624 625static void 626VMwareXineramaResetProc(ExtensionEntry* extEntry) 627{ 628 /* Called by CloseDownExtensions() */ 629 630 ScrnInfoPtr pScrn = extEntry->extPrivate; 631 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 632 633 if (pVMWARE->xineramaState) { 634 xfree(pVMWARE->xineramaState); 635 pVMWARE->xineramaState = NULL; 636 pVMWARE->xineramaNumOutputs = 0; 637 pVMWARE->xinerama = FALSE; 638 } 639} 640 641 642/* 643 *---------------------------------------------------------------------------- 644 * 645 * VMwareCtrl_ExitInit -- 646 * 647 * Initialiser for the Xinerama protocol extension. 648 * 649 * Results: 650 * None. 651 * 652 * Side effects: 653 * Protocol extension will be registered if successful. 654 * 655 *---------------------------------------------------------------------------- 656 */ 657 658void 659VMwareXinerama_ExtInit(ScrnInfoPtr pScrn) 660{ 661 ExtensionEntry *myext; 662 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 663 664#ifdef PANORAMIX 665 if(!noPanoramiXExtension) { 666 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 667 "Built-in Xinerama active, not initializing VMware Xinerama\n"); 668 pVMWARE->xinerama = FALSE; 669 return; 670 } 671#endif 672 673 if (!(myext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { 674 if (!(myext = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0, 675 VMwareXineramaDispatch, 676 SVMwareXineramaDispatch, 677 VMwareXineramaResetProc, 678 StandardMinorOpcode))) { 679 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 680 "Failed to add VMware Xinerama extension.\n"); 681 return; 682 } 683 684 pVMWARE->xinerama = TRUE; 685 686 myext->extPrivate = pScrn; 687 688 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 689 "Initialized VMware Xinerama extension.\n"); 690 } 691} 692