Changeset 27529 in vbox for trunk/src/VBox/Additions/x11
- Timestamp:
- Mar 19, 2010 12:38:52 PM (15 years ago)
- Location:
- trunk/src/VBox/Additions/x11/vboxvideo
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
r26054 r27529 50 50 $(VBOX_PATH_X11_XFREE_4_3)/include/X11 \ 51 51 $(VBOX_PATH_X11_XFREE_4_3)/include/X11/extensions \ 52 $(VBOX_PATH_X11_XFREE_4_3)/include/extensions \ 52 53 $(VBOX_PATH_X11_XFREE_4_3)/include/fonts \ 53 54 $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/afb \ … … 73 74 $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/miext/shadow \ 74 75 $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/render \ 76 $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/randr \ 75 77 $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/Xext 76 78 else -
trunk/src/VBox/Additions/x11/vboxvideo/undefined_70
r26054 r27529 144 144 xf86sprintf 145 145 _GLOBAL_OFFSET_TABLE_ 146 XNFstrdup 147 FatalError -
trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c
r27314 r27529 48 48 /* #define DEBUG_POINTER */ 49 49 50 #define BOOL_STR(a) ((a) ? "TRUE" : "FALSE") 51 52 #ifdef DEBUG_VIDEO 53 # define TRACE_LINE() do \ 54 { \ 55 ErrorF ("%s: line %d\n", __FUNCTION__, __LINE__); \ 56 } while(0) 50 #ifdef DEBUG 57 51 # define PUT_PIXEL(c) ErrorF ("%c", c) 58 52 #else /* DEBUG_VIDEO not defined */ 59 53 # define PUT_PIXEL(c) do { } while(0) 60 # define TRACE_LINE() do { } while(0)61 54 #endif /* DEBUG_VIDEO not defined */ 62 55 … … 472 465 int rc; 473 466 474 TRACE_ENTRY();475 467 pVBox->reqp->fFlags = 0; 476 468 rc = VbglR3SetPointerShapeReq(pVBox->reqp); … … 490 482 int rc; 491 483 492 TRACE_ENTRY();493 484 if (vbox_host_uses_hwcursor(pScrn)) { 494 485 pVBox->reqp->fFlags = VBOX_MOUSE_POINTER_VISIBLE; … … 512 503 reqp = (VMMDevReqMousePointer *)image; 513 504 514 TRACE_LOG("w=%d h=%d size=%d\n", reqp->width, reqp->height, reqp->header.size);515 505 #ifdef DEBUG_POINTER 516 506 vbox_show_shape(reqp->width, reqp->height, 0, image); … … 530 520 vbox_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg) 531 521 { 532 TRACE_ENTRY();533 534 522 NOREF(pScrn); 535 523 NOREF(bg); … … 554 542 VBOXPtr pVBox = pScrn->driverPrivate; 555 543 556 TRACE_ENTRY();557 558 544 vbox_vmm_hide_cursor(pScrn, pVBox); 559 545 } … … 564 550 VBOXPtr pVBox = pScrn->driverPrivate; 565 551 566 TRACE_ENTRY();567 568 552 vbox_vmm_show_cursor(pScrn, pVBox); 569 553 } … … 573 557 { 574 558 VBOXPtr pVBox = pScrn->driverPrivate; 575 576 TRACE_ENTRY();577 559 578 560 vbox_vmm_load_cursor_image(pScrn, pVBox, image); … … 604 586 VMMDevReqMousePointer *reqp; 605 587 606 TRACE_ENTRY();607 588 pVBox = infoPtr->pScrn->driverPrivate; 608 589 bitsp = pCurs->bits; … … 728 709 Bool rc = TRUE; 729 710 730 TRACE_ENTRY();731 711 if (!vbox_host_uses_hwcursor(pScrn)) 732 712 rc = FALSE; -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
r27309 r27529 57 57 #define _VBOXVIDEO_H_ 58 58 59 #ifdef DEBUG_michael 60 # define DEBUG_VIDEO 1 61 #endif 62 63 #ifdef DEBUG_VIDEO 59 #ifdef DEBUG 64 60 65 61 #define TRACE_ENTRY() \ … … 82 78 ErrorF ("%s: line %d\n", __FUNCTION__, __LINE__); \ 83 79 } while(0) 84 85 #else /* DEBUG_VIDEO not defined */ 80 # define XF86ASSERT(expr, out) \ 81 if (!(expr)) \ 82 { \ 83 ErrorF ("\nAssertion failed!\n\n"); \ 84 ErrorF ("%s\n", #expr); \ 85 ErrorF ("at %s (%s:%d)\n", __PRETTY_FUNCTION__, __FILE__, __LINE__); \ 86 ErrorF out; \ 87 FatalError("Aborting"); \ 88 } 89 #else /* !DEBUG */ 86 90 87 91 #define TRACE_ENTRY() do { } while(0) … … 89 93 #define TRACE_LOG(...) do { } while(0) 90 94 91 #endif /* DEBUG_VIDEO not defined*/95 #endif /* !DEBUG */ 92 96 93 97 #define BOOL_STR(a) ((a) ? "TRUE" : "FALSE") … … 202 206 CARD8 *fonts; 203 207 vgaRegRec vgaRegs; /* Space for saving VGA information */ 204 /* DGA info */205 DGAModePtr pDGAMode;206 int nDGAMode;207 208 CloseScreenProcPtr CloseScreen; 208 209 /** Default X server procedure for enabling and disabling framebuffer access */ … … 212 213 OptionInfoPtr Options; 213 214 IOADDRESS ioBase; 215 /** The width of the last resolution set, used to avoid resetting modes */ 216 int cLastWidth; 217 /** The height of the last resolution set */ 218 int cLastHeight; 214 219 VMMDevReqMousePointer *reqp; 215 220 xf86CursorInfoPtr pCurs; -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_70.c
r26493 r27529 51 51 * Authors: Paulo César Pereira de Andrade <[email protected]> 52 52 */ 53 54 #ifdef DEBUG_michael55 # define DEBUG_VIDEO 156 #endif57 #ifdef DEBUG_VIDEO58 59 #define TRACE \60 do { \61 xf86Msg(X_INFO, __PRETTY_FUNCTION__); \62 xf86Msg(X_INFO, ": entering\n"); \63 } while(0)64 #define TRACE2 \65 do { \66 xf86Msg(X_INFO, __PRETTY_FUNCTION__); \67 xf86Msg(X_INFO, ": leaving\n"); \68 } while(0)69 #define TRACE3(...) \70 do { \71 xf86Msg(X_INFO, __PRETTY_FUNCTION__); \72 xf86Msg(X_INFO, __VA_ARGS__); \73 } while(0)74 75 #else /* DEBUG_VIDEO not defined */76 77 #define TRACE do { } while(0)78 #define TRACE2 do { } while(0)79 #define TRACE3(...) do { } while(0)80 81 #endif /* DEBUG_VIDEO not defined */82 53 83 54 #ifdef XORG_7X … … 132 103 static Bool VBOXSaveRestore(ScrnInfoPtr pScrn, 133 104 vbeSaveRestoreFunction function); 134 135 /* Initialise DGA */ 136 137 static Bool VBOXDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); 105 static void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent); 106 static bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, DisplayModePtr pMode); 138 107 139 108 /* … … 387 356 } 388 357 358 /** 359 * Fills a display mode M with a built-in mode of name pszName and dimensions 360 * cx and cy. 361 */ 362 static void vboxFillDisplayMode(DisplayModePtr m, const char *pszName, 363 unsigned cx, unsigned cy) 364 { 365 TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy); 366 m->status = MODE_OK; 367 m->type = M_T_BUILTIN; 368 /* VBox only supports screen widths which are a multiple of 8 */ 369 m->HDisplay = cx & ~7; 370 m->HSyncStart = m->HDisplay + 2; 371 m->HSyncEnd = m->HDisplay + 4; 372 m->HTotal = m->HDisplay + 6; 373 m->VDisplay = cy; 374 m->VSyncStart = m->VDisplay + 2; 375 m->VSyncEnd = m->VDisplay + 4; 376 m->VTotal = m->VDisplay + 6; 377 m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */ 378 if (pszName) 379 { 380 if (m->name) 381 xfree(m->name); 382 m->name = xnfstrdup(pszName); 383 } 384 } 385 386 /** vboxvideo's list of standard video modes */ 387 struct 388 { 389 /** mode width */ 390 uint32_t cx; 391 /** mode height */ 392 uint32_t cy; 393 } vboxStandardModes[] = 394 { 395 { 1600, 1200 }, 396 { 1440, 1050 }, 397 { 1280, 960 }, 398 { 1024, 768 }, 399 { 800, 600 }, 400 { 640, 480 }, 401 { 0, 0 } 402 }; 403 enum 404 { 405 vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0]) 406 }; 407 408 /** 409 * Returns a standard mode which the host likes. Can be called multiple 410 * times with the index returned by the previous call to get a list of modes. 411 * @returns the index of the mode in the list, or 0 if no more modes are 412 * available 413 * @param pScrn the screen information structure 414 * @param pScrn->bitsPerPixel 415 * if this is non-null, only modes with this BPP will be 416 * returned 417 * @param cIndex the index of the last mode queried, or 0 to query the 418 * first mode available. Note: the first index is 1 419 * @param pcx where to store the mode's width 420 * @param pcy where to store the mode's height 421 * @param pcBits where to store the mode's BPP 422 */ 423 static unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex, 424 uint32_t *pcx, uint32_t *pcy, 425 uint32_t *pcBits) 426 { 427 XF86ASSERT(cIndex < vboxNumStdModes, 428 ("cIndex = %d, vboxNumStdModes = %d\n", cIndex, 429 vboxNumStdModes)); 430 for (unsigned i = cIndex; i < vboxNumStdModes - 1; ++i) 431 { 432 uint32_t cBits = pScrn->bitsPerPixel; 433 uint32_t cx = vboxStandardModes[i].cx; 434 uint32_t cy = vboxStandardModes[i].cy; 435 436 if (cBits != 0 && !vboxHostLikesVideoMode(pScrn, cx, cy, cBits)) 437 continue; 438 if (vboxHostLikesVideoMode(pScrn, cx, cy, 32)) 439 cBits = 32; 440 else if (vboxHostLikesVideoMode(pScrn, cx, cy, 16)) 441 cBits = 16; 442 else 443 continue; 444 if (pcx) 445 *pcx = cx; 446 if (pcy) 447 *pcy = cy; 448 if (pcBits) 449 *pcBits = cBits; 450 return i + 1; 451 } 452 return 0; 453 } 454 455 /** 456 * Returns the preferred video mode. The current order of preference is 457 * (from highest to least preferred): 458 * - The mode corresponding to the last size hint from the host 459 * - The video mode saved from the last session 460 * - The largest standard mode which the host likes, falling back to 461 * 640x480x32 as a worst case 462 * - If the host can't be contacted at all, we return 1024x768x32 463 * 464 * The return type is void as we guarantee we will return some mode. 465 */ 466 static void vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t *pcx, 467 uint32_t *pcy, uint32_t *pcBits) 468 { 469 /* Query the host for the preferred resolution and colour depth */ 470 uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 32; 471 VBOXPtr pVBox = pScrn->driverPrivate; 472 473 TRACE_ENTRY(); 474 if (pVBox->useDevice) 475 { 476 bool found = vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits, &iDisplay); 477 if ((cx == 0) || (cy == 0)) 478 found = false; 479 if (!found) 480 found = vboxRetrieveVideoMode(pScrn, &cx, &cy, &cBits); 481 if ((cx == 0) || (cy == 0)) 482 found = false; 483 if (found) 484 /* Adjust to a multiple of eight */ 485 cx -= cx % 8; 486 if (!found) 487 found = (vboxNextStandardMode(pScrn, 0, &cx, &cy, &cBits) != 0); 488 if (!found) 489 { 490 /* Last resort */ 491 cx = 640; 492 cy = 480; 493 cBits = 32; 494 } 495 } 496 else 497 { 498 cx = 1024; 499 cy = 768; 500 } 501 if (pcx) 502 *pcx = cx; 503 if (pcy) 504 *pcy = cy; 505 if (pcx) 506 *pcBits = cBits; 507 } 508 509 /* Move a screen mode found to the end of the list, so that RandR will give 510 * it the highest priority when a mode switch is requested. Returns the mode 511 * that was previously before the mode in the list in order to allow the 512 * caller to continue walking the list. */ 513 static DisplayModePtr vboxMoveModeToFront(ScrnInfoPtr pScrn, 514 DisplayModePtr pMode) 515 { 516 DisplayModePtr pPrev = pMode->prev; 517 if (pMode != pScrn->modes) 518 { 519 pMode->prev->next = pMode->next; 520 pMode->next->prev = pMode->prev; 521 pMode->next = pScrn->modes; 522 pMode->prev = pScrn->modes->prev; 523 pMode->next->prev = pMode; 524 pMode->prev->next = pMode; 525 pScrn->modes = pMode; 526 } 527 return pPrev; 528 } 529 530 /** 531 * Rewrites the first dynamic mode found which is not the current screen mode 532 * to contain the host's currently preferred screen size, then moves that 533 * mode to the front of the screen information structure's mode list. 534 * Additionally, if the current mode is not dynamic, the second dynamic mode 535 * will be set to match the current mode and also added to the front. This 536 * ensures that the user can always reset the current size to kick the driver 537 * to update its mode list. 538 */ 539 static void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent) 540 { 541 uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 0; 542 DisplayModePtr pMode; 543 bool found = false; 544 545 TRACE_ENTRY(); 546 vboxGetPreferredMode(pScrn, &cx, &cy, &cBits); 547 #ifdef DEBUG 548 /* Count the number of modes for sanity */ 549 unsigned cModes = 1, cMode = 0; 550 DisplayModePtr pCount; 551 for (pCount = pScrn->modes; ; pCount = pCount->next, ++cModes) 552 if (pCount->next == pScrn->modes) 553 break; 554 #endif 555 for (pMode = pScrn->modes; ; pMode = pMode->next) 556 { 557 #ifdef DEBUG 558 XF86ASSERT (cMode++ < cModes, (NULL)); 559 #endif 560 if ( pMode != pCurrent 561 && !strcmp(pMode->name, "VBoxDynamicMode")) 562 { 563 if (!found) 564 vboxFillDisplayMode(pMode, NULL, cx, cy); 565 else if (pCurrent) 566 vboxFillDisplayMode(pMode, NULL, pCurrent->HDisplay, 567 pCurrent->VDisplay); 568 found = true; 569 pMode = vboxMoveModeToFront(pScrn, pMode); 570 } 571 if (pMode->next == pScrn->modes) 572 break; 573 } 574 XF86ASSERT (found, 575 ("vboxvideo: no free dynamic mode found. Exiting.\n")); 576 XF86ASSERT ( (pScrn->modes->HDisplay == (long) cx) 577 || ( (pScrn->modes->HDisplay == pCurrent->HDisplay) 578 && (pScrn->modes->next->HDisplay == (long) cx)), 579 ("pScrn->modes->HDisplay=%u, pScrn->modes->next->HDisplay=%u\n", 580 pScrn->modes->HDisplay, pScrn->modes->next->HDisplay)); 581 XF86ASSERT ( (pScrn->modes->VDisplay == (long) cy) 582 || ( (pScrn->modes->VDisplay == pCurrent->VDisplay) 583 && (pScrn->modes->next->VDisplay == (long) cy)), 584 ("pScrn->modes->VDisplay=%u, pScrn->modes->next->VDisplay=%u\n", 585 pScrn->modes->VDisplay, pScrn->modes->next->VDisplay)); 586 } 587 588 /** 589 * Allocates an empty display mode and links it into the doubly linked list of 590 * modes pointed to by pScrn->modes. Returns a pointer to the newly allocated 591 * memory. 592 */ 593 static DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn) 594 { 595 DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1); 596 597 TRACE_ENTRY(); 598 if (!pScrn->modes) 599 { 600 pScrn->modes = pMode; 601 pMode->next = pMode; 602 pMode->prev = pMode; 603 } 604 else 605 { 606 pMode->next = pScrn->modes; 607 pMode->prev = pScrn->modes->prev; 608 pMode->next->prev = pMode; 609 pMode->prev->next = pMode; 610 } 611 return pMode; 612 } 613 614 /** 615 * Create display mode entries in the screen information structure for each 616 * of the initial graphics modes that we wish to support. This includes: 617 * - An initial mode, of the size requested by the caller 618 * - Two dynamic modes, one of which will be updated to match the last size 619 * hint from the host on each mode switch, but initially also of the 620 * requested size 621 * - Several standard modes, if possible ones that the host likes 622 * - Any modes that the user requested in xorg.conf/XFree86Config 623 */ 624 static void 625 vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, uint32_t cyInit) 626 { 627 unsigned cx = 0, cy = 0, cIndex = 0; 628 /* For reasons related to the way RandR 1.1 is implemented, we need to 629 * make sure that the initial mode (more precisely, a mode equal to the 630 * initial virtual resolution) is always present in the mode list. RandR 631 * has the assumption build in that there will either be a mode of that 632 * size present at all times, or that the first mode in the list will 633 * always be smaller than the initial virtual resolution. Since our 634 * approach to dynamic resizing isn't quite the way RandR was intended to 635 * be, and breaks the second assumption, we guarantee the first. */ 636 DisplayModePtr pMode = vboxAddEmptyScreenMode(pScrn); 637 vboxFillDisplayMode(pMode, "VBoxInitialMode", cxInit, cyInit); 638 /* Create our two dynamic modes. */ 639 pMode = vboxAddEmptyScreenMode(pScrn); 640 vboxFillDisplayMode(pMode, "VBoxDynamicMode", cxInit, cyInit); 641 pMode = vboxAddEmptyScreenMode(pScrn); 642 vboxFillDisplayMode(pMode, "VBoxDynamicMode", cxInit, cyInit); 643 /* Add standard modes supported by the host */ 644 for ( ; ; ) 645 { 646 char szName[256]; 647 cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy, NULL); 648 if (cIndex == 0) 649 break; 650 sprintf(szName, "VBox-%ux%u", cx, cy); 651 pMode = vboxAddEmptyScreenMode(pScrn); 652 vboxFillDisplayMode(pMode, szName, cx, cy); 653 } 654 /* And finally any modes specified by the user. We assume here that 655 * the mode names reflect the mode sizes. */ 656 for (unsigned i = 0; pScrn->display->modes != NULL 657 && pScrn->display->modes[i] != NULL; i++) 658 { 659 if (sscanf(pScrn->display->modes[i], "%ux%u", &cx, &cy) == 2) 660 { 661 pMode = vboxAddEmptyScreenMode(pScrn); 662 vboxFillDisplayMode(pMode, pScrn->display->modes[i], cx, cy); 663 } 664 } 665 } 666 389 667 /* 390 668 * QUOTE from the XFree86 DESIGN document: … … 417 695 Gamma gzeros = {0.0, 0.0, 0.0}; 418 696 rgb rzeros = {0, 0, 0}; 419 ClockRange *clockRanges;420 697 int i; 421 DisplayModePtr m_prev; 422 char szHostModeName[256] = ""; 423 698 DisplayModePtr pMode; 699 enum { MODE_MIN_SIZE = 64 }; 700 701 TRACE_ENTRY(); 424 702 /* Are we really starting the server, or is this just a dummy run? */ 425 703 if (flags & PROBE_DETECT) … … 493 771 494 772 /* Set up clock information that will support all modes we need. */ 495 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 496 clockRanges->next = NULL; 497 clockRanges->minClock = 1000; 498 clockRanges->maxClock = 1000000000; 499 clockRanges->clockIndex = -1; 500 clockRanges->ClockMulFactor = 1; 501 clockRanges->ClockDivFactor = 1; 502 503 /* Query the host for the preferred resolution and colour depth */ 504 { 505 uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 24; 506 507 if (vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits, &iDisplay)) 508 { 509 /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */ 510 if (cBits != 16) 511 cBits = 24; 512 if ((0 != cx) && (0 != cy)) { 513 cx -= cx % 8; 514 xf86sprintf(szHostModeName, "%dx%d", cx, cy); 515 } 516 } 773 pScrn->clockRanges = xnfcalloc(sizeof(ClockRange), 1); 774 pScrn->clockRanges->minClock = 1000; 775 pScrn->clockRanges->maxClock = 1000000000; 776 pScrn->clockRanges->clockIndex = -1; 777 pScrn->clockRanges->ClockMulFactor = 1; 778 pScrn->clockRanges->ClockDivFactor = 1; 779 780 /* Determine the preferred size and colour depth and setup video modes */ 781 { 782 uint32_t cx = 0, cy = 0, cBits = 0; 783 784 vboxGetPreferredMode(pScrn, &cx, &cy, &cBits); 785 /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */ 786 if (cBits != 16) 787 cBits = 24; 517 788 if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb)) 518 789 return FALSE; 790 vboxAddModes(pScrn, cx, cy); 519 791 } 520 792 if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16) … … 525 797 } 526 798 xf86PrintDepthBpp(pScrn); 527 528 /* To get around the problem of SUSE specifying a single, invalid mode in their529 * Xorg.conf by default, we add additional modes to the end of the user specified530 * list. This means that if all user modes are invalid, X will try our mode before531 * falling back to its standard mode list. */532 if (pScrn->display->modes == NULL)533 {534 i = 0;535 /* The user specified no modes at all. */536 pScrn->display->modes = xnfalloc(5 * sizeof(char*));537 }538 else539 {540 for (i = 0; pScrn->display->modes[i] != NULL; i++);541 pScrn->display->modes = xnfrealloc(pScrn->display->modes, (i + 5)542 * sizeof(char *));543 }544 /* Add additional modes to the end of the mode list in case the others are545 all invalid. */546 if (szHostModeName[0])547 {548 pScrn->display->modes[i] = szHostModeName;549 ++i;550 }551 if (vboxHostLikesVideoMode(pScrn, 1600, 1200, pScrn->bitsPerPixel))552 {553 pScrn->display->modes[i] = "1600x1200";554 ++i;555 }556 if (vboxHostLikesVideoMode(pScrn, 1440, 1050, pScrn->bitsPerPixel))557 {558 pScrn->display->modes[i] = "1440x1050";559 ++i;560 }561 if (vboxHostLikesVideoMode(pScrn, 1280, 960, pScrn->bitsPerPixel))562 {563 pScrn->display->modes[i] = "1280x960";564 ++i;565 }566 if (vboxHostLikesVideoMode(pScrn, 1024, 768, pScrn->bitsPerPixel))567 {568 pScrn->display->modes[i] = "1024x768";569 ++i;570 }571 if (vboxHostLikesVideoMode(pScrn, 800, 600, pScrn->bitsPerPixel))572 {573 pScrn->display->modes[i] = "800x600";574 ++i;575 }576 /* A mode of last resort */577 pScrn->display->modes[i] = "640x480";578 ++i;579 pScrn->display->modes[i] = NULL;580 581 /* Create a builtin mode for every specified mode. This allows to specify arbitrary582 * screen resolutions */583 m_prev = NULL;584 for (i = 0; pScrn->display->modes[i] != NULL; i++)585 {586 DisplayModePtr m;587 int x = 0, y = 0;588 589 if (sscanf(pScrn->display->modes[i], "%dx%d", &x, &y) == 2)590 {591 m = xnfcalloc(sizeof(DisplayModeRec), 1);592 m->status = MODE_OK;593 m->type = M_T_BUILTIN;594 /* VBox only supports screen widths which are a multiple of 8 */595 m->HDisplay = (x + 7) & ~7;596 m->HSyncStart = m->HDisplay + 2;597 m->HSyncEnd = m->HDisplay + 4;598 m->HTotal = m->HDisplay + 6;599 m->VDisplay = y;600 m->VSyncStart = m->VDisplay + 2;601 m->VSyncEnd = m->VDisplay + 4;602 m->VTotal = m->VDisplay + 6;603 m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */604 m->name = strdup(pScrn->display->modes[i]);605 if (!m_prev)606 pScrn->modePool = m;607 else608 m_prev->next = m;609 m->prev = m_prev;610 m_prev = m;611 }612 }613 799 614 800 /* Colour weight - we always call this, since we are always in … … 623 809 xf86SetGamma(pScrn, gzeros); 624 810 625 /* Set a sane minimum mode size and the maximum allowed by the available VRAM */ 626 { 627 unsigned maxSize, trySize = 512; 628 629 do { 630 maxSize = trySize; 631 trySize += 128; 632 } while (trySize * trySize * pScrn->bitsPerPixel / 8 < (unsigned)pScrn->videoRam * 1024); 633 634 /* I don't know exactly what these are for (and they are only used in a couple 635 of places in the X server code). */ 636 pScrn->display->virtualX = maxSize; 637 pScrn->display->virtualY = maxSize; 638 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 639 "The maximum supported resolution is currently %dx%d\n", maxSize, maxSize); 640 } 641 642 /* Filter out video modes not supported by the virtual hardware 643 we described. */ 644 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 645 pScrn->display->modes, 646 clockRanges, NULL, 64, pScrn->display->virtualX, 1, 647 64, pScrn->display->virtualY, 0, 0, 648 pScrn->videoRam * 1024, LOOKUP_BEST_REFRESH); 649 650 if (i <= 0) { 651 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No usable graphics modes found.\n"); 652 return (FALSE); 653 } 654 xf86PruneDriverModes(pScrn); 811 /* We don't validate with xf86ValidateModes and xf86PruneModes as we 812 * already know what we like and what we don't. */ 655 813 656 814 pScrn->currentMode = pScrn->modes; 815 816 /* Set the right virtual resolution. */ 817 pScrn->virtualX = pScrn->currentMode->HDisplay; 818 pScrn->virtualY = pScrn->currentMode->VDisplay; 819 657 820 pScrn->displayWidth = pScrn->virtualX; 658 821 659 822 xf86PrintModes(pScrn); 660 823 661 /* Set display resolution. Perhaps we should read this from the host.*/824 /* Set the DPI. Perhaps we should read this from the host? */ 662 825 xf86SetDpi(pScrn, 96, 96); 663 664 if (pScrn->modes == NULL) {665 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No graphics modes available\n");666 return (FALSE);667 }668 826 669 827 /* options */ … … 676 834 /* Framebuffer-related setup */ 677 835 pScrn->bitmapBitOrder = BITMAP_BIT_ORDER; 836 TRACE_EXIT(); 678 837 return (TRUE); 679 838 } … … 691 850 * mode. 692 851 * 693 * End QUOTE. Initialise the initial video mode.852 * End QUOTE. 694 853 */ 695 854 static Bool … … 701 860 unsigned flags; 702 861 862 TRACE_ENTRY(); 703 863 /* We make use of the X11 VBE code to save and restore text mode, in 704 864 order to keep our code simple. */ … … 724 884 pVBox->savedPal = VBESetGetPaletteData(pVBox->pVbe, FALSE, 0, 256, 725 885 NULL, FALSE, FALSE); 726 727 /* set first video mode */728 if (!VBOXSetMode(pScrn, pScrn->currentMode))729 return FALSE;730 886 731 887 /* set the viewport */ … … 769 925 fbPictureInit(pScreen, 0, 0); 770 926 771 VBOXDGAInit(pScrn, pScreen);772 773 927 xf86SetBlackWhitePixels(pScreen); 774 928 miInitializeBackingStore(pScreen); … … 800 954 if (serverGeneration == 1) 801 955 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 956 957 /* set first video mode */ 958 if (!VBOXSetMode(pScrn, pScrn->currentMode)) 959 return FALSE; 960 /* And make sure that a non-current dynamic mode is at the front of the 961 * list */ 962 vboxWriteHostModes(pScrn, pScrn->currentMode); 802 963 803 964 if (vbox_open (pScrn, pScreen, pVBox)) { … … 809 970 "The VBox video extensions are now enabled.\n"); 810 971 } 972 TRACE_EXIT(); 811 973 return (TRUE); 812 974 } … … 852 1014 VBOXUnmapVidMem(pScrn); 853 1015 } 854 if (pVBox->pDGAMode) {855 xfree(pVBox->pDGAMode);856 pVBox->pDGAMode = NULL;857 pVBox->nDGAMode = 0;858 }859 1016 pScrn->vtSema = FALSE; 860 1017 … … 876 1033 if (VBOXSetMode(pScrn, pMode) != TRUE) 877 1034 return FALSE; 1035 if (VBOXAdjustScreenPixmap(pScrn, pMode) != TRUE) 1036 return FALSE; 1037 vboxSaveVideoMode(pScrn, pMode->HDisplay, pMode->VDisplay, 1038 pScrn->bitsPerPixel); 1039 vboxWriteHostModes(pScrn, pMode); 1040 xf86PrintModes(pScrn); 878 1041 if (pVBox->useVbva == TRUE) 879 1042 if (vboxEnableVbva(pScrn) != TRUE) /* Bad but not fatal */ … … 886 1049 VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) 887 1050 { 1051 TRACE_ENTRY(); 888 1052 int bpp = pScrn->depth == 24 ? 32 : 16; 889 int xRes = pMode->HDisplay;890 1053 VBOXPtr pVBox = VBOXGetRec(pScrn); 891 1054 … … 898 1061 return FALSE; 899 1062 } 900 /* We only support horizontal resolutions which are a multiple of 8. Round down if 901 necessary. */ 902 if (xRes % 8 != 0) 903 { 904 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 905 "VirtualBox only supports screen widths which are a multiple of 8. Rounding down from %d to %d\n", 906 xRes, xRes - (xRes % 8)); 907 xRes = xRes - (xRes % 8); 908 } 909 910 /* We force a software cursor if the guests virtual resolution is different 911 * to it's actual resolution, as in this case host and guest will disagree 912 * about the pointer position. */ 913 if ( (pScrn->virtualX - xRes >= 8) 914 || (pScrn->virtualY - pMode->VDisplay >= 8)) 915 pVBox->forceSWCursor = TRUE; 916 else 917 pVBox->forceSWCursor = FALSE; 1063 /* Do not reset the current mode - we use this as a way of kicking 1064 * the driver */ 1065 if ( (pMode->HDisplay == pVBox->cLastWidth) 1066 && (pMode->VDisplay == pVBox->cLastHeight)) 1067 return TRUE; 918 1068 919 1069 pScrn->vtSema = TRUE; … … 929 1079 the display part of the scanlines. */ 930 1080 outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES); 931 outw(VBE_DISPI_IOPORT_DATA, xRes);1081 outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay); 932 1082 outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES); 933 1083 outw(VBE_DISPI_IOPORT_DATA, pMode->VDisplay); … … 939 1089 the virtual offset. */ 940 1090 outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH); 941 outw(VBE_DISPI_IOPORT_DATA, pScrn->displayWidth); 1091 outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay); 1092 pVBox->cLastWidth = pMode->HDisplay; 1093 pVBox->cLastHeight = pMode->VDisplay; 1094 TRACE_EXIT(); 942 1095 return (TRUE); 1096 } 1097 1098 static bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, DisplayModePtr pMode) 1099 { 1100 ScreenPtr pScreen = pScrn->pScreen; 1101 PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen); 1102 VBOXPtr pVBox = VBOXGetRec(pScrn); 1103 int bpp = pScrn->depth == 24 ? 32 : 16; 1104 if (!pPixmap) { 1105 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1106 "Failed to get the screen pixmap.\n"); 1107 return FALSE; 1108 } 1109 pScreen->ModifyPixmapHeader(pPixmap, pMode->HDisplay, pMode->VDisplay, 1110 pScrn->depth, bpp, pMode->HDisplay * bpp / 8, 1111 pVBox->base); 1112 pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE); 1113 pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE); 1114 return TRUE; 943 1115 } 944 1116 … … 1321 1493 } 1322 1494 1323 1324 1325 1326 /***********************************************************************1327 * DGA stuff1328 ***********************************************************************/1329 static Bool VBOXDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName,1330 unsigned char **ApertureBase,1331 int *ApertureSize, int *ApertureOffset,1332 int *flags);1333 static Bool VBOXDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode);1334 static void VBOXDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags);1335 1336 static Bool1337 VBOXDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName,1338 unsigned char **ApertureBase, int *ApertureSize,1339 int *ApertureOffset, int *flags)1340 {1341 VBOXPtr pVBox = VBOXGetRec(pScrn);1342 1343 *DeviceName = NULL; /* No special device */1344 *ApertureBase = (unsigned char *)(long)(pVBox->mapPhys);1345 *ApertureSize = pVBox->mapSize;1346 *ApertureOffset = pVBox->mapOff;1347 *flags = DGA_NEED_ROOT;1348 1349 return (TRUE);1350 }1351 1352 static Bool1353 VBOXDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode)1354 {1355 DisplayModePtr pMode;1356 int scrnIdx = pScrn->pScreen->myNum;1357 int frameX0, frameY0;1358 1359 if (pDGAMode) {1360 pMode = pDGAMode->mode;1361 frameX0 = frameY0 = 0;1362 }1363 else {1364 if (!(pMode = pScrn->currentMode))1365 return (TRUE);1366 1367 frameX0 = pScrn->frameX0;1368 frameY0 = pScrn->frameY0;1369 }1370 1371 if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0))1372 return (FALSE);1373 (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0);1374 1375 return (TRUE);1376 }1377 1378 static void1379 VBOXDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)1380 {1381 (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags);1382 }1383 1384 static int1385 VBOXDGAGetViewport(ScrnInfoPtr pScrn)1386 {1387 return (0);1388 }1389 1390 static DGAFunctionRec VBOXDGAFunctions =1391 {1392 VBOXDGAOpenFramebuffer,1393 NULL, /* CloseFramebuffer */1394 VBOXDGASetMode,1395 VBOXDGASetViewport,1396 VBOXDGAGetViewport,1397 NULL, /* Sync */1398 NULL, /* FillRect */1399 NULL, /* BlitRect */1400 NULL, /* BlitTransRect */1401 };1402 1403 static void1404 VBOXDGAAddModes(ScrnInfoPtr pScrn)1405 {1406 VBOXPtr pVBox = VBOXGetRec(pScrn);1407 DisplayModePtr pMode = pScrn->modes;1408 DGAModePtr pDGAMode;1409 1410 do {1411 pDGAMode = xrealloc(pVBox->pDGAMode,1412 (pVBox->nDGAMode + 1) * sizeof(DGAModeRec));1413 if (!pDGAMode)1414 break;1415 1416 pVBox->pDGAMode = pDGAMode;1417 pDGAMode += pVBox->nDGAMode;1418 (void)memset(pDGAMode, 0, sizeof(DGAModeRec));1419 1420 ++pVBox->nDGAMode;1421 pDGAMode->mode = pMode;1422 pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;1423 pDGAMode->byteOrder = pScrn->imageByteOrder;1424 pDGAMode->depth = pScrn->depth;1425 pDGAMode->bitsPerPixel = pScrn->bitsPerPixel;1426 pDGAMode->red_mask = pScrn->mask.red;1427 pDGAMode->green_mask = pScrn->mask.green;1428 pDGAMode->blue_mask = pScrn->mask.blue;1429 pDGAMode->visualClass = TrueColor;1430 pDGAMode->xViewportStep = 1;1431 pDGAMode->yViewportStep = 1;1432 pDGAMode->viewportWidth = pMode->HDisplay;1433 pDGAMode->viewportHeight = pMode->VDisplay;1434 1435 pDGAMode->bytesPerScanline = pVBox->maxBytesPerScanline;1436 pDGAMode->imageWidth = pMode->HDisplay;1437 pDGAMode->imageHeight = pMode->VDisplay;1438 pDGAMode->pixmapWidth = pDGAMode->imageWidth;1439 pDGAMode->pixmapHeight = pDGAMode->imageHeight;1440 pDGAMode->maxViewportX = pScrn->virtualX -1441 pDGAMode->viewportWidth;1442 pDGAMode->maxViewportY = pScrn->virtualY -1443 pDGAMode->viewportHeight;1444 1445 pDGAMode->address = pVBox->base;1446 1447 pMode = pMode->next;1448 } while (pMode != pScrn->modes);1449 }1450 1451 static Bool1452 VBOXDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen)1453 {1454 VBOXPtr pVBox = VBOXGetRec(pScrn);1455 1456 if (!pVBox->nDGAMode)1457 VBOXDGAAddModes(pScrn);1458 1459 return (DGAInit(pScreen, &VBOXDGAFunctions,1460 pVBox->pDGAMode, pVBox->nDGAMode));1461 }
Note:
See TracChangeset
for help on using the changeset viewer.