VirtualBox

Ignore:
Timestamp:
Jun 19, 2007 9:40:23 AM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
22071
Message:

Multimonitor support.

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Display
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h

    r2558 r3153  
    2323#include "../Miniport/vboxioctl.h"
    2424
     25#include <VBox/VBoxVideo.h>
     26
    2527/* Forward declaration. */
    2628struct _PDEV;
    2729typedef struct _PDEV PDEV;
    2830typedef PDEV *PPDEV;
     31
     32typedef struct _VBOXDISPLAYINFO
     33{
     34    VBOXVIDEOINFOHDR         hdrLink;
     35    VBOXVIDEOINFOLINK        link;
     36    VBOXVIDEOINFOHDR         hdrScreen;
     37    VBOXVIDEOINFOSCREEN      screen;
     38    VBOXVIDEOINFOHDR         hdrHostEvents;
     39    VBOXVIDEOINFOHOSTEVENTS  hostEvents;
     40    VBOXVIDEOINFOHDR         hdrEnd;
     41} VBOXDISPLAYINFO;
    2942
    3043#include "vbvavrdp.h"
     
    5265    POINTL  ptlOrg;                     // Where this display is anchored in
    5366                                        //   the virtual desktop.
     67    POINTL  ptlDevOrg;                  // Device origin for DualView (0,0 for primary view).
    5468    ULONG   ulMode;                     // Mode the mini-port driver is in.
    5569    LONG    lDeltaScreen;               // Distance from one scan to the next.
     
    7488   
    7589    VBVAENABLERESULT vbva;
    76     HSEMAPHORE       hsemHwBuffer;
     90    uint32_t         u32VRDPResetFlag;
    7791    BOOL             fHwBufferOverflow;
    7892    VBVARECORD       *pRecord;
     
    8195    ULONG cSSB;                 // Number of active saved screen bits records in the following array.
    8296    SSB aSSB[4];                // LIFO type stack for saved screen areas.
     97
     98    VBOXDISPLAYINFO *pInfo;
     99    ULONG iDevice;
    83100};
     101
     102/* The global semaphore handle for all driver instances. */
     103extern HSEMAPHORE ghsemHwBuffer;
     104
    84105
    85106DWORD getAvailableModes(HANDLE, PVIDEO_MODE_INFORMATION *, DWORD *);
     
    126147BOOL vboxOrderSupported (PPDEV ppdev, unsigned code);
    127148
     149void VBoxProcessDisplayInfo(PPDEV ppdev);
     150void VBoxUpdateDisplayInfo (PPDEV ppdev);
    128151
    129152void drvLoadEng (void);
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/drv.c

    r2981 r3153  
    9999        PPDEV ppdev = (PPDEV)__psoDest->dhpdev;                       \
    100100                                                                      \
    101         if (vboxHwBufferBeginUpdate (ppdev))                          \
     101        if (ppdev->pInfo && vboxHwBufferBeginUpdate (ppdev))          \
    102102        {                                                             \
    103103            vbva##__fn __a;                                           \
    104104                                                                      \
    105             if (ppdev->vbva.pVbvaMemory->fu32ModeFlags                \
    106                 & VBVA_F_MODE_VRDP_RESET)                             \
     105            if (  ppdev->pInfo->hostEvents.fu32Events                 \
     106                & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)           \
    107107            {                                                         \
    108108                vrdpReset (ppdev);                                    \
    109109                                                                      \
    110                 ppdev->vbva.pVbvaMemory->fu32ModeFlags &=             \
    111                     ~VBVA_F_MODE_VRDP_RESET;                          \
     110                ppdev->pInfo->hostEvents.fu32Events &=                \
     111                          ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;  \
    112112            }                                                         \
    113113                                                                      \
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c

    r2558 r3153  
    167167    {   INDEX_DrvSaveScreenBits,        (PFN) DrvSaveScreenBits     },  // 40 0x28
    168168    {   INDEX_DrvGetModes,              (PFN) DrvGetModes           },  // 41 0x29
     169    {   INDEX_DrvNotify,                (PFN) DrvNotify             },  // 87 0x57
    169170//     /* Experimental. */
    170171//     {   0x7,                            (PFN) DrvResetPDEV          },       // 0x7
     
    191192#define HOOKS_BMF32BPP gflHooks
    192193
     194HSEMAPHORE ghsemHwBuffer = 0;
     195
    193196/******************************Public*Routine******************************\
    194197* DrvEnableDriver
     
    238241            DDI_DRIVER_VERSION_NT4;
    239242
     243    if (!ghsemHwBuffer)
     244    {
     245        ghsemHwBuffer = EngCreateSemaphore ();
     246    }
     247
    240248    return(TRUE);
    241249}
     
    252260{
    253261    DISPDBG((0, "VBoxDisp::DrvDisableDriver called.\n"));
     262
     263    if (ghsemHwBuffer)
     264    {
     265        EngDeleteSemaphore (ghsemHwBuffer);
     266        ghsemHwBuffer = NULL;
     267    }
     268
    254269    return;
    255270}
     
    822837}
    823838
     839/******************************Public*Routine******************************\
     840* DrvNotify
     841*
     842* Called by GDI to notify us of certain "interesting" events
     843*
     844* DN_DEVICE_ORIGIN is used to communicate the X/Y offsets of individual monitors
     845*                  when DualView is in effect.
     846*
     847\**************************************************************************/
     848
     849VOID DrvNotify(
     850SURFOBJ *pso,
     851ULONG iType,
     852PVOID pvData)
     853{
     854    PDEV*   ppdev = (PDEV*) pso->dhpdev;
     855
     856    DISPDBG((0, "VBoxDisp::DrvNotify called.\n"));
     857
     858    switch(iType)
     859    {
     860        case DN_DEVICE_ORIGIN:
     861            ppdev->ptlDevOrg = *(PPOINTL)pvData;
     862            DISPDBG((3, "DN_DEVICE_ORIGIN: %d, %d (PSO = %p, pInfo = %p)\n", ppdev->ptlDevOrg.x,
     863                     ppdev->ptlDevOrg.y, pso, ppdev->pInfo));
     864            if (ppdev->pInfo)
     865            {
     866                ppdev->pInfo->screen.xOrigin = ppdev->ptlDevOrg.x;
     867                ppdev->pInfo->screen.yOrigin = ppdev->ptlDevOrg.y;
     868                VBoxProcessDisplayInfo(ppdev);
     869            }
     870            break;
     871        case DN_DRAWING_BEGIN:
     872            DISPDBG((3, "DN_DRAWING_BEGIN (PSO = %p)\n", pso));
     873            break;
     874    }
     875}
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c

    r1 r3153  
    3535};
    3636
     37/* Setup display information after remapping. */
     38static void vboxSetupDisplayInfo (PPDEV ppdev, VIDEO_MEMORY_INFORMATION *pMemoryInformation)
     39{
     40    VBOXDISPLAYINFO *pInfo;
     41    uint8_t *pu8;
     42   
     43    DWORD returnedDataLength;
     44    QUERYDISPLAYINFORESULT DispInfo;
     45    RtlZeroMemory(&DispInfo, sizeof (DispInfo));
     46    if (EngDeviceIoControl(ppdev->hDriver,
     47                           IOCTL_VIDEO_QUERY_DISPLAY_INFO,
     48                           NULL,
     49                           0,
     50                           &DispInfo,
     51                           sizeof(DispInfo),
     52                           &returnedDataLength))
     53    {
     54        DISPDBG((1, "DISP bInitSURF failed IOCTL_VIDEO_QUERY_DISPLAY_INFO\n"));
     55        ppdev->pInfo = NULL;
     56        return;
     57    }
     58   
     59    if (returnedDataLength != sizeof (QUERYDISPLAYINFORESULT)
     60        || DispInfo.u32DisplayInfoSize >= pMemoryInformation->VideoRamLength)
     61    {
     62        DISPDBG((1, "DISP bInitSURF failed DispInfo.u32DisplayInfoSize 0x%x >= pMemoryInformation->VideoRamLength 0x%x\n",
     63                 DispInfo.u32DisplayInfoSize, pMemoryInformation->VideoRamLength));
     64        ppdev->pInfo = NULL;
     65        return;
     66    }
     67   
     68    ppdev->iDevice = DispInfo.iDevice;
     69
     70    pu8 = (uint8_t *)pMemoryInformation->VideoRamBase;
     71    pu8 += pMemoryInformation->VideoRamLength - DispInfo.u32DisplayInfoSize;
     72
     73    pInfo = (VBOXDISPLAYINFO *)pu8;
     74    pu8 += sizeof (VBOXDISPLAYINFO);
     75
     76    pInfo->hdrLink.u8Type     = VBOX_VIDEO_INFO_TYPE_LINK;
     77    pInfo->hdrLink.u8Reserved = 0;
     78    pInfo->hdrLink.u16Length  = sizeof (VBOXVIDEOINFOLINK);
     79    pInfo->link.i32Offset = 0;
     80
     81    pInfo->hdrScreen.u8Type     = VBOX_VIDEO_INFO_TYPE_SCREEN;
     82    pInfo->hdrScreen.u8Reserved = 0;
     83    pInfo->hdrScreen.u16Length  = sizeof (VBOXVIDEOINFOSCREEN);
     84    DISPDBG((1, "Setup: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     85    pInfo->screen.xOrigin      = ppdev->ptlDevOrg.x;
     86    pInfo->screen.yOrigin      = ppdev->ptlDevOrg.y;
     87    pInfo->screen.u32LineSize  = 0;
     88    pInfo->screen.u16Width     = 0;
     89    pInfo->screen.u16Height    = 0;
     90    pInfo->screen.bitsPerPixel = 0;
     91    pInfo->screen.u8Flags      = VBOX_VIDEO_INFO_SCREEN_F_NONE;
     92   
     93    pInfo->hdrHostEvents.u8Type     = VBOX_VIDEO_INFO_TYPE_HOST_EVENTS;
     94    pInfo->hdrHostEvents.u8Reserved = 0;
     95    pInfo->hdrHostEvents.u16Length  = sizeof (VBOXVIDEOINFOHOSTEVENTS);
     96    pInfo->hostEvents.fu32Events = VBOX_VIDEO_INFO_HOST_EVENTS_F_NONE;
     97
     98    pInfo->hdrEnd.u8Type     = VBOX_VIDEO_INFO_TYPE_END;
     99    pInfo->hdrEnd.u8Reserved = 0;
     100    pInfo->hdrEnd.u16Length  = 0;
     101
     102    ppdev->pInfo = pInfo;
     103}
     104
     105
     106static void vboxUpdateDisplayInfo (PPDEV ppdev)
     107{
     108    if (ppdev->pInfo)
     109    {
     110        ppdev->pInfo->screen.u32LineSize  = ppdev->lDeltaScreen;
     111        ppdev->pInfo->screen.u16Width     = (uint16_t)ppdev->cxScreen;
     112        ppdev->pInfo->screen.u16Height    = (uint16_t)ppdev->cyScreen;
     113        ppdev->pInfo->screen.bitsPerPixel = (uint8_t)ppdev->ulBitCount;
     114        ppdev->pInfo->screen.u8Flags      = VBOX_VIDEO_INFO_SCREEN_F_ACTIVE;
     115
     116        DISPDBG((1, "Update: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     117        VBoxProcessDisplayInfo(ppdev);
     118    }
     119}
     120
     121
    37122/******************************Public*Routine******************************\
    38123* bInitSURF
     
    155240        ppdev->pPointerAttributes->Row = 0;
    156241        ppdev->pPointerAttributes->Enable = 0;
     242
     243        /* Setup the display information. */
     244        vboxSetupDisplayInfo (ppdev, &videoMemoryInformation);
    157245    }
    158246
     
    164252        || ppdev->ulBitCount == 32)
    165253    {
    166         /* Enable VBVA for this video mode. */
    167         vboxVbvaEnable (ppdev);
     254        if (ppdev->pInfo) /* Do not use VBVA on old hosts. */
     255        {
     256            /* Enable VBVA for this video mode. */
     257            vboxVbvaEnable (ppdev);
     258        }
    168259    }
    169260
    170261    DISPDBG((1, "DISP bInitSURF success\n"));
     262
     263    /* Update the display information. */
     264    vboxUpdateDisplayInfo (ppdev);
    171265   
    172266    return(TRUE);
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c

    r2981 r3153  
    5555
    5656    DISPDBG((1, "VBoxDisp::vboxVbvaEnable called\n"));
     57   
     58    if (!ghsemHwBuffer)
     59    {
     60        return FALSE;
     61    }
    5762
    5863    if (EngDeviceIoControl(ppdev->hDriver,
     
    7176            && ppdev->vbva.pvFlush)
    7277        {
    73             if (!ppdev->hsemHwBuffer)
    74             {
    75                 ppdev->hsemHwBuffer = EngCreateSemaphore ();
    76             }
    77 
    78             if (ppdev->hsemHwBuffer)
    79             {
    80                 ppdev->fHwBufferOverflow = FALSE;
    81                 ppdev->pRecord           = NULL;
    82 
    83                 /* All have been initialized. */
    84                 bRc = TRUE;
    85             }
    86             else
    87             {
    88                 DISPDBG((1, "VBoxDisp::vboxVbvaEnable failed to create semaphore!!!\n"));
    89             }
     78            ppdev->fHwBufferOverflow = FALSE;
     79            ppdev->pRecord           = NULL;
     80
     81            /* All have been initialized. */
     82            bRc = TRUE;
    9083        }
    9184    }
     
    10497
    10598    RtlZeroMemory (&ppdev->vbva, sizeof (ppdev->vbva));
    106 
    107     if (ppdev->hsemHwBuffer)
    108     {
    109         EngDeleteSemaphore (ppdev->hsemHwBuffer);
    110         ppdev->hsemHwBuffer = NULL;
    111     }
    11299
    113100    ppdev->fHwBufferOverflow = FALSE;
     
    130117        uint32_t indexRecordNext;
    131118
    132         EngAcquireSemaphore (ppdev->hsemHwBuffer);
     119        EngAcquireSemaphore (ghsemHwBuffer);
    133120
    134121        VBVA_ASSERT (!ppdev->fHwBufferOverflow);
     
    148135            DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate no space in the queue of records!!! first %d, last %d\n",
    149136                     pVbvaMemory->indexRecordFirst, pVbvaMemory->indexRecordFree));
    150             EngReleaseSemaphore (ppdev->hsemHwBuffer);
     137            EngReleaseSemaphore (ghsemHwBuffer);
    151138        }
    152139        else
     
    190177    ppdev->pRecord = NULL;
    191178
    192     EngReleaseSemaphore (ppdev->hsemHwBuffer);
     179    EngReleaseSemaphore (ghsemHwBuffer);
    193180
    194181    return;
     
    336323}
    337324
     325void VBoxProcessDisplayInfo(PPDEV ppdev)
     326{
     327    DWORD returnedDataLength;
     328
     329    DISPDBG((1, "Process: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     330
     331    EngDeviceIoControl(ppdev->hDriver,
     332                       IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY,
     333                       NULL,
     334                       0,
     335                       NULL,
     336                       0,
     337                       &returnedDataLength);
     338}
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vbva.c

    r2981 r3153  
    2323#include "driver.h"
    2424
    25 void vboxReportDirtyRect (PPDEV ppdev, RECTL *pRect)
     25void vboxReportDirtyRect (PPDEV ppdev, RECTL *pRectOrig)
    2626{
    2727    if (ppdev)
    2828    {
    2929        VBVACMDHDR hdr;
    30 
    31         hdr.x = (int16_t)pRect->left;
    32         hdr.y = (int16_t)pRect->top;
    33         hdr.w = (uint16_t)(pRect->right - pRect->left);
    34         hdr.h = (uint16_t)(pRect->bottom - pRect->top);
     30       
     31        RECTL rect = *pRectOrig;
     32
     33        if (rect.left < 0) rect.left = 0;
     34        if (rect.top < 0) rect.top = 0;
     35        if (rect.right > (int)ppdev->cxScreen) rect.right = ppdev->cxScreen;
     36        if (rect.bottom > (int)ppdev->cyScreen) rect.bottom = ppdev->cyScreen;
     37
     38        hdr.x = (int16_t)rect.left;
     39        hdr.y = (int16_t)rect.top;
     40        hdr.w = (uint16_t)(rect.right - rect.left);
     41        hdr.h = (uint16_t)(rect.bottom - rect.top);
     42
     43        hdr.x += (int16_t)ppdev->ptlDevOrg.x;
     44        hdr.y += (int16_t)ppdev->ptlDevOrg.y;
    3545
    3646        vboxWrite (ppdev, &hdr, sizeof(hdr));
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vrdp.c

    r2981 r3153  
    304304            DISPDBG((1, "%d rects\n", cRects));
    305305
    306             VBVA_ASSERT(cRects > 0);
    307 
    308             for (; cRects != 0; cRects--, prclClipSrc++)
    309             {
    310                 vrdpIntersectRects (prclClipDst, prclClipSrc, &pClipRects->rclDst);
    311 
    312                 if (vrdpIsRectEmpty (prclClipDst))
     306            if (cRects > 0)
     307            {
     308                for (; cRects != 0; cRects--, prclClipSrc++)
    313309                {
    314                     pClipRects->rects.c--;
     310                    vrdpIntersectRects (prclClipDst, prclClipSrc, &pClipRects->rclDst);
     311
     312                    if (vrdpIsRectEmpty (prclClipDst))
     313                    {
     314                        pClipRects->rects.c--;
     315                    }
     316                    else
     317                    {
     318                        prclClipDst++;
     319                    }
    315320                }
    316                 else
    317                 {
    318                     prclClipDst++;
    319                 }
     321            }
     322            else
     323            {
     324                pClipRects->rclDst.left = pClipRects->rclDst.right = 0;
    320325            }
    321326        }
     
    757762    memcpy (order.pattern, pBrush->u.pat.au8Pattern, sizeof (order.pattern));
    758763
    759     vrdpReportOrderGeneric (ppdev, pClipRects, &order, sizeof (order), VBVA_VRDP_PATBLT_BRUSH);
     764    vrdpReportOrderGeneric (ppdev, pClipRects, &order, sizeof (order), VBVA_VRDP_PATBLTBRUSH);
    760765}
    761766
     
    10511056                int cacheResult;
    10521057
     1058                DISPDBG((1, "VRDP::vrdpBitBlt: MEMBLT.\n"));
    10531059                if (   (psoSrc->fjBitmap & BMF_DONTCACHE) != 0
    10541060                    || psoSrc->iUniq == 0)
     
    10591065                else
    10601066                {
     1067                    DISPDBG((1, "VRDP::vrdpBitBlt: going to cache.\n"));
    10611068                    cacheResult = vrdpbmpCacheSurface (&ppdev->cache, psoSrc, &hash, &hashDeleted);
    10621069                }
     
    17421749void vrdpReset (PPDEV ppdev)
    17431750{
     1751    DISPDBG((1, "vrdpReset %p\n", ppdev));
     1752
    17441753    vrdpbmpReset (&ppdev->cache);
    17451754
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vrdpbmp.c

    r2981 r3153  
    138138{
    139139    BOOL bRc = FALSE;
     140    VRDPBCENTRY *pEntry;
     141
     142    DISPDBG((1, "insert hash cache %p, tail %p.\n", pCache, pCache->tail));
    140143
    141144    /* Get the free entry to be used. Try tail, that should be */
    142     VRDPBCENTRY *pEntry = pCache->tail;
     145    pEntry = pCache->tail;
     146   
     147    if (pEntry == NULL)
     148    {
     149        return bRc;
     150    }
    143151
    144152    if (pEntry->fUsed)
     
    172180    BOOL bResult = bcComputeHash (pso, &hash);
    173181
     182    DISPDBG((1, "vrdpbmpCacheSurface: compute hash %d.\n", bResult));
    174183    if (!bResult)
    175184    {
     
    180189    bResult = bcFindHash (pCache, &hash);
    181190
     191    DISPDBG((1, "vrdpbmpCacheSurface: find hash %d.\n", bResult));
    182192    *phash = hash;
    183193
     
    191201    bResult = bcInsertHash (pCache, &hash, phashDeleted);
    192202
     203    DISPDBG((1, "vrdpbmpCacheSurface: insert hash %d.\n", bResult));
    193204    if (bResult)
    194205    {
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