VirtualBox

Changeset 59361 in vbox


Ignore:
Timestamp:
Jan 15, 2016 1:51:19 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
105049
Message:

FE/Qt: Qt5 migration (part 58): Reworking keyboard-handler: General rework/cleanup for Mac OS X.

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

Legend:

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

    r59360 r59361  
    492492
    493493#if QT_VERSION < 0x050000
    494 # if defined(Q_WS_WIN)
     494# if defined(Q_WS_MAC)
     495
     496bool UIKeyboardHandler::macEventFilter(const void *pvCocoaEvent, EventRef event, ulong uScreenId)
     497{
     498    /* Check if some system event should be filtered out.
     499     * Returning @c true means filtering-out,
     500     * Returning @c false means passing event to Qt. */
     501    bool fResult = false; /* Pass to Qt by default. */
     502
     503    /* Depending on event kind: */
     504    const UInt32 uEventKind = ::GetEventKind(event);
     505    switch(uEventKind)
     506    {
     507        /* Watch for simple key-events: */
     508        case kEventRawKeyDown:
     509        case kEventRawKeyRepeat:
     510        case kEventRawKeyUp:
     511        {
     512            /* Acquire keycode: */
     513            UInt32 uKeyCode = ~0U;
     514            ::GetEventParameter(event, kEventParamKeyCode, typeUInt32,
     515                                NULL, sizeof(uKeyCode), NULL, &uKeyCode);
     516
     517            /* The usb keyboard driver translates these codes to different virtual
     518             * keycodes depending of the keyboard type. There are ANSI, ISO, JIS
     519             * and unknown. For European keyboards (ISO) the key 0xa and 0x32 have
     520             * to be switched. Here we are doing this at runtime, cause the user
     521             * can have more than one keyboard (of different type), where he may
     522             * switch at will all the time. Default is the ANSI standard as defined
     523             * in g_aDarwinToSet1. Please note that the "~" on some English ISO
     524             * keyboards will be wrongly swapped. This can maybe fixed by
     525             * using a Apple keyboard layout in the guest. */
     526            if (   (uKeyCode == 0xa || uKeyCode == 0x32)
     527                && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO)
     528                uKeyCode = 0x3c - uKeyCode;
     529
     530            /* Translate keycode to set 1 scan code: */
     531            unsigned uScanCode = ::DarwinKeycodeToSet1Scancode(uKeyCode);
     532
     533            /* If scan code is valid: */
     534            if (uScanCode)
     535            {
     536                /* Calculate flags: */
     537                int iFlags = 0;
     538                if (uEventKind != kEventRawKeyUp)
     539                    iFlags |= KeyPressed;
     540                if (uScanCode & VBOXKEY_EXTENDED)
     541                    iFlags |= KeyExtended;
     542                /** @todo KeyPause, KeyPrint. */
     543                uScanCode &= VBOXKEY_SCANCODE_MASK;
     544
     545                /* Get the unicode string (if present): */
     546                AssertCompileSize(wchar_t, 2);
     547                AssertCompileSize(UniChar, 2);
     548                ByteCount cbWritten = 0;
     549                wchar_t ucs[8];
     550                if (::GetEventParameter(event, kEventParamKeyUnicodes, typeUnicodeText,
     551                                        NULL, sizeof(ucs), &cbWritten, &ucs[0]) != 0)
     552                    cbWritten = 0;
     553                ucs[cbWritten / sizeof(wchar_t)] = 0; /* The api doesn't terminate it. */
     554
     555                /* Finally, handle parsed key-event: */
     556                fResult = keyEvent(uKeyCode, uScanCode, iFlags, uScreenId, ucs[0] ? ucs : NULL);
     557            }
     558
     559            break;
     560        }
     561        /* Watch for modifier key-events: */
     562        case kEventRawKeyModifiersChanged:
     563        {
     564            /* Acquire new modifier mask, it may contain
     565             * multiple modifier changes, kind of annoying: */
     566            UInt32 uNewMask = 0;
     567            ::GetEventParameter(event, kEventParamKeyModifiers, typeUInt32,
     568                                NULL, sizeof(uNewMask), NULL, &uNewMask);
     569
     570            /* Adjust new modifier mask to distinguish left/right modifiers: */
     571            uNewMask = ::DarwinAdjustModifierMask(uNewMask, pvCocoaEvent);
     572
     573            /* Determine what is really changed: */
     574            const UInt32 changed = uNewMask ^ m_uDarwinKeyModifiers;
     575            if (changed)
     576            {
     577                for (UInt32 bit = 0; bit < 32; ++bit)
     578                {
     579                    /* Skip unchanged bits: */
     580                    if (!(changed & (1 << bit)))
     581                        continue;
     582                    /* Acquire set 1 scan code from new mask: */
     583                    unsigned uScanCode = ::DarwinModifierMaskToSet1Scancode(1 << bit);
     584                    /* Skip invalid scan codes: */
     585                    if (!uScanCode)
     586                        continue;
     587                    /* Acquire darwin keycode from new mask: */
     588                    unsigned uKeyCode = ::DarwinModifierMaskToDarwinKeycode(1 << bit);
     589                    /* Assert invalid keycodes: */
     590                    Assert(uKeyCode);
     591
     592                    /* For non-lockable modifier: */
     593                    if (!(uScanCode & VBOXKEY_LOCK))
     594                    {
     595                        /* Calculate flags: */
     596                        unsigned uFlags = (uNewMask & (1 << bit)) ? KeyPressed : 0;
     597                        if (uScanCode & VBOXKEY_EXTENDED)
     598                            uFlags |= KeyExtended;
     599                        uScanCode &= VBOXKEY_SCANCODE_MASK;
     600
     601                        /* Finally, handle parsed key-event: */
     602                        keyEvent(uKeyCode, uScanCode & 0xff, uFlags, uScreenId);
     603                    }
     604                    /* For lockable modifier: */
     605                    else
     606                    {
     607                        /* Calculate flags: */
     608                        unsigned uFlags = 0;
     609                        if (uScanCode & VBOXKEY_EXTENDED)
     610                            uFlags |= KeyExtended;
     611                        uScanCode &= VBOXKEY_SCANCODE_MASK;
     612
     613                        /* Finally, handle parsed press/release pair: */
     614                        keyEvent(uKeyCode, uScanCode, uFlags | KeyPressed, uScreenId);
     615                        keyEvent(uKeyCode, uScanCode, uFlags, uScreenId);
     616                    }
     617                }
     618            }
     619
     620            /* Remember new modifier mask: */
     621            m_uDarwinKeyModifiers = uNewMask;
     622
     623            /* Always return true here because we'll otherwise getting a Qt event
     624             * we don't want and that will only cause the Pause warning to pop up: */
     625            fResult = true;
     626
     627            break;
     628        }
     629        default:
     630            break;
     631    }
     632
     633    /* Return result: */
     634    return fResult;
     635}
     636
     637# elif defined(Q_WS_WIN)
    495638
    496639bool UIKeyboardHandler::winEventFilter(MSG *pMsg, ulong uScreenId)
     
    12361379#if defined(Q_WS_MAC)
    12371380
     1381/* static */
    12381382bool UIKeyboardHandler::macKeyboardProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser)
    12391383{
    1240     UIKeyboardHandler *pKeyboardHandler = (UIKeyboardHandler*)pvUser;
    1241     EventRef inEvent = (EventRef)pvCarbonEvent;
    1242     UInt32 eventClass = ::GetEventClass(inEvent);
     1384    /* Determine the event class: */
     1385    EventRef event = (EventRef)pvCarbonEvent;
     1386    UInt32 uEventClass = ::GetEventClass(event);
    12431387
    12441388    /* Check if this is an application key combo. In that case we will not pass
     
    12471391        return false;
    12481392
    1249     /* All keyboard class events needs to be handled. */
    1250     if (eventClass == kEventClassKeyboard)
    1251     {
    1252         if (pKeyboardHandler->macKeyboardEvent(pvCocoaEvent, inEvent))
    1253             return true;
    1254     }
    1255     /* Pass the event along. */
     1393    /* Get the keyboard handler from the user's void data: */
     1394    UIKeyboardHandler *pKeyboardHandler = static_cast<UIKeyboardHandler*>(pvUser);
     1395
     1396    /* All keyboard class events needs to be handled: */
     1397    if (uEventClass == kEventClassKeyboard && pKeyboardHandler && pKeyboardHandler->macKeyboardEvent(pvCocoaEvent, event))
     1398        return true;
     1399
     1400    /* Pass the event along: */
    12561401    return false;
    12571402}
    12581403
    1259 bool UIKeyboardHandler::macKeyboardEvent(const void *pvCocoaEvent, EventRef inEvent)
    1260 {
    1261     bool ret = false;
    1262     UInt32 EventKind = ::GetEventKind(inEvent);
    1263     if (EventKind != kEventRawKeyModifiersChanged)
    1264     {
    1265         /* Convert keycode to set 1 scan code. */
    1266         UInt32 keyCode = ~0U;
    1267         ::GetEventParameter(inEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof (keyCode), NULL, &keyCode);
    1268         /* The usb keyboard driver translates these codes to different virtual
    1269          * key codes depending of the keyboard type. There are ANSI, ISO, JIS
    1270          * and unknown. For European keyboards (ISO) the key 0xa and 0x32 have
    1271          * to be switched. Here we are doing this at runtime, cause the user
    1272          * can have more than one keyboard (of different type), where he may
    1273          * switch at will all the time. Default is the ANSI standard as defined
    1274          * in g_aDarwinToSet1. Please note that the "~" on some English ISO
    1275          * keyboards will be wrongly swapped. This can maybe fixed by
    1276          * using a Apple keyboard layout in the guest. */
    1277         if (   (keyCode == 0xa || keyCode == 0x32)
    1278             && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO)
    1279             keyCode = 0x3c - keyCode;
    1280         unsigned scanCode = ::DarwinKeycodeToSet1Scancode(keyCode);
    1281         if (scanCode)
    1282         {
    1283             /* Calc flags. */
    1284             int flags = 0;
    1285             if (EventKind != kEventRawKeyUp)
    1286                 flags |= KeyPressed;
    1287             if (scanCode & VBOXKEY_EXTENDED)
    1288                 flags |= KeyExtended;
    1289             /** @todo KeyPause, KeyPrint. */
    1290             scanCode &= VBOXKEY_SCANCODE_MASK;
    1291 
    1292             /* Get the unicode string (if present). */
    1293             AssertCompileSize(wchar_t, 2);
    1294             AssertCompileSize(UniChar, 2);
    1295             ByteCount cbWritten = 0;
    1296             wchar_t ucs[8];
    1297             if (::GetEventParameter(inEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL,
    1298                                     sizeof(ucs), &cbWritten, &ucs[0]) != 0)
    1299                 cbWritten = 0;
    1300             ucs[cbWritten / sizeof(wchar_t)] = 0; /* The api doesn't terminate it. */
    1301 
    1302             ret = keyEvent(keyCode, scanCode, flags, m_iKeyboardHookViewIndex, ucs[0] ? ucs : NULL);
    1303         }
    1304     }
    1305     else
    1306     {
    1307         /* May contain multiple modifier changes, kind of annoying. */
    1308         UInt32 newMask = 0;
    1309         ::GetEventParameter(inEvent, kEventParamKeyModifiers, typeUInt32, NULL,
    1310                             sizeof(newMask), NULL, &newMask);
    1311         newMask = ::DarwinAdjustModifierMask(newMask, pvCocoaEvent);
    1312         UInt32 changed = newMask ^ m_uDarwinKeyModifiers;
    1313         if (changed)
    1314         {
    1315             for (UInt32 bit = 0; bit < 32; bit++)
    1316             {
    1317                 if (!(changed & (1 << bit)))
    1318                     continue;
    1319                 unsigned scanCode = ::DarwinModifierMaskToSet1Scancode(1 << bit);
    1320                 if (!scanCode)
    1321                     continue;
    1322                 unsigned keyCode = ::DarwinModifierMaskToDarwinKeycode(1 << bit);
    1323                 Assert(keyCode);
    1324 
    1325                 if (!(scanCode & VBOXKEY_LOCK))
    1326                 {
    1327                     unsigned flags = (newMask & (1 << bit)) ? KeyPressed : 0;
    1328                     if (scanCode & VBOXKEY_EXTENDED)
    1329                         flags |= KeyExtended;
    1330                     scanCode &= VBOXKEY_SCANCODE_MASK;
    1331                     ret |= keyEvent(keyCode, scanCode & 0xff, flags, m_iKeyboardHookViewIndex);
    1332                 }
    1333                 else
    1334                 {
    1335                     unsigned flags = 0;
    1336                     if (scanCode & VBOXKEY_EXTENDED)
    1337                         flags |= KeyExtended;
    1338                     scanCode &= VBOXKEY_SCANCODE_MASK;
    1339                     keyEvent(keyCode, scanCode, flags | KeyPressed, m_iKeyboardHookViewIndex);
    1340                     keyEvent(keyCode, scanCode, flags, m_iKeyboardHookViewIndex);
    1341                 }
    1342             }
    1343         }
    1344 
    1345         m_uDarwinKeyModifiers = newMask;
    1346 
    1347         /* Always return true here because we'll otherwise getting a Qt event
    1348            we don't want and that will only cause the Pause warning to pop up. */
    1349         ret = true;
    1350     }
    1351 
    1352     return ret;
     1404bool UIKeyboardHandler::macKeyboardEvent(const void *pvCocoaEvent, EventRef event)
     1405{
     1406    /* Check what related machine-view was NOT unregistered yet: */
     1407    if (!m_views.contains(m_iKeyboardHookViewIndex))
     1408        return false;
     1409
     1410    /* Pass event to machine-view's event handler: */
     1411#if QT_VERSION < 0x050000
     1412    return m_views[m_iKeyboardHookViewIndex]->macEvent(pvCocoaEvent, event);
     1413#endif /* QT_VERSION < 0x050000 */
    13531414}
    13541415
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h

    r59359 r59361  
    107107
    108108#if QT_VERSION < 0x050000
    109 # if defined(Q_WS_WIN)
     109# if defined(Q_WS_MAC)
     110    /** Qt4: Mac: Performs final pre-processing of all the native events. */
     111    bool macEventFilter(const void *pvCocoaEvent, EventRef event, ulong uScreenId);
     112# elif defined(Q_WS_WIN)
    110113    /** Qt4: Win: Performs final pre-processing of all the native events. */
    111114    bool winEventFilter(MSG *pMsg, ulong uScreenId);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r59344 r59361  
    16871687#endif /* VBOX_WITH_DRAG_AND_DROP */
    16881688
    1689 #if defined(Q_WS_WIN)
     1689#if QT_VERSION < 0x050000
     1690# if defined(Q_WS_MAC)
     1691
     1692bool UIMachineView::macEvent(const void *pvCocoaEvent, EventRef event)
     1693{
     1694    /* Make sure arguments valid: */
     1695    AssertPtrReturn(pvCocoaEvent, false);
     1696    AssertReturn(event != NULL, false);
     1697
     1698    /* Check if some system event should be filtered out.
     1699     * Returning @c true means filtering-out,
     1700     * Returning @c false means passing event to Qt. */
     1701    bool fResult = false; /* Pass to Qt by default. */
     1702    switch(::GetEventClass(event))
     1703    {
     1704        /* Watch for keyboard-events: */
     1705        case kEventClassKeyboard:
     1706        {
     1707            switch(::GetEventKind(event))
     1708            {
     1709                /* Watch for key-events: */
     1710                case kEventRawKeyDown:
     1711                case kEventRawKeyRepeat:
     1712                case kEventRawKeyUp:
     1713                case kEventRawKeyModifiersChanged:
     1714                {
     1715                    /* Filter using keyboard-filter? */
     1716                    bool fKeyboardFilteringResult =
     1717                        machineLogic()->keyboardHandler()->macEventFilter(pvCocoaEvent, event, screenId());
     1718                    /* Keyboard filter rules the result? */
     1719                    fResult = fKeyboardFilteringResult;
     1720                    break;
     1721                }
     1722                default:
     1723                    break;
     1724            }
     1725            break;
     1726        }
     1727        default:
     1728            break;
     1729    }
     1730
     1731    /* Return result: */
     1732    return fResult;
     1733}
     1734
     1735# elif defined(Q_WS_WIN)
    16901736
    16911737bool UIMachineView::winEvent(MSG *pMsg, long* /* piResult */)
     
    17261772}
    17271773
    1728 #elif defined(Q_WS_X11)
    1729 
    1730 # if QT_VERSION < 0x050000
     1774# elif defined(Q_WS_X11)
     1775
    17311776bool UIMachineView::x11Event(XEvent *pEvent)
    17321777{
     
    17601805    return fResult;
    17611806}
    1762 # endif /* QT_VERSION < 0x050000 */
    1763 
    1764 #endif /* Q_WS_X11 */
     1807
     1808# endif /* Q_WS_X11 */
     1809#endif /* QT_VERSION < 0x050000 */
    17651810
    17661811QSize UIMachineView::scaledForward(QSize size) const
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h

    r59344 r59361  
    344344#endif /* VBOX_WITH_DRAG_AND_DROP */
    345345
    346     /* Platform specific event processors: */
    347 #if defined(Q_WS_WIN)
    348     bool winEvent(MSG *pMsg, long *puResult);
    349 #elif defined(Q_WS_X11)
    350 # if QT_VERSION < 0x050000
    351     /** X11: Qt4: Handles all native events. */
    352     bool x11Event(XEvent *pEvent);
    353 # endif /* QT_VERSION < 0x050000 */
    354 #endif /* Q_WS_X11 */
     346#if QT_VERSION < 0x050000
     347# if defined(Q_WS_MAC)
     348    /** Qt4: Mac: Performs pre-processing of all the native events.
     349      * @note     Take into account this function is _not_ called by
     350      *           the Qt itself because it has another signature,
     351      *           only by the keyboard-hook of the keyboard-handler. */
     352    virtual bool macEvent(const void *pvCocoaEvent, EventRef event);
     353# elif defined(Q_WS_WIN)
     354    /** Qt4: Win: Performs pre-processing of all the native events.
     355      * @note     Take into account this function is called by
     356      *           the Qt as well opposing to other host (Mac)
     357      *           because it has required signature. */
     358    virtual bool winEvent(MSG *pMsg, long *piResult);
     359# elif defined(Q_WS_X11)
     360    /** Qt4: X11: Performs pre-processing of all the native events.
     361      * @note     Take into account this function is called by
     362      *           the Qt as well opposing to other host (Mac)
     363      *           because it has required signature. */
     364    virtual bool x11Event(XEvent *pEvent);
     365# endif /* Q_WS_X11 */
     366#endif /* QT_VERSION < 0x050000 */
    355367
    356368    /** Scales passed size forward. */
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