VirtualBox

Changeset 59403 in vbox


Ignore:
Timestamp:
Jan 19, 2016 10:04:02 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
105109
Message:

FE/Qt: Qt5 migration (part 65): Implementing keyboard handling for Qt5 under Windows.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/runtime
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp

    r59384 r59403  
    950950# elif defined(Q_WS_WIN)
    951951
    952 #  warning "implement me!"
     952    /* Ignore this event if m_fSkipKeyboardEvents is set by winSkipKeyboardEvents(). */
     953    if (m_fSkipKeyboardEvents)
     954        return false;
     955
     956    /* Cast to MSG event: */
     957    MSG *pMsg = static_cast<MSG*>(pMessage);
     958
     959    /* Depending on message type: */
     960    switch (pMsg->message)
     961    {
     962        /* Watch for key-events: */
     963        case WM_KEYDOWN:
     964        case WM_KEYUP:
     965        case WM_SYSKEYDOWN:
     966        case WM_SYSKEYUP:
     967        {
     968            /* Check for our own special flag to ignore this event.
     969             * That flag could only be set later in this function
     970             * so having it here means this event came here
     971             * for the second time already. */
     972            if (pMsg->lParam & (0x1 << 25))
     973            {
     974                /* Remove that flag as well: */
     975                pMsg->lParam &= ~(0x1 << 25);
     976                fResult = false;
     977                break;
     978            }
     979
     980            /* Scan codes 0x80 and 0x00 should be filtered out: */
     981            unsigned uScan = (pMsg->lParam >> 16) & 0x7F;
     982            if (!uScan)
     983            {
     984                fResult = true;
     985                break;
     986            }
     987
     988            /* Get the virtual key: */
     989            int iVKey = pMsg->wParam;
     990
     991            /* Calculate flags: */
     992            int iFlags = 0;
     993            if (pMsg->lParam & 0x1000000)
     994                iFlags |= KeyExtended;
     995            if (!(pMsg->lParam & 0x80000000))
     996                iFlags |= KeyPressed;
     997
     998            /* Make sure AltGr monitor exists: */
     999            AssertPtrReturn(m_pAltGrMonitor, false);
     1000            {
     1001                /* Filter event out if we are sure that this is a fake left control event: */
     1002                if (m_pAltGrMonitor->isCurrentEventDefinitelyFake(uScan, iFlags & KeyPressed, iFlags & KeyExtended))
     1003                {
     1004                    fResult = true;
     1005                    break;
     1006                }
     1007                /* Update AltGR monitor state from key-event: */
     1008                m_pAltGrMonitor->updateStateFromKeyEvent(uScan, iFlags & KeyPressed, iFlags & KeyExtended);
     1009                /* And release left Ctrl key early (if required): */
     1010                if (m_pAltGrMonitor->isLeftControlReleaseNeeded())
     1011                    keyboard().PutScancode(0x1D | 0x80);
     1012            }
     1013
     1014            /* Check for special Korean keys. Based on the keyboard layout selected
     1015             * on the host, the scan code in lParam might be 0x71/0x72 or 0xF1/0xF2.
     1016             * In either case, we must deliver 0xF1/0xF2 scan code to the guest when
     1017             * the key is pressed and nothing when it's released. */
     1018            if (uScan == 0x71 || uScan == 0x72)
     1019            {
     1020                uScan |= 0x80;
     1021                iFlags = KeyPressed;   /* Because a release would be ignored. */
     1022                iVKey = VK_PROCESSKEY; /* In case it was 0xFF. */
     1023            }
     1024
     1025            /* When one of the SHIFT keys is held and one of the cursor movement
     1026             * keys is pressed, Windows duplicates SHIFT press/release messages,
     1027             * but with the virtual keycode set to 0xFF. These virtual keys are also
     1028             * sent in some other situations (Pause, PrtScn, etc.). Filter out such messages. */
     1029            if (iVKey == 0xFF)
     1030            {
     1031                fResult = true;
     1032                break;
     1033            }
     1034
     1035            /* Handle special virtual keys: */
     1036            switch (iVKey)
     1037            {
     1038                case VK_SHIFT:
     1039                case VK_CONTROL:
     1040                case VK_MENU:
     1041                {
     1042                    /* Overcome Win32 modifier key generalization: */
     1043                    int iKeyscan = uScan;
     1044                    if (iFlags & KeyExtended)
     1045                        iKeyscan |= 0xE000;
     1046                    switch (iKeyscan)
     1047                    {
     1048                        case 0x002A: iVKey = VK_LSHIFT;   break;
     1049                        case 0x0036: iVKey = VK_RSHIFT;   break;
     1050                        case 0x001D: iVKey = VK_LCONTROL; break;
     1051                        case 0xE01D: iVKey = VK_RCONTROL; break;
     1052                        case 0x0038: iVKey = VK_LMENU;    break;
     1053                        case 0xE038: iVKey = VK_RMENU;    break;
     1054                    }
     1055                    break;
     1056                }
     1057                case VK_NUMLOCK:
     1058                    /* Win32 sets the extended bit for the NumLock key. Reset it: */
     1059                    iFlags &= ~KeyExtended;
     1060                    break;
     1061                case VK_SNAPSHOT:
     1062                    iFlags |= KeyPrint;
     1063                    break;
     1064                case VK_PAUSE:
     1065                    iFlags |= KeyPause;
     1066                    break;
     1067            }
     1068
     1069            /* Finally, handle parsed key-event: */
     1070            fResult = keyEvent(iVKey, uScan, iFlags, uScreenId);
     1071
     1072            /* Always let Windows see key releases to prevent stuck keys.
     1073             * Hopefully this won't cause any other issues. */
     1074            if (pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP)
     1075            {
     1076                fResult = false;
     1077                break;
     1078            }
     1079
     1080            /* Above keyEvent() returned that it didn't processed the event, but since the
     1081             * keyboard is captured, we don't want to pass it to Windows. We just want
     1082             * to let Qt process the message (to handle non-alphanumeric <HOST>+key
     1083             * shortcuts for example). So send it directly to the window with the
     1084             * special flag in the reserved area of lParam (to avoid recursion). */
     1085            if (!fResult && m_fIsKeyboardCaptured)
     1086            {
     1087                ::SendMessage(pMsg->hwnd, pMsg->message,
     1088                              pMsg->wParam, pMsg->lParam | (0x1 << 25));
     1089                fResult = true;
     1090                break;
     1091            }
     1092
     1093            /* These special keys have to be handled by Windows as well to update the
     1094             * internal modifier state and to enable/disable the keyboard LED: */
     1095            if (iVKey == VK_NUMLOCK || iVKey == VK_CAPITAL || iVKey == VK_LSHIFT || iVKey == VK_RSHIFT)
     1096            {
     1097                fResult = false;
     1098                break;
     1099            }
     1100
     1101            break;
     1102        }
     1103        default:
     1104            break;
     1105    }
    9531106
    9541107# elif defined(Q_WS_X11)
     
    14971650    long dummyResult;
    14981651    return m_views[m_iKeyboardHookViewIndex]->winEvent(&message, &dummyResult);
    1499 #endif /* QT_VERSION < 0x050000 */
     1652#else /* QT_VERSION >= 0x050000 */
     1653    return m_views[m_iKeyboardHookViewIndex]->nativeEvent(&message);
     1654#endif /* QT_VERSION >= 0x050000 */
    15001655}
    15011656
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r59384 r59403  
    7272
    7373/* Qt includes: */
    74 #ifdef Q_WS_X11
     74#if defined(Q_WS_WIN) || defined(Q_WS_X11)
    7575# if QT_VERSION >= 0x050000
    7676#  include <QAbstractNativeEventFilter>
    7777# endif /* QT_VERSION >= 0x050000 */
    78 #endif /* Q_WS_X11 */
     78#endif /* Q_WS_WIN || Q_WS_X11 */
    7979
    8080/* GUI includes: */
     
    130130
    131131
    132 #ifdef Q_WS_X11
     132#if defined(Q_WS_WIN) || defined(Q_WS_X11)
    133133# if QT_VERSION >= 0x050000
    134134/** QAbstractNativeEventFilter extension
     
    147147    {
    148148        /* Redirect event to parent: */
    149         return m_pParent->nativeEvent(eventType, pMessage, pResult);
     149        Q_UNUSED(eventType); Q_UNUSED(pResult);
     150        return m_pParent->nativeEvent(pMessage);
    150151    }
    151152
     
    156157};
    157158# endif /* QT_VERSION >= 0x050000 */
    158 #endif /* Q_WS_X11 */
     159#endif /* Q_WS_WIN || Q_WS_X11 */
    159160
    160161
     
    661662    , m_fIsDraggingFromGuest(false)
    662663#endif
    663 #ifdef Q_WS_X11
     664#if defined(Q_WS_WIN) || defined(Q_WS_X11)
    664665# if QT_VERSION >= 0x050000
    665666    , m_pPrivateEventFilter(0)
    666667# endif /* QT_VERSION >= 0x050000 */
    667 #endif /* Q_WS_X11 */
     668#endif /* Q_WS_WIN || Q_WS_X11 */
    668669{
    669670}
     
    843844    machineWindow()->installEventFilter(this);
    844845
    845 #ifdef Q_WS_X11
     846#if defined(Q_WS_WIN) || defined(Q_WS_X11)
    846847# if QT_VERSION >= 0x050000
    847848    /* Prepare private event-filter: */
     
    849850    qApp->installNativeEventFilter(m_pPrivateEventFilter);
    850851# endif /* QT_VERSION >= 0x050000 */
    851 #endif /* Q_WS_X11 */
     852#endif /* Q_WS_WIN || Q_WS_X11 */
    852853}
    853854
     
    879880void UIMachineView::cleanupFilters()
    880881{
    881 #ifdef Q_WS_X11
     882#if defined(Q_WS_WIN) || defined(Q_WS_X11)
    882883# if QT_VERSION >= 0x050000
    883884    /* Cleanup private event-filter: */
     
    886887    m_pPrivateEventFilter = 0;
    887888# endif /* QT_VERSION >= 0x050000 */
    888 #endif /* Q_WS_X11 */
     889#endif /* Q_WS_WIN || Q_WS_X11 */
    889890}
    890891
     
    18841885#else /* QT_VERSION >= 0x050000 */
    18851886
    1886 bool UIMachineView::nativeEvent(const QByteArray &eventType, void *pMessage, long *pResult)
     1887bool UIMachineView::nativeEvent(void *pMessage)
    18871888{
    18881889# if defined(Q_WS_MAC)
     
    18921893# elif defined(Q_WS_WIN)
    18931894
    1894 #  warning "implement me!"
     1895    /* Cast to generic MSG event: */
     1896    MSG *pEvent = static_cast<MSG*>(pMessage);
     1897
     1898    /* Check if some MSG event should be filtered out.
     1899     * Returning @c true means filtering-out,
     1900     * Returning @c false means passing event to Qt. */
     1901    switch (pEvent->message)
     1902    {
     1903        /* Watch for key-events: */
     1904        case WM_KEYDOWN:
     1905        case WM_SYSKEYDOWN:
     1906        case WM_KEYUP:
     1907        case WM_SYSKEYUP:
     1908        {
     1909            /* Delegate key-event handling to the keyboard-handler: */
     1910            return machineLogic()->keyboardHandler()->nativeEventFilter(pMessage, screenId());
     1911        }
     1912        default:
     1913            break;
     1914    }
    18951915
    18961916# elif defined(Q_WS_X11)
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h

    r59384 r59403  
    6060# if QT_VERSION < 0x050000
    6161typedef union _XEvent XEvent;
    62 # else /* QT_VERSION >= 0x050000 */
     62# endif /* QT_VERSION < 0x050000 */
     63#endif /* Q_WS_X11 */
     64#if defined(Q_WS_WIN) || defined(Q_WS_X11)
     65# if QT_VERSION >= 0x050000
    6366class PrivateEventFilter;
    6467# endif /* QT_VERSION >= 0x050000 */
    65 #endif /* Q_WS_X11 */
     68#endif /* Q_WS_WIN || Q_WS_X11 */
    6669#ifdef VBOX_WITH_DRAG_AND_DROP
    6770 class CDnDTarget;
     
    372375      *           the Qt itself because it has another signature,
    373376      *           only by the keyboard-hook of the keyboard-handler. */
    374     virtual bool nativeEvent(const QByteArray &eventType, void *pMessage, long *pResult);
     377    virtual bool nativeEvent(void *pMessage);
    375378#endif /* QT_VERSION >= 0x050000 */
    376379
     
    430433#endif
    431434
    432 #ifdef Q_WS_X11
     435#if defined(Q_WS_WIN) || defined(Q_WS_X11)
    433436# if QT_VERSION >= 0x050000
    434437    /** X11: Holds the native event filter instance. */
     
    438441    friend class PrivateEventFilter;
    439442# endif /* QT_VERSION >= 0x050000 */
    440 #endif /* Q_WS_X11 */
     443#endif /* Q_WS_WIN || Q_WS_X11 */
    441444
    442445    /* Friend classes: */
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