VirtualBox

Changeset 1285 in vbox


Ignore:
Timestamp:
Mar 7, 2007 5:34:38 AM (18 years ago)
Author:
vboxsync
Message:

Darwin: fixed the screen update issue and started implementing the keyboard stuff.

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

Legend:

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

    r1178 r1285  
    128128        src/linux/keyboard.c
    129129endif
     130
     131VirtualBox_SOURCES.darwin = \
     132        src/darwin/DarwinKeyboard.cpp
    130133
    131134VirtualBox_DEFS           = VBOX_GUI_SEPARATE_VM_PROCESS
     
    175178 endif
    176179endif
     180VirtualBox_LDFLAGS.darwin = -framework IOKit
    177181VirtualBox_LIBS.win       = \
    178182        $(PATH_SDK_WINPSDK_LIB)/Htmlhelp.Lib \
  • trunk/src/VBox/Frontends/VirtualBox/include/QIHotKeyEdit.h

    r382 r1285  
    2525
    2626#include <qlabel.h>
     27#ifdef Q_WS_MAC
     28#include <Carbon/Carbon.h>
     29#endif
     30
    2731
    2832class QIHotKeyEdit : public QLabel
     
    3337
    3438    QIHotKeyEdit( QWidget * parent, const char * name = 0 );
     39    virtual ~QIHotKeyEdit();
    3540
    3641    void setKey( int keyval );
     
    5560#elif defined(Q_WS_X11)
    5661    bool x11Event( XEvent *event );
     62#elif defined(Q_WS_MAC)
     63    static pascal OSStatus darwinEventHandlerProc( EventHandlerCallRef inHandlerCallRef,
     64                                                   EventRef inEvent, void *inUserData );
     65    bool darwinKeyboardEvent( EventRef inEvent );
    5766#endif
    5867
     
    7180    QColorGroup true_acg;
    7281
     82#if defined(Q_WS_MAC)
     83    /** Event handler reference. NULL if the handler isn't installed. */
     84    EventHandlerRef m_darwinEventHandlerRef;
     85    /** The current modifier key mask. Used to figure out which modifier
     86     *  key was pressed when we get a kEventRawKeyModifiersChanged event. */
     87    UInt32 m_darwinKeyModifiers;
     88#endif
     89
    7390    static const char *NoneSymbName;
    7491};
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h

    r896 r1285  
    3636#include <qkeysequence.h>
    3737
     38#if defined (Q_WS_MAC)
     39# include <Carbon/Carbon.h>
     40#endif
     41
    3842class VBoxConsoleWnd;
    3943class MousePointerChangeEvent;
     
    103107#elif defined(Q_WS_X11)
    104108    bool x11Event (XEvent *event );
     109#elif defined(Q_WS_MAC)
     110    bool darwinKeyboardEvent (EventRef inEvent);
     111    void darwinGrabKeyboardEvents (bool fGrab);
    105112#endif
    106113
     
    116123
    117124    void focusEvent (bool focus);
    118     bool keyEvent (int key, uint8_t scan, int flags);
     125    bool keyEvent (int key, uint8_t scan, int flags, wchar_t *aUniKey = NULL);
    119126    bool mouseEvent (int aType, const QPoint &aPos, const QPoint &aGlobalPos,
    120127                     ButtonState aButton,
     
    210217#endif
    211218
     219#if defined(Q_WS_MAC)
     220    /** Event handler reference. NULL if the handler isn't installed. */
     221    EventHandlerRef m_darwinEventHandlerRef;
     222    /** The current modifier key mask. Used to figure out which modifier
     223     *  key was pressed when we get a kEventRawKeyModifiersChanged event. */
     224    UInt32 m_darwinKeyModifiers;
     225#endif
     226
    212227#if defined (VBOX_GUI_USE_REFRESH_TIMER)
    213228    QPixmap pm;
     
    223238    static LRESULT CALLBACK lowLevelKeyboardProc (int nCode,
    224239                                                  WPARAM wParam, LPARAM lParam);
     240#elif defined (Q_WS_MAC)
     241    static pascal OSStatus darwinEventHandlerProc (EventHandlerCallRef inHandlerCallRef,
     242                                                   EventRef inEvent, void *inUserData);
    225243#endif
    226244
  • trunk/src/VBox/Frontends/VirtualBox/src/QIHotKeyEdit.cpp

    r382 r1285  
    6262#endif
    6363
     64#ifdef Q_WS_MAC
     65#include "DarwinKeyboard.h"
     66#endif
     67
    6468
    6569#ifdef Q_WS_WIN32
     
    129133    p.setActive( p.inactive() );
    130134    setPalette( p );
     135
     136#ifdef Q_WS_MAC
     137    m_darwinKeyModifiers = GetCurrentEventKeyModifiers();
     138
     139    EventTypeSpec eventTypes[4];
     140    eventTypes[0].eventClass = kEventClassKeyboard;
     141    eventTypes[0].eventKind  = kEventRawKeyDown;
     142    eventTypes[1].eventClass = kEventClassKeyboard;
     143    eventTypes[1].eventKind  = kEventRawKeyUp;
     144    eventTypes[2].eventClass = kEventClassKeyboard;
     145    eventTypes[2].eventKind  = kEventRawKeyRepeat;
     146    eventTypes[3].eventClass = kEventClassKeyboard;
     147    eventTypes[3].eventKind  = kEventRawKeyModifiersChanged;
     148
     149    EventHandlerUPP eventHandler = ::NewEventHandlerUPP( QIHotKeyEdit::darwinEventHandlerProc );
     150
     151    m_darwinEventHandlerRef = NULL;
     152    ::InstallApplicationEventHandler( eventHandler, RT_ELEMENTS( eventTypes ), &eventTypes[0],
     153                                      this, &m_darwinEventHandlerRef );
     154    ::DisposeEventHandlerUPP( eventHandler );
     155    ::DarwinGrabKeyboard( false /* just modifiers */ );
     156
     157#endif
     158
     159}
     160
     161QIHotKeyEdit::~QIHotKeyEdit()
     162{
     163#ifdef Q_WS_MAC
     164    ::DarwinReleaseKeyboard();
     165    ::RemoveEventHandler( m_darwinEventHandlerRef );
     166    m_darwinEventHandlerRef = NULL;
     167#endif
    131168}
    132169
     
    226263        else
    227264            name = QString( "<key_%1>" ).arg( key );
     265#elif defined(Q_WS_MAC)
     266        UInt32 modMask = DarwinKeyCodeToDarwinModifierMask( key );
     267        switch ( modMask ) {
     268            case shiftKey:
     269            case optionKey:
     270            case controlKey:
     271            case cmdKey:
     272                name = tr("Left ");
     273                break;
     274            case rightShiftKey:
     275            case rightOptionKey:
     276            case rightControlKey:
     277            case kEventKeyModifierRightCmdKeyMask:
     278                name = tr("Right ");
     279                break;
     280            default:
     281                AssertMsgFailedReturn(( "modMask=%#x\n", modMask ), QString());
     282        }
     283        switch ( modMask ) {
     284            case shiftKey:
     285            case rightShiftKey:
     286                name += QChar( kShiftUnicode );
     287                break;
     288            case optionKey:
     289            case rightOptionKey:
     290                name += QChar( kOptionUnicode );
     291                break;
     292            case controlKey:
     293            case rightControlKey:
     294                name += QChar( kControlUnicode );
     295                break;
     296            case cmdKey:
     297            case kEventKeyModifierRightCmdKeyMask:
     298                name += QChar( kCommandUnicode );
     299                break;
     300        }
    228301#else
    229302        name = QString( "<key_%1>" ).arg( key );
     
    259332            IsMiscFunctionKey( ks )
    260333        );
     334#elif defined(Q_WS_MAC)
     335    UInt32 modMask = ::DarwinKeyCodeToDarwinModifierMask( k );
     336    switch ( modMask ) {
     337        case shiftKey:
     338        case optionKey:
     339        case controlKey:
     340        case rightShiftKey:
     341        case rightOptionKey:
     342        case rightControlKey:
     343        case cmdKey:
     344        case kEventKeyModifierRightCmdKeyMask:
     345            return true;
     346        default:
     347            return false;
     348    }
    261349#else
    262350    Q_UNUSED( k );
     
    367455}
    368456
     457#elif defined(Q_WS_MAC)
     458
     459/* static */
     460pascal OSStatus QIHotKeyEdit::darwinEventHandlerProc( EventHandlerCallRef inHandlerCallRef,
     461                                                      EventRef inEvent, void *inUserData )
     462{
     463    QIHotKeyEdit *edit = (QIHotKeyEdit *)inUserData;
     464    UInt32 EventClass = ::GetEventClass( inEvent );
     465    if (EventClass == kEventClassKeyboard)
     466    {
     467        if (edit->darwinKeyboardEvent( inEvent ))
     468            return 0;
     469    }
     470    return CallNextEventHandler (inHandlerCallRef, inEvent);
     471}
     472
     473#ifdef DEBUG_bird
     474# include <iprt/stream.h>
     475#endif
     476
     477bool QIHotKeyEdit::darwinKeyboardEvent( EventRef inEvent )
     478{
     479    UInt32 eventKind = ::GetEventKind( inEvent );
     480    switch ( eventKind ) {
     481        /*case kEventRawKeyDown:
     482        case kEventRawKeyUp:
     483        case kEventRawKeyRepeat:*/
     484        case kEventRawKeyModifiersChanged: {
     485            UInt32 modifierMask = 0;
     486            ::GetEventParameter( inEvent, kEventParamKeyModifiers, typeUInt32, NULL,
     487                                 sizeof( modifierMask ), NULL, &modifierMask );
     488
     489            modifierMask = ::DarwinAdjustModifierMask(modifierMask);
     490            UInt32 changed = m_darwinKeyModifiers ^ modifierMask;
     491#ifdef DEBUG_bird
     492RTPrintf("old=%04x new=%04x changed=%04x %04x %04x\n",
     493         m_darwinKeyModifiers, modifierMask, changed, GetCurrentEventKeyModifiers(), GetCurrentKeyModifiers());
     494#endif
     495            m_darwinKeyModifiers = modifierMask;
     496
     497            // skip key releases
     498            if ( changed && ( changed & modifierMask ) )
     499                break;
     500
     501            // convert to keycode and skip keycodes we don't care about.
     502            unsigned keyCode = ::DarwinModifierMaskToDarwinKeycode( changed );
     503RTPrintf("keyCode=%#x valid=%d\n", keyCode, isValidKey( keyCode ));
     504            if ( !keyCode || keyCode == ~0U || !isValidKey( keyCode ) )
     505                break;
     506
     507            // update key current key.
     508            keyval = keyCode;
     509            symbname = QIHotKeyEdit::keyName( keyCode );
     510            updateText();
     511            break; //return true;
     512        }
     513        break;
     514    }
     515    return false;
     516}
     517
     518#else
     519# warning "Port me!"
    369520#endif
    370521
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r1007 r1285  
    7878#endif
    7979
     80#if defined (Q_WS_MAC)
     81# include "DarwinKeyboard.h"
     82#endif /* defined (Q_WS_MAC) */
     83
    8084#if defined (VBOX_GUI_USE_REFRESH_TIMER)
    8185enum { UPDATE_FREQ = 1000 / 60 }; // a-la 60Hz
     
    99103
    100104#endif
     105
     106#if defined (Q_WS_MAC)
     107
     108/**
     109 *  Event handler callback for Mac OS X.
     110 */
     111/* static */
     112pascal OSStatus VBoxConsoleView::darwinEventHandlerProc(EventHandlerCallRef inHandlerCallRef,
     113                                                        EventRef inEvent, void *inUserData)
     114{
     115    VBoxConsoleView *view = (VBoxConsoleView *)inUserData;
     116    UInt32 EventClass = ::GetEventClass (inEvent);
     117    if (EventClass == kEventClassKeyboard)
     118    {
     119        if (    view->darwinKeyboardEvent (inEvent)
     120            &&  ::GetEventKind (inEvent) != kEventRawKeyModifiersChanged)
     121            return 0;
     122    }
     123    return CallNextEventHandler (inHandlerCallRef, inEvent);
     124}
     125
     126#endif /* Q_WS_MAC */
    101127
    102128/** Guest mouse pointer shape change event. */
     
    358384    , mAlphaCursor (NULL)
    359385#endif
     386#if defined(Q_WS_MAC)
     387    , m_darwinEventHandlerRef (NULL)
     388    , m_darwinKeyModifiers (0)
     389#endif
    360390{
    361391    Assert (!cconsole.isNull() &&
     
    752782                return true;
    753783            }
    754 /// @todo (dmik) not currently used, but may become necessary later
    755 //            case VBoxDefs::RepaintEventType: {
    756 //                VBoxRepaintEvent *re = (VBoxRepaintEvent *) e;
    757 //                viewport()->repaint (re->x(), re->y(), re->width(), re->height(), false);
    758 //                cconsole.GetDisplay().UpdateCompleted();
    759 //                return true;
    760 //            }
     784
     785#ifdef Q_WS_MAC /* see VBoxQImageFrameBuffer::NotifyUpdate. */
     786            case VBoxDefs::RepaintEventType:
     787            {
     788                VBoxRepaintEvent *re = (VBoxRepaintEvent *) e;
     789                viewport()->repaint (re->x(), re->y(), re->width(), re->height(), false);
     790                /*cconsole.GetDisplay().UpdateCompleted(); - the event was acked already */
     791                return true;
     792            }
     793#endif /* Q_WS_MAC */
    761794
    762795            case VBoxDefs::MousePointerChangeEventType:
     
    9831016                break;
    9841017            }
    985 #endif
     1018#endif /* defined (Q_WS_WIN32) */
     1019#if defined (Q_WS_MAC)
     1020            /*
     1021             *  Install/remove the keyboard event handler.
     1022             */
     1023            case QEvent::WindowActivate:
     1024                darwinGrabKeyboardEvents (true);
     1025                break;
     1026            case QEvent::WindowDeactivate:
     1027                darwinGrabKeyboardEvents (false);
     1028                break;
     1029#endif /* defined (Q_WS_MAC) */
    9861030            case QEvent::Resize:
    9871031            {
     
    12821326}
    12831327
     1328#elif defined (Q_WS_MAC)
     1329
     1330/**
     1331 *  Invoked by VBoxConsoleView::darwinEventHandlerProc when it gets a raw keyboard event.
     1332 *
     1333 *  @param inEvent      The keyboard event.
     1334 *
     1335 *  @return true if the key was processed, false if it wasn't processed and should be passed on.
     1336 */
     1337bool VBoxConsoleView::darwinKeyboardEvent (EventRef inEvent)
     1338{
     1339    bool ret = false;
     1340    UInt32 EventKind = ::GetEventKind (inEvent);
     1341    if (EventKind != kEventRawKeyModifiersChanged)
     1342    {
     1343        /* convert keycode to set 1 scan code. */
     1344        UInt32 keyCode = ~0U;
     1345        ::GetEventParameter (inEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(keyCode), NULL, &keyCode);
     1346        unsigned scanCode = ::DarwinKeycodeToSet1Scancode (keyCode);
     1347        if (scanCode)
     1348        {
     1349            /* calc flags. */
     1350            int flags = 0;
     1351            UInt32 EventKind = ::GetEventKind (inEvent);
     1352            if (EventKind == kEventRawKeyDown)
     1353                flags |= KeyPressed;
     1354            if (scanCode & 0x8000) /* modifiers */
     1355            {
     1356                flags |= KeyPressed;
     1357                scanCode &= ~0x8000;
     1358            }
     1359            if (scanCode & 0x80)
     1360            {
     1361                flags |= KeyExtended;
     1362                scanCode &= ~0x80;
     1363            }
     1364            /** @todo KeyPause, KeyPrint. */
     1365
     1366            /* get the keycode and unicode string (if present). */
     1367            UInt32 keyCode = ~0;
     1368            ::GetEventParameter (inEvent, kEventParamKeyCode, typeUInt32, NULL,
     1369                                 sizeof (keyCode), NULL, &keyCode);
     1370            AssertCompileSize(wchar_t, 2);
     1371            AssertCompileSize(UniChar, 2);
     1372            wchar_t ucs[32];
     1373            if (::GetEventParameter (inEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL,
     1374                                     sizeof (ucs), NULL, &ucs[0]) != 0)
     1375                ucs[0] = 0;
     1376
     1377            ret = keyEvent (keyCode, scanCode, flags, ucs[0] ? ucs : NULL);
     1378        }
     1379    }
     1380    else
     1381    {
     1382        /* May contain multiple modifier changes, kind of annoying. */
     1383        UInt32 newMask = 0;
     1384        ::GetEventParameter (inEvent, kEventParamKeyModifiers, typeUInt32, NULL,
     1385                             sizeof (newMask), NULL, &newMask);
     1386        UInt32 changed = newMask ^ m_darwinKeyModifiers;
     1387        if (changed)
     1388        {
     1389            for (Uint32 bit = 0; bit < 32; bit++)
     1390            {
     1391                if (!(changed & (1 << bit)))
     1392                    continue;
     1393                unsigned scanCode = ::DarwinModifierMaskToSet1Scancode (1 << bit);
     1394                if (!scanCode)
     1395                    continue;
     1396
     1397                unsigned flags = (newMask & (1 << bit)) ? KeyPressed : 0;
     1398                if (scanCode & 0x80)
     1399                {
     1400                    flags |= KeyExtended;
     1401                    scanCode &= ~0x80;
     1402                }
     1403                keyEvent (0, scanCode, flags);
     1404            }
     1405        }
     1406
     1407        m_darwinKeyModifiers = newMask;
     1408
     1409        /* ret is intentionally false. */
     1410    }
     1411
     1412    return ret;
     1413}
     1414
     1415
     1416/**
     1417 * Installs or removes the keyboard event handler.
     1418 *
     1419 * @param   fGrab    True if we're to grab the events, false if we're not to.
     1420 */
     1421void VBoxConsoleView::darwinGrabKeyboardEvents (bool fGrab)
     1422{
     1423    if (fGrab)
     1424    {
     1425        ::SetMouseCoalescingEnabled (false, NULL);      //??
     1426        ::CGSetLocalEventsSuppressionInterval (0.0);    //??
     1427
     1428        EventTypeSpec eventTypes[4];
     1429        eventTypes[0].eventClass = kEventClassKeyboard;
     1430        eventTypes[0].eventKind  = kEventRawKeyDown;
     1431        eventTypes[1].eventClass = kEventClassKeyboard;
     1432        eventTypes[1].eventKind  = kEventRawKeyUp;
     1433        eventTypes[2].eventClass = kEventClassKeyboard;
     1434        eventTypes[2].eventKind  = kEventRawKeyRepeat;
     1435        eventTypes[3].eventClass = kEventClassKeyboard;
     1436        eventTypes[3].eventKind  = kEventRawKeyModifiersChanged;
     1437
     1438        EventHandlerUPP eventHandler = ::NewEventHandlerUPP (VBoxConsoleView::darwinEventHandlerProc);
     1439
     1440        m_darwinEventHandlerRef = NULL;
     1441        ::InstallApplicationEventHandler (eventHandler, RT_ELEMENTS (eventTypes), &eventTypes[0],
     1442                                          this, &m_darwinEventHandlerRef);
     1443        ::DisposeEventHandlerUPP (eventHandler);
     1444    }
     1445    else if (m_darwinEventHandlerRef)
     1446    {
     1447        ::RemoveEventHandler (m_darwinEventHandlerRef);
     1448        m_darwinEventHandlerRef = NULL;
     1449    }
     1450}
     1451
    12841452#endif
    12851453
     
    13961564 *  @scan       hardware scan code
    13971565 *  @flags      flags, a combination of Key* constants
     1566 *  @aUniKey    Unicode translation of the key. Optional.
    13981567 *
    13991568 *  @return     true to consume the event and false to pass it to Qt
    14001569 */
    1401 bool VBoxConsoleView::keyEvent (int key, uint8_t scan, int flags)
     1570bool VBoxConsoleView::keyEvent (int key, uint8_t scan, int flags, wchar_t *aUniKey/* = NULL*/)
    14021571{
    14031572//    char bbbuf[256];
     
    15891758            }
    15901759        }
     1760#elif defined (Q_WS_MAC)
     1761        if (aUniKey && aUniKey[0] && !aUniKey[1])
     1762            processed = processHotKey (QKeySequence (UNICODE_ACCEL +
     1763                                            QChar (aUniKey [0]).upper().unicode()),
     1764                                       mainwnd->menuBar());
    15911765#endif
    15921766        // grab the key from Qt if processed, or pass it to Qt otherwise
     
    19592133     * by QWidget::grabKeyboard()) because the latter causes problems under
    19602134     * metacity 2.16 (in particular, due to a bug, a window cannot be moved
    1961      * using the mouse if it is currently grabing the keyboard). */
     2135     * using the mouse if it is currently grabing the keyboard). On Mac OS X,
     2136     * we use the Qt methods + disabling global hot keys + watching modifiers
     2137     * (for right/left separation). */
    19622138#if defined (Q_WS_WIN32)
    19632139    /**/
     
    19702146                XUngrabKey (x11Display(),  AnyKey, AnyModifier,
    19712147                    topLevelWidget()->winId());
     2148#elif defined (Q_WS_MAC)
     2149    if (capture)
     2150    {
     2151        grabKeyboard();
     2152        ::DarwinGrabKeyboard (true);
     2153    }
     2154    else
     2155    {
     2156        ::DarwinReleaseKeyboard();
     2157        releaseKeyboard();
     2158    }
    19722159#else
    19732160    if (capture)
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp

    r1062 r1285  
    999999                        /*
    10001000                         *  set success to true even if we fail to discard the
    1001                          *  current state later -- the conosle window will be
     1001                         *  current state later -- the console window will be
    10021002                         *  closed anyway
    10031003                         */
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp

    r470 r1285  
    253253                                                  BOOL *aFinished)
    254254{
     255#ifdef Q_WS_MAC
     256    /* we're not on the GUI thread and update() isn't thread safe on Qt 3.3.x
     257       on the Mac (4.2.x is), so post the event instead.  */
     258    QApplication::postEvent (mView,
     259                             new VBoxRepaintEvent (aX, aY, aW, aH));
     260
     261#else /* !Q_WS_MAC */
    255262    /* we're not on the GUI thread, so update() instead of repaint()! */
    256263    mView->viewport()->update (aX - mView->contentsX(),
    257264                               aY - mView->contentsY(),
    258265                               aW, aH);
     266#endif /* !Q_WS_MAC */
    259267    /* the update has been finished, return TRUE */
    260268    *aFinished = TRUE;
  • trunk/src/VBox/Frontends/VirtualBox/src/VMGlobalSettings.cpp

    r382 r1285  
    4646    hostkey = 0xffe4; // XK_Control_R
    4747//    hostkey = 65514; // XK_Alt_R
     48#elif defined (Q_WS_MAC)
     49    hostkey = 0x36; // QZ_RMETA
     50//    hostkey = 0x3e; // QZ_RCTRL
     51//    hostkey = 0x3d; // QZ_RALT
    4852#else
     53# warning "port me!"
    4954    hostkey = 0;
    5055#endif
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