Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/kernel/qapplication_s60.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation ([email protected])
     
    6363#include "private/qmenubar_p.h"
    6464#include "private/qsoftkeymanager_p.h"
     65
     66
     67
    6568
    6669#include "apgwgnam.h" // For CApaWindowGroupName
    6770#include <mdaaudiotoneplayer.h>     // For CMdaAudioToneUtility
    6871
    69 #if defined(Q_WS_S60)
    70 # if !defined(QT_NO_IM)
    71 #  include "qinputcontext.h"
    72 #  include <private/qcoefepinputcontext_p.h>
    73 # endif
     72#if defined(Q_OS_SYMBIAN)
    7473# include <private/qs60mainapplication_p.h>
    7574# include <centralrepository.h>
    7675# include "qs60mainappui.h"
     76
     77
     78
     79
     80
     81
     82
    7783#endif
    7884
     
    8288#include <hal_data.h>
    8389
     90
     91
     92
     93
    8494QT_BEGIN_NAMESPACE
     95
     96
     97
     98
    8599
    86100#if defined(QT_DEBUG)
     
    101115{
    102116    return qt_s60Data();
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
    103168}
    104169
     
    198263
    199264
    200 QHash<TInt, TUint> QApplicationPrivate::scanCodeCache;
    201 
    202265static Qt::KeyboardModifiers mapToQtModifiers(TUint s60Modifiers)
    203266{
     
    346409    if (!desktop)
    347410    {
    348         if (isWindowOwning or !qwidget->parentWidget())
     411        if (isWindowOwning !qwidget->parentWidget())
    349412            CreateWindowL(S60->windowGroup());
    350413        else
     
    365428        SetFocusing(true);
    366429        m_longTapDetector = QLongTapTimer::NewL(this);
     430
    367431
    368432        DrawableWindow()->SetPointerGrab(ETrue);
    369433    }
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
     458
     459
     460
     461
    370462}
    371463
    372464QSymbianControl::~QSymbianControl()
    373465{
     466
     467
     468
     469
    374470    if (S60->curWin == this)
    375471        S60->curWin = 0;
     
    408504{
    409505    QApplicationPrivate *d = QApplicationPrivate::instance();
     506
    410507    qreal pressure;
    411508    if(d->pressureSupported
     
    414511    else
    415512        pressure = qreal(1.0);
    416 
     513    processTouchEvent(event->PointerNumber(), event->iType, screenPos, pressure);
     514}
     515#endif
     516
     517void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure)
     518{
    417519    QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget);
    418520
     521
     522
    419523    QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints;
    420     while (points.count() <= event->PointerNumber())
     524    while (points.count() <= )
    421525        points.append(QTouchEvent::TouchPoint(points.count()));
    422526
     
    425529        QTouchEvent::TouchPoint &touchPoint = points[i];
    426530
    427         if (touchPoint.id() == event->PointerNumber()) {
     531        if (touchPoint.id() == ) {
    428532            Qt::TouchPointStates state;
    429             switch (event->iType) {
     533            switch (ype) {
    430534            case TPointerEvent::EButton1Down:
     535
    431536            case TPointerEvent::EEnterHighPressure:
     537
    432538                state = Qt::TouchPointPressed;
    433539                break;
    434540            case TPointerEvent::EButton1Up:
     541
    435542            case TPointerEvent::EExitCloseProximity:
     543
    436544                state = Qt::TouchPointReleased;
    437545                break;
     
    444552                break;
    445553            }
    446             if (event->PointerNumber() == 0)
     554            if ( == 0)
    447555                state |= Qt::TouchPointPrimary;
    448556            touchPoint.setState(state);
    449557
    450             QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY));
    451558            touchPoint.setScreenPos(screenPos);
    452559            touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
     
    473580                                                points);
    474581}
    475 #endif
    476582
    477583void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
     
    547653#endif
    548654
     655
     656
     657
     658
     659
     660
     661
    549662    sendMouseEvent(receiver, type, globalPos, button, modifiers);
    550663}
     
    594707TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type)
    595708{
    596     switch (type) {
    597     //case EEventKeyDown: // <-- Intentionally left out. See below.
    598     case EEventKeyUp:
    599     case EEventKey:
    600     {
    601         // S60 has a confusing way of delivering key events. There are three types of
    602         // events: EKeyEvent, EKeyEventDown and EKeyEventUp. When a key is pressed, the
    603         // two first events are generated. When releasing the key, the last one is
    604         // generated.
    605         // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp events,
    606         // we need to do some special tricks to map it to the Qt way. First, we completely
    607         // discard EKeyEventDown events, since they are redundant. Second, since
    608         // EKeyEventUp does not give us a keysym, we need to cache the keysyms from
    609         // the EKeyEvent events. This is what resolveS60ScanCode does.
    610 
    611 
    612         // ### hackish way to send Qt application to background when pressing right softkey
    613         /*
    614         if( keyEvent.iScanCode == EStdKeyDevice1 ) {
    615             S60->window_group->SetOrdinalPosition(-1);
    616             qApp->setActiveWindow(0);
    617             return EKeyWasNotConsumed;
    618         }
    619         */
    620 
    621         TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode,
    622                 keyEvent.iCode);
    623         int keyCode;
    624         if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
    625             keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
    626         } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
    627             // Normal characters keys.
    628             keyCode = s60Keysym;
     709    /*
     710      S60 has a confusing way of delivering key events. There are three types of
     711      events: EEventKey, EEventKeyDown and EEventKeyUp. When a key is pressed,
     712      EEventKeyDown is first generated, followed by EEventKey. Then, when the key is
     713      released, EEventKeyUp is generated.
     714      However, it is possible that only the EEventKey is generated alone, typically
     715      in relation to virtual keyboards. In that case we need to take care to
     716      generate both press and release events in Qt, since applications expect that.
     717      We do this by having three states for each used scan code, depending on the
     718      events received. See the switch below for what happens in each state
     719      transition.
     720    */
     721
     722    if (type != EEventKeyDown)
     723        if (handleVirtualMouse(keyEvent, type) == EKeyWasConsumed)
     724            return EKeyWasConsumed;
     725
     726    TKeyResponse ret = EKeyWasNotConsumed;
     727#define GET_RETURN(x) (ret = ((x) == EKeyWasConsumed) ? EKeyWasConsumed : ret)
     728
     729    // This top level switch corresponds to the states, and the inner switches
     730    // correspond to the transitions.
     731    QS60Data::ScanCodeState &scanCodeState = S60->scanCodeStates[keyEvent.iScanCode];
     732    switch (scanCodeState) {
     733    case QS60Data::Unpressed:
     734        switch (type) {
     735        case EEventKeyDown:
     736            scanCodeState = QS60Data::KeyDown;
     737            break;
     738        case EEventKey:
     739            GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
     740            GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
     741            break;
     742        case EEventKeyUp:
     743            // No action.
     744            break;
     745        }
     746        break;
     747    case QS60Data::KeyDown:
     748        switch (type) {
     749        case EEventKeyDown:
     750            // This should never happen, just stay in this state to be safe.
     751            break;
     752        case EEventKey:
     753            GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
     754            scanCodeState = QS60Data::KeyDownAndKey;
     755            break;
     756        case EEventKeyUp:
     757            scanCodeState = QS60Data::Unpressed;
     758            break;
     759        }
     760        break;
     761    case QS60Data::KeyDownAndKey:
     762        switch (type) {
     763        case EEventKeyDown:
     764            // This should never happen, just stay in this state to be safe.
     765            break;
     766        case EEventKey:
     767            GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
     768            GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
     769            break;
     770        case EEventKeyUp:
     771            GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
     772            scanCodeState = QS60Data::Unpressed;
     773            break;
     774        }
     775        break;
     776    }
     777    return ret;
     778
     779#undef GET_RETURN
     780}
     781
     782TKeyResponse QSymbianControl::sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type)
     783{
     784    // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp
     785    // events, we need to cache the keysyms from the EKeyEvent events. This is what
     786    // resolveS60ScanCode does.
     787    TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode,
     788            keyEvent.iCode);
     789    int keyCode;
     790    if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
     791        keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
     792    } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
     793        // Normal characters keys.
     794        keyCode = s60Keysym;
     795    } else {
     796        // Special S60 keys.
     797        keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym);
     798    }
     799
     800    Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
     801    QKeyEventEx qKeyEvent(type, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
     802            (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers);
     803    QWidget *widget;
     804    widget = QWidget::keyboardGrabber();
     805    if (!widget) {
     806        if (QApplicationPrivate::popupWidgets != 0) {
     807            widget = QApplication::activePopupWidget()->focusWidget();
     808            if (!widget) {
     809                widget = QApplication::activePopupWidget();
     810            }
    629811        } else {
    630             // Special S60 keys.
    631             keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym);
    632         }
    633 
     812            widget = QApplicationPrivate::focus_widget;
     813            if (!widget) {
     814                widget = qwidget;
     815            }
     816        }
     817    }
     818
     819    QEventDispatcherS60 *dispatcher;
     820    // It is theoretically possible for someone to install a different event dispatcher.
     821    if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) {
     822        if (dispatcher->excludeUserInputEvents()) {
     823            dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent));
     824            return EKeyWasConsumed;
     825        }
     826    }
     827    return sendKeyEvent(widget, &qKeyEvent);
     828}
     829
     830TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type)
     831{
    634832#ifndef QT_NO_CURSOR
    635         if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
    636             //translate keys to pointer
    637             if (keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down || keyCode == Qt::Key_Select) {
    638                 /*Explanation about virtualMouseAccel:
    639                  Tapping an arrow key allows precise pixel positioning
    640                  Holding an arrow key down, acceleration is applied to allow cursor
    641                  to be quickly moved to another part of the screen by key repeats.
    642                  */
    643                 if (S60->virtualMouseLastKey == keyCode) {
    644                     S60->virtualMouseAccel *= 2;
    645                     if (S60->virtualMouseAccel > S60->virtualMouseMaxAccel)
    646                         S60->virtualMouseAccel = S60->virtualMouseMaxAccel;
    647                 }
    648                 else
    649                     S60->virtualMouseAccel = 1;
    650                 S60->virtualMouseLastKey = keyCode;
    651 
    652                 QPoint pos = QCursor::pos();
    653                 TPointerEvent fakeEvent;
    654                 fakeEvent.iType = (TPointerEvent::TType)(-1);
    655                 TInt x = pos.x();
    656                 TInt y = pos.y();
    657                 if (type == EEventKeyUp) {
    658                     if (keyCode == Qt::Key_Select &&
    659                         (S60->virtualMousePressedKeys & QS60Data::Select))
     833    if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
     834        //translate keys to pointer
     835        if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) ||
     836                (keyEvent.iScanCode >= EStdKeyDevice10 && keyEvent.iScanCode <= EStdKeyDevice13) ||
     837                keyEvent.iScanCode == EStdKeyDevice3) {
     838            QPoint pos = QCursor::pos();
     839            TPointerEvent fakeEvent;
     840            fakeEvent.iType = (TPointerEvent::TType)(-1);
     841            fakeEvent.iModifiers = keyEvent.iModifiers;
     842            TInt x = pos.x();
     843            TInt y = pos.y();
     844            if (type == EEventKeyUp) {
     845                S60->virtualMouseAccelTimeout.start();
     846                switch (keyEvent.iScanCode) {
     847                case EStdKeyLeftArrow:
     848                    S60->virtualMousePressedKeys &= ~QS60Data::Left;
     849                    break;
     850                case EStdKeyRightArrow:
     851                    S60->virtualMousePressedKeys &= ~QS60Data::Right;
     852                    break;
     853                case EStdKeyUpArrow:
     854                    S60->virtualMousePressedKeys &= ~QS60Data::Up;
     855                    break;
     856                case EStdKeyDownArrow:
     857                    S60->virtualMousePressedKeys &= ~QS60Data::Down;
     858                    break;
     859                // diagonal keys (named aliases don't exist in 3.1 SDK)
     860                case EStdKeyDevice10:
     861                    S60->virtualMousePressedKeys &= ~QS60Data::LeftUp;
     862                    break;
     863                case EStdKeyDevice11:
     864                    S60->virtualMousePressedKeys &= ~QS60Data::RightUp;
     865                    break;
     866                case EStdKeyDevice12:
     867                    S60->virtualMousePressedKeys &= ~QS60Data::RightDown;
     868                    break;
     869                case EStdKeyDevice13:
     870                    S60->virtualMousePressedKeys &= ~QS60Data::LeftDown;
     871                    break;
     872                case EStdKeyDevice3: //select
     873                    if (S60->virtualMousePressedKeys & QS60Data::Select)
    660874                        fakeEvent.iType = TPointerEvent::EButton1Up;
    661                     S60->virtualMouseAccel = 1;
    662                     S60->virtualMouseLastKey = 0;
    663                     switch (keyCode) {
    664                     case Qt::Key_Left:
    665                         S60->virtualMousePressedKeys &= ~QS60Data::Left;
    666                         break;
    667                     case Qt::Key_Right:
    668                         S60->virtualMousePressedKeys &= ~QS60Data::Right;
    669                         break;
    670                     case Qt::Key_Up:
    671                         S60->virtualMousePressedKeys &= ~QS60Data::Up;
    672                         break;
    673                     case Qt::Key_Down:
    674                         S60->virtualMousePressedKeys &= ~QS60Data::Down;
    675                         break;
    676                     case Qt::Key_Select:
    677                         S60->virtualMousePressedKeys &= ~QS60Data::Select;
    678                         break;
    679                     }
    680                 }
    681                 else if (type == EEventKey) {
    682                     switch (keyCode) {
    683                     case Qt::Key_Left:
    684                         S60->virtualMousePressedKeys |= QS60Data::Left;
    685                         x -= S60->virtualMouseAccel;
    686                         fakeEvent.iType = TPointerEvent::EMove;
    687                         break;
    688                     case Qt::Key_Right:
    689                         S60->virtualMousePressedKeys |= QS60Data::Right;
    690                         x += S60->virtualMouseAccel;
    691                         fakeEvent.iType = TPointerEvent::EMove;
    692                         break;
    693                     case Qt::Key_Up:
    694                         S60->virtualMousePressedKeys |= QS60Data::Up;
    695                         y -= S60->virtualMouseAccel;
    696                         fakeEvent.iType = TPointerEvent::EMove;
    697                         break;
    698                     case Qt::Key_Down:
    699                         S60->virtualMousePressedKeys |= QS60Data::Down;
    700                         y += S60->virtualMouseAccel;
    701                         fakeEvent.iType = TPointerEvent::EMove;
    702                         break;
    703                     case Qt::Key_Select:
    704                         // Platform bug. If you start pressing several keys simultaneously (for
    705                         // example for drag'n'drop), Symbian starts producing spurious up and
    706                         // down messages for some keys. Therefore, make sure we have a clean slate
    707                         // of pressed keys before starting a new button press.
    708                         if (S60->virtualMousePressedKeys & QS60Data::Select) {
    709                             return EKeyWasConsumed;
    710                         } else {
    711                             S60->virtualMousePressedKeys |= QS60Data::Select;
    712                             fakeEvent.iType = TPointerEvent::EButton1Down;
    713                         }
    714                         break;
    715                     }
    716                 }
    717                 //clip to screen size (window server allows a sprite hotspot to be outside the screen)
    718                 if (x < 0)
    719                     x = 0;
    720                 else if (x >= S60->screenWidthInPixels)
    721                     x = S60->screenWidthInPixels - 1;
    722                 if (y < 0)
    723                     y = 0;
    724                 else if (y >= S60->screenHeightInPixels)
    725                     y = S60->screenHeightInPixels - 1;
    726                 TPoint epos(x, y);
    727                 TPoint cpos = epos - PositionRelativeToScreen();
    728                 fakeEvent.iModifiers = keyEvent.iModifiers;
    729                 fakeEvent.iPosition = cpos;
    730                 fakeEvent.iParentPosition = epos;
    731                 if(fakeEvent.iType != -1)
    732                     HandlePointerEvent(fakeEvent);
    733                 return EKeyWasConsumed;
    734             }
    735             else {
    736                 S60->virtualMouseLastKey = keyCode;
    737                 S60->virtualMouseAccel = 1;
    738             }
    739         }
    740 #endif
    741 
    742         Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
    743         QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode,
    744                 mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
    745                 (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers);
    746 //        WId wid = reinterpret_cast<RWindowGroup *>(keyEvent.Handle())->Child();
    747 //        if (!wid)
    748 //             Could happen if window isn't shown yet.
    749 //            return EKeyWasNotConsumed;
    750         QWidget *widget;
    751         widget = QWidget::keyboardGrabber();
    752         if (!widget) {
    753             if (QApplicationPrivate::popupWidgets != 0) {
    754                 widget = QApplication::activePopupWidget()->focusWidget();
    755                 if (!widget) {
    756                     widget = QApplication::activePopupWidget();
    757                 }
    758             } else {
    759                 widget = QApplicationPrivate::focus_widget;
    760                 if (!widget) {
    761                     widget = qwidget;
     875                    S60->virtualMousePressedKeys &= ~QS60Data::Select;
     876                    break;
    762877                }
    763878            }
    764         }
    765 
    766         QEventDispatcherS60 *dispatcher;
    767         // It is theoretically possible for someone to install a different event dispatcher.
    768         if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) {
    769             if (dispatcher->excludeUserInputEvents()) {
    770                 dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent));
    771                 return EKeyWasConsumed;
     879            else if (type == EEventKey) {
     880                int dx = 0;
     881                int dy = 0;
     882                if (keyEvent.iScanCode != EStdKeyDevice3) {
     883                    m_doubleClickTimer.invalidate();
     884                    //reset mouse accelleration after a short time with no moves
     885                    const int maxTimeBetweenKeyEventsMs = 500;
     886                    if (S60->virtualMouseAccelTimeout.isValid() &&
     887                            S60->virtualMouseAccelTimeout.hasExpired(maxTimeBetweenKeyEventsMs)) {
     888                        S60->virtualMouseAccelDX = 0;
     889                        S60->virtualMouseAccelDY = 0;
     890                    }
     891                    S60->virtualMouseAccelTimeout.invalidate();
     892                }
     893                switch (keyEvent.iScanCode) {
     894                case EStdKeyLeftArrow:
     895                    S60->virtualMousePressedKeys |= QS60Data::Left;
     896                    dx = -1;
     897                    fakeEvent.iType = TPointerEvent::EMove;
     898                    break;
     899                case EStdKeyRightArrow:
     900                    S60->virtualMousePressedKeys |= QS60Data::Right;
     901                    dx = 1;
     902                    fakeEvent.iType = TPointerEvent::EMove;
     903                    break;
     904                case EStdKeyUpArrow:
     905                    S60->virtualMousePressedKeys |= QS60Data::Up;
     906                    dy = -1;
     907                    fakeEvent.iType = TPointerEvent::EMove;
     908                    break;
     909                case EStdKeyDownArrow:
     910                    S60->virtualMousePressedKeys |= QS60Data::Down;
     911                    dy = 1;
     912                    fakeEvent.iType = TPointerEvent::EMove;
     913                    break;
     914                case EStdKeyDevice10:
     915                    S60->virtualMousePressedKeys |= QS60Data::LeftUp;
     916                    dx = -1;
     917                    dy = -1;
     918                    fakeEvent.iType = TPointerEvent::EMove;
     919                    break;
     920                case EStdKeyDevice11:
     921                    S60->virtualMousePressedKeys |= QS60Data::RightUp;
     922                    dx = 1;
     923                    dy = -1;
     924                    fakeEvent.iType = TPointerEvent::EMove;
     925                    break;
     926                case EStdKeyDevice12:
     927                    S60->virtualMousePressedKeys |= QS60Data::RightDown;
     928                    dx = 1;
     929                    dy = 1;
     930                    fakeEvent.iType = TPointerEvent::EMove;
     931                    break;
     932                case EStdKeyDevice13:
     933                    S60->virtualMousePressedKeys |= QS60Data::LeftDown;
     934                    dx = -1;
     935                    dy = 1;
     936                    fakeEvent.iType = TPointerEvent::EMove;
     937                    break;
     938                case EStdKeyDevice3:
     939                    // Platform bug. If you start pressing several keys simultaneously (for
     940                    // example for drag'n'drop), Symbian starts producing spurious up and
     941                    // down messages for some keys. Therefore, make sure we have a clean slate
     942                    // of pressed keys before starting a new button press.
     943                    if (S60->virtualMousePressedKeys & QS60Data::Select) {
     944                        return EKeyWasConsumed;
     945                    } else {
     946                        S60->virtualMousePressedKeys |= QS60Data::Select;
     947                        fakeEvent.iType = TPointerEvent::EButton1Down;
     948                        if (m_doubleClickTimer.isValid()
     949                                && !m_doubleClickTimer.hasExpired(QApplication::doubleClickInterval())) {
     950                            fakeEvent.iModifiers |= EModifierDoubleClick;
     951                            m_doubleClickTimer.invalidate();
     952                        } else {
     953                            m_doubleClickTimer.start();
     954                        }
     955                    }
     956                    break;
     957                }
     958                if (dx) {
     959                    int cdx = S60->virtualMouseAccelDX;
     960                    //reset accel on change of sign, else double accel
     961                    if (dx * cdx <= 0)
     962                        cdx = dx;
     963                    else
     964                        cdx *= 4;
     965                    //cap accelleration
     966                    if (dx * cdx > S60->virtualMouseMaxAccel)
     967                        cdx = dx * S60->virtualMouseMaxAccel;
     968                    //move mouse position
     969                    x += cdx;
     970                    S60->virtualMouseAccelDX = cdx;
     971                }
     972
     973                if (dy) {
     974                    int cdy = S60->virtualMouseAccelDY;
     975                    if (dy * cdy <= 0)
     976                        cdy = dy;
     977                    else
     978                        cdy *= 4;
     979                    if (dy * cdy > S60->virtualMouseMaxAccel)
     980                        cdy = dy * S60->virtualMouseMaxAccel;
     981                    y += cdy;
     982                    S60->virtualMouseAccelDY = cdy;
     983                }
    772984            }
    773         }
    774         return sendKeyEvent(widget, &qKeyEvent);
    775     }
    776     }
     985            //clip to screen size (window server allows a sprite hotspot to be outside the screen)
     986            if (x < 0)
     987                x = 0;
     988            else if (x >= S60->screenWidthInPixels)
     989                x = S60->screenWidthInPixels - 1;
     990            if (y < 0)
     991                y = 0;
     992            else if (y >= S60->screenHeightInPixels)
     993                y = S60->screenHeightInPixels - 1;
     994            TPoint epos(x, y);
     995            TPoint cpos = epos - PositionRelativeToScreen();
     996            fakeEvent.iPosition = cpos;
     997            fakeEvent.iParentPosition = epos;
     998            if(fakeEvent.iType != -1)
     999                HandlePointerEvent(fakeEvent);
     1000            return EKeyWasConsumed;
     1001        }
     1002    }
     1003#endif
     1004
    7771005    return EKeyWasNotConsumed;
    7781006}
     
    8061034            return EKeyWasConsumed;
    8071035    }
    808 #endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
     1036#endif // !defined(QT_NO_IM) && defined(Q_)
    8091037
    8101038    if (widget && qt_sendSpontaneousEvent(widget, keyEvent))
     
    8441072    if (!topExtra->inExpose) {
    8451073        topExtra->inExpose = true;
     1074
     1075
     1076
     1077
     1078
     1079
     1080
     1081
    8461082        QRect exposeRect = qt_TRect2QRect(controlRect);
    8471083        qwidget->d_func()->syncBackingStore(exposeRect);
     
    8671103
    8681104    if (engine->type() == QPaintEngine::Raster) {
    869         QS60WindowSurface *s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
     1105        QS60WindowSurface *s60Surface;
     1106#ifdef QT_GRAPHICSSYSTEM_RUNTIME
     1107        if (QApplicationPrivate::runtime_graphics_system) {
     1108            QRuntimeWindowSurface *rtSurface =
     1109                    static_cast<QRuntimeWindowSurface*>(qwidget->windowSurface());
     1110            s60Surface = static_cast<QS60WindowSurface *>(rtSurface->m_windowSurface.data());
     1111        } else
     1112#endif
     1113            s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
     1114
    8701115        CFbsBitmap *bitmap = s60Surface->symbianBitmap();
    8711116        CWindowGc &gc = SystemGc();
    8721117
    873         switch(qwidget->d_func()->extraData()->nativePaintMode) {
     1118        QWExtra::NativePaintMode nativePaintMode = qwidget->d_func()->extraData()->nativePaintMode;
     1119        if(qwidget->d_func()->paintOnScreen())
     1120            nativePaintMode = QWExtra::Disable;
     1121
     1122        switch(nativePaintMode) {
    8741123        case QWExtra::Disable:
    8751124            // Do nothing
    8761125            break;
    877 
    8781126        case QWExtra::Blit:
    8791127            if (qwidget->d_func()->isOpaque)
     
    8811129            gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
    8821130            break;
    883 
    8841131        case QWExtra::ZeroFill:
    885             if (Window().DisplayMode() == EColor16MA) {
     1132            if (Window().DisplayMode() == EColor16MA
     1133                || Window().DisplayMode() == Q_SYMBIAN_ECOLOR16MAP) {
    8861134                gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    8871135                gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
     
    8931141            };
    8941142            break;
    895 
    8961143        default:
    8971144            Q_ASSERT(false);
     
    9361183                tlwExtra->inTopLevelResize = false;
    9371184        } else {
    938             QResizeEvent *e = new QResizeEvent(newSize, oldSize);
    939             QApplication::postEvent(qwidget, e);
     1185            if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
     1186                QResizeEvent *e = new QResizeEvent(newSize, oldSize);
     1187                QApplication::postEvent(qwidget, e);
     1188            }
    9401189        }
    9411190    }
     
    9961245#ifdef Q_WS_S60
    9971246        // If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
    998         CEikStatusPane *statusPane = S60->statusPane();
    999         CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
    1000         TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
    1001         if (statusPane)
    1002             statusPane->MakeVisible(visible);
    1003         if (buttonGroup) {
    1004             // Visibility
    1005             const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
    1006             const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
    1007             buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint));
     1247        QWidget *const window = qwidget->window();
     1248        if (!window->parentWidget()) { // Only top level native windows have control over cba/status pane
     1249            const bool decorationsVisible = !(window->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
     1250            const bool statusPaneVisibility = decorationsVisible;
     1251            const bool isFullscreen = window->windowState() & Qt::WindowFullScreen;
     1252            const bool cbaVisibilityHint = window->windowFlags() & Qt::WindowSoftkeysVisibleHint;
     1253            const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaVisibilityHint));
     1254            S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
    10081255        }
    10091256#endif
    10101257    } else if (QApplication::activeWindow() == qwidget->window()) {
    1011         if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
    1012             QWidget *fw = QApplication::focusWidget();
    1013             if (fw) {
    1014                 QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
    1015                 QCoreApplication::sendEvent(fw, &event);
     1258        bool focusedControlFound = false;
     1259        WId winId = 0;
     1260        for (QWidget *w = qwidget->parentWidget(); w && (winId = w->internalWinId()); w = w->parentWidget()) {
     1261            if (winId->IsFocused() && winId->IsVisible()) {
     1262                focusedControlFound = true;
     1263                break;
     1264            } else if (w->isWindow())
     1265                break;
     1266        }
     1267        if (!focusedControlFound) {
     1268            if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
     1269                QWidget *fw = QApplication::focusWidget();
     1270                if (fw) {
     1271                    QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
     1272                    QCoreApplication::sendEvent(fw, &event);
     1273                }
     1274                m_symbianPopupIsOpen = true;
     1275                return;
    10161276            }
    1017             m_symbianPopupIsOpen = true;
    1018             return;
    1019         }
    1020 
    1021         QApplication::setActiveWindow(0);
     1277
     1278            QApplication::setActiveWindow(0);
     1279        }
    10221280    }
    10231281    // else { We don't touch the active window unless we were explicitly activated or deactivated }
     
    10621320    {
    10631321        handleClientAreaChange();
     1322
     1323
     1324
    10641325        break;
    10651326    }
     
    10911352    // the top of the stack may randomly be assigned focus by Symbian, for example
    10921353    // when creating new windows (specifically in CCoeAppUi::HandleStackChanged()).
     1354
     1355
     1356
     1357
    10931358    if (focus) {
    10941359        S60->appUi()->RemoveFromStack(this);
     
    11111376}
    11121377
     1378
     1379
     1380
     1381
     1382
    11131383/*!
    11141384    \typedef QApplication::QS60MainApplicationFactory
     
    11611431        TTrapHandler *origTrapHandler = User::TrapHandler();
    11621432
    1163         // The S60 framework has not been initalized. We need to do it.
     1433        // The S60 framework has not been initalized. We need to do it.
    11641434        TApaApplicationFactory factory(S60->s60ApplicationFactory ?
    11651435                S60->s60ApplicationFactory : newS60Application);
     
    11681438        // After this construction, CEikonEnv will be available from CEikonEnv::Static().
    11691439        // (much like our qApp).
    1170         CEikonEnv* coe = new CEikonEnv;
     1440        EikonEnv;
    11711441        //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
    11721442        if(err == KErrNone)
     
    12751545        }
    12761546    }
    1277 #endif
    1278 
     1547    delete repository;
     1548    repository = 0;
     1549#endif
     1550
     1551#ifdef QT_KEYPAD_NAVIGATION
    12791552    if (touch) {
    12801553        QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
     
    12821555        QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
    12831556    }
     1557
    12841558
    12851559#ifndef QT_NO_CURSOR
     
    13141588    QApplicationPrivate::setSystemFont(systemFont);
    13151589
     1590
     1591
     1592
     1593
    13161594/*
    13171595 ### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
     
    13371615
    13381616    // Register WId with the metatype system.  This is to enable
    1339     // QWidgetPrivate::create_sys to used delayed slot invokation in order
     1617    // QWidgetPrivate::create_sys to used delayed slot invoation in order
    13401618    // to destroy WId objects during reparenting.
    13411619    qRegisterMetaType<WId>("WId");
    13421620}
     1621
     1622
    13431623
    13441624/*****************************************************************************
     
    13521632    }
    13531633    QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles
     1634
     1635
     1636
    13541637// S60 structure and window server session are freed in eventdispatcher destructor as they are needed there
    13551638
     
    13631646    S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
    13641647
     1648
     1649
     1650
     1651
     1652
     1653
     1654
    13651655    if (S60->qtOwnsS60Environment) {
    13661656        // Restore the S60 framework trap handler. See qt_init().
     
    13981688void QApplicationPrivate::enterModal_sys(QWidget *widget)
    13991689{
     1690
     1691
     1692
    14001693    if (widget) {
    14011694        static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(ETrue);
     
    14131706void QApplicationPrivate::leaveModal_sys(QWidget *widget)
    14141707{
     1708
     1709
     1710
    14151711    if (widget) {
    14161712        static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse);
     
    17031999                return 1;
    17042000            const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
    1705             QWidget *w = QWidgetPrivate::mapper->value(control);
    1706             if (!w->d_func()->maybeTopData())
    1707                 break;
    1708             if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
    1709                 delete w->d_func()->topData()->backingStore;
    1710                 w->d_func()->topData()->backingStore = 0;
    1711                 // In order to ensure that any resources used by the window surface
    1712                 // are immediately freed, we flush the WSERV command buffer.
    1713                 S60->wsSession().Flush();
    1714             } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
    1715                        && !w->d_func()->maybeBackingStore()) {
    1716                 w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);
    1717                 w->d_func()->invalidateBuffer(w->rect());
    1718                 w->repaint();
    1719             }
     2001            if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible)
     2002                S60->controlVisibilityChanged(control, false);
     2003            else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
     2004                S60->controlVisibilityChanged(control, true);
    17202005            return 1;
    17212006        }
     
    17352020        }
    17362021#endif
     2022
     2023
     2024
    17372025        break;
    17382026    case EEventFocusLost:
     
    17512039#endif
    17522040        break;
     2041
     2042
     2043
     2044
     2045
     2046
     2047
     2048
     2049
     2050
     2051
     2052
     2053
     2054
     2055
     2056
     2057
     2058
     2059
     2060
     2061
     2062
     2063
     2064
     2065
     2066
     2067
     2068
     2069
     2070
     2071
     2072
     2073
     2074
     2075
     2076
     2077
     2078
     2079
     2080
     2081
     2082
     2083
     2084
     2085
     2086
     2087
     2088
     2089
     2090
    17532091    default:
    17542092        break;
     
    18172155        break;
    18182156    default:
     2157
    18192158        bool handled = QSoftKeyManager::handleCommand(command);
    18202159        if (handled)
    18212160            ret = 1;
    1822 #ifdef Q_WS_S60
    18232161        else
    18242162            ret = QMenuBarPrivate::symbianCommands(command);
     
    19162254TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym)
    19172255{
     2256
     2257
     2258
     2259
     2260
    19182261    if (keysym) {
    19192262        // If keysym is specified, cache it.
    1920         scanCodeCache.insert(scanCode, keysym);
     2263        scanCodeCache.insert(scanCode, keysym);
    19212264        return keysym;
    19222265    } else {
    19232266        // If not, retrieve the cached version.
    1924         return scanCodeCache[scanCode];
     2267        return scanCodeCache[scanCode];
    19252268    }
    19262269}
     
    19332276    if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone)
    19342277        maxTouchPressure = KMaxTInt;
     2278
     2279
     2280
    19352281#endif
    19362282}
     
    20392385#endif // QT_NO_CURSOR
    20402386
     2387
     2388
     2389
     2390
     2391
     2392
     2393
     2394
     2395
     2396
     2397
     2398
     2399
     2400
     2401
     2402
     2403
     2404
     2405
     2406
     2407
     2408
     2409
     2410
     2411
     2412
     2413
     2414
     2415
     2416
     2417
     2418
     2419
    20412420QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.