VirtualBox

Changeset 34715 in vbox


Ignore:
Timestamp:
Dec 3, 2010 11:25:52 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
68518
Message:

Additions/x11/vboxvideo: switch to HGSMI and merge the two drivers into one file

Location:
trunk/src/VBox/Additions/x11/vboxvideo
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/vboxvideo/Makefile.kmk

    r33540 r34715  
    3838        BUILDDEBUG X_BYTE_ORDER=X_LITTLE_ENDIAN DNDEBUG FUNCPROTO=15 NARROWPROTO \
    3939        IN_MODULE XFree86Module
     40 vboxvideo_drv_DEFS += memset=xf86memset memcpy=xf86memcpy
    4041 vboxvideo_drv_INCS = \
    4142        $(VBOX_PATH_X11_XFREE_4_3)/include \
     
    6869        $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/randr \
    6970        $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/Xext
     71 vboxvideo_drv_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    7072 vboxvideo_drv_SOURCES = \
    71         vboxvideo_70.c \
    72         vboxutils.c
     73        vboxvideo_13.c \
     74        vboxutils.c \
     75        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
     76        $(PATH_ROOT)/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp \
     77        $(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapsimple.cpp \
     78        $(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapoffset.cpp \
     79        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
     80        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
    7381endif   # target linux
    7482
     
    97105        $(VBOX_PATH_X11_XORG_7_0)/X11 \
    98106        $(VBOX_PATH_X11_XORG_7_0)/xorg
     107vboxvideo_drv_70_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    99108vboxvideo_drv_70_SOURCES  = $(vboxvideo_drv_SOURCES)
    100109
     
    111120        $(VBOX_PATH_X11_XORG_7_1)/X11 \
    112121        $(VBOX_PATH_X11_XORG_7_1)/xorg
     122vboxvideo_drv_71_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    113123vboxvideo_drv_71_SOURCES  = $(vboxvideo_drv_SOURCES)
    114124
     
    129139        $(VBOX_PATH_X11_ROOT)/libdrm-2.4.13 \
    130140        $(VBOX_PATH_X11_ROOT)/xf86driproto-2.1.0
     141vboxvideo_drv_13_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    131142vboxvideo_drv_13_SOURCES = \
    132143        vboxvideo_13.c \
    133         vboxutils.c
     144        vboxutils.c \
     145        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
     146        $(PATH_ROOT)/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp \
     147        $(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapsimple.cpp \
     148        $(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapoffset.cpp \
     149        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
     150        $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
    134151
    135152
     
    152169        $(VBOX_PATH_X11_ROOT)/libdrm-2.4.13 \
    153170        $(VBOX_PATH_X11_ROOT)/xf86driproto-2.1.0
     171vboxvideo_drv_14_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    154172vboxvideo_drv_14_SOURCES  = $(vboxvideo_drv_13_SOURCES)
    155173
     
    174192        $(VBOX_PATH_X11_ROOT)/xf86driproto-2.1.0 \
    175193        $(VBOX_PATH_X11_ROOT)/xorg-server-1.5.3
     194vboxvideo_drv_15_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    176195vboxvideo_drv_15_SOURCES  = $(vboxvideo_drv_13_SOURCES)
    177196if1of ($(KBUILD_TARGET), linux solaris)
     
    197216        $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0 \
    198217        $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local
     218vboxvideo_drv_16_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    199219vboxvideo_drv_16_SOURCES := $(vboxvideo_drv_15_SOURCES)
    200220
     
    223243        $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local \
    224244        $(VBOX_PATH_X11_ROOT)/xproto-7.0.18
     245vboxvideo_drv_17_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    225246vboxvideo_drv_17_SOURCES := $(vboxvideo_drv_15_SOURCES)
    226247
     
    249270        $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local \
    250271        $(VBOX_PATH_X11_ROOT)/xproto-7.0.18
     272vboxvideo_drv_18_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    251273vboxvideo_drv_18_SOURCES := $(vboxvideo_drv_15_SOURCES)
    252274
     
    275297        $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local \
    276298        $(VBOX_PATH_X11_ROOT)/xproto-7.0.18
     299vboxvideo_drv_19_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
    277300vboxvideo_drv_19_SOURCES := $(vboxvideo_drv_15_SOURCES)
    278301
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c

    r33460 r34715  
    5959    while (0)
    6060
     61/** Structure to pass cursor image data between realise_cursor() and
     62 * load_cursor_image().  The members match the parameters to
     63 * @a VBoxHGSMIUpdatePointerShape(). */
     64struct vboxCursorImage
     65{
     66    uint32_t fFlags;
     67    uint32_t cHotX;
     68    uint32_t cHotY;
     69    uint32_t cWidth;
     70    uint32_t cHeight;
     71    uint8_t *pPixels;
     72    uint32_t cbLength;
     73};
     74
    6175#ifdef DEBUG_POINTER
    6276static void
     
    6983    size_t sizeMask;
    7084
    71     image    += offsetof(VMMDevReqMousePointer, pointerData);
     85    image    += sizeof(struct vboxCursorImage);
    7286    mask      = image;
    7387    pitch     = (w + 7) / 8;
     
    150164}
    151165
    152 /**
    153  * Macro to disable VBVA extensions and return, for use when an
    154  * unexplained error occurs.
    155  */
    156 #define DISABLE_VBVA_AND_RETURN(pScrn, ...) \
    157     do \
    158     { \
    159         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, __VA_ARGS__); \
    160         vboxDisableVbva(pScrn); \
    161         pVBox->useVbva = FALSE; \
    162         return; \
    163     } \
    164     while (0)
    165 
    166166/**************************************************************************
    167167* Main functions                                                          *
     
    193193    VBVACMDHDR cmdHdr;
    194194    VBOXPtr pVBox;
    195     VBVARECORD *pRecord;
    196     VBVAMEMORY *pMem;
    197     CARD32 indexRecordNext;
    198     CARD32 off32Data;
    199     CARD32 off32Free;
    200     INT32 i32Diff;
    201     CARD32 cbHwBufferAvail;
    202     int scrnIndex;
    203195    int i;
     196    unsigned j;
    204197
    205198    pVBox = pScrn->driverPrivate;
    206     if (pVBox->useVbva == FALSE)
     199    if (pVBox->fHaveHGSMI == FALSE)
    207200        return;
    208     pMem = pVBox->pVbvaMemory;
    209     /* Just return quietly if VBVA is not currently active. */
    210     if ((pMem->fu32ModeFlags & VBVA_F_MODE_ENABLED) == 0)
    211         return;
    212     scrnIndex = pScrn->scrnIndex;
    213 
    214     for (i = 0; i < iRects; i++)
    215     {
    216         cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->viewportX;
    217         cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->viewportY;
    218         cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
    219         cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
    220 
    221         /* Get the active record and move the pointer along */
    222         indexRecordNext = (pMem->indexRecordFree + 1) % VBVA_MAX_RECORDS;
    223         if (indexRecordNext == pMem->indexRecordFirst)
     201
     202    for (i = 0; i < iRects; ++i)
     203        for (j = 0; j < pVBox->cScreens; ++j)
    224204        {
    225             /* All slots in the records queue are used. */
    226             if (VbglR3VideoAccelFlush() < 0)
    227                 DISABLE_VBVA_AND_RETURN(pScrn,
    228                     "Unable to clear the VirtualBox graphics acceleration queue "
    229                     "- the request to the virtual machine failed.  Switching to "
    230                     "unaccelerated mode.\n");
     205            /* Just continue quietly if VBVA is not currently active. */
     206            struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
     207            if (   !pVBVA
     208                || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
     209                continue;
     210            if (   aRects[i].x1 >   pVBox->aScreenLocation[j].x
     211                                  + pVBox->aScreenLocation[j].cx
     212                || aRects[i].y1 >   pVBox->aScreenLocation[j].y
     213                                  + pVBox->aScreenLocation[j].cy
     214                || aRects[i].x2 <   pVBox->aScreenLocation[j].x
     215                || aRects[i].y2 <   pVBox->aScreenLocation[j].y)
     216                continue;
     217            cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->aScreenLocation[j].x;
     218            cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->aScreenLocation[j].y;
     219            cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
     220            cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
     221
     222            TRACE_LOG("x=%d, y=%d, w=%d, z=%d\n", cmdHdr.x, cmdHdr.y,
     223                      cmdHdr.w, cmdHdr.h);
     224           
     225            VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j], &pVBox->guestCtx);
     226            VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
     227                          sizeof(cmdHdr));
     228            VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);
    231229        }
    232         if (indexRecordNext == pMem->indexRecordFirst)
    233             DISABLE_VBVA_AND_RETURN(pScrn,
    234                 "Failed to clear the VirtualBox graphics acceleration queue.  "
    235                 "Switching to unaccelerated mode.\n");
    236         pRecord = &pMem->aRecords[pMem->indexRecordFree];
    237         /* Mark the record as being updated. */
    238         pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;
    239         pMem->indexRecordFree = indexRecordNext;
    240         /* Compute how many bytes we have in the ring buffer. */
    241         off32Free = pMem->off32Free;
    242         off32Data = pMem->off32Data;
    243         /* Free is writing position. Data is reading position.
    244          * Data == Free means buffer is free.
    245          * There must be always gap between free and data when data
    246          * are in the buffer.
    247          * Guest only changes free, host only changes data.
    248          */
    249         i32Diff = off32Data - off32Free;
    250         cbHwBufferAvail = i32Diff > 0 ? i32Diff : VBVA_RING_BUFFER_SIZE + i32Diff;
    251         if (cbHwBufferAvail <= VBVA_RING_BUFFER_THRESHOLD)
    252         {
    253             if (VbglR3VideoAccelFlush() < 0)
    254                 DISABLE_VBVA_AND_RETURN(pScrn,
    255                     "Unable to clear the VirtualBox graphics acceleration queue "
    256                     "- the request to the virtual machine failed.  Switching to "
    257                     "unaccelerated mode.\n");
    258             /* Calculate the free space again. */
    259             off32Free = pMem->off32Free;
    260             off32Data = pMem->off32Data;
    261             i32Diff = off32Data - off32Free;
    262             cbHwBufferAvail = i32Diff > 0? i32Diff:
    263                                   VBVA_RING_BUFFER_SIZE + i32Diff;
    264             if (cbHwBufferAvail <= VBVA_RING_BUFFER_THRESHOLD)
    265                 DISABLE_VBVA_AND_RETURN(pScrn,
    266                     "No space left in the VirtualBox graphics acceleration command buffer, "
    267                     "despite clearing the queue.  Switching to unaccelerated mode.\n");
    268         }
    269         /* Now copy the data into the buffer */
    270         if (off32Free + sizeof(cmdHdr) < VBVA_RING_BUFFER_SIZE)
    271         {
    272             memcpy(&pMem->au8RingBuffer[off32Free], &cmdHdr, sizeof(cmdHdr));
    273             pMem->off32Free = pMem->off32Free + sizeof(cmdHdr);
    274         }
    275         else
    276         {
    277             CARD32 u32First = VBVA_RING_BUFFER_SIZE - off32Free;
    278             /* The following is impressively ugly! */
    279             CARD8 *pu8Second = (CARD8 *)&cmdHdr + u32First;
    280             CARD32 u32Second = sizeof(cmdHdr) - u32First;
    281             memcpy(&pMem->au8RingBuffer[off32Free], &cmdHdr, u32First);
    282             if (u32Second)
    283                 memcpy(&pMem->au8RingBuffer[0], pu8Second, u32Second);
    284             pMem->off32Free = u32Second;
    285         }
    286         pRecord->cbRecord += sizeof(cmdHdr);
    287         /* Mark the record completed. */
    288         pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;
    289     }
    290 }
    291 
    292 #ifdef PCIACCESS
    293 /* As of X.org server 1.5, we are using the pciaccess library functions to
    294  * access PCI.  This structure describes our VMM device. */
    295 /** Structure describing the VMM device */
    296 static const struct pci_id_match vboxVMMDevID =
    297 { VMMDEV_VENDORID, VMMDEV_DEVICEID, PCI_MATCH_ANY, PCI_MATCH_ANY,
    298   0, 0, 0 };
    299 #endif
     230}
     231
     232/** Callback to fill in the view structures */
     233static int
     234vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
     235{
     236    VBOXPtr pVBox = (VBOXPtr)pvVBox;
     237    unsigned i;
     238    for (i = 0; i < cViews; ++i)
     239    {
     240        pViews[i].u32ViewIndex = i;
     241        pViews[i].u32ViewOffset = 0;
     242        pViews[i].u32ViewSize = pVBox->cbFramebuffer;
     243        pViews[i].u32MaxScreenSize = pVBox->cbFramebuffer;
     244    }
     245    return VINF_SUCCESS;
     246}
    300247
    301248/**
     
    307254vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
    308255{
    309 #ifdef PCIACCESS
    310     struct pci_device_iterator *devIter = NULL;
    311 
    312     TRACE_ENTRY();
    313     pVBox->vmmDevInfo = NULL;
    314     devIter = pci_id_match_iterator_create(&vboxVMMDevID);
    315     if (devIter)
    316     {
    317         pVBox->vmmDevInfo = pci_device_next(devIter);
    318         pci_iterator_destroy(devIter);
    319     }
    320     if (pVBox->vmmDevInfo)
    321     {
    322         if (pci_device_probe(pVBox->vmmDevInfo) != 0)
    323         {
    324             xf86DrvMsg (scrnIndex, X_ERROR,
    325                         "Failed to probe VMM device (vendor=%04x, devid=%04x)\n",
    326                         pVBox->vmmDevInfo->vendor_id,
    327                         pVBox->vmmDevInfo->device_id);
    328         }
    329         else
    330         {
    331             if (pci_device_map_range(pVBox->vmmDevInfo,
    332                                      pVBox->vmmDevInfo->regions[1].base_addr,
    333                                      pVBox->vmmDevInfo->regions[1].size,
    334                                      PCI_DEV_MAP_FLAG_WRITABLE,
    335                                      (void **)&pVBox->pVMMDevMemory) != 0)
    336                 xf86DrvMsg (scrnIndex, X_ERROR,
    337                             "Failed to map VMM device range\n");
    338         }
    339     }
    340 #else
    341     PCITAG pciTagDev;
    342     ADDRESS pciAddrDev;
    343 
    344     TRACE_ENTRY();
    345     /* Locate the device.  It should already have been enabled by
    346        the kernel driver. */
    347     pciTagDev = pciFindFirst((unsigned) VMMDEV_DEVICEID << 16 | VMMDEV_VENDORID,
    348                              (CARD32) ~0);
    349     if (pciTagDev == PCI_NOT_FOUND)
    350     {
    351         xf86DrvMsg(scrnIndex, X_ERROR,
    352                    "Could not find the VirtualBox base device on the PCI bus.\n");
     256    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     257    int rc = VINF_SUCCESS;
     258    unsigned i;
     259    uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory,
     260             cScreens;
     261    void *pvGuestHeapMemory;
     262
     263    pVBox->cScreens = 1;
     264    if (!VBoxHGSMIIsSupported())
     265    {
     266        xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI.  Disableing video acceleration.\n");
    353267        return FALSE;
    354268    }
    355     /* Read the address and size of the second I/O region. */
    356     pciAddrDev = pciReadLong(pciTagDev, PCI_MAP_REG_START + 4);
    357     if (pciAddrDev == 0 || pciAddrDev == (CARD32) ~0)
    358         RETERROR(scrnIndex, FALSE,
    359                  "The VirtualBox base device contains an invalid memory address.\n");
    360     if (PCI_MAP_IS64BITMEM(pciAddrDev))
    361         RETERROR(scrnIndex, FALSE,
    362                  "The VirtualBox base device has a 64bit mapping address.  "
    363                  "This is currently not supported.\n");
    364     /* Map it.  We hardcode the size as X does not export the
    365        function needed to determine it. */
    366     pVBox->pVMMDevMemory = xf86MapPciMem(scrnIndex, 0, pciTagDev, pciAddrDev,
    367                                          sizeof(VMMDevMemory));
    368 #endif
    369     if (pVBox->pVMMDevMemory == NULL)
    370     {
    371         xf86DrvMsg(scrnIndex, X_ERROR,
    372                    "Failed to map VirtualBox video extension memory.\n");
     269    VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
     270                                NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
     271                                NULL);
     272    pvGuestHeapMemory =   ((uint8_t *)pVBox->base) + offVRAMBaseMapping
     273                        + offGuestHeapMemory;
     274    rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
     275                                    cbGuestHeapMemory,
     276                                    offVRAMBaseMapping + offGuestHeapMemory);
     277    if (RT_FAILURE(rc))
     278    {
     279        xf86DrvMsg(scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
    373280        return FALSE;
    374281    }
    375     pVBox->pVbvaMemory = &pVBox->pVMMDevMemory->vbvaMemory;
     282    pVBox->cbFramebuffer = offVRAMBaseMapping;
     283    pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
     284    xf86DrvMsg(scrnIndex, X_INFO, "Requested monitor count: %u\n",
     285               pVBox->cScreens);
     286    rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
     287                               vboxFillViewInfo, (void *)pVBox);
     288    for (i = 0; i < pVBox->cScreens; ++i)
     289    {
     290        pVBox->cbFramebuffer -= VBVA_MIN_BUFFER_SIZE;
     291        pVBox->aoffVBVABuffer[i] = pVBox->cbFramebuffer;
     292        VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],
     293                                   pVBox->aoffVBVABuffer[i],
     294                                   VBVA_MIN_BUFFER_SIZE);
     295    }
     296
    376297    /* Set up the dirty rectangle handler.  Since this seems to be a
    377298       delicate operation, and removing it doubly so, this will
     
    396317
    397318    TRACE_ENTRY();
    398     pVBox->useVbva = FALSE;
    399319    vrc = VbglR3Init();
    400320    if (RT_FAILURE(vrc))
     
    423343    if (!pVBox->useDevice)
    424344        return FALSE;
    425     pVBox->useVbva = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
     345    pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
    426346    return TRUE;
    427347}
     
    438358    int rc;
    439359
    440     rc = VbglR3SetPointerShape(0, 0, 0, 0, 0, NULL, 0);
     360    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, 0, 0, 0, 0, 0, NULL, 0);
    441361    if (RT_FAILURE(rc))
    442362    {
     
    456376    if (!vbox_host_uses_hwcursor(pScrn))
    457377        return;
    458     rc = VbglR3SetPointerShape(VBOX_MOUSE_POINTER_VISIBLE, 0, 0, 0, 0, NULL, 0);
     378    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, VBOX_MOUSE_POINTER_VISIBLE,
     379                                     0, 0, 0, 0, NULL, 0);
    459380    if (RT_FAILURE(rc)) {
    460381        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not unhide the virtual mouse pointer.\n");
     
    468389static void
    469390vbox_vmm_load_cursor_image(ScrnInfoPtr pScrn, VBOXPtr pVBox,
    470                            unsigned char *image)
     391                           unsigned char *pvImage)
    471392{
    472393    int rc;
    473     VMMDevReqMousePointer *reqp;
    474     reqp = (VMMDevReqMousePointer *)image;
     394    struct vboxCursorImage *pImage;
     395    pImage = (struct vboxCursorImage *)pvImage;
    475396
    476397#ifdef DEBUG_POINTER
    477     vbox_show_shape(reqp->width, reqp->height, 0, image);
     398    vbox_show_shape(pImage->cWidth, pImage->cHeight, 0, pvImage);
    478399#endif
    479400
    480     rc = VbglR3SetPointerShapeReq(reqp);
     401    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, pImage->fFlags,
     402             pImage->cHotX, pImage->cHotY, pImage->cWidth, pImage->cHeight,
     403             pImage->pPixels, pImage->cbLength);
    481404    if (RT_FAILURE(rc)) {
    482405        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,  "Unable to set the virtual mouse pointer image.\n");
     
    555478    CARD32 fc, bc, *cp;
    556479    int rc, scrnIndex = infoPtr->pScrn->scrnIndex;
    557     VMMDevReqMousePointer *reqp;
     480    struct vboxCursorImage *pImage;
    558481
    559482    pVBox = infoPtr->pScrn->driverPrivate;
     
    575498    sizeMask = ((dstPitch * h) + 3) & (size_t) ~3;
    576499    sizeRgba = w * h * 4;
    577     sizeRequest = sizeMask + sizeRgba + sizeof(VMMDevReqMousePointer);
     500    sizeRequest = sizeMask + sizeRgba + sizeof(*pImage);
    578501
    579502    p = c = calloc (1, sizeRequest);
     
    583506                 (unsigned long) sizeRequest);
    584507
    585     rc = vmmdevInitRequest((VMMDevRequestHeader *)p, VMMDevReq_SetPointerShape);
    586     if (RT_FAILURE(rc))
    587     {
    588         xf86DrvMsg(scrnIndex, X_ERROR, "Could not init VMM request: rc = %d\n", rc);
    589         free(p);
    590         return NULL;
    591     }
    592 
    593     m = p + offsetof(VMMDevReqMousePointer, pointerData);
     508    pImage = (struct vboxCursorImage *)p;
     509    pImage->pPixels = m = p + sizeof(*pImage);
    594510    cp = (CARD32 *)(m + sizeMask);
    595511
     
    656572    }
    657573
    658     reqp = (VMMDevReqMousePointer *)p;
    659     reqp->width  = w;
    660     reqp->height = h;
    661     reqp->xHot   = bitsp->xhot;
    662     reqp->yHot   = bitsp->yhot;
    663     reqp->fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
    664     reqp->header.size = sizeRequest;
     574    pImage->cWidth   = w;
     575    pImage->cHeight  = h;
     576    pImage->cHotX    = bitsp->xhot;
     577    pImage->cHotY    = bitsp->yhot;
     578    pImage->fFlags   = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
     579    pImage->cbLength = sizeRequest - sizeof(*pImage);
    665580
    666581#ifdef DEBUG_POINTER
     
    775690    }
    776691
    777     rc = VbglR3SetPointerShape(fFlags, bitsp->xhot, bitsp->yhot, w, h, p, sizeData);
     692    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, fFlags, bitsp->xhot,
     693                                     bitsp->yhot, w, h, p, sizeData);
    778694    TRACE_LOG(": leaving, returning %d\n", rc);
    779695    free(p);
     
    790706
    791707    TRACE_ENTRY();
    792     if (!pVBox->useDevice)
     708    if (!pVBox->fHaveHGSMI)
    793709        return FALSE;
    794710    pVBox->pCurs = pCurs = xf86CreateCursorInfoRec();
     
    844760    bool rc = TRUE;
    845761    int scrnIndex = pScrn->scrnIndex;
    846     VBOXPtr pVBox = pScrn->driverPrivate;
    847 
    848     TRACE_ENTRY();
    849     if (pVBox->useVbva != TRUE)
    850         rc = FALSE;
    851     if (rc && RT_FAILURE(VbglR3VideoAccelEnable(true)))
     762    unsigned i;
     763    VBOXPtr pVBox = pScrn->driverPrivate;
     764
     765    TRACE_ENTRY();
     766    if (!pVBox->fHaveHGSMI)
     767        return FALSE;
     768    for (i = 0; i < pVBox->cScreens; ++i)
     769    {
     770        struct VBVABUFFER *pVBVA;
     771
     772        pVBVA = (struct VBVABUFFER *) (  ((uint8_t *)pVBox->base)
     773                                       + pVBox->aoffVBVABuffer[i]);
     774        if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
     775            rc = FALSE;
     776    }
     777    if (!rc)
     778    {
    852779        /* Request not accepted - disable for old hosts. */
    853780        xf86DrvMsg(scrnIndex, X_ERROR,
    854                    "Unable to activate VirtualBox graphics acceleration "
    855                    "- the request to the virtual machine failed.  "
    856                    "You may be running an old version of VirtualBox.\n");
    857     pVBox->useVbva = rc;
    858     if (!rc)
    859         VbglR3VideoAccelEnable(false);
     781                   "Failed to enable screen update reporting for at least one virtual monitor.\n");
     782         vboxDisableVbva(pScrn);
     783    }
    860784    return rc;
    861785}
     
    869793 * @param   pScrn   Pointer to a structure describing the X screen in use
    870794 */
    871 Bool
     795void
    872796vboxDisableVbva(ScrnInfoPtr pScrn)
    873797{
    874798    int rc;
    875799    int scrnIndex = pScrn->scrnIndex;
    876     VBOXPtr pVBox = pScrn->driverPrivate;
    877 
    878     TRACE_ENTRY();
    879     if (pVBox->useVbva != TRUE)  /* Ths function should not have been called */
    880         return FALSE;
    881     rc = VbglR3VideoAccelEnable(false);
    882     if (RT_FAILURE(rc))
    883     {
    884         xf86DrvMsg(scrnIndex, X_ERROR,
    885                    "Unable to disable VirtualBox graphics acceleration "
    886                    "- the request to the virtual machine failed.\n");
    887     }
    888     else
    889         memset(pVBox->pVbvaMemory, 0, sizeof(VBVAMEMORY));
    890     return TRUE;
     800    unsigned i;
     801    VBOXPtr pVBox = pScrn->driverPrivate;
     802
     803    TRACE_ENTRY();
     804    if (!pVBox->fHaveHGSMI)  /* Ths function should not have been called */
     805        return;
     806    for (i = 0; i < pVBox->cScreens; ++i)
     807        VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
    891808}
    892809
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h

    r34400 r34715  
    5252#ifndef _VBOXVIDEO_H_
    5353#define _VBOXVIDEO_H_
     54
     55#include <VBox/VBoxVideoGuest.h>
     56#include <VBox/VBoxVideo.h>
    5457
    5558#ifdef DEBUG
     
    168171/*XXX*/
    169172
    170 typedef struct _VBOXRec
     173typedef struct VBOXRec
    171174{
    172175    vbeInfoPtr pVbe;  /** @todo do the VBE bits ourselves? */
     
    179182    PCITAG pciTag;
    180183#endif
    181     unsigned long mapSize;      /* video memory */
    182184    void *base;
     185    /** The amount of VRAM available for use as a framebuffer */
     186    unsigned long cbFramebuffer;
    183187    CARD8 *state, *pstate;      /* SVGA state */
    184188    int statePage, stateSize, stateMode;
     
    201205     * safe to touch the hardware. */
    202206    Bool vtSwitch;
    203     Bool useVbva;
    204     int viewportX, viewportY;
    205     VMMDevMemory *pVMMDevMemory;
    206     VBVAMEMORY *pVbvaMemory;
     207    /** Does this host support sending graphics commands using HGSMI? */
     208    Bool fHaveHGSMI;
     209    /** Number of screens attached */
     210    uint32_t cScreens;
     211    /** Position information for each virtual screen for the purposes of
     212     * sending dirty rectangle information to the right one. */
     213    RTRECT2 aScreenLocation[VBOX_VIDEO_MAX_SCREENS];
     214    /** Offsets of VBVA buffers in video RAM */
     215    uint32_t aoffVBVABuffer[VBOX_VIDEO_MAX_SCREENS];
     216    /** Context information about the VBVA buffers for each screen */
     217    struct VBVABUFFERCONTEXT aVbvaCtx[VBOX_VIDEO_MAX_SCREENS];
     218    /** HGSMI guest heap context */
     219    HGSMIGUESTCOMMANDCONTEXT guestCtx;
    207220    Bool fAnyX;   /* Unrestricted horizontal resolution flag. */
    208221#ifdef VBOX_DRI
     
    222235
    223236extern Bool vboxEnableVbva(ScrnInfoPtr pScrn);
    224 extern Bool vboxDisableVbva(ScrnInfoPtr pScrn);
     237extern void vboxDisableVbva(ScrnInfoPtr pScrn);
    225238
    226239extern Bool vboxEnableGraphicsCap(VBOXPtr pVBox);
     
    246259extern void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox);
    247260
     261/* Xinerama stuff */
     262#define VBOXRAMA_MAJOR_VERSION 1
     263#define VBOXRAMA_MINOR_VERSION 0
     264
    248265#endif /* _VBOXVIDEO_H_ */
    249266
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_13.c

    r33540 r34715  
    11/* $Id$ */
    22/** @file
     3 *
    34 * Linux Additions X11 graphics driver
    45 */
     
    4849 */
    4950
    50 #include "xorg-server.h"
     51#ifdef XORG_7X
     52# include "xorg-server.h"
     53# include <string.h>
     54#endif
    5155#include "vboxvideo.h"
    5256#include "version-generated.h"
     
    7175#include "vgaHW.h"
    7276
     77#ifdef VBOXVIDEO_13
    7378/* X.org 1.3+ mode setting */
    74 #define _HAVE_STRING_ARCH_strsep /* bits/string2.h, __strsep_1c. */
    75 #include "xf86Crtc.h"
    76 #include "xf86Modes.h"
     79# define _HAVE_STRING_ARCH_strsep /* bits/string2.h, __strsep_1c. */
     80# include "xf86Crtc.h"
     81# include "xf86Modes.h"
     82#endif
    7783
    7884/* Mandatory functions */
     
    9298static void VBOXLeaveVT(int scrnIndex, int flags);
    9399static Bool VBOXCloseScreen(int scrnIndex, ScreenPtr pScreen);
     100static Bool VBOXSaveScreen(ScreenPtr pScreen, int mode);
    94101static Bool VBOXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags);
    95 static ModeStatus VBOXValidMode(int scrn, DisplayModePtr p, Bool flag, int pass);
    96 static Bool VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
     102static Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
     103                        unsigned cHeight, int x, int y);
    97104static void VBOXAdjustFrame(int scrnIndex, int x, int y, int flags);
    98105static void VBOXFreeScreen(int scrnIndex, int flags);
    99106static void VBOXFreeRec(ScrnInfoPtr pScrn);
     107static void VBOXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode,
     108                                          int flags);
    100109
    101110/* locally used functions */
     
    104113static Bool VBOXSaveRestore(ScrnInfoPtr pScrn,
    105114                            vbeSaveRestoreFunction function);
     115static Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);
    106116
    107117enum GenericTypes
     
    141151 */
    142152
    143 _X_EXPORT DriverRec VBOXVIDEO = {
     153#ifdef XORG_7X
     154_X_EXPORT
     155#endif
     156DriverRec VBOXVIDEO = {
    144157    VBOX_VERSION,
    145158    VBOX_DRIVER_NAME,
     
    153166    NULL,
    154167    0,
     168#ifdef XORG_7X
    155169    NULL,
    156 
     170#endif
    157171#ifdef PCIACCESS
    158172    vbox_device_match,
     
    166180};
    167181
     182#ifndef XORG_7X
     183/*
     184 * List of symbols from other modules that this module references.  This
     185 * list is used to tell the loader that it is OK for symbols here to be
     186 * unresolved providing that it hasn't been told that they haven't been
     187 * told that they are essential via a call to xf86LoaderReqSymbols() or
     188 * xf86LoaderReqSymLists().  The purpose is this is to avoid warnings about
     189 * unresolved symbols that are not required.
     190 */
     191static const char *fbSymbols[] = {
     192    "fbPictureInit",
     193    "fbScreenInit",
     194    NULL
     195};
     196
     197static const char *shadowfbSymbols[] = {
     198  "ShadowFBInit2",
     199  NULL
     200};
     201
     202static const char *vbeSymbols[] = {
     203    "VBEExtendedInit",
     204    "VBEFindSupportedDepths",
     205    "VBEGetModeInfo",
     206    "VBEGetVBEInfo",
     207    "VBEGetVBEMode",
     208    "VBEPrintModes",
     209    "VBESaveRestore",
     210    "VBESetDisplayStart",
     211    "VBESetGetDACPaletteFormat",
     212    "VBESetGetLogicalScanlineLength",
     213    "VBESetGetPaletteData",
     214    "VBESetModeNames",
     215    "VBESetModeParameters",
     216    "VBESetVBEMode",
     217    "VBEValidateModes",
     218    "vbeDoEDID",
     219    "vbeFree",
     220    NULL
     221};
     222
     223static const char *ramdacSymbols[] = {
     224    "xf86InitCursor",
     225    "xf86CreateCursorInfoRec",
     226    NULL
     227};
     228
     229static const char *vgahwSymbols[] = {
     230    "vgaHWGetHWRec",
     231    "vgaHWHandleColormaps",
     232    "vgaHWFreeHWRec",
     233    "vgaHWMapMem",
     234    "vgaHWUnmapMem",
     235    "vgaHWSaveFonts",
     236    "vgaHWRestoreFonts",
     237    "vgaHWGetIndex",
     238    "vgaHWSaveScreen",
     239    "vgaHWDPMSSet",
     240    NULL
     241};
     242#endif /* !XORG_7X */
     243
    168244static VBOXPtr
    169245VBOXGetRec(ScrnInfoPtr pScrn)
    170246{
    171     if (!pScrn->driverPrivate) {
     247    if (!pScrn->driverPrivate)
     248    {
    172249        pScrn->driverPrivate = calloc(sizeof(VBOXRec), 1);
    173250    }
     
    186263}
    187264
     265#ifdef VBOXVIDEO_13
    188266/* X.org 1.3+ mode-setting support ******************************************/
    189267
     
    192270   X.Org source tree. */
    193271
    194 static Bool
    195 VBOXCrtcResize(ScrnInfoPtr scrn, int width, int height)
    196 {
    197     int bpp = scrn->bitsPerPixel;
    198     ScreenPtr pScreen = scrn->pScreen;
    199     PixmapPtr pPixmap = NULL;
    200     VBOXPtr pVBox = VBOXGetRec(scrn);
    201     Bool rc = TRUE;
    202 
    203     TRACE_LOG("width=%d, height=%d\n", width, height);
    204     if (width * height * bpp / 8 >= scrn->videoRam * 1024)
    205     {
    206         xf86DrvMsg(scrn->scrnIndex, X_ERROR,
    207                    "Unable to set up a virtual screen size of %dx%d with %d Kb of video memory.  Please increase the video memory size.\n",
    208                    width, height, scrn->videoRam);
    209         rc = FALSE;
    210     }
    211     if (rc) {
    212         pPixmap = pScreen->GetScreenPixmap(pScreen);
    213         if (NULL == pPixmap) {
    214             xf86DrvMsg(scrn->scrnIndex, X_ERROR,
    215                        "Failed to get the screen pixmap.\n");
    216             rc = FALSE;
    217         }
    218     }
    219     if (rc) {
    220         if (
    221             !pScreen->ModifyPixmapHeader(pPixmap, width, height,
    222                                          scrn->depth, bpp, width * bpp / 8,
    223                                          pVBox->base)
    224            ) {
    225             xf86DrvMsg(scrn->scrnIndex, X_ERROR,
    226                        "Failed to set up the screen pixmap.\n");
    227             rc = FALSE;
    228         }
    229     }
    230     if (rc) {
    231         scrn->virtualX = width;
    232         scrn->virtualY = height;
    233         scrn->displayWidth = width;
    234 #ifdef VBOX_DRI
    235         if (pVBox->useDRI)
    236             VBOXDRIUpdateStride(scrn, pVBox);
    237 #endif
    238         /* Write the new values to the hardware */
    239         rc = xf86SetDesiredModes(scrn);
    240     }
    241     TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
    242     return rc;
    243 }
    244 
    245272static const xf86CrtcConfigFuncsRec VBOXCrtcConfigFuncs = {
    246     VBOXCrtcResize
     273    VBOXAdjustScreenPixmap
    247274};
    248275
     
    269296{
    270297    (void) mode;
     298    VBOXPtr pVBox = VBOXGetRec(crtc->scrn);
     299    int bpp = crtc->scrn->depth == 24 ? 32 : 16;
     300
    271301    TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name,
    272302           adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y);
    273     VBOXSetMode(crtc->scrn, adjusted_mode);
    274     VBOXAdjustFrame(crtc->scrn->scrnIndex, x, y, 0);
     303    VBOXSetMode(crtc->scrn, 0, adjusted_mode->HDisplay, adjusted_mode->VDisplay,
     304                x, y);
    275305    /* Don't remember any modes set while we are seamless, as they are
    276306     * just temporary. */
     
    454484    .destroy = vbox_output_stub
    455485};
     486#endif /* VBOXVIDEO_13 */
    456487
    457488#ifdef XFree86LOADER
     
    465496    MODINFOSTRING1,
    466497    MODINFOSTRING2,
     498#ifdef XORG_7X
    467499    XORG_VERSION_CURRENT,
     500#else
     501    XF86_VERSION_CURRENT,
     502#endif
    468503    1,                          /* Module major version. Xorg-specific */
    469504    0,                          /* Module minor version. Xorg-specific */
     
    479514 * followed by "ModuleData".
    480515 */
    481 _X_EXPORT XF86ModuleData vboxvideoModuleData = { &vboxVersionRec, vboxSetup, NULL };
     516#ifdef XORG_7X
     517_X_EXPORT
     518#endif
     519XF86ModuleData vboxvideoModuleData = { &vboxVersionRec, vboxSetup, NULL };
    482520
    483521static pointer
     
    494532        xf86AddDriver(&VBOXVIDEO, Module, 0);
    495533#endif
     534#ifndef XORG_7X
     535        LoaderRefSymLists(fbSymbols,
     536                          shadowfbSymbols,
     537                          vbeSymbols,
     538                          ramdacSymbols,
     539                          vgahwSymbols,
     540                          NULL);
     541#endif
    496542        xf86Msg(X_CONFIG, "Load address of symbol \"VBOXVIDEO\" is %p\n",
    497543                (void *)&VBOXVIDEO);
     
    543589        pScrn->ScreenInit    = VBOXScreenInit;
    544590        pScrn->SwitchMode    = VBOXSwitchMode;
    545         pScrn->ValidMode     = VBOXValidMode;
    546591        pScrn->AdjustFrame   = VBOXAdjustFrame;
    547592        pScrn->EnterVT       = VBOXEnterVT;
     
    599644                        pScrn->ScreenInit    = VBOXScreenInit;
    600645                        pScrn->SwitchMode    = VBOXSwitchMode;
    601                         pScrn->ValidMode     = VBOXValidMode;
    602646                        pScrn->AdjustFrame   = VBOXAdjustFrame;
    603647                        pScrn->EnterVT       = VBOXEnterVT;
     
    618662#endif
    619663
    620 /*
    621  * QUOTE from the XFree86 DESIGN document:
    622  *
    623  * The purpose of this function is to find out all the information
    624  * required to determine if the configuration is usable, and to initialise
    625  * those parts of the ScrnInfoRec that can be set once at the beginning of
    626  * the first server generation.
    627  *
    628  * (...)
    629  *
    630  * This includes probing for video memory, clocks, ramdac, and all other
    631  * HW info that is needed. It includes determining the depth/bpp/visual
    632  * and related info. It includes validating and determining the set of
    633  * video modes that will be used (and anything that is required to
    634  * determine that).
    635  *
    636  * This information should be determined in the least intrusive way
    637  * possible. The state of the HW must remain unchanged by this function.
    638  * Although video memory (including MMIO) may be mapped within this
    639  * function, it must be unmapped before returning.
    640  *
    641  * END QUOTE
    642  */
    643 
    644 static Bool
    645 VBOXPreInit(ScrnInfoPtr pScrn, int flags)
    646 {
    647     VBOXPtr pVBox;
    648     Gamma gzeros = {0.0, 0.0, 0.0};
    649     rgb rzeros = {0, 0, 0};
    650     xf86OutputPtr output;
    651     unsigned DispiId;
    652 
    653     /* Are we really starting the server, or is this just a dummy run? */
    654     if (flags & PROBE_DETECT)
    655         return (FALSE);
    656 
    657     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    658                "VirtualBox guest additions video driver version "
    659                VBOX_VERSION_STRING "\n");
    660 
    661     /* Get our private data from the ScrnInfoRec structure. */
    662     pVBox = VBOXGetRec(pScrn);
    663 
    664     /* Initialise the guest library */
    665     vbox_init(pScrn->scrnIndex, pVBox);
    666 
    667     /* Entity information seems to mean bus information. */
    668     pVBox->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
    669 
    670     /* We need the vbe module because we use VBE code to save and restore
    671        text mode, in order to keep our code simple. */
    672     if (!xf86LoadSubModule(pScrn, "vbe"))
    673         return (FALSE);
    674 
    675     if ((pVBox->pVbe = VBEExtendedInit(NULL, pVBox->pEnt->index,
    676                                        SET_BIOS_SCRATCH
    677                                        | RESTORE_BIOS_SCRATCH)) == NULL)
    678         return (FALSE);
    679 
    680 #ifndef PCIACCESS
    681     if (pVBox->pEnt->location.type != BUS_PCI)
    682         return FALSE;
    683 
    684     pVBox->pciInfo = xf86GetPciInfoForEntity(pVBox->pEnt->index);
    685     pVBox->pciTag = pciTag(pVBox->pciInfo->bus,
    686                            pVBox->pciInfo->device,
    687                            pVBox->pciInfo->func);
    688 #endif
    689 
    690     /* The ramdac module is needed for the hardware cursor. */
    691     if (!xf86LoadSubModule(pScrn, "ramdac"))
    692         return FALSE;
    693 
    694     /* The framebuffer module. */
    695     if (xf86LoadSubModule(pScrn, "fb") == NULL)
    696         return (FALSE);
    697 
    698     if (!xf86LoadSubModule(pScrn, "shadowfb"))
    699         return FALSE;
    700 
    701     if (!xf86LoadSubModule(pScrn, "vgahw"))
    702         return FALSE;
    703 
    704     /* Set up our ScrnInfoRec structure to describe our virtual
    705        capabilities to X. */
    706 
    707     pScrn->chipset = "vbox";
    708 
    709     /* This *is* still needed, at least for server version 1.3 */
    710     pScrn->monitor = pScrn->confScreen->monitor;
    711 
    712     pScrn->progClock = TRUE;
    713     pScrn->rgbBits = 8;
    714 
    715     /* Using the PCI information caused problems with non-powers-of-two
    716        sized video RAM configurations */
    717     pScrn->videoRam = inl(VBE_DISPI_IOPORT_DATA) / 1024;
    718 
    719     /* Check if the chip restricts horizontal resolution or not. */
    720     outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
    721     outw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
    722     DispiId = inw(VBE_DISPI_IOPORT_DATA);
    723     if (DispiId == VBE_DISPI_ID_ANYX)
    724         pVBox->fAnyX = TRUE;
    725     else
    726         pVBox->fAnyX = FALSE;
    727 
    728     /* Query the host for the preferred colour depth */
    729     {
    730         uint32_t cx, cy, iDisplay, cBits = 24;
    731 
    732         if (vbox_device_available(pVBox))
    733         {
    734             /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
    735             if (   vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits,
    736                                                &iDisplay)
    737                 && (cBits != 16)
    738                )
    739                 cBits = 24;
    740         }
    741         if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
    742             return FALSE;
    743     }
    744     if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
    745     {
    746         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    747                    "The VBox additions only support 16 and 32bpp graphics modes\n");
    748         return FALSE;
    749     }
    750     xf86PrintDepthBpp(pScrn);
    751 
    752     /* options */
    753     xf86CollectOptions(pScrn, NULL);
    754     if (!(pVBox->Options = malloc(sizeof(VBOXOptions))))
    755         return FALSE;
    756     memcpy(pVBox->Options, VBOXOptions, sizeof(VBOXOptions));
    757     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVBox->Options);
    758 
    759     /* Work around a bug in the original X server modesetting code, which
    760      * took the first valid values set to these two as maxima over the
    761      * server lifetime. */
    762     pScrn->virtualX = 32000;
    763     pScrn->virtualY = 32000;
    764 
    765     /* Initialise CRTC and output configuration for use with randr1.2. */
    766     xf86CrtcConfigInit(pScrn, &VBOXCrtcConfigFuncs);
    767 
    768     /* Setup our single virtual CRTC. */
    769     xf86CrtcCreate(pScrn, &VBOXCrtcFuncs);
    770 
    771     /* Set up our single virtual output. */
    772     output = xf86OutputCreate(pScrn, &VBOXOutputFuncs, "VBOX1");
    773 
    774     /* Set a sane minimum and maximum mode size */
    775     xf86CrtcSetSizeRange(pScrn, 64, 64, 32000, 32000);
    776 
    777     /* We are not interested in the monitor section in the configuration file. */
    778     xf86OutputUseScreenMonitor(output, FALSE);
    779     output->possible_crtcs = 1;
    780     output->possible_clones = 0;
    781 
    782     /* Now create our initial CRTC/output configuration. */
    783     if (!xf86InitialConfiguration(pScrn, TRUE)) {
    784         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Initial CRTC configuration failed!\n");
    785         return (FALSE);
    786     }
    787 
    788     /* Colour weight - we always call this, since we are always in
    789        truecolour. */
    790     if (!xf86SetWeight(pScrn, rzeros, rzeros))
    791         return (FALSE);
    792 
    793     /* visual init */
    794     if (!xf86SetDefaultVisual(pScrn, -1))
    795         return (FALSE);
    796 
    797     xf86SetGamma(pScrn, gzeros);
    798 
    799     /* Set a default display resolution. */
    800     xf86SetDpi(pScrn, 96, 96);
    801 
    802     /* Framebuffer-related setup */
    803     pScrn->bitmapBitOrder = BITMAP_BIT_ORDER;
    804 
    805     /* VGA hardware initialisation */
    806     if (!vgaHWGetHWRec(pScrn))
    807         return FALSE;
    808 
    809 #ifdef VBOX_DRI
    810     /* Load the dri module. */
    811     if (!xf86LoadSubModule(pScrn, "dri"))
    812         return FALSE;
    813 #endif
    814     return (TRUE);
    815 }
    816 
    817664/**
    818665 * This function hooks into the chain that is called when framebuffer access
     
    839686 * QUOTE from the XFree86 DESIGN document:
    840687 *
     688 * The purpose of this function is to find out all the information
     689 * required to determine if the configuration is usable, and to initialise
     690 * those parts of the ScrnInfoRec that can be set once at the beginning of
     691 * the first server generation.
     692 *
     693 * (...)
     694 *
     695 * This includes probing for video memory, clocks, ramdac, and all other
     696 * HW info that is needed. It includes determining the depth/bpp/visual
     697 * and related info. It includes validating and determining the set of
     698 * video modes that will be used (and anything that is required to
     699 * determine that).
     700 *
     701 * This information should be determined in the least intrusive way
     702 * possible. The state of the HW must remain unchanged by this function.
     703 * Although video memory (including MMIO) may be mapped within this
     704 * function, it must be unmapped before returning.
     705 *
     706 * END QUOTE
     707 */
     708
     709static Bool
     710VBOXPreInit(ScrnInfoPtr pScrn, int flags)
     711{
     712    VBOXPtr pVBox;
     713    Gamma gzeros = {0.0, 0.0, 0.0};
     714    rgb rzeros = {0, 0, 0};
     715#ifdef VBOXVIDEO_13
     716    xf86OutputPtr output;
     717#endif
     718    unsigned DispiId;
     719
     720    TRACE_ENTRY();
     721    /* Are we really starting the server, or is this just a dummy run? */
     722    if (flags & PROBE_DETECT)
     723        return (FALSE);
     724
     725    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
     726               "VirtualBox guest additions video driver version "
     727               VBOX_VERSION_STRING "\n");
     728
     729    /* Get our private data from the ScrnInfoRec structure. */
     730    pVBox = VBOXGetRec(pScrn);
     731
     732    /* Initialise the guest library */
     733    vbox_init(pScrn->scrnIndex, pVBox);
     734
     735    /* Entity information seems to mean bus information. */
     736    pVBox->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
     737
     738    /* The ramdac module is needed for the hardware cursor. */
     739    if (!xf86LoadSubModule(pScrn, "ramdac"))
     740        return FALSE;
     741
     742    /* We need the vbe module because we use VBE code to save and restore
     743       text mode, in order to keep our code simple. */
     744    if (!xf86LoadSubModule(pScrn, "vbe"))
     745        return (FALSE);
     746
     747    /* The framebuffer module. */
     748    if (xf86LoadSubModule(pScrn, "fb") == NULL)
     749        return (FALSE);
     750
     751    if (!xf86LoadSubModule(pScrn, "shadowfb"))
     752        return FALSE;
     753
     754    if (!xf86LoadSubModule(pScrn, "vgahw"))
     755        return FALSE;
     756
     757#ifdef VBOX_DRI
     758    /* Load the dri module. */
     759    if (!xf86LoadSubModule(pScrn, "dri"))
     760        return FALSE;
     761#endif
     762
     763#ifndef PCIACCESS
     764    if (pVBox->pEnt->location.type != BUS_PCI)
     765        return FALSE;
     766
     767    pVBox->pciInfo = xf86GetPciInfoForEntity(pVBox->pEnt->index);
     768    pVBox->pciTag = pciTag(pVBox->pciInfo->bus,
     769                           pVBox->pciInfo->device,
     770                           pVBox->pciInfo->func);
     771#endif
     772
     773    /* Set up our ScrnInfoRec structure to describe our virtual
     774       capabilities to X. */
     775
     776    pScrn->chipset = "vbox";
     777    pScrn->rgbBits = 8;
     778
     779    /* Let's create a nice, capable virtual monitor.
     780     * This *is* still needed, at least for server version 1.3 */
     781    pScrn->monitor = pScrn->confScreen->monitor;
     782    pScrn->monitor->DDC = NULL;
     783    pScrn->monitor->nHsync = 1;
     784    pScrn->monitor->hsync[0].lo = 1;
     785    pScrn->monitor->hsync[0].hi = 10000;
     786    pScrn->monitor->nVrefresh = 1;
     787    pScrn->monitor->vrefresh[0].lo = 1;
     788    pScrn->monitor->vrefresh[0].hi = 100;
     789
     790    pScrn->progClock = TRUE;
     791
     792    /* Using the PCI information caused problems with non-powers-of-two
     793       sized video RAM configurations */
     794    pVBox->cbFramebuffer = inl(VBE_DISPI_IOPORT_DATA);
     795    pScrn->videoRam = pVBox->cbFramebuffer / 1024;
     796
     797    /* Check if the chip restricts horizontal resolution or not. */
     798    outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
     799    outw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
     800    DispiId = inw(VBE_DISPI_IOPORT_DATA);
     801    if (DispiId == VBE_DISPI_ID_ANYX)
     802        pVBox->fAnyX = TRUE;
     803    else
     804        pVBox->fAnyX = FALSE;
     805
     806    /* Set up clock information that will support all modes we need. */
     807    pScrn->clockRanges = xnfcalloc(sizeof(ClockRange), 1);
     808    pScrn->clockRanges->minClock = 1000;
     809    pScrn->clockRanges->maxClock = 1000000000;
     810    pScrn->clockRanges->clockIndex = -1;
     811    pScrn->clockRanges->ClockMulFactor = 1;
     812    pScrn->clockRanges->ClockDivFactor = 1;
     813
     814    /* Query the host for the preferred colour depth */
     815    {
     816        uint32_t cx = 0, cy = 0, cBits = 0;
     817
     818        vboxGetPreferredMode(pScrn, &cx, &cy, &cBits);
     819        /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
     820        if (cBits != 16)
     821            cBits = 24;
     822        if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
     823            return FALSE;
     824#ifndef VBOXVIDEO_13
     825        vboxAddModes(pScrn, cx, cy);
     826#endif
     827    }
     828    if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
     829    {
     830        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
     831                   "The VBox additions only support 16 and 32bpp graphics modes\n");
     832        return FALSE;
     833    }
     834    xf86PrintDepthBpp(pScrn);
     835
     836#ifdef VBOXVIDEO_13
     837    /* Work around a bug in the original X server modesetting code, which
     838     * took the first valid values set to these two as maxima over the
     839     * server lifetime. */
     840    pScrn->virtualX = 32000;
     841    pScrn->virtualY = 32000;
     842
     843    /* Initialise CRTC and output configuration for use with randr1.2. */
     844    xf86CrtcConfigInit(pScrn, &VBOXCrtcConfigFuncs);
     845
     846    /* Setup our single virtual CRTC. */
     847    xf86CrtcCreate(pScrn, &VBOXCrtcFuncs);
     848
     849    /* Set up our single virtual output. */
     850    output = xf86OutputCreate(pScrn, &VBOXOutputFuncs, "VBOX1");
     851
     852    /* Set a sane minimum and maximum mode size */
     853    xf86CrtcSetSizeRange(pScrn, 64, 64, 32000, 32000);
     854
     855    /* We are not interested in the monitor section in the configuration file. */
     856    xf86OutputUseScreenMonitor(output, FALSE);
     857    output->possible_crtcs = 1;
     858    output->possible_clones = 0;
     859
     860    /* Now create our initial CRTC/output configuration. */
     861    if (!xf86InitialConfiguration(pScrn, TRUE)) {
     862        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Initial CRTC configuration failed!\n");
     863        return (FALSE);
     864    }
     865#else /* !VBOXVIDEO_13 */
     866    /* We don't validate with xf86ValidateModes and xf86PruneModes as we
     867     * already know what we like and what we don't. */
     868
     869    pScrn->currentMode = pScrn->modes;
     870
     871    /* Set the right virtual resolution. */
     872    pScrn->virtualX = pScrn->currentMode->HDisplay;
     873    pScrn->virtualY = pScrn->currentMode->VDisplay;
     874
     875    pScrn->displayWidth = pScrn->virtualX;
     876
     877    xf86PrintModes(pScrn);
     878
     879#endif /* !VBOXVIDEO_13 */
     880
     881    /* Colour weight - we always call this, since we are always in
     882       truecolour. */
     883    if (!xf86SetWeight(pScrn, rzeros, rzeros))
     884        return (FALSE);
     885
     886    /* visual init */
     887    if (!xf86SetDefaultVisual(pScrn, -1))
     888        return (FALSE);
     889
     890    xf86SetGamma(pScrn, gzeros);
     891
     892    /* Set the DPI.  Perhaps we should read this from the host? */
     893    xf86SetDpi(pScrn, 96, 96);
     894
     895    /* Framebuffer-related setup */
     896    pScrn->bitmapBitOrder = BITMAP_BIT_ORDER;
     897
     898    /* VGA hardware initialisation */
     899    if (!vgaHWGetHWRec(pScrn))
     900        return FALSE;
     901
     902    TRACE_EXIT();
     903    return (TRUE);
     904}
     905
     906/**
     907 * Dummy function for setting the colour palette, which we actually never
     908 * touch.  However, the server still requires us to provide this.
     909 */
     910static void
     911vboxLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
     912          LOCO *colors, VisualPtr pVisual)
     913{
     914    (void)pScrn; (void) numColors; (void) indices; (void) colors;
     915    (void)pVisual;
     916}
     917
     918/*
     919 * QUOTE from the XFree86 DESIGN document:
     920 *
    841921 * This is called at the start of each server generation.
    842922 *
     
    848928 * mode.
    849929 *
    850  * End QUOTE.Initialise the initial video mode.
     930 * End QUOTE.
    851931 */
    852932static Bool
     
    857937    VisualPtr visual;
    858938    unsigned flags;
     939
     940    TRACE_ENTRY();
     941    /* We make use of the X11 VBE code to save and restore text mode, in
     942       order to keep our code simple. */
     943    if ((pVBox->pVbe = VBEExtendedInit(NULL, pVBox->pEnt->index,
     944                                       SET_BIOS_SCRATCH
     945                                       | RESTORE_BIOS_SCRATCH)) == NULL)
     946        return (FALSE);
    859947
    860948    if (pScrn->memPhysBase == 0) {
     
    864952        pScrn->memPhysBase = pVBox->pciInfo->memBase[0];
    865953#endif
    866 /*        pVBox->mapSize = 1 << pVBox->pciInfo->size[0]; */
    867         /* Using the PCI information caused problems with
    868            non-powers-of-two sized video RAM configurations */
    869         pVBox->mapSize = inl(VBE_DISPI_IOPORT_DATA);
    870954        pScrn->fbOffset = 0;
    871955    }
     
    876960    /* save current video state */
    877961    VBOXSaveRestore(pScrn, MODE_SAVE);
    878     pVBox->savedPal = VBESetGetPaletteData(pVBox->pVbe, FALSE, 0, 256,
    879                                            NULL, FALSE, FALSE);
    880962
    881963    /* mi layer - reset the visual list (?)*/
     
    9281010     */
    9291011    pVBox->vtSwitch = FALSE;
    930     /* Initialise DGA.  The cast is unfortunately correct - it gets cast back
    931        to (unsigned char *) later. */
    932     xf86DiDGAInit(pScreen, (unsigned long) pVBox->base);
    933 
    934     /* Initialise randr 1.2 mode-setting functions and set first mode. */
     1012
     1013    if (vbox_device_available(pVBox) && vbox_open (pScrn, pScreen, pVBox)) {
     1014        vboxEnableVbva(pScrn);
     1015        vboxEnableGraphicsCap(pVBox);
     1016    }
     1017
     1018#ifdef VBOXVIDEO_13
     1019    /* Initialise randr 1.2 mode-setting functions and set first mode.
     1020     * Note that the mode won't be usable until the server has resized the
     1021     * framebuffer to something reasonable. */
    9351022    if (!xf86CrtcScreenInit(pScreen)) {
    9361023        return FALSE;
     
    9401027        return FALSE;
    9411028    }
     1029#else /* !VBOXVIDEO_13 */
     1030    /* set first video mode */
     1031    if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay,
     1032                     pScrn->currentMode->VDisplay, pScrn->frameX0,
     1033                     pScrn->frameY0))
     1034        return FALSE;
     1035    /* And make sure that a non-current dynamic mode is at the front of the
     1036     * list */
     1037    vboxWriteHostModes(pScrn, pScrn->currentMode);
     1038#endif /* !VBOXVIDEO_13 */
    9421039
    9431040    /* software cursor */
     
    9481045        return (FALSE);
    9491046
    950     flags = CMAP_RELOAD_ON_MODE_SWITCH;
    951 
    952     if(!vgaHWHandleColormaps(pScreen))
     1047    if(!xf86HandleColormaps(pScreen, 256, 8, vboxLoadPalette, NULL, 0))
    9531048        return (FALSE);
    9541049
     
    9621057    pVBox->CloseScreen = pScreen->CloseScreen;
    9631058    pScreen->CloseScreen = VBOXCloseScreen;
    964     pScreen->SaveScreen = xf86SaveScreen;
     1059    pScreen->SaveScreen = VBOXSaveScreen;
    9651060
    9661061    /* We probably do want to support power management - even if we just use
    9671062       a dummy function. */
    968     xf86DPMSInit(pScreen, xf86DPMSSet, 0);
     1063    xf86DPMSInit(pScreen, VBOXDisplayPowerManagementSet, 0);
    9691064
    9701065    /* Report any unused options (only for the first generation) */
     
    9721067        xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
    9731068
    974     if (vbox_device_available(pVBox) && vbox_open (pScrn, pScreen, pVBox)) {
    975         if (vbox_cursor_init(pScreen) != TRUE)
    976             xf86DrvMsg(scrnIndex, X_ERROR,
    977                        "Unable to start the VirtualBox mouse pointer integration with the host system.\n");
    978         if (vboxEnableVbva(pScrn) == TRUE)
    979             xf86DrvMsg(scrnIndex, X_INFO,
    980                       "The VBox video extensions are now enabled.\n");
    981         vboxEnableGraphicsCap(pVBox);
    982     }
     1069    if (vbox_cursor_init(pScreen) != TRUE)
     1070        xf86DrvMsg(scrnIndex, X_ERROR,
     1071                   "Unable to start the VirtualBox mouse pointer integration with the host system.\n");
    9831072
    9841073#ifdef VBOX_DRI
     
    9941083    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
    9951084    VBOXPtr pVBox = VBOXGetRec(pScrn);
    996     bool rc;
    9971085
    9981086    TRACE_ENTRY();
     
    10021090        DRIUnlock(screenInfo.screens[scrnIndex]);
    10031091#endif
    1004     rc = xf86SetDesiredModes(pScrn);
    1005     TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
    1006     return rc;
     1092#ifdef VBOXVIDEO_13
     1093    if (!xf86SetDesiredModes(pScrn))
     1094        return FALSE;
     1095#else
     1096    if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay,
     1097                     pScrn->currentMode->VDisplay, pScrn->frameX0,
     1098                     pScrn->frameY0))
     1099        return FALSE;
     1100#endif
     1101    if (pVBox->fHaveHGSMI)
     1102        vboxEnableVbva(pScrn);
     1103    return TRUE;
    10071104}
    10081105
     
    10161113    pVBox->vtSwitch = TRUE;
    10171114    VBOXSaveRestore(pScrn, MODE_RESTORE);
    1018     if (vbox_device_available(pVBox))
    1019     {
    1020         if (pVBox->useVbva == TRUE)
    1021             vboxDisableVbva(pScrn);
    1022         vboxDisableGraphicsCap(pVBox);
    1023     }
     1115    if (pVBox->fHaveHGSMI)
     1116        vboxDisableVbva(pScrn);
     1117    vboxDisableGraphicsCap(pVBox);
    10241118#ifdef VBOX_DRI
    10251119    if (pVBox->useDRI)
     
    10411135#endif
    10421136
    1043     if (vbox_device_available(pVBox))
    1044     {
    1045         if (TRUE == pVBox->useVbva)
    1046             vboxDisableVbva(pScrn);
    1047         vboxDisableGraphicsCap(pVBox);
    1048     }
     1137    if (pVBox->fHaveHGSMI)
     1138        vboxDisableVbva(pScrn);
     1139    vboxDisableGraphicsCap(pVBox);
    10491140    if (pScrn->vtSema) {
    1050         VBOXSaveRestore(xf86Screens[scrnIndex], MODE_RESTORE);
    1051         if (pVBox->savedPal)
    1052             VBESetGetPaletteData(pVBox->pVbe, TRUE, 0, 256,
    1053                                  pVBox->savedPal, FALSE, TRUE);
    1054         VBOXUnmapVidMem(pScrn);
     1141        VBOXSaveRestore(xf86Screens[scrnIndex], MODE_RESTORE);
     1142        VBOXUnmapVidMem(pScrn);
    10551143    }
    10561144    pScrn->vtSema = FALSE;
     
    10661154    pScreen->CloseScreen = pVBox->CloseScreen;
    10671155    return pScreen->CloseScreen(scrnIndex, pScreen);
    1068 }
    1069 
    1070 /**
    1071  * Quoted from "How to add an (S)VGA driver to XFree86"
    1072  * (http://www.xfree86.org/3.3.6/VGADriver.html):
    1073  *
    1074  * The ValidMode() function is required. It is used to check for any
    1075  * chipset-dependent reasons why a graphics mode might not be valid. It gets
    1076  * called by higher levels of the code after the Probe() stage. In many cases
    1077  * no special checking will be required and this function will simply return
    1078  * TRUE always.
    1079  *
    1080  * Note: we check here that our generated video modes fulfil the X server's
    1081  * criteria for the monitor, since this can otherwise cause problems in
    1082  * randr 1.2.
    1083  */
    1084 static ModeStatus
    1085 VBOXValidMode(int scrn, DisplayModePtr p, Bool flag, int pass)
    1086 {
    1087     static int warned = 0;
    1088     ScrnInfoPtr pScrn = xf86Screens[scrn];
    1089     MonPtr mon = pScrn->monitor;
    1090     ModeStatus ret = MODE_BAD;
    1091     DisplayModePtr mode;
    1092     float v;
    1093 
    1094     TRACE_LOG("HDisplay=%d, VDisplay=%d, flag=%s, pass=%d\n",
    1095            p->HDisplay, p->VDisplay, flag ? "TRUE" : "FALSE", pass);
    1096     if (pass != MODECHECK_FINAL) {
    1097         if (!warned) {
    1098             xf86DrvMsg(scrn, X_WARNING, "VBOXValidMode called unexpectedly\n");
    1099             warned = 1;
    1100         }
    1101     }
    1102 #if 0
    1103     /*
    1104      * First off, if this isn't a mode we handed to the server (ie,
    1105      * M_T_BUILTIN), then we reject it out of hand.
    1106      */
    1107     if (!(p->type & M_T_BUILTIN))
    1108         return MODE_NOMODE;
    1109 #endif
    1110     /*
    1111      * Finally, walk through the vsync rates 1Hz at a time looking for a mode
    1112      * that will fit.  This is assuredly a terrible way to do this, but
    1113      * there's no obvious method for computing a mode of a given size that
    1114      * will pass xf86CheckModeForMonitor.
    1115      */
    1116     for (v = mon->vrefresh[0].lo; v <= mon->vrefresh[0].hi; v++) {
    1117         mode = xf86CVTMode(p->HDisplay, p->VDisplay, v, 0, 0);
    1118         ret = xf86CheckModeForMonitor(mode, mon);
    1119         free(mode);
    1120         if (ret == MODE_OK)
    1121             break;
    1122     }
    1123 
    1124     if (ret != MODE_OK)
    1125     {
    1126         xf86DrvMsg(scrn, X_WARNING, "Graphics mode %s rejected by the X server\n", p->name);
    1127     }
    1128     TRACE_LOG("returning %d\n", ret);
    1129     return ret;
    11301156}
    11311157
     
    11441170    if (pVBox->accessEnabled)
    11451171        pVBox->EnableDisableFBAccess(scrnIndex, FALSE);
     1172#ifdef VBOXVIDEO_13
    11461173    rc = xf86SetSingleMode(pScrn, pMode, 0);
     1174#else
     1175    rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay,
     1176                     pScrn->frameX0, pScrn->frameY0);
     1177    if (rc)
     1178    {
     1179        vboxWriteHostModes(pScrn, pMode);
     1180        xf86PrintModes(pScrn);
     1181    }
     1182#endif
     1183    if (rc && !vboxGuestIsSeamless(pScrn))
     1184        vboxSaveVideoMode(pScrn, pMode->HDisplay, pMode->VDisplay,
     1185                          pScrn->bitsPerPixel);
    11471186    if (pVBox->accessEnabled)
    11481187        pVBox->EnableDisableFBAccess(scrnIndex, TRUE);
     
    11551194   graphics functions. */
    11561195static Bool
    1157 VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
     1196VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
     1197            unsigned cHeight, int x, int y)
    11581198{
    11591199    VBOXPtr pVBox;
     
    11611201
    11621202    int bpp = pScrn->depth == 24 ? 32 : 16;
    1163     TRACE_LOG("HDisplay=%d, VDisplay=%d, displayWidth=%d\n",
    1164               pMode->HDisplay, pMode->VDisplay, pScrn->displayWidth);
     1203    TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
     1204              cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
    11651205    pVBox = VBOXGetRec(pScrn);
    11661206    /* Don't fiddle with the hardware if we are switched
     
    11681208    if (!pVBox->vtSwitch)
    11691209    {
    1170         if (    vbox_device_available(pVBox)
    1171             && (TRUE == pVBox->useVbva)
    1172             && (vboxDisableVbva(pScrn) != TRUE)
    1173            )  /* This would be bad. */
    1174             rc = FALSE;
    1175         if (rc)
    1176         {
    1177             /* Disable linear framebuffer mode before making changes to the resolution. */
    1178             outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
    1179             outw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED);
    1180             /* Unlike the resolution, the depth is fixed for a given screen
    1181                for the lifetime of the X session. */
    1182             outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
    1183             outw(VBE_DISPI_IOPORT_DATA, bpp);
    1184             /* HDisplay and VDisplay are actually monitor information about
    1185                the display part of the scanlines. */
    1186             outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
    1187             outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay);
    1188             outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
    1189             outw(VBE_DISPI_IOPORT_DATA, pMode->VDisplay);
    1190             /* Set the virtual resolution.  We are still using VESA to control
    1191                the virtual offset. */
    1192             outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH);
    1193             outw(VBE_DISPI_IOPORT_DATA, pScrn->displayWidth);
    1194             /* Enable linear framebuffer mode. */
    1195             outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
    1196             outw(VBE_DISPI_IOPORT_DATA,
    1197                  VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
    1198             /* Enable acceleration and tell the host we support graphics */
    1199             if (vbox_device_available(pVBox))
    1200             {
    1201                 if ((TRUE == pVBox->useVbva) && (vboxEnableVbva(pScrn) != TRUE))
    1202                 /* Bad but not fatal */
    1203                     pVBox->useVbva = FALSE;
    1204                 vboxEnableGraphicsCap(pVBox);
    1205             }
    1206         }
    1207     }
     1210        if (cDisplay == 0)
     1211            VBoxVideoSetModeRegisters(cWidth, cHeight, pScrn->displayWidth,
     1212                                      bpp, x, y);
     1213        /* Tell the host we support graphics */
     1214        if (vbox_device_available(pVBox))
     1215            vboxEnableGraphicsCap(pVBox);
     1216    }
     1217    if (    vbox_device_available(pVBox)
     1218        && (pVBox->fHaveHGSMI)
     1219        && !pVBox->vtSwitch)
     1220        VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
     1221                                    (y * pScrn->displayWidth + x) * bpp / 8,
     1222                                    pScrn->displayWidth * bpp / 8,
     1223                                    cWidth, cHeight, bpp);
     1224    pVBox->aScreenLocation[0].cx = cWidth;
     1225    pVBox->aScreenLocation[0].cy = cHeight;
     1226    pVBox->aScreenLocation[0].x = x;
     1227    pVBox->aScreenLocation[0].y = y;
    12081228    TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
    12091229    return rc;
     1230}
     1231
     1232static Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
     1233{
     1234    ScreenPtr pScreen = pScrn->pScreen;
     1235    PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
     1236    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1237    int bpp = pScrn->depth == 24 ? 32 : 16;
     1238
     1239    TRACE_LOG("width=%d, height=%d\n", width, height);
     1240    if ((uint64_t)width * height * bpp / 8 >= pVBox->cbFramebuffer)
     1241    {
     1242        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
     1243                   "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available.  Please increase the video memory size.\n",
     1244                   width, height, pVBox->cbFramebuffer / 1024, pScrn->videoRam);
     1245        return FALSE;
     1246    }
     1247    if (!pPixmap) {
     1248        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
     1249                   "Failed to get the screen pixmap.\n");
     1250        return FALSE;
     1251    }
     1252    pScreen->ModifyPixmapHeader(pPixmap, width, height,
     1253                                pScrn->depth, bpp, width * bpp / 8,
     1254                                pVBox->base);
     1255    pScrn->virtualX = width;
     1256    pScrn->virtualY = height;
     1257    pScrn->displayWidth = width;
     1258#ifdef VBOX_DRI
     1259    if (pVBox->useDRI)
     1260        VBOXDRIUpdateStride(pScrn, pVBox);
     1261#endif
     1262#ifdef VBOXVIDEO_13
     1263    /* Write the new values to the hardware */
     1264    xf86SetDesiredModes(pScrn);
     1265#else
     1266    pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
     1267    pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
     1268#endif
     1269    return TRUE;
    12101270}
    12111271
     
    12191279    /* Don't fiddle with the hardware if we are switched
    12201280     * to a virtual terminal. */
    1221     if (!pVBox->vtSwitch) {
    1222         pVBox->viewportX = x;
    1223         pVBox->viewportY = y;
    1224         /* If VBVA is enabled the graphics card will not notice the change. */
    1225         if (pVBox->useVbva == TRUE)
    1226             vboxDisableVbva(pScrn);
    1227         VBESetDisplayStart(pVBox->pVbe, x, y, TRUE);
    1228         if (pVBox->useVbva == TRUE)
    1229             vboxEnableVbva(pScrn);
    1230     }
     1281    VBOXSetMode(pScrn, 0, pVBox->aScreenLocation[0].cx,
     1282                pVBox->aScreenLocation[0].cy, x, y);
    12311283    TRACE_EXIT();
    12321284}
     
    12501302        (void) pci_device_map_range(pVBox->pciInfo,
    12511303                                    pScrn->memPhysBase,
    1252                                     pVBox->mapSize,
     1304                                    pScrn->videoRam * 1024,
    12531305                                    PCI_DEV_MAP_FLAG_WRITABLE,
    12541306                                    & pVBox->base);
     
    12571309                                    VIDMEM_FRAMEBUFFER,
    12581310                                    pVBox->pciTag, pScrn->memPhysBase,
    1259                                     (unsigned) pVBox->mapSize);
     1311                                    (unsigned) pScrn->videoRam * 1024);
    12601312#endif
    12611313        if (pVBox->base)
     
    12841336    (void) pci_device_unmap_range(pVBox->pciInfo,
    12851337                                  pVBox->base,
    1286                                   pVBox->mapSize);
     1338                                  pScrn->videoRam * 1024);
    12871339#else
    12881340    xf86UnMapVidMem(pScrn->scrnIndex, pVBox->base,
    1289                     (unsigned) pVBox->mapSize);
     1341                    (unsigned) pScrn->videoRam * 1024);
    12901342#endif
    12911343    vgaHWUnmapMem(pScrn);
     
    12941346}
    12951347
     1348static Bool
     1349VBOXSaveScreen(ScreenPtr pScreen, int mode)
     1350{
     1351    (void)pScreen; (void)mode;
     1352    return TRUE;
     1353}
    12961354
    12971355Bool
     
    13571415    return rc;
    13581416}
     1417
     1418static void
     1419VBOXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode,
     1420                int flags)
     1421{
     1422    (void)pScrn; (void)mode; (void) flags;
     1423}
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c

    r32495 r34715  
    175175        || (pVBox->pciInfo == NULL)
    176176        || (pVBox->base == NULL)
    177         || (pVBox->mapSize == 0))
     177        || (pVBox->cbFramebuffer == 0))
    178178    {
    179179        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: preconditions failed\n",
     
    256256        pDRIInfo->maxDrawableTableEntry = VBOX_MAX_DRAWABLES;
    257257        pDRIInfo->frameBufferPhysicalAddress = (pointer)pScrn->memPhysBase;
    258         pDRIInfo->frameBufferSize = pVBox->mapSize;
     258        pDRIInfo->frameBufferSize = pVBox->cbFramebuffer;
    259259        pDRIInfo->frameBufferStride =   pScrn->displayWidth
    260260                                      * pScrn->bitsPerPixel / 8;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette