VirtualBox

Changeset 59384 in vbox


Ignore:
Timestamp:
Jan 18, 2016 5:30:57 PM (9 years ago)
Author:
vboxsync
Message:

FE/Qt: Qt5 migration (part 64): Implementing keyboard handling for Qt5 under X11.

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

Legend:

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

    r59377 r59384  
    268268            {
    269269# if QT_VERSION >= 0x050000
    270                 xcb_grab_key_checked(QX11Info::connection(), 0, m_views.value(uScreenId)->viewport()->winId(), XCB_MOD_MASK_ANY, XCB_GRAB_ANY, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
     270                xcb_grab_key_checked(QX11Info::connection(), 0, m_windows.value(uScreenId)->winId(), XCB_MOD_MASK_ANY, XCB_GRAB_ANY, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
    271271# else /* QT_VERSION < 0x050000 */
    272272                XGrabKey(QX11Info::display(), AnyKey, AnyModifier, m_windows[uScreenId]->winId(), False, GrabModeAsync, GrabModeAsync);
     
    279279            {
    280280# if QT_VERSION >= 0x050000
    281                 xcb_grab_keyboard(QX11Info::connection(), 0, m_views.value(uScreenId)->viewport()->winId(), XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
     281                xcb_grab_keyboard(QX11Info::connection(), 0, m_windows.value(uScreenId)->winId(), XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
    282282# else /* QT_VERSION < 0x050000 */
    283283                /* Keyboard grabbing can fail because of some keyboard shortcut is still grabbed by window manager.
     
    367367            {
    368368# if QT_VERSION >= 0x050000
    369                 xcb_ungrab_key(QX11Info::connection(), XCB_GRAB_ANY, m_views.value(m_iKeyboardCaptureViewIndex)->viewport()->winId(), XCB_MOD_MASK_ANY);
     369                xcb_ungrab_key(QX11Info::connection(), XCB_GRAB_ANY, m_windows.value(m_iKeyboardCaptureViewIndex)->winId(), XCB_MOD_MASK_ANY);
    370370# else /* QT_VERSION < 0x050000 */
    371371                XUngrabKey(QX11Info::display(), AnyKey, AnyModifier, m_windows[m_iKeyboardCaptureViewIndex]->winId());
     
    939939bool UIKeyboardHandler::nativeEventFilter(void *pMessage, ulong uScreenId)
    940940{
    941     /* Cast to XCB event: */
    942     xcb_generic_event_t *pEvent = static_cast<xcb_generic_event_t*>(pMessage);
    943 
    944941    /* Check if some system event should be filtered out.
    945942     * Returning @c true means filtering-out,
    946943     * Returning @c false means passing event to Qt. */
    947944    bool fResult = false; /* Pass to Qt by default. */
     945
     946# if defined(Q_WS_MAC)
     947
     948#  warning "implement me!"
     949
     950# elif defined(Q_WS_WIN)
     951
     952#  warning "implement me!"
     953
     954# elif defined(Q_WS_X11)
     955
     956    /* Cast to XCB event: */
     957    xcb_generic_event_t *pEvent = static_cast<xcb_generic_event_t*>(pMessage);
     958
     959    /* Depending on event type: */
    948960    switch (pEvent->response_type & ~0x80)
    949961    {
    950         /* Watch for keyboard behavior: */
     962        /* Watch for key-events: */
    951963        case XCB_KEY_PRESS:
    952964        case XCB_KEY_RELEASE:
     
    955967            xcb_key_press_event_t *pKeyEvent = static_cast<xcb_key_press_event_t*>(pMessage);
    956968
    957             /* Translate the keycode to a PC scancode: */
    958             unsigned scan = handleXKeyEvent(QX11Info::display(), pKeyEvent->detail);
    959 
    960             /* Scancodes 0x00 (no valid translation) and 0x80 (extended flag) are ignored: */
    961             if (!(scan & 0x7F))
     969            /* Translate the keycode to a PC scan code: */
     970            unsigned uScan = handleXKeyEvent(QX11Info::display(), pKeyEvent->detail);
     971
     972            /* Scan codes 0x00 (no valid translation) and 0x80 (extended flag) are ignored: */
     973            if (!(uScan & 0x7F))
    962974            {
    963975                fResult = true;
     
    976988//            }
    977989
    978             /* Detect common scancode flags: */
    979             int flags = 0;
    980             if (scan >> 8)
    981                 flags |= KeyExtended;
     990            /* Calculate flags: */
     991            int iflags = 0;
     992            if (uScan >> 8)
     993                iflags |= KeyExtended;
    982994            if ((pEvent->response_type & ~0x80) == XCB_KEY_PRESS)
    983                 flags |= KeyPressed;
     995                iflags |= KeyPressed;
    984996
    985997            /* Remove the extended flag: */
    986             scan &= 0x7F;
    987 
    988             /* Special Korean keys must send scancode 0xF1/0xF2
     998            uScan &= 0x7F;
     999
     1000            /* Special Korean keys must send scan code 0xF1/0xF2
    9891001             * when pressed and nothing when released. */
    990             if (scan == 0x71 || scan == 0x72)
     1002            if (uScan == 0x71 || uScan == 0x72)
    9911003            {
    9921004                if ((pEvent->response_type & ~0x80) == XCB_KEY_RELEASE)
     
    9951007                    break;
    9961008                }
    997                 /* Re-create the bizarre scancode: */
    998                 scan |= 0x80;
     1009                /* Re-create the bizarre scan code: */
     1010                uScan |= 0x80;
    9991011            }
    10001012
     
    10021014            KeySym ks = ::wrapXkbKeycodeToKeysym(QX11Info::display(), pKeyEvent->detail, 0, 0);
    10031015
    1004             /* Detect particular scancode flags: */
     1016            /* Update special flags: */
    10051017            switch (ks)
    10061018            {
    10071019                case XK_Print:
    1008                     flags |= KeyPrint;
     1020                    iflags |= KeyPrint;
    10091021                    break;
    10101022                case XK_Pause:
    1011                     if (pKeyEvent->state & ControlMask)
     1023                    if (pKeyEvent->state & ControlMask) /* Break */
    10121024                    {
    10131025                        ks = XK_Break;
    1014                         flags |= KeyExtended;
    1015                         scan = 0x46;
     1026                        iflags |= KeyExtended;
     1027                        uScan = 0x46;
    10161028                    }
    10171029                    else
    1018                         flags |= KeyPause;
     1030                        iflags |= KeyPause;
    10191031                    break;
    10201032            }
    10211033
    1022             /* Handle key-event: */
    1023             fResult = keyEvent(ks, scan, flags, uScreenId);
     1034            /* Finally, handle parsed key-event: */
     1035            fResult = keyEvent(ks, uScan, iflags, uScreenId);
     1036
    10241037            break;
    10251038        }
     
    10271040            break;
    10281041    }
     1042
     1043# else
     1044
     1045#  warning "port me!"
     1046
     1047# endif
     1048
    10291049    /* Return result: */
    10301050    return fResult;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r59380 r59384  
    7070
    7171#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
     72
     73/* Qt includes: */
     74#ifdef Q_WS_X11
     75# if QT_VERSION >= 0x050000
     76#  include <QAbstractNativeEventFilter>
     77# endif /* QT_VERSION >= 0x050000 */
     78#endif /* Q_WS_X11 */
    7279
    7380/* GUI includes: */
     
    121128# define DNDDEBUG(x)
    122129#endif
     130
     131
     132#ifdef Q_WS_X11
     133# if QT_VERSION >= 0x050000
     134/** QAbstractNativeEventFilter extension
     135  * allowing to pre-process native platform events. */
     136class PrivateEventFilter : public QAbstractNativeEventFilter
     137{
     138public:
     139
     140    /** Constructor which takes the passed @a pParent to redirect events to. */
     141    PrivateEventFilter(UIMachineView *pParent)
     142        : m_pParent(pParent)
     143    {}
     144
     145    /** Handles all native events. */
     146    bool nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pResult)
     147    {
     148        /* Redirect event to parent: */
     149        return m_pParent->nativeEvent(eventType, pMessage, pResult);
     150    }
     151
     152private:
     153
     154    /** Holds the passed parent reference. */
     155    UIMachineView *m_pParent;
     156};
     157# endif /* QT_VERSION >= 0x050000 */
     158#endif /* Q_WS_X11 */
    123159
    124160
     
    215251        return;
    216252
     253    /* Cleanup event-filters: */
     254    pMachineView->cleanupFilters();
     255
    217256    /* Cleanup frame-buffer: */
    218257    pMachineView->cleanupFrameBuffer();
     
    622661    , m_fIsDraggingFromGuest(false)
    623662#endif
     663#ifdef Q_WS_X11
     664# if QT_VERSION >= 0x050000
     665    , m_pPrivateEventFilter(0)
     666# endif /* QT_VERSION >= 0x050000 */
     667#endif /* Q_WS_X11 */
    624668{
    625669}
     
    798842    /* We want to be notified on some parent's events: */
    799843    machineWindow()->installEventFilter(this);
     844
     845#ifdef Q_WS_X11
     846# if QT_VERSION >= 0x050000
     847    /* Prepare private event-filter: */
     848    m_pPrivateEventFilter = new PrivateEventFilter(this);
     849    qApp->installNativeEventFilter(m_pPrivateEventFilter);
     850# endif /* QT_VERSION >= 0x050000 */
     851#endif /* Q_WS_X11 */
    800852}
    801853
     
    823875    /* Machine state-change updater: */
    824876    connect(uisession(), SIGNAL(sigMachineStateChange()), this, SLOT(sltMachineStateChanged()));
     877}
     878
     879void UIMachineView::cleanupFilters()
     880{
     881#ifdef Q_WS_X11
     882# if QT_VERSION >= 0x050000
     883    /* Cleanup private event-filter: */
     884    qApp->removeNativeEventFilter(m_pPrivateEventFilter);
     885    delete m_pPrivateEventFilter;
     886    m_pPrivateEventFilter = 0;
     887# endif /* QT_VERSION >= 0x050000 */
     888#endif /* Q_WS_X11 */
    825889}
    826890
     
    18181882
    18191883# endif /* Q_WS_X11 */
    1820 #endif /* QT_VERSION < 0x050000 */
     1884#else /* QT_VERSION >= 0x050000 */
     1885
     1886bool UIMachineView::nativeEvent(const QByteArray &eventType, void *pMessage, long *pResult)
     1887{
     1888# if defined(Q_WS_MAC)
     1889
     1890#  warning "implement me!"
     1891
     1892# elif defined(Q_WS_WIN)
     1893
     1894#  warning "implement me!"
     1895
     1896# elif defined(Q_WS_X11)
     1897
     1898    /* Make sure it's generic XCB event: */
     1899    if (eventType != "xcb_generic_event_t")
     1900        return QAbstractScrollArea::nativeEvent(eventType, pMessage, pResult);
     1901    xcb_generic_event_t *pEvent = static_cast<xcb_generic_event_t*>(pMessage);
     1902
     1903    /* Check if some XCB event should be filtered out.
     1904     * Returning @c true means filtering-out,
     1905     * Returning @c false means passing event to Qt. */
     1906    switch (pEvent->response_type & ~0x80)
     1907    {
     1908        /* Watch for key-events: */
     1909        case XCB_KEY_PRESS:
     1910        case XCB_KEY_RELEASE:
     1911        {
     1912            /* Delegate key-event handling to the keyboard-handler: */
     1913            return machineLogic()->keyboardHandler()->nativeEventFilter(pMessage, screenId());
     1914        }
     1915        default:
     1916            break;
     1917    }
     1918
     1919# else
     1920
     1921#  warning "port me!"
     1922
     1923# endif
     1924
     1925    /* Filter nothing by default: */
     1926    return false;
     1927}
     1928
     1929#endif /* QT_VERSION >= 0x050000 */
    18211930
    18221931QSize UIMachineView::scaledForward(QSize size) const
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h

    r59380 r59384  
    6060# if QT_VERSION < 0x050000
    6161typedef union _XEvent XEvent;
    62 # endif /* QT_VERSION < 0x050000 */
     62# else /* QT_VERSION >= 0x050000 */
     63class PrivateEventFilter;
     64# endif /* QT_VERSION >= 0x050000 */
    6365#endif /* Q_WS_X11 */
    6466#ifdef VBOX_WITH_DRAG_AND_DROP
     
    184186    //virtual void cleanupConsoleConnections() {}
    185187    //virtual void cleanupConnections() {}
    186     //virtual void cleanupFilters() {}
     188    virtual void cleanupFilters();
    187189    //virtual void cleanupCommon() {}
    188190    virtual void cleanupFrameBuffer();
     
    365367    virtual bool x11Event(XEvent *pEvent);
    366368# endif /* Q_WS_X11 */
    367 #endif /* QT_VERSION < 0x050000 */
     369#else /* QT_VERSION >= 0x050000 */
     370    /** Qt5: Performs pre-processing of all the native events.
     371      * @note     Take into account this function is _not_ called by
     372      *           the Qt itself because it has another signature,
     373      *           only by the keyboard-hook of the keyboard-handler. */
     374    virtual bool nativeEvent(const QByteArray &eventType, void *pMessage, long *pResult);
     375#endif /* QT_VERSION >= 0x050000 */
    368376
    369377    /** Scales passed size forward. */
     
    422430#endif
    423431
     432#ifdef Q_WS_X11
     433# if QT_VERSION >= 0x050000
     434    /** X11: Holds the native event filter instance. */
     435    PrivateEventFilter *m_pPrivateEventFilter;
     436    /** X11: Allows the native event filter to
     437      * redirect events directly to nativeEvent handler. */
     438    friend class PrivateEventFilter;
     439# endif /* QT_VERSION >= 0x050000 */
     440#endif /* Q_WS_X11 */
     441
    424442    /* Friend classes: */
    425443    friend class UIKeyboardHandler;
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