VirtualBox

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


Ignore:
Timestamp:
May 22, 2023 10:40:30 AM (21 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
157533
Message:

FE/VBoxBFE: Some crude keyboard implementation for some input support inside the guest for now, bugref:10397

Location:
trunk/src/VBox/Frontends/VBoxBFE
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxBFE/Display.cpp

    r99546 r99890  
    146146
    147147
    148 int Display::i_invalidateAndUpdateScreen(uint32_t aScreenId)
     148void Display::i_invalidateAndUpdateScreen(uint32_t aScreenId)
    149149{
    150150    mpDrv->IConnector.pbData     = m_pFramebuffer->getPixelData();
  • trunk/src/VBox/Frontends/VBoxBFE/Display.h

    r99549 r99890  
    6767    void i_handleDisplayUpdate (int x, int y, int w, int h);
    6868
    69     int i_invalidateAndUpdateScreen(uint32_t aScreenId);
     69    void i_invalidateAndUpdateScreen(uint32_t aScreenId);
    7070
    7171
  • trunk/src/VBox/Frontends/VBoxBFE/Makefile.kmk

    r99548 r99890  
    5959        VBoxBFE.cpp \
    6060        Display.cpp \
    61         Framebuffer.cpp
     61        Framebuffer.cpp \
     62        Keyboard.cpp
    6263ifdef VBOX_WITH_HARDENING
    6364 VBoxBFE_LDFLAGS.darwin += -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxBFE.dylib
  • trunk/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp

    r99751 r99890  
    3232*********************************************************************************************************************************/
    3333#define LOG_GROUP LOG_GROUP_GUI
     34
     35#ifdef RT_OS_DARWIN
     36# include <Carbon/Carbon.h>
     37# undef PVM
     38#endif
    3439
    3540#include <VBox/log.h>
     
    5863#include "Display.h"
    5964#include "Framebuffer.h"
     65#include "Keyboard.h"
    6066
    6167
     
    7783*********************************************************************************************************************************/
    7884
     85enum TitlebarMode
     86{
     87    TITLEBAR_NORMAL   = 1,
     88    TITLEBAR_STARTUP  = 2,
     89    TITLEBAR_SAVE     = 3,
     90    TITLEBAR_SNAPSHOT = 4
     91};
     92
    7993
    8094/*********************************************************************************************************************************
    8195*   Global Variables                                                                                                             *
    8296*********************************************************************************************************************************/
     97static int gHostKeyMod  = KMOD_RCTRL;
     98static int gHostKeySym1 = SDLK_RCTRL;
     99static int gHostKeySym2 = SDLK_UNKNOWN;
     100static bool gfGrabbed = FALSE;
     101static bool gfGrabOnMouseClick = TRUE;
     102static bool gfFullscreenResize = FALSE;
     103static bool gfAllowFullscreenToggle = TRUE;
     104static bool gfAbsoluteMouseHost = FALSE;
     105static bool gfAbsoluteMouseGuest = FALSE;
     106static bool gfRelativeMouseGuest = TRUE;
     107static bool gfGuestNeedsHostCursor = FALSE;
     108static bool gfOffCursorActive = FALSE;
     109static bool gfGuestNumLockPressed = FALSE;
     110static bool gfGuestCapsLockPressed = FALSE;
     111static bool gfGuestScrollLockPressed = FALSE;
     112
     113/** modifier keypress status (scancode as index) */
     114static uint8_t gaModifiersState[256];
     115
    83116/** flag whether frontend should terminate */
    84117static volatile bool    g_fTerminateFE      = false;
     
    99132static Display          *g_pDisplay         = NULL;
    100133static Framebuffer      *g_pFramebuffer     = NULL;
     134static Keyboard         *g_pKeyboard        = NULL;
    101135static bool gfIgnoreNextResize = false;
     136static uint32_t gcMonitors = 1;
    102137static SDL_TimerID gSdlResizeTimer = 0;
    103138
     
    107142extern DECL_HIDDEN_DATA(RTSEMEVENT) g_EventSemSDLEvents;
    108143extern DECL_HIDDEN_DATA(volatile int32_t) g_cNotifyUpdateEventsPending;
     144
     145
     146/* The damned GOTOs forces this to be up here - totally out of place. */
     147/*
     148 * Host key handling.
     149 *
     150 * The golden rule is that host-key combinations should not be seen
     151 * by the guest. For instance a CAD should not have any extra RCtrl down
     152 * and RCtrl up around itself. Nor should a resume be followed by a Ctrl-P
     153 * that could encourage applications to start printing.
     154 *
     155 * We must not confuse the hostkey processing into any release sequences
     156 * either, the host key is supposed to be explicitly pressing one key.
     157 *
     158 * Quick state diagram:
     159 *
     160 *            host key down alone
     161 *  (Normal) ---------------
     162 *    ^ ^                  |
     163 *    | |                  v          host combination key down
     164 *    | |            (Host key down) ----------------
     165 *    | | host key up v    |                        |
     166 *    | |--------------    | other key down         v           host combination key down
     167 *    |                    |                  (host key used) -------------
     168 *    |                    |                        |      ^              |
     169 *    |              (not host key)--               |      |---------------
     170 *    |                    |     |  |               |
     171 *    |                    |     ---- other         |
     172 *    |  modifiers = 0     v                        v
     173 *    -----------------------------------------------
     174 */
     175enum HKEYSTATE
     176{
     177    /** The initial and most common state, pass keystrokes to the guest.
     178     * Next state: HKEYSTATE_DOWN
     179     * Prev state: Any */
     180    HKEYSTATE_NORMAL = 1,
     181    /** The first host key was pressed down
     182     */
     183    HKEYSTATE_DOWN_1ST,
     184    /** The second host key was pressed down (if gHostKeySym2 != SDLK_UNKNOWN)
     185     */
     186    HKEYSTATE_DOWN_2ND,
     187    /** The host key has been pressed down.
     188     * Prev state: HKEYSTATE_NORMAL
     189     * Next state: HKEYSTATE_NORMAL - host key up, capture toggle.
     190     * Next state: HKEYSTATE_USED   - host key combination down.
     191     * Next state: HKEYSTATE_NOT_IT - non-host key combination down.
     192     */
     193    HKEYSTATE_DOWN,
     194    /** A host key combination was pressed.
     195     * Prev state: HKEYSTATE_DOWN
     196     * Next state: HKEYSTATE_NORMAL - when modifiers are all 0
     197     */
     198    HKEYSTATE_USED,
     199    /** A non-host key combination was attempted. Send hostkey down to the
     200     * guest and continue until all modifiers have been released.
     201     * Prev state: HKEYSTATE_DOWN
     202     * Next state: HKEYSTATE_NORMAL - when modifiers are all 0
     203     */
     204    HKEYSTATE_NOT_IT
     205} enmHKeyState = HKEYSTATE_NORMAL;
    109206
    110207
     
    112209*   Internal Functions                                                                                                           *
    113210*********************************************************************************************************************************/
     211
     212/**
     213 * Build the titlebar string
     214 */
     215static void UpdateTitlebar(TitlebarMode mode, uint32_t u32User = 0)
     216{
     217    static char szTitle[1024] = {0};
     218
     219    /* back up current title */
     220    char szPrevTitle[1024];
     221    strcpy(szPrevTitle, szTitle);
     222
     223    RTStrPrintf(szTitle, sizeof(szTitle), "%s - " VBOX_PRODUCT,
     224                "<noname>");
     225
     226    /* which mode are we in? */
     227    switch (mode)
     228    {
     229        case TITLEBAR_NORMAL:
     230        {
     231            if (gfGrabbed)
     232                RTStrPrintf(szTitle + strlen(szTitle), sizeof(szTitle) - strlen(szTitle), " - [Input captured]");
     233            break;
     234        }
     235
     236        case TITLEBAR_STARTUP:
     237        {
     238            RTStrPrintf(szTitle + strlen(szTitle), sizeof(szTitle) - strlen(szTitle),
     239                        " - Starting...");
     240            /* ignore other states, we could already be in running or aborted state */
     241            break;
     242        }
     243
     244        case TITLEBAR_SAVE:
     245        {
     246            AssertMsg(u32User <= 100, ("%d\n", u32User));
     247            RTStrPrintf(szTitle + strlen(szTitle), sizeof(szTitle) - strlen(szTitle),
     248                        " - Saving %d%%...", u32User);
     249            break;
     250        }
     251
     252        case TITLEBAR_SNAPSHOT:
     253        {
     254            AssertMsg(u32User <= 100, ("%d\n", u32User));
     255            RTStrPrintf(szTitle + strlen(szTitle), sizeof(szTitle) - strlen(szTitle),
     256                        " - Taking snapshot %d%%...", u32User);
     257            break;
     258        }
     259
     260        default:
     261            RTPrintf("Error: Invalid title bar mode %d!\n", mode);
     262            return;
     263    }
     264
     265    /*
     266     * Don't update if it didn't change.
     267     */
     268    if (!strcmp(szTitle, szPrevTitle))
     269        return;
     270
     271    /*
     272     * Set the new title
     273     */
     274    g_pFramebuffer->setWindowTitle(szTitle);
     275}
     276
     277
     278#ifdef RT_OS_DARWIN
     279RT_C_DECLS_BEGIN
     280/* Private interface in 10.3 and later. */
     281typedef int CGSConnection;
     282typedef enum
     283{
     284    kCGSGlobalHotKeyEnable = 0,
     285    kCGSGlobalHotKeyDisable,
     286    kCGSGlobalHotKeyInvalid = -1 /* bird */
     287} CGSGlobalHotKeyOperatingMode;
     288extern CGSConnection _CGSDefaultConnection(void);
     289extern CGError CGSGetGlobalHotKeyOperatingMode(CGSConnection Connection, CGSGlobalHotKeyOperatingMode *enmMode);
     290extern CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection Connection, CGSGlobalHotKeyOperatingMode enmMode);
     291RT_C_DECLS_END
     292
     293/** Keeping track of whether we disabled the hotkeys or not. */
     294static bool g_fHotKeysDisabled = false;
     295/** Whether we've connected or not. */
     296static bool g_fConnectedToCGS = false;
     297/** Cached connection. */
     298static CGSConnection g_CGSConnection;
     299
     300/**
     301 * Disables or enabled global hot keys.
     302 */
     303static void DisableGlobalHotKeys(bool fDisable)
     304{
     305    if (!g_fConnectedToCGS)
     306    {
     307        g_CGSConnection = _CGSDefaultConnection();
     308        g_fConnectedToCGS = true;
     309    }
     310
     311    /* get current mode. */
     312    CGSGlobalHotKeyOperatingMode enmMode = kCGSGlobalHotKeyInvalid;
     313    CGSGetGlobalHotKeyOperatingMode(g_CGSConnection, &enmMode);
     314
     315    /* calc new mode. */
     316    if (fDisable)
     317    {
     318        if (enmMode != kCGSGlobalHotKeyEnable)
     319            return;
     320        enmMode = kCGSGlobalHotKeyDisable;
     321    }
     322    else
     323    {
     324        if (    enmMode != kCGSGlobalHotKeyDisable
     325            /*||  !g_fHotKeysDisabled*/)
     326            return;
     327        enmMode = kCGSGlobalHotKeyEnable;
     328    }
     329
     330    /* try set it and check the actual result. */
     331    CGSSetGlobalHotKeyOperatingMode(g_CGSConnection, enmMode);
     332    CGSGlobalHotKeyOperatingMode enmNewMode = kCGSGlobalHotKeyInvalid;
     333    CGSGetGlobalHotKeyOperatingMode(g_CGSConnection, &enmNewMode);
     334    if (enmNewMode == enmMode)
     335        g_fHotKeysDisabled = enmMode == kCGSGlobalHotKeyDisable;
     336}
     337#endif /* RT_OS_DARWIN */
     338
     339
     340/**
     341 * Start grabbing the mouse.
     342 */
     343static void InputGrabStart(void)
     344{
     345#ifdef RT_OS_DARWIN
     346    DisableGlobalHotKeys(true);
     347#endif
     348    if (!gfGuestNeedsHostCursor && gfRelativeMouseGuest)
     349        SDL_ShowCursor(SDL_DISABLE);
     350    SDL_SetRelativeMouseMode(SDL_TRUE);
     351    gfGrabbed = TRUE;
     352    UpdateTitlebar(TITLEBAR_NORMAL);
     353}
     354
     355/**
     356 * End mouse grabbing.
     357 */
     358static void InputGrabEnd(void)
     359{
     360    SDL_SetRelativeMouseMode(SDL_FALSE);
     361    if (!gfGuestNeedsHostCursor && gfRelativeMouseGuest)
     362        SDL_ShowCursor(SDL_ENABLE);
     363#ifdef RT_OS_DARWIN
     364    DisableGlobalHotKeys(false);
     365#endif
     366    gfGrabbed = FALSE;
     367    UpdateTitlebar(TITLEBAR_NORMAL);
     368}
     369
     370
     371
     372/**
     373 * Handles a host key down event
     374 */
     375static int HandleHostKey(const SDL_KeyboardEvent *pEv)
     376{
     377    /*
     378     * Revalidate the host key modifier
     379     */
     380    if ((SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED)) != gHostKeyMod)
     381        return VERR_NOT_SUPPORTED;
     382
     383    /*
     384     * What was pressed?
     385     */
     386    switch (pEv->keysym.sym)
     387    {
     388#if 0
     389        /* Control-Alt-Delete */
     390        case SDLK_DELETE:
     391        {
     392            //g_pKeyboard->PutCAD();
     393            break;
     394        }
     395
     396        /*
     397         * Fullscreen / Windowed toggle.
     398         */
     399        case SDLK_f:
     400        {
     401            if (   strchr(gHostKeyDisabledCombinations, 'f')
     402                || !gfAllowFullscreenToggle)
     403                return VERR_NOT_SUPPORTED;
     404
     405            /*
     406             * We have to pause/resume the machine during this
     407             * process because there might be a short moment
     408             * without a valid framebuffer
     409             */
     410            /** @todo */
     411            //SetFullscreen(!g_pFramebuffer->getFullscreen());
     412
     413            /*
     414             * We have switched from/to fullscreen, so request a full
     415             * screen repaint, just to be sure.
     416             */
     417            gpDisplay->InvalidateAndUpdate();
     418            break;
     419        }
     420
     421        /*
     422         * Pause / Resume toggle.
     423         */
     424        case SDLK_p:
     425        {
     426            if (strchr(gHostKeyDisabledCombinations, 'p'))
     427                return VERR_NOT_SUPPORTED;
     428
     429            /** @todo */
     430            UpdateTitlebar(TITLEBAR_NORMAL);
     431            break;
     432        }
     433
     434        /*
     435         * Reset the VM
     436         */
     437        case SDLK_r:
     438        {
     439            if (strchr(gHostKeyDisabledCombinations, 'r'))
     440                return VERR_NOT_SUPPORTED;
     441
     442            ResetVM();
     443            break;
     444        }
     445
     446        /*
     447         * Terminate the VM
     448         */
     449        case SDLK_q:
     450        {
     451            if (strchr(gHostKeyDisabledCombinations, 'q'))
     452                return VERR_NOT_SUPPORTED;
     453
     454            return VINF_EM_TERMINATE;
     455        }
     456
     457        /*
     458         * Save the machine's state and exit
     459         */
     460        case SDLK_s:
     461        {
     462            if (strchr(gHostKeyDisabledCombinations, 's'))
     463                return VERR_NOT_SUPPORTED;
     464
     465            SaveState();
     466            return VINF_EM_TERMINATE;
     467        }
     468
     469        case SDLK_h:
     470        {
     471            if (strchr(gHostKeyDisabledCombinations, 'h'))
     472                return VERR_NOT_SUPPORTED;
     473
     474            if (gpConsole)
     475                gpConsole->PowerButton();
     476            break;
     477        }
     478#endif
     479
     480        case SDLK_F1: case SDLK_F2: case SDLK_F3:
     481        case SDLK_F4: case SDLK_F5: case SDLK_F6:
     482        case SDLK_F7: case SDLK_F8: case SDLK_F9:
     483        case SDLK_F10: case SDLK_F11: case SDLK_F12:
     484        {
     485            /* send Ctrl-Alt-Fx to guest */
     486            g_pKeyboard->PutUsageCode(0xE0 /*left ctrl*/, 0x07 /*usage code page id*/, FALSE);
     487            g_pKeyboard->PutUsageCode(0xE2 /*left alt*/, 0x07 /*usage code page id*/, FALSE);
     488            g_pKeyboard->PutUsageCode(pEv->keysym.sym,  0x07 /*usage code page id*/, FALSE);
     489            g_pKeyboard->PutUsageCode(pEv->keysym.sym,  0x07 /*usage code page id*/, TRUE);
     490            g_pKeyboard->PutUsageCode(0xE0 /*left ctrl*/, 0x07 /*usage code page id*/, TRUE);
     491            g_pKeyboard->PutUsageCode(0xE2 /*left alt*/, 0x07 /*usage code page id*/, TRUE);
     492            return VINF_SUCCESS;
     493        }
     494
     495        /*
     496         * Not a host key combination.
     497         * Indicate this by returning false.
     498         */
     499        default:
     500            return VERR_NOT_SUPPORTED;
     501    }
     502
     503    return VINF_SUCCESS;
     504}
     505
     506
     507/**
     508 * Releases any modifier keys that are currently in pressed state.
     509 */
     510static void ResetKeys(void)
     511{
     512    int i;
     513
     514    if (!g_pKeyboard)
     515        return;
     516
     517    for(i = 0; i < 256; i++)
     518    {
     519        if (gaModifiersState[i])
     520        {
     521            if (i & 0x80)
     522                g_pKeyboard->PutScancode(0xe0);
     523            g_pKeyboard->PutScancode(i | 0x80);
     524            gaModifiersState[i] = 0;
     525        }
     526    }
     527}
     528
     529/**
     530 * Keyboard event handler.
     531 *
     532 * @param ev SDL keyboard event.
     533 */
     534static void ProcessKey(SDL_KeyboardEvent *ev)
     535{
     536    /* According to SDL2/SDL_scancodes.h ev->keysym.sym stores scancodes which are
     537    * based on USB usage page standard. This is what we can directly pass to
     538    * IKeyboard::putUsageCode. */
     539    g_pKeyboard->PutUsageCode(SDL_GetScancodeFromKey(ev->keysym.sym), 0x07 /*usage code page id*/, ev->type == SDL_KEYUP ? TRUE : FALSE);
     540}
     541
    114542
    115543/**
     
    270698        return vrc;
    271699
     700    vrc = pCallbacks->pfnRegister(pCallbacks, &Keyboard::DrvReg);
     701    if (RT_FAILURE(vrc))
     702        return vrc;
     703
    272704    return VINF_SUCCESS;
    273705}
     
    317749     * PDM.
    318750     */
    319 #ifdef DEBUG_aeichner
    320     PCFGMNODE pPdm = NULL;
    321     PCFGMNODE pPdmDevices = NULL;
    322     PCFGMNODE pPdmDevicesNvme = NULL;
    323     rc = pVMM->pfnCFGMR3InsertNode(pRoot, "PDM", &pPdm);                                        UPDATE_RC();
    324     rc = pVMM->pfnCFGMR3InsertNode(pPdm, "Devices", &pPdmDevices);                              UPDATE_RC();
    325     rc = pVMM->pfnCFGMR3InsertNode(pPdmDevices, "VBoxNvme", &pPdmDevicesNvme);                  UPDATE_RC();
    326     rc = pVMM->pfnCFGMR3InsertString(pPdmDevicesNvme, "Path", "/Users/vbox/vbox-intern/out/darwin.arm64/debug/dist/VirtualBox.app/Contents/MacOS/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack/darwin.arm64/VBoxNvmeR3.dylib"); UPDATE_RC();
    327 #endif
    328 
    329751    rc = pVMM->pfnPDMR3DrvStaticRegistration(pVM, VBoxDriversRegister);                         UPDATE_RC();
    330752
     
    413835    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "MmioPioBase",    0x3eff0000);                  UPDATE_RC();
    414836    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "MmioPioSize",    0x0000ffff);                  UPDATE_RC();
     837    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "IntPinA",        3);                           UPDATE_RC();
     838    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "IntPinB",        4);                           UPDATE_RC();
     839    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "IntPinC",        5);                           UPDATE_RC();
     840    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "IntPinD",        6);                           UPDATE_RC();
    415841
    416842    rc = pVMM->pfnCFGMR3InsertNode(pDevices, "usb-xhci",      &pDev);                        UPDATE_RC();
    417843    rc = pVMM->pfnCFGMR3InsertNode(pDev,     "0",            &pInst);                        UPDATE_RC();
    418     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "Trusted",           1);                        UPDATE_RC();
    419     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "PCIBusNo",          0);                        UPDATE_RC();
    420     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "PCIDeviceNo",       2);                        UPDATE_RC();
    421     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "PCIFunctionNo",     0);                        UPDATE_RC();
     844    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "Trusted",           1);                        UPDATE_RC();
     845    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "PCIBusNo",          0);                        UPDATE_RC();
     846    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "PCIDeviceNo",       2);                        UPDATE_RC();
     847    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "PCIFunctionNo",     0);                        UPDATE_RC();
    422848    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "Config",        &pCfg);                        UPDATE_RC();
    423849    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "LUN#0",       &pLunL0);                        UPDATE_RC();
     
    426852    rc = pVMM->pfnCFGMR3InsertString(pLunL0, "Driver","VUSBRootHub");                        UPDATE_RC();
    427853
    428 #ifdef DEBUG_aeichner
    429     rc = pVMM->pfnCFGMR3InsertNode(pDevices, "virtio-net",    &pDev);                        UPDATE_RC();
     854    rc = pVMM->pfnCFGMR3InsertNode(pDevices, "e1000",         &pDev);                        UPDATE_RC();
    430855    rc = pVMM->pfnCFGMR3InsertNode(pDev,     "0",            &pInst);                        UPDATE_RC();
    431     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "Trusted",           1);                        UPDATE_RC();
    432     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "PCIBusNo",          0);                        UPDATE_RC();
    433     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "PCIDeviceNo",       1);                        UPDATE_RC();
    434     rc = pVMM->pfnCFGMR3InsertInteger(pDev, "PCIFunctionNo",     0);                        UPDATE_RC();
     856    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "Trusted",           1);                        UPDATE_RC();
     857    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "PCIBusNo",          0);                        UPDATE_RC();
     858    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "PCIDeviceNo",       1);                        UPDATE_RC();
     859    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "PCIFunctionNo",     0);                        UPDATE_RC();
    435860    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "Config",        &pCfg);                        UPDATE_RC();
    436861    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "CableConnected",    1);                        UPDATE_RC();
    437862    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "LineSpeed",         0);                        UPDATE_RC();
     863    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "AdapterType",       0);                        UPDATE_RC();
    438864
    439865    const char *pszMac = "080027ede92c";
     
    465891    rc = pVMM->pfnCFGMR3InsertInteger(pLunL1Cfg,  "UseHostResolver",    0);                 UPDATE_RC();
    466892
    467     rc = pVMM->pfnCFGMR3InsertNode(pDevices, "nvme",          &pDev);                        UPDATE_RC();
     893    PCFGMNODE pUsb = NULL;
     894    rc = pVMM->pfnCFGMR3InsertNode(pRoot,    "USB",           &pUsb);                        UPDATE_RC();
     895    rc = pVMM->pfnCFGMR3InsertNode(pUsb,     "Msd",           &pDev);                        UPDATE_RC();
    468896    rc = pVMM->pfnCFGMR3InsertNode(pDev,     "0",            &pInst);                        UPDATE_RC();
    469     rc = pVMM->pfnCFGMR3InsertInteger(pDev,  "Trusted",           1);                        UPDATE_RC();
    470     rc = pVMM->pfnCFGMR3InsertInteger(pDev,  "PCIBusNo",          0);                        UPDATE_RC();
    471     rc = pVMM->pfnCFGMR3InsertInteger(pDev,  "PCIDeviceNo",       3);                        UPDATE_RC();
    472     rc = pVMM->pfnCFGMR3InsertInteger(pDev,  "PCIFunctionNo",     0);                        UPDATE_RC();
     897    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "Trusted",           1);                        UPDATE_RC();
    473898    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "Config",        &pCfg);                        UPDATE_RC();
    474     rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "CtrlMemBufSize",    0);                        UPDATE_RC();
    475899    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "LUN#0",       &pLunL0);                        UPDATE_RC();
    476     rc = pVMM->pfnCFGMR3InsertString(pLunL0, "Driver","RamDisk");                            UPDATE_RC();
    477     rc = pVMM->pfnCFGMR3InsertNode(pLunL0,    "Config",  &pLunL1Cfg);                        UPDATE_RC();
    478     rc = pVMM->pfnCFGMR3InsertInteger(pLunL1Cfg,  "Size", 1073741824);                       UPDATE_RC();
    479 #endif
     900    rc = pVMM->pfnCFGMR3InsertString(pLunL0, "Driver",       "SCSI");                        UPDATE_RC();
     901    rc = pVMM->pfnCFGMR3InsertNode(pLunL0,   "AttachedDriver",  &pLunL1);                    UPDATE_RC();
     902    rc = pVMM->pfnCFGMR3InsertString(pLunL1, "Driver",          "VD");                       UPDATE_RC();
     903    rc = pVMM->pfnCFGMR3InsertNode(pLunL1,    "Config",         &pLunL1Cfg);                 UPDATE_RC();
     904    rc = pVMM->pfnCFGMR3InsertString(pLunL1Cfg,  "Path", "/Users/vbox/rootfs.img");          UPDATE_RC();
     905    rc = pVMM->pfnCFGMR3InsertString(pLunL1Cfg,  "Type", "HardDisk");                        UPDATE_RC();
     906    rc = pVMM->pfnCFGMR3InsertString(pLunL1Cfg,  "Format", "Raw");                           UPDATE_RC();
     907
     908    rc = pVMM->pfnCFGMR3InsertNode(pUsb,     "HidKeyboard",   &pDev);                        UPDATE_RC();
     909    rc = pVMM->pfnCFGMR3InsertNode(pDev,     "0",            &pInst);                        UPDATE_RC();
     910    rc = pVMM->pfnCFGMR3InsertInteger(pInst, "Trusted",           1);                        UPDATE_RC();
     911    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "Config",        &pCfg);                        UPDATE_RC();
     912    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "LUN#0",       &pLunL0);                        UPDATE_RC();
     913    rc = pVMM->pfnCFGMR3InsertString(pLunL0, "Driver",       "KeyboardQueue");               UPDATE_RC();
     914    rc = pVMM->pfnCFGMR3InsertNode(pLunL0,   "AttachedDriver",  &pLunL1);                    UPDATE_RC();
     915    rc = pVMM->pfnCFGMR3InsertString(pLunL1, "Driver",          "MainKeyboard");             UPDATE_RC();
    480916
    481917#undef UPDATE_RC
     
    5911027        return g_pDisplay;
    5921028
     1029    if (!RTUuidCompareStr(pUuid, KEYBOARD_OID))
     1030        return g_pKeyboard;
     1031
    5931032    return NULL;
    5941033}
     
    8331272        return RTEXITCODE_FAILURE;
    8341273
     1274    g_pKeyboard = new Keyboard();
    8351275    g_pDisplay = new Display();
    8361276    g_pFramebuffer = new Framebuffer(g_pDisplay, 0, false /*fFullscreen*/, false /*fResizable*/, true /*fShowSDLConfig*/, false,
     
    8681308    LogFlow(("VBoxSDL: Entering big event loop\n"));
    8691309    SDL_Event event;
     1310    /** The host key down event which we have been hiding from the guest.
     1311     * Used when going from HKEYSTATE_DOWN to HKEYSTATE_NOT_IT. */
     1312    SDL_Event EvHKeyDown1;
     1313    SDL_Event EvHKeyDown2;
     1314
    8701315    uint32_t uResizeWidth  = ~(uint32_t)0;
    8711316    uint32_t uResizeHeight = ~(uint32_t)0;
     
    9191364
    9201365            /*
     1366             * Keyboard events.
     1367             */
     1368            case SDL_KEYDOWN:
     1369            case SDL_KEYUP:
     1370            {
     1371                SDL_Keycode ksym = event.key.keysym.sym;
     1372                switch (enmHKeyState)
     1373                {
     1374                    case HKEYSTATE_NORMAL:
     1375                    {
     1376                        if (   event.type == SDL_KEYDOWN
     1377                            && ksym != SDLK_UNKNOWN
     1378                            && (ksym == gHostKeySym1 || ksym == gHostKeySym2))
     1379                        {
     1380                            EvHKeyDown1  = event;
     1381                            enmHKeyState = ksym == gHostKeySym1 ? HKEYSTATE_DOWN_1ST
     1382                                                                : HKEYSTATE_DOWN_2ND;
     1383                            break;
     1384                        }
     1385                        ProcessKey(&event.key);
     1386                        break;
     1387                    }
     1388
     1389                    case HKEYSTATE_DOWN_1ST:
     1390                    case HKEYSTATE_DOWN_2ND:
     1391                    {
     1392                        if (gHostKeySym2 != SDLK_UNKNOWN)
     1393                        {
     1394                            if (   event.type == SDL_KEYDOWN
     1395                                && ksym != SDLK_UNKNOWN
     1396                                && (   (enmHKeyState == HKEYSTATE_DOWN_1ST && ksym == gHostKeySym2)
     1397                                    || (enmHKeyState == HKEYSTATE_DOWN_2ND && ksym == gHostKeySym1)))
     1398                            {
     1399                                EvHKeyDown2  = event;
     1400                                enmHKeyState = HKEYSTATE_DOWN;
     1401                                break;
     1402                            }
     1403                            enmHKeyState = event.type == SDL_KEYUP ? HKEYSTATE_NORMAL
     1404                                                                 : HKEYSTATE_NOT_IT;
     1405                            ProcessKey(&EvHKeyDown1.key);
     1406                            /* ugly hack: Some guests (e.g. mstsc.exe on Windows XP)
     1407                             * expect a small delay between two key events. 5ms work
     1408                             * reliable here so use 10ms to be on the safe side. A
     1409                             * better but more complicated fix would be to introduce
     1410                             * a new state and don't wait here. */
     1411                            RTThreadSleep(10);
     1412                            ProcessKey(&event.key);
     1413                            break;
     1414                        }
     1415                    }
     1416                    RT_FALL_THRU();
     1417
     1418                    case HKEYSTATE_DOWN:
     1419                    {
     1420                        if (event.type == SDL_KEYDOWN)
     1421                        {
     1422                            /* potential host key combination, try execute it */
     1423                            int irc = HandleHostKey(&event.key);
     1424                            if (irc == VINF_SUCCESS)
     1425                            {
     1426                                enmHKeyState = HKEYSTATE_USED;
     1427                                break;
     1428                            }
     1429                            if (RT_SUCCESS(irc))
     1430                                goto leave;
     1431                        }
     1432                        else /* SDL_KEYUP */
     1433                        {
     1434                            if (   ksym != SDLK_UNKNOWN
     1435                                && (ksym == gHostKeySym1 || ksym == gHostKeySym2))
     1436                            {
     1437                                /* toggle grabbing state */
     1438                                if (!gfGrabbed)
     1439                                    InputGrabStart();
     1440                                else
     1441                                    InputGrabEnd();
     1442
     1443                                /* SDL doesn't always reset the keystates, correct it */
     1444                                ResetKeys();
     1445                                enmHKeyState = HKEYSTATE_NORMAL;
     1446                                break;
     1447                            }
     1448                        }
     1449
     1450                        /* not host key */
     1451                        enmHKeyState = HKEYSTATE_NOT_IT;
     1452                        ProcessKey(&EvHKeyDown1.key);
     1453                        /* see the comment for the 2-key case above */
     1454                        RTThreadSleep(10);
     1455                        if (gHostKeySym2 != SDLK_UNKNOWN)
     1456                        {
     1457                            ProcessKey(&EvHKeyDown2.key);
     1458                            /* see the comment for the 2-key case above */
     1459                            RTThreadSleep(10);
     1460                        }
     1461                        ProcessKey(&event.key);
     1462                        break;
     1463                    }
     1464
     1465                    case HKEYSTATE_USED:
     1466                    {
     1467                        if ((SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED)) == 0)
     1468                            enmHKeyState = HKEYSTATE_NORMAL;
     1469                        if (event.type == SDL_KEYDOWN)
     1470                        {
     1471                            int irc = HandleHostKey(&event.key);
     1472                            if (RT_SUCCESS(irc) && irc != VINF_SUCCESS)
     1473                                goto leave;
     1474                        }
     1475                        break;
     1476                    }
     1477
     1478                    default:
     1479                        AssertMsgFailed(("enmHKeyState=%d\n", enmHKeyState));
     1480                        RT_FALL_THRU();
     1481                    case HKEYSTATE_NOT_IT:
     1482                    {
     1483                        if ((SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED)) == 0)
     1484                            enmHKeyState = HKEYSTATE_NORMAL;
     1485                        ProcessKey(&event.key);
     1486                        break;
     1487                    }
     1488                } /* state switch */
     1489                break;
     1490            }
     1491
     1492            /*
    9211493             * The window was closed.
    9221494             */
     
    9981570    }
    9991571
     1572leave:
    10001573    LogRel(("VBoxBFE: exiting\n"));
    10011574    return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
Note: See TracChangeset for help on using the changeset viewer.

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