VirtualBox

Changeset 35686 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Jan 24, 2011 4:05:20 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
69612
Message:

FE/Qt4: special signal handler for reseting pressed keys

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r35634 r35686  
    130130        $(if $(VBOX_WITH_VDE),VBOX_WITH_VDE) \
    131131        $(if $(VBOX_WITH_EHCI),VBOX_WITH_EHCI) \
    132         $(if $(VBOX_GUI_WITH_PIDFILE),VBOX_GUI_WITH_PIDFILE,)
     132        $(if $(VBOX_GUI_WITH_PIDFILE),VBOX_GUI_WITH_PIDFILE) \
     133        $(if $(VBOX_GUI_WITH_KEYS_RESET_HANDLER),VBOX_GUI_WITH_KEYS_RESET_HANDLER)
    133134ifdef VBOX_WITH_DEBUGGER_GUI
    134135 VirtualBox_DEFS        += VBOX_WITH_DEBUGGER_GUI
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp

    r35351 r35686  
    268268        emit keyboardStateChanged(keyboardState());
    269269    }
     270}
     271
     272void UIKeyboardHandler::releaseAllPressedKeys(bool aReleaseHostKey /* = true */)
     273{
     274    CKeyboard keyboard = session().GetConsole().GetKeyboard();
     275    bool fSentRESEND = false;
     276
     277    /* Send a dummy scan code (RESEND) to prevent the guest OS from recognizing
     278     * a single key click (for ex., Alt) and performing an unwanted action
     279     * (for ex., activating the menu) when we release all pressed keys below.
     280     * Note, that it's just a guess that sending RESEND will give the desired
     281     * effect :), but at least it works with NT and W2k guests. */
     282    for (uint i = 0; i < SIZEOF_ARRAY (m_pressedKeys); i++)
     283    {
     284        if (m_pressedKeys[i] & IsKeyPressed)
     285        {
     286            if (!fSentRESEND)
     287            {
     288                keyboard.PutScancode (0xFE);
     289                fSentRESEND = true;
     290            }
     291            keyboard.PutScancode(i | 0x80);
     292        }
     293        else if (m_pressedKeys[i] & IsExtKeyPressed)
     294        {
     295            if (!fSentRESEND)
     296            {
     297                keyboard.PutScancode(0xFE);
     298                fSentRESEND = true;
     299            }
     300            QVector <LONG> codes(2);
     301            codes[0] = 0xE0;
     302            codes[1] = i | 0x80;
     303            keyboard.PutScancodes(codes);
     304        }
     305        m_pressedKeys[i] = 0;
     306    }
     307
     308    if (aReleaseHostKey)
     309        m_bIsHostkeyPressed = false;
     310
     311#ifdef Q_WS_MAC
     312    /* Clear most of the modifiers: */
     313    m_darwinKeyModifiers &=
     314        alphaLock | kEventKeyModifierNumLockMask |
     315        (aReleaseHostKey ? 0 : ::DarwinKeyCodeToDarwinModifierMask(m_globalSettings.hostKey()));
     316#endif
     317
     318    emit keyboardStateChanged(keyboardState());
    270319}
    271320
     
    14321481}
    14331482
    1434 void UIKeyboardHandler::releaseAllPressedKeys(bool aReleaseHostKey /* = true */)
    1435 {
    1436     CKeyboard keyboard = session().GetConsole().GetKeyboard();
    1437     bool fSentRESEND = false;
    1438 
    1439     /* Send a dummy scan code (RESEND) to prevent the guest OS from recognizing
    1440      * a single key click (for ex., Alt) and performing an unwanted action
    1441      * (for ex., activating the menu) when we release all pressed keys below.
    1442      * Note, that it's just a guess that sending RESEND will give the desired
    1443      * effect :), but at least it works with NT and W2k guests. */
    1444     for (uint i = 0; i < SIZEOF_ARRAY (m_pressedKeys); i++)
    1445     {
    1446         if (m_pressedKeys[i] & IsKeyPressed)
    1447         {
    1448             if (!fSentRESEND)
    1449             {
    1450                 keyboard.PutScancode (0xFE);
    1451                 fSentRESEND = true;
    1452             }
    1453             keyboard.PutScancode(i | 0x80);
    1454         }
    1455         else if (m_pressedKeys[i] & IsExtKeyPressed)
    1456         {
    1457             if (!fSentRESEND)
    1458             {
    1459                 keyboard.PutScancode(0xFE);
    1460                 fSentRESEND = true;
    1461             }
    1462             QVector <LONG> codes(2);
    1463             codes[0] = 0xE0;
    1464             codes[1] = i | 0x80;
    1465             keyboard.PutScancodes(codes);
    1466         }
    1467         m_pressedKeys[i] = 0;
    1468     }
    1469 
    1470     if (aReleaseHostKey)
    1471         m_bIsHostkeyPressed = false;
    1472 
    1473 #ifdef Q_WS_MAC
    1474     /* Clear most of the modifiers: */
    1475     m_darwinKeyModifiers &=
    1476         alphaLock | kEventKeyModifierNumLockMask |
    1477         (aReleaseHostKey ? 0 : ::DarwinKeyCodeToDarwinModifierMask(m_globalSettings.hostKey()));
    1478 #endif
    1479 
    1480     emit keyboardStateChanged(keyboardState());
    1481 }
    1482 
    14831483void UIKeyboardHandler::sendChangedKeyStates()
    14841484{
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h

    r30645 r35686  
    6565    void captureKeyboard(ulong uScreenId);
    6666    void releaseKeyboard();
     67    void releaseAllPressedKeys(bool aReleaseHostKey = true);
    6768
    6869    /* Current keyboard state: */
     
    129130    void fixModifierState(LONG *piCodes, uint *puCount);
    130131    void saveKeyStates();
    131     void releaseAllPressedKeys(bool aReleaseHostKey = true);
    132132    void sendChangedKeyStates();
    133133
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r35564 r35686  
    4646# endif
    4747#endif
     48
     49#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
     50# include "UIKeyboardHandler.h"
     51# include <signal.h>
     52#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    4853
    4954UISession::UISession(UIMachine *pMachine, CSession &sessionReference)
     
    134139    /* Load uisession settings: */
    135140    loadSessionSettings();
     141
     142#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
     143    struct sigaction sa;
     144    sa.sa_sigaction = &signalHandlerSIGUSR1;
     145    sigemptyset(&sa.sa_mask);
     146    sa.sa_flags = SA_RESTART | SA_SIGINFO;
     147    sigaction(SIGUSR1, &sa, NULL);
     148#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    136149}
    137150
     
    10361049}
    10371050#endif
     1051
     1052#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
     1053/**
     1054 * Custom signal handler. When switching VTs, we might not get release events
     1055 * for Ctrl-Alt and in case a savestate is performed on the new VT, the VM will
     1056 * be saved with modifier keys stuck. This is annoying enough for introducing
     1057 * this hack.
     1058 */
     1059/* static */
     1060void UISession::signalHandlerSIGUSR1(int sig, siginfo_t * /* pInfo */, void * /*pSecret */)
     1061{
     1062    /* only SIGUSR1 is interesting */
     1063    if (sig == SIGUSR1)
     1064        if (UIMachine *pMachine = vboxGlobal().virtualMachine())
     1065            pMachine->uisession()->machineLogic()->keyboardHandler()->releaseAllPressedKeys();
     1066}
     1067#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
     1068
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h

    r33386 r35686  
    3131class QMenu;
    3232class QMenuBar;
     33#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
     34struct siginfo;
     35typedef struct siginfo siginfo_t;
     36#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    3337
    3438/* Local forwards */
     
    205209    void preparePowerUp();
    206210
     211#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
     212    static void signalHandlerSIGUSR1(int sig, siginfo_t *pInfo, void *pSecret);
     213#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
     214
    207215    /* Private variables: */
    208216    UIMachine *m_pMachine;
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