VirtualBox

Changeset 26834 in vbox for trunk/src/VBox/Frontends/VBoxBFE


Ignore:
Timestamp:
Feb 26, 2010 12:10:36 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
58109
Message:

FE/BFE: resynchronise MouseImpl from Main

Location:
trunk/src/VBox/Frontends/VBoxBFE
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxBFE/COMDefs.h

    r11663 r26834  
    6161# define E_UNEXPECTED   ((unsigned long) 0x8000ffffL)
    6262# define E_INVALIDARG   ((unsigned long) 0x80070057L)
     63#define E_ACCESSDENIED  ((unsigned long) 0x80070005L)
     64#define VBOX_E_IPRT_ERROR ((unsigned long) 0x80BB0005L)
    6365
    6466# if ! defined(FALSE)
  • trunk/src/VBox/Frontends/VBoxBFE/ConsoleImpl.h

    r8155 r26834  
    2323#ifndef ____H_CONSOLEIMPL
    2424#define ____H_CONSOLEIMPL
     25
     26#include <VBox/types.h>
    2527
    2628/*
     
    100102} CONEVENT;
    101103
     104/**
     105 *  Checks the availability of the underlying VM device driver corresponding
     106 *  to the COM interface (IKeyboard, IMouse, IDisplay, etc.). When the driver is
     107 *  not available (NULL), sets error info and returns returns E_ACCESSDENIED.
     108 *  The translatable error message is defined in null context.
     109 *
     110 *  Intended to used only within Console children (i.e. Keyboard, Mouse,
     111 *  Display, etc.).
     112 *
     113 *  @param drv  driver pointer to check (compare it with NULL)
     114 */
     115#define CHECK_CONSOLE_DRV(drv) \
     116    do { \
     117        if (!(drv)) \
     118            return setError(E_ACCESSDENIED, tr("The console is not powered up")); \
     119    } while (0)
     120
    102121class Console
    103122{
  • trunk/src/VBox/Frontends/VBoxBFE/MouseImpl.cpp

    r26173 r26834  
    11/* $Id$ */
    22/** @file
    3  * VBox frontends: Basic Frontend (BFE):
    4  * Implementation of Mouse class
     3 * VirtualBox VBoxBFE/COM class implementation
    54 */
    65
    76/*
    8  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
    98 *
    109 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2120 */
    2221
    23 #ifdef VBOXBFE_WITHOUT_COM
    24 # include "COMDefs.h"
    25 #else
    26 # include <VBox/com/defs.h>
    27 #endif
    28 #include <VBox/pdm.h>
    29 #include <VBox/cfgm.h>
    30 #include <VBox/err.h>
    31 #include <iprt/assert.h>
    32 #include <VBox/log.h>
    33 #include <iprt/asm.h>
    34 #include <iprt/uuid.h>
    35 #include <VBox/VMMDev.h>
    3622#include "MouseImpl.h"
    3723#include "DisplayImpl.h"
    38 #include "VMMDevInterface.h"
     24#ifdef VBOXBFE_WITHOUT_COM
     25# include "VMMDevInterface.h"
     26# include <iprt/uuid.h>
     27class AutoInitSpan
     28{
     29public:
     30    AutoInitSpan(VirtualBoxBase *) {}
     31    bool isOk() { return true; }
     32    void setSucceeded() {}
     33};
     34
     35class AutoUninitSpan
     36{
     37public:
     38    AutoUninitSpan(VirtualBoxBase *) {}
     39    bool uninitDone() { return false; }
     40};
     41
     42class AutoCaller
     43{
     44public:
     45    AutoCaller(VirtualBoxBase *) {}
     46    int rc() { return S_OK; }
     47};
     48
     49class AutoWriteLock
     50{
     51public:
     52    AutoWriteLock(VirtualBoxBase *) {}
     53};
     54#define COMMA_LOCKVAL_SRC_POS
     55enum
     56{
     57    MouseButtonState_LeftButton = 1,
     58    MouseButtonState_RightButton = 2,
     59    MouseButtonState_MiddleButton = 4,
     60    MouseButtonState_XButton1 = 8,
     61    MouseButtonState_XButton2 = 16,
     62};
     63#else
     64# include "VMMDev.h"
     65
     66# include "AutoCaller.h"
     67#endif
     68#include "Logging.h"
     69
     70#include <VBox/pdmdrv.h>
     71#include <iprt/asm.h>
     72#include <VBox/VMMDev.h>
    3973
    4074/**
     
    4377typedef struct DRVMAINMOUSE
    4478{
    45     /** Pointer to the associated mouse driver. */
    46     Mouse                      *mpDrv;
     79    /** Pointer to the mouse object. */
     80    Mouse                      *pMouse;
    4781    /** Pointer to the driver instance structure. */
    4882    PPDMDRVINS                  pDrvIns;
     
    5084    PPDMIMOUSEPORT              pUpPort;
    5185    /** Our mouse connector interface. */
    52     PDMIMOUSECONNECTOR          Connector;
     86    PDMIMOUSECONNECTOR          IConnector;
    5387} DRVMAINMOUSE, *PDRVMAINMOUSE;
    5488
     89
     90// constructor / destructor
     91/////////////////////////////////////////////////////////////////////////////
     92
     93DEFINE_EMPTY_CTOR_DTOR (Mouse)
     94
     95HRESULT Mouse::FinalConstruct()
     96{
     97    mpDrv = NULL;
     98    uDevCaps = MOUSE_DEVCAP_RELATIVE;
     99    fVMMDevCanAbs = false;
     100    fVMMDevNeedsHostCursor = false;
     101    mLastAbsX = 0x8000;
     102    mLastAbsY = 0x8000;
     103    mLastButtons = 0;
     104    return S_OK;
     105}
     106
     107void Mouse::FinalRelease()
     108{
     109    uninit();
     110}
     111
     112// public methods only for internal purposes
     113/////////////////////////////////////////////////////////////////////////////
     114
     115/**
     116 * Initializes the mouse object.
     117 *
     118 * @returns COM result indicator
     119 * @param parent handle of our parent object
     120 */
     121HRESULT Mouse::init (Console *parent)
     122{
     123    LogFlowThisFunc(("\n"));
     124
     125    ComAssertRet(parent, E_INVALIDARG);
     126
     127    /* Enclose the state transition NotReady->InInit->Ready */
     128    AutoInitSpan autoInitSpan(this);
     129    AssertReturn(autoInitSpan.isOk(), E_FAIL);
     130
     131#ifdef VBOXBFE_WITHOUT_COM
     132    mParent = parent;
     133#else
     134    unconst(mParent) = parent;
     135#endif
     136
     137#ifdef RT_OS_L4
     138    /* L4 console has no own mouse cursor */
     139    uHostCaps = VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER;
     140#else
     141    uHostCaps = 0;
     142#endif
     143    uDevCaps = 0;
     144
     145    /* Confirm a successful initialization */
     146    autoInitSpan.setSucceeded();
     147
     148    return S_OK;
     149}
     150
     151/**
     152 *  Uninitializes the instance and sets the ready flag to FALSE.
     153 *  Called either from FinalRelease() or by the parent when it gets destroyed.
     154 */
     155void Mouse::uninit()
     156{
     157    LogFlowThisFunc(("\n"));
     158
     159    /* Enclose the state transition Ready->InUninit->NotReady */
     160    AutoUninitSpan autoUninitSpan(this);
     161    if (autoUninitSpan.uninitDone())
     162        return;
     163
     164    if (mpDrv)
     165        mpDrv->pMouse = NULL;
     166    mpDrv = NULL;
     167
     168#ifdef VBOXBFE_WITHOUT_COM
     169    mParent = NULL;
     170#else
     171    unconst(mParent).setNull();
     172#endif
     173}
     174
     175
     176// IMouse properties
     177/////////////////////////////////////////////////////////////////////////////
     178
     179#ifdef VBOXBFE_WITHOUT_COM
     180int Mouse::getVMMDevMouseCaps(uint32_t *pfCaps)
     181{
     182    gVMMDev->QueryMouseCapabilities(pfCaps);
     183    return S_OK;
     184}
     185
     186int Mouse::setVMMDevMouseCaps(uint32_t fCaps)
     187{
     188    gVMMDev->SetMouseCapabilities(fCaps);
     189    return S_OK;
     190}
     191#else
     192int Mouse::getVMMDevMouseCaps(uint32_t *pfCaps)
     193{
     194    AssertPtrReturn(pfCaps, E_POINTER);
     195    VMMDev *pVMMDev = mParent->getVMMDev();
     196    ComAssertRet(pVMMDev, E_FAIL);
     197    PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
     198    ComAssertRet(pVMMDevPort, E_FAIL);
     199
     200    int rc = pVMMDevPort->pfnQueryMouseCapabilities(pVMMDevPort, pfCaps);
     201    return RT_SUCCESS(rc) ? S_OK : E_FAIL;
     202}
     203
     204int Mouse::setVMMDevMouseCaps(uint32_t fCaps)
     205{
     206    VMMDev *pVMMDev = mParent->getVMMDev();
     207    ComAssertRet(pVMMDev, E_FAIL);
     208    PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
     209    ComAssertRet(pVMMDevPort, E_FAIL);
     210
     211    int rc = pVMMDevPort->pfnSetMouseCapabilities(pVMMDevPort, fCaps);
     212    return RT_SUCCESS(rc) ? S_OK : E_FAIL;
     213}
     214#endif /* !VBOXBFE_WITHOUT_COM */
     215
     216/**
     217 * Returns whether the current setup can accept absolute mouse
     218 * events.
     219 *
     220 * @returns COM status code
     221 * @param absoluteSupported address of result variable
     222 */
     223STDMETHODIMP Mouse::COMGETTER(AbsoluteSupported) (BOOL *absoluteSupported)
     224{
     225    if (!absoluteSupported)
     226        return E_POINTER;
     227
     228    AutoCaller autoCaller(this);
     229    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     230
     231    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     232
     233    CHECK_CONSOLE_DRV (mpDrv);
     234
     235    if (uDevCaps & MOUSE_DEVCAP_ABSOLUTE)
     236        *absoluteSupported = TRUE;
     237    else
     238        *absoluteSupported = fVMMDevCanAbs;
     239
     240    return S_OK;
     241}
     242
     243/**
     244 * Returns whether the current setup can accept relative mouse
     245 * events.
     246 *
     247 * @returns COM status code
     248 * @param relativeSupported address of result variable
     249 */
     250STDMETHODIMP Mouse::COMGETTER(RelativeSupported) (BOOL *relativeSupported)
     251{
     252    if (!relativeSupported)
     253        return E_POINTER;
     254
     255    AutoCaller autoCaller(this);
     256    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     257
     258    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     259
     260    CHECK_CONSOLE_DRV (mpDrv);
     261
     262    if (uDevCaps & MOUSE_DEVCAP_RELATIVE)
     263        *relativeSupported = TRUE;
     264
     265    return S_OK;
     266}
     267
     268/**
     269 * Returns whether the guest can currently draw the mouse cursor itself.
     270 *
     271 * @returns COM status code
     272 * @param pfNeedsHostCursor address of result variable
     273 */
     274STDMETHODIMP Mouse::COMGETTER(NeedsHostCursor) (BOOL *pfNeedsHostCursor)
     275{
     276    if (!pfNeedsHostCursor)
     277        return E_POINTER;
     278
     279    AutoCaller autoCaller(this);
     280    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     281
     282    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     283
     284    CHECK_CONSOLE_DRV (mpDrv);
     285
     286    *pfNeedsHostCursor = fVMMDevNeedsHostCursor;
     287    return S_OK;
     288}
    55289
    56290// IMouse methods
    57291/////////////////////////////////////////////////////////////////////////////
    58292
    59 int Mouse::setAbsoluteCoordinates(bool a_fAbsolute)
    60 {
    61     this->fAbsolute = a_fAbsolute;
    62     return S_OK;
    63 }
    64 
    65 int Mouse::setNeedsHostCursor(bool a_fNeedsHostCursor)
    66 {
    67     this->fNeedsHostCursor = a_fNeedsHostCursor;
    68     return S_OK;
    69 }
    70 
    71 int Mouse::setHostCursor(bool enable)
    72 {
    73     uHostCaps = enable ? 0 : VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER;
    74     gVMMDev->SetMouseCapabilities(uHostCaps);
     293static uint32_t mouseButtonsToPDM(LONG buttonState)
     294{
     295    uint32_t fButtons = 0;
     296    if (buttonState & MouseButtonState_LeftButton)
     297        fButtons |= PDMIMOUSEPORT_BUTTON_LEFT;
     298    if (buttonState & MouseButtonState_RightButton)
     299        fButtons |= PDMIMOUSEPORT_BUTTON_RIGHT;
     300    if (buttonState & MouseButtonState_MiddleButton)
     301        fButtons |= PDMIMOUSEPORT_BUTTON_MIDDLE;
     302    if (buttonState & MouseButtonState_XButton1)
     303        fButtons |= PDMIMOUSEPORT_BUTTON_X1;
     304    if (buttonState & MouseButtonState_XButton2)
     305        fButtons |= PDMIMOUSEPORT_BUTTON_X2;
     306    return fButtons;
     307}
     308
     309
     310/**
     311 * Send a relative event to the mouse device.
     312 *
     313 * @returns   COM status code
     314 */
     315int Mouse::reportRelEventToMouseDev(int32_t dx, int32_t dy, int32_t dz,
     316                                    int32_t dw, uint32_t fButtons)
     317{
     318    if (dx || dy || dz || dw || fButtons != mLastButtons)
     319    {
     320        PPDMIMOUSEPORT pUpPort = mpDrv->pUpPort;
     321        int vrc = pUpPort->pfnPutEvent(pUpPort, dx, dy, dz, dw, fButtons);
     322
     323        if (RT_FAILURE(vrc))
     324            setError(VBOX_E_IPRT_ERROR,
     325                     tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
     326                     vrc);
     327        AssertRCReturn(vrc, VBOX_E_IPRT_ERROR);
     328    }
     329    return S_OK;
     330}
     331
     332
     333/**
     334 * Send an absolute position event to the mouse device.
     335 *
     336 * @returns   COM status code
     337 */
     338int Mouse::reportAbsEventToMouseDev(uint32_t mouseXAbs, uint32_t mouseYAbs,
     339                                    int32_t dz, int32_t dw, uint32_t fButtons)
     340{
     341    if (   mouseXAbs != mLastAbsX
     342        || mouseYAbs != mLastAbsY
     343        || dz
     344        || dw
     345        || fButtons != mLastButtons)
     346    {
     347        int vrc = mpDrv->pUpPort->pfnPutEventAbs(mpDrv->pUpPort, mouseXAbs,
     348                                                 mouseYAbs, dz, dw, fButtons);
     349        if (RT_FAILURE(vrc))
     350            setError(VBOX_E_IPRT_ERROR,
     351                     tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
     352                     vrc);
     353        AssertRCReturn(vrc, VBOX_E_IPRT_ERROR);
     354    }
     355    return S_OK;
     356}
     357
     358
     359/**
     360 * Send an absolute position event to the VMM device.
     361 *
     362 * @returns   COM status code
     363 */
     364int Mouse::reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs)
     365{
     366#ifdef VBOXBFE_WITHOUT_COM
     367    VMMDev *pVMMDev = gVMMDev;
     368#else
     369    VMMDev *pVMMDev = mParent->getVMMDev();
     370#endif
     371    ComAssertRet(pVMMDev, E_FAIL);
     372    PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
     373    ComAssertRet(pVMMDevPort, E_FAIL);
     374
     375    if (mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY)
     376    {
     377        int vrc = pVMMDevPort->pfnSetAbsoluteMouse(pVMMDevPort,
     378                                                   mouseXAbs, mouseYAbs);
     379        if (RT_FAILURE(vrc))
     380            setError(VBOX_E_IPRT_ERROR,
     381                     tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
     382                     vrc);
     383        AssertRCReturn(vrc, VBOX_E_IPRT_ERROR);
     384    }
    75385    return S_OK;
    76386}
     
    85395 * @param buttonState The mouse button state
    86396 */
    87 int Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG buttonState)
    88 {
    89     uint32_t mouseCaps;
    90     gVMMDev->QueryMouseCapabilities(&mouseCaps);
    91 
    92     /*
    93      * This method being called implies that the host no
    94      * longer wants to use absolute coordinates. If the VMM
    95      * device isn't aware of that yet, tell it.
    96      */
    97     if (mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)
    98     {
    99         gVMMDev->SetMouseCapabilities(uHostCaps);
    100     }
    101 
    102     uint32_t fButtons = 0;
    103     if (buttonState & PDMIMOUSEPORT_BUTTON_LEFT)
    104         fButtons |= PDMIMOUSEPORT_BUTTON_LEFT;
    105     if (buttonState & PDMIMOUSEPORT_BUTTON_RIGHT)
    106         fButtons |= PDMIMOUSEPORT_BUTTON_RIGHT;
    107     if (buttonState & PDMIMOUSEPORT_BUTTON_MIDDLE)
    108         fButtons |= PDMIMOUSEPORT_BUTTON_MIDDLE;
    109 
    110     int vrc = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, dx, dy, dz, 0 /* Horizontal wheel */, fButtons);
    111     if (RT_FAILURE (vrc))
    112         return E_FAIL;
    113 
    114     return S_OK;
    115 }
     397STDMETHODIMP Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG dw, LONG buttonState)
     398{
     399    HRESULT rc = S_OK;
     400
     401    AutoCaller autoCaller(this);
     402    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     403
     404    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     405
     406    CHECK_CONSOLE_DRV (mpDrv);
     407
     408    LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__,
     409             dx, dy, dz, dw));
     410    if (!(uDevCaps & MOUSE_DEVCAP_ABSOLUTE))
     411    {
     412        /*
     413         * This method being called implies that the host no
     414         * longer wants to use absolute coordinates. If the VMM
     415         * device isn't aware of that yet, tell it.
     416         */
     417        uint32_t mouseCaps;
     418        rc = getVMMDevMouseCaps(&mouseCaps);
     419        ComAssertComRCRet(rc, rc);
     420
     421        if (mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)
     422            setVMMDevMouseCaps(uHostCaps);
     423    }
     424
     425    uint32_t fButtons = mouseButtonsToPDM(buttonState);
     426    rc = reportRelEventToMouseDev(dx, dy, dz, dw, fButtons);
     427    if (SUCCEEDED(rc))
     428        mLastButtons = fButtons;
     429
     430    return rc;
     431}
     432
     433/**
     434 * Convert an X value in screen co-ordinates to a value from 0 to 0xffff
     435 *
     436 * @returns   COM status value
     437 */
     438int Mouse::convertDisplayWidth(LONG x, uint32_t *pcX)
     439{
     440    AssertPtrReturn(pcX, E_POINTER);
     441#ifndef VBOXBFE_WITHOUT_COM
     442    Display *pDisplay = mParent->getDisplay();
     443    ComAssertRet(pDisplay, E_FAIL);
     444#endif
     445
     446    ULONG displayWidth;
     447#ifdef VBOXBFE_WITHOUT_COM
     448    displayWidth = gDisplay->getWidth();
     449#else
     450    int rc = pDisplay->COMGETTER(Width)(&displayWidth);
     451    ComAssertComRCRet(rc, rc);
     452#endif
     453
     454    *pcX = displayWidth ? (x * 0xFFFF) / displayWidth: 0;
     455    return S_OK;
     456}
     457
     458/**
     459 * Convert a Y value in screen co-ordinates to a value from 0 to 0xffff
     460 *
     461 * @returns   COM status value
     462 */
     463int Mouse::convertDisplayHeight(LONG y, uint32_t *pcY)
     464{
     465    AssertPtrReturn(pcY, E_POINTER);
     466#ifndef VBOXBFE_WITHOUT_COM
     467    Display *pDisplay = mParent->getDisplay();
     468    ComAssertRet(pDisplay, E_FAIL);
     469#endif
     470
     471    ULONG displayHeight;
     472#ifdef VBOXBFE_WITHOUT_COM
     473    displayHeight = gDisplay->getHeight();
     474#else
     475    int rc = pDisplay->COMGETTER(Height)(&displayHeight);
     476    ComAssertComRCRet(rc, rc);
     477#endif
     478
     479    *pcY = displayHeight ? (y * 0xFFFF) / displayHeight: 0;
     480    return S_OK;
     481}
     482
    116483
    117484/**
     
    125492 * @param buttonState The mouse button state
    126493 */
    127 int Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG buttonState)
    128 {
    129     uint32_t mouseCaps;
    130     gVMMDev->QueryMouseCapabilities(&mouseCaps);
    131 
    132     /*
    133      * This method being called implies that the host no
    134      * longer wants to use absolute coordinates. If the VMM
    135      * device isn't aware of that yet, tell it.
    136      */
    137     if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
    138     {
    139         gVMMDev->SetMouseCapabilities(uHostCaps | VMMDEV_MOUSE_HOST_CAN_ABSOLUTE);
    140     }
    141 
    142     ULONG displayWidth;
    143     ULONG displayHeight;
    144     displayHeight = gDisplay->getHeight();
    145     displayWidth  = gDisplay->getWidth();
    146 
    147     uint32_t mouseXAbs = (x * 0xFFFF) / displayWidth;
    148     uint32_t mouseYAbs = (y * 0xFFFF) / displayHeight;
    149 
    150     /*
    151      * Send the absolute mouse position to the VMM device
    152      */
    153     int vrc = gVMMDev->SetAbsoluteMouse(mouseXAbs, mouseYAbs);
    154     AssertRC(vrc);
    155 
    156     // check if the guest actually wants absolute mouse positions
    157     if (mouseCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
    158     {
    159         uint32_t fButtons = 0;
    160         if (buttonState & PDMIMOUSEPORT_BUTTON_LEFT)
    161             fButtons |= PDMIMOUSEPORT_BUTTON_LEFT;
    162         if (buttonState & PDMIMOUSEPORT_BUTTON_RIGHT)
    163             fButtons |= PDMIMOUSEPORT_BUTTON_RIGHT;
    164         if (buttonState & PDMIMOUSEPORT_BUTTON_MIDDLE)
    165             fButtons |= PDMIMOUSEPORT_BUTTON_MIDDLE;
    166 
    167         vrc = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, 1, 1, dz, 0 /* Horizontal wheel */, fButtons);
    168         if (RT_FAILURE (vrc))
    169             return E_FAIL;
    170     }
    171 
    172     return S_OK;
    173 }
    174 
     494STDMETHODIMP Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG dw,
     495                                          LONG buttonState)
     496{
     497    AutoCaller autoCaller(this);
     498    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     499
     500    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     501
     502    LogRel3(("%s: x=%d, y=%d, dz=%d, dw=%d, buttonState=0x%x\n",
     503             __PRETTY_FUNCTION__, x, y, dz, dw, buttonState));
     504
     505    CHECK_CONSOLE_DRV(mpDrv);
     506
     507    uint32_t mouseXAbs;
     508    HRESULT rc = convertDisplayWidth(x, &mouseXAbs);
     509    ComAssertComRCRet(rc, rc);
     510    if (mouseXAbs > 0xffff)
     511        mouseXAbs = mLastAbsX;
     512
     513    uint32_t mouseYAbs;
     514    rc = convertDisplayHeight(y, &mouseYAbs);
     515    ComAssertComRCRet(rc, rc);
     516    if (mouseYAbs > 0xffff)
     517        mouseYAbs = mLastAbsY;
     518
     519    uint32_t fButtons = mouseButtonsToPDM(buttonState);
     520
     521    /* Older guest additions rely on a small phony movement event on the
     522     * PS/2 device to notice absolute events. */
     523    bool fNeedsJiggle = false;
     524
     525    if (uDevCaps & MOUSE_DEVCAP_ABSOLUTE)
     526        rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
     527    else
     528    {
     529        uint32_t mouseCaps;
     530        rc = getVMMDevMouseCaps(&mouseCaps);
     531        ComAssertComRCRet(rc, rc);
     532
     533        /*
     534         * This method being called implies that the host wants
     535         * to use absolute coordinates. If the VMM device isn't
     536         * aware of that yet, tell it.
     537         */
     538        if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
     539            setVMMDevMouseCaps(uHostCaps | VMMDEV_MOUSE_HOST_CAN_ABSOLUTE);
     540
     541        /*
     542         * Send the absolute mouse position to the VMM device.
     543         */
     544        rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs);
     545        fNeedsJiggle = !(mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV);
     546    }
     547    ComAssertComRCRet(rc, rc);
     548
     549    mLastAbsX = mouseXAbs;
     550    mLastAbsY = mouseYAbs;
     551
     552    if (!(uDevCaps & MOUSE_DEVCAP_ABSOLUTE))
     553    {
     554        /* We may need to send a relative event for button information or to
     555         * wake the guest up to the changed absolute co-ordinates.
     556         * If the event is a pure wake up one, we make sure it contains some
     557         * (possibly phony) event data to make sure it isn't just discarded on
     558         * the way. */
     559        if (fNeedsJiggle || fButtons != mLastButtons || dz || dw)
     560        {
     561            rc = reportRelEventToMouseDev(fNeedsJiggle ? 1 : 0, 0, dz, dw,
     562                                          fButtons);
     563            ComAssertComRCRet(rc, rc);
     564        }
     565    }
     566    mLastButtons = fButtons;
     567    return rc;
     568}
     569
     570// private methods
    175571/////////////////////////////////////////////////////////////////////////////
    176572
     573
     574void Mouse::sendMouseCapsCallback(void)
     575{
     576    bool fAbsSupported =   uDevCaps & MOUSE_DEVCAP_ABSOLUTE
     577                         ? true : fVMMDevCanAbs;
     578#ifndef VBOXBFE_WITHOUT_COM
     579    mParent->onMouseCapabilityChange(fAbsSupported, uDevCaps & MOUSE_DEVCAP_RELATIVE, fVMMDevNeedsHostCursor);
     580#endif
     581}
     582
     583
     584/**
     585 * @interface_method_impl{PDMIMOUSECONNECTOR,pfnAbsModeChange}
     586 */
     587DECLCALLBACK(void) Mouse::mouseAbsModeChange(PPDMIMOUSECONNECTOR pInterface, bool fEnabled)
     588{
     589    PDRVMAINMOUSE pDrv = RT_FROM_MEMBER(pInterface, DRVMAINMOUSE, IConnector);
     590    if (fEnabled)
     591        pDrv->pMouse->uDevCaps |= MOUSE_DEVCAP_ABSOLUTE;
     592    else
     593        pDrv->pMouse->uDevCaps &= ~MOUSE_DEVCAP_ABSOLUTE;
     594
     595    pDrv->pMouse->sendMouseCapsCallback();
     596}
     597
     598
    177599/**
    178600 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     
    180602DECLCALLBACK(void *)  Mouse::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
    181603{
    182     PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    183     PDRVMAINMOUSE pDrv = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
    184     if (RTUuidCompare2Strs(pszIID, PDMIBASE_IID) == 0)
    185         return &pDrvIns->IBase;
    186     if (RTUuidCompare2Strs(pszIID, PDMIMOUSECONNECTOR_IID) == 0)
    187         return &pDrv->Connector;
     604    PPDMDRVINS      pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
     605    PDRVMAINMOUSE   pDrv    = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
     606
     607    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     608    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUSECONNECTOR, &pDrv->IConnector);
    188609    return NULL;
    189610}
     
    198619DECLCALLBACK(void) Mouse::drvDestruct(PPDMDRVINS pDrvIns)
    199620{
    200     //PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
     621    PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
    201622    LogFlow(("Mouse::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
     623    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     624
     625    if (pData->pMouse)
     626    {
     627        AutoWriteLock mouseLock(pData->pMouse COMMA_LOCKVAL_SRC_POS);
     628        pData->pMouse->mpDrv = NULL;
     629    }
    202630}
    203631
     
    212640    PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
    213641    LogFlow(("drvMainMouse_Construct: iInstance=%d\n", pDrvIns->iInstance));
     642    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    214643
    215644    /*
     
    227656    pDrvIns->IBase.pfnQueryInterface        = Mouse::drvQueryInterface;
    228657
     658    pData->IConnector.pfnAbsModeChange      = Mouse::mouseAbsModeChange;
     659
    229660    /*
    230661     * Get the IMousePort interface of the above driver/device.
    231662     */
    232         pData->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMOUSEPORT);
     663    pData->pUpPort = (PPDMIMOUSEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMIMOUSEPORT_IID);
    233664    if (!pData->pUpPort)
    234665    {
     
    247678        return rc;
    248679    }
    249 
    250     pData->mpDrv = (Mouse*)pv;        /** @todo Check this cast! */
    251     pData->mpDrv->mpDrv = pData;
     680    pData->pMouse = (Mouse *)pv;        /** @todo Check this cast! */
     681    pData->pMouse->mpDrv = pData;
    252682
    253683    return VINF_SUCCESS;
     
    305735    PDM_DRVREG_VERSION
    306736};
    307 
     737/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Frontends/VBoxBFE/MouseImpl.h

    r26173 r26834  
    11/* $Id$ */
    22/** @file
    3  * VBox frontends: Basic Frontend (BFE):
    4  * Declaration of Mouse class
     3 * VirtualBox VBoxBFE/COM class implementation
    54 */
    65
    76/*
    8  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
    98 *
    109 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2423#define ____H_MOUSEIMPL
    2524
    26 #include <VBox/pdm.h>
     25#include "VirtualBoxBase.h"
     26#ifndef VBOXBFE_WITHOUT_COM
     27# include "ConsoleEvents.h"
     28#endif
     29#include "ConsoleImpl.h"
     30#include <VBox/pdmdrv.h>
    2731
    2832/** Simple mouse event class. */
     
    3034{
    3135public:
    32     MouseEvent() : dx(0), dy(0), dz(0), state(-1) {}
    33     MouseEvent(int _dx, int _dy, int _dz, int _state) :
    34         dx(_dx), dy(_dy), dz(_dz), state(_state) {}
     36    MouseEvent() : dx(0), dy(0), dz(0), dw(0), state(-1) {}
     37    MouseEvent(int32_t _dx, int32_t _dy, int32_t _dz, int32_t _dw, int32_t _state) :
     38        dx(_dx), dy(_dy), dz(_dz), dw(_dw), state(_state) {}
    3539    bool isValid()
    3640    {
    3741        return state != -1;
    3842    }
    39     // not logical to be int but that's how it's defined in QEMU
    40     /** @todo r=bird: and what is the logical declaration then? We'll be using int32_t btw. */
    41     int dx, dy, dz;
    42     int state;
     43    /* Note: dw is the horizontal scroll wheel */
     44    int32_t dx, dy, dz, dw;
     45    int32_t state;
     46};
     47#ifndef VBOXBFE_WITHOUT_COM
     48// template instantiation
     49typedef ConsoleEventBuffer<MouseEvent> MouseEventBuffer;
     50#endif
     51
     52enum
     53{
     54    MOUSE_DEVCAP_RELATIVE = 1,
     55    MOUSE_DEVCAP_ABSOLUTE = 2
    4356};
    4457
    45 class Mouse
     58class ATL_NO_VTABLE Mouse :
     59    public VirtualBoxBase
     60#ifndef VBOXBFE_WITHOUT_COM
     61    ,
     62    public VirtualBoxSupportErrorInfoImpl<Mouse, IMouse>,
     63    public VirtualBoxSupportTranslation<Mouse>,
     64    VBOX_SCRIPTABLE_IMPL(IMouse)
     65#endif
    4666{
    4767public:
    4868
    49     Mouse() : fAbsolute(false), fNeedsHostCursor(false), mpDrv(NULL), uHostCaps(0) {}
     69#ifndef VBOXBFE_WITHOUT_COM
     70    VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (Mouse)
     71
     72    DECLARE_NOT_AGGREGATABLE(Mouse)
     73
     74    DECLARE_PROTECT_FINAL_CONSTRUCT()
     75
     76    BEGIN_COM_MAP(Mouse)
     77        COM_INTERFACE_ENTRY  (ISupportErrorInfo)
     78        COM_INTERFACE_ENTRY  (IMouse)
     79        COM_INTERFACE_ENTRY2 (IDispatch, IMouse)
     80    END_COM_MAP()
     81#endif
     82
     83    DECLARE_EMPTY_CTOR_DTOR (Mouse)
     84
     85    HRESULT FinalConstruct();
     86    void FinalRelease();
     87
     88    // public initializer/uninitializer for internal purposes only
     89    HRESULT init(Console *parent);
     90    void uninit();
     91
     92    // IMouse properties
     93    STDMETHOD(COMGETTER(AbsoluteSupported)) (BOOL *absoluteSupported);
     94    STDMETHOD(COMGETTER(RelativeSupported)) (BOOL *relativeSupported);
     95    STDMETHOD(COMGETTER(NeedsHostCursor)) (BOOL *needsHostCursor);
    5096
    5197    // IMouse methods
    52     int  PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG buttonState);
    53     int  PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG buttonState);
     98    STDMETHOD(PutMouseEvent)(LONG dx, LONG dy, LONG dz, LONG dw,
     99                             LONG buttonState);
     100    STDMETHOD(PutMouseEventAbsolute)(LONG x, LONG y, LONG dz, LONG dw,
     101                                     LONG buttonState);
    54102
    55     int  setAbsoluteCoordinates(bool fAbsolute);
    56     int  setNeedsHostCursor(bool fNeedsHostCursor);
    57 #ifdef RT_OS_L4
    58     // So far L4Con does not support an own mouse pointer.
    59     bool getAbsoluteCoordinates() { return false; }
    60 #else
    61     bool getAbsoluteCoordinates() { return fAbsolute; }
    62 #endif
    63     bool getNeedsHostCursor() { return fNeedsHostCursor; }
    64     int  setHostCursor(bool enable);
     103    // for VirtualBoxSupportErrorInfoImpl
     104    static const wchar_t *getComponentName() { return L"Mouse"; }
    65105
    66106    static const PDMDRVREG  DrvReg;
     107
     108#ifndef VBOXBFE_WITHOUT_COM
     109    Console *getParent() const
     110    {
     111        return mParent;
     112    }
     113#endif
     114
     115    // for VMMDevInterface
     116    void onVMMDevCanAbsChange(bool canAbs)
     117    {
     118        fVMMDevCanAbs = canAbs;
     119        sendMouseCapsCallback();
     120    }
     121
     122    void onVMMDevNeedsHostChange(bool needsHost)
     123    {
     124        fVMMDevNeedsHostCursor = needsHost;
     125        sendMouseCapsCallback();
     126    }
    67127
    68128private:
    69129
    70130    static DECLCALLBACK(void *) drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
     131    static DECLCALLBACK(void)   mouseAbsModeChange (PPDMIMOUSECONNECTOR pInterface, bool fAbs);
    71132    static DECLCALLBACK(int)    drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
    72133    static DECLCALLBACK(void)   drvDestruct(PPDMDRVINS pDrvIns);
     134   
     135    int getVMMDevMouseCaps(uint32_t *pfCaps);
     136    int setVMMDevMouseCaps(uint32_t fCaps);
     137    int reportRelEventToMouseDev(int32_t dx, int32_t dy, int32_t dz,
     138                                 int32_t dw, uint32_t fButtons);
     139    int reportAbsEventToMouseDev(uint32_t mouseXAbs, uint32_t mouseYAbs,
     140                                 int32_t dz, int32_t dw, uint32_t fButtons);
     141    int reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs);
     142    int convertDisplayWidth(LONG x, uint32_t *pcX);
     143    int convertDisplayHeight(LONG y, uint32_t *pcY);
     144   
     145    void sendMouseCapsCallback(void);
    73146
    74     /** Guest supports absolute coordinates */
    75     bool fAbsolute;
    76     /** Guest is not able to draw a cursor itself */
    77     bool fNeedsHostCursor;
     147#ifdef VBOXBFE_WITHOUT_COM
     148    Console *mParent;
     149#else
     150    const ComObjPtr<Console, ComWeakRef> mParent;
     151#endif
    78152    /** Pointer to the associated mouse driver. */
    79153    struct DRVMAINMOUSE    *mpDrv;
    80     /** Host capabilities */
     154
    81155    LONG uHostCaps;
     156    LONG uDevCaps;
     157    bool fVMMDevCanAbs;
     158    bool fVMMDevNeedsHostCursor;
     159    uint32_t mLastAbsX;
     160    uint32_t mLastAbsY;
     161    uint32_t mLastButtons;
    82162};
    83163
     164#ifdef VBOXBFE_WITHOUT_COM
    84165extern Mouse *gMouse;
     166#endif
    85167
    86168#endif // !____H_MOUSEIMPL
     169/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Frontends/VBoxBFE/SDLConsole.cpp

    r26509 r26834  
    135135     */
    136136    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
     137
     138    /*
     139     * Initialise "children" (so far only Mouse)
     140     */
     141    if (FAILED(gMouse->init(this)))
     142    {
     143        RTPrintf("VBoxBFE: failed to initialise the mouse device\n");
     144        return;
     145    }
     146
    137147    mfInitialized = true;
    138148}
     
    142152    if (mfInputGrab)
    143153        inputGrabEnd();
     154
     155    /*
     156     * Uninitialise "children" (so far only Mouse)
     157     */
     158    gMouse->uninit();
     159
    144160    if (mWMIcon)
    145161    {
     
    277293        case SDL_MOUSEMOTION:
    278294        {
    279             if (mfInputGrab || gMouse->getAbsoluteCoordinates())
     295            bool fMouseAbsolute;
     296            gMouse->COMGETTER(AbsoluteSupported)(&fMouseAbsolute);
     297            if (mfInputGrab || fMouseAbsolute)
    280298                mouseSendEvent(0);
    281299            break;
     
    288306        case SDL_MOUSEBUTTONUP:
    289307        {
     308            bool fMouseAbsolute;
     309            gMouse->COMGETTER(AbsoluteSupported)(&fMouseAbsolute);
    290310            SDL_MouseButtonEvent *bev = &ev->button;
    291             if (!mfInputGrab && !gMouse->getAbsoluteCoordinates())
     311            if (!mfInputGrab && !fMouseAbsolute)
    292312            {
    293313                if (ev->type == SDL_MOUSEBUTTONDOWN && (bev->state & SDL_BUTTON_LMASK))
     
    11371157void SDLConsole::inputGrabStart()
    11381158{
     1159    bool fNeedsHostCursor;
     1160    gMouse->COMGETTER(NeedsHostCursor)(&fNeedsHostCursor);
    11391161#ifdef RT_OS_DARWIN
    11401162    DisableGlobalHotKeys(true);
    11411163#endif
    1142     if (!gMouse->getNeedsHostCursor())
     1164    if (!fNeedsHostCursor)
    11431165        SDL_ShowCursor(SDL_DISABLE);
    11441166    SDL_WM_GrabInput(SDL_GRAB_ON);
     
    11541176void SDLConsole::inputGrabEnd()
    11551177{
     1178    bool fNeedsHostCursor;
     1179    gMouse->COMGETTER(NeedsHostCursor)(&fNeedsHostCursor);
    11561180    SDL_WM_GrabInput(SDL_GRAB_OFF);
    1157     if (!gMouse->getNeedsHostCursor())
     1181    if (!fNeedsHostCursor)
    11581182        SDL_ShowCursor(SDL_ENABLE);
    11591183#ifdef RT_OS_DARWIN
     
    11771201    int x, y, state, buttons;
    11781202    bool abs;
    1179 
    1180     abs = (gMouse->getAbsoluteCoordinates() && !mfInputGrab) || gMouse->getNeedsHostCursor();
     1203    bool fMouseAbsolute;
     1204    bool fNeedsHostCursor;
     1205
     1206    gMouse->COMGETTER(AbsoluteSupported)(&fMouseAbsolute);
     1207    gMouse->COMGETTER(NeedsHostCursor)(&fNeedsHostCursor);
     1208    abs = (fMouseAbsolute && !mfInputGrab) || fNeedsHostCursor;
    11811209
    11821210    state = abs ? SDL_GetMouseState(&x, &y) : SDL_GetRelativeMouseState(&x, &y);
     
    12021230        /* only send if outside the extra offset area */
    12031231        if (y >= gFramebuffer->getYOffset())
    1204             gMouse->PutMouseEventAbsolute(x + 1, y + 1 - gFramebuffer->getYOffset(), dz, buttons);
     1232            gMouse->PutMouseEventAbsolute(x + 1, y + 1 - gFramebuffer->getYOffset(), dz, 0, buttons);
    12051233    }
    12061234    else
    12071235    {
    1208         gMouse->PutMouseEvent(x, y, dz, buttons);
     1236        gMouse->PutMouseEvent(x, y, dz, 0, buttons);
    12091237    }
    12101238}
     
    13251353     * don't do anything if there are no guest additions loaded (anymore)
    13261354     */
    1327     if (!gMouse->getAbsoluteCoordinates())
     1355    bool fMouseAbsolute;
     1356    gMouse->COMGETTER(AbsoluteSupported)(&fMouseAbsolute);
     1357    if (!fMouseAbsolute)
    13281358        return;
    13291359
  • trunk/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp

    r25771 r26834  
    790790    gKeyboard = new Keyboard();
    791791    gMouse = new Mouse();
     792    if (FAILED(gMouse->FinalConstruct()))
     793        goto leave;
    792794    gVMMDev = new VMMDev();
    793795    gDisplay = new VMDisplay();
     
    979981    delete gDisplay;
    980982    delete gKeyboard;
     983    gMouse->FinalRelease();
    981984    delete gMouse;
    982985    delete gStatus;
     
    12571260    }
    12581261#endif /* VBOXBFE_WITH_USB */
    1259 
    1260 #ifdef RT_OS_L4
    1261     /* L4 console cannot draw a host cursor */
    1262     gMouse->setHostCursor(false);
    1263 #else
    1264     gMouse->setHostCursor(true);
    1265 #endif
    12661262
    12671263    /*
  • trunk/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp

    r26173 r26834  
    173173    if (gMouse)
    174174    {
    175         gMouse->setAbsoluteCoordinates(!!(newCapabilities & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE));
    176         gMouse->setNeedsHostCursor(!!(newCapabilities & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR));
     175        gMouse->onVMMDevCanAbsChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE));
     176        gMouse->onVMMDevNeedsHostChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR));
    177177    }
    178178    if (gConsole)
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