Changeset 846 for trunk/src/gui/kernel/qapplication_s60.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/kernel/qapplication_s60.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation ([email protected]) … … 63 63 #include "private/qmenubar_p.h" 64 64 #include "private/qsoftkeymanager_p.h" 65 66 67 65 68 66 69 #include "apgwgnam.h" // For CApaWindowGroupName 67 70 #include <mdaaudiotoneplayer.h> // For CMdaAudioToneUtility 68 71 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) 74 73 # include <private/qs60mainapplication_p.h> 75 74 # include <centralrepository.h> 76 75 # include "qs60mainappui.h" 76 77 78 79 80 81 82 77 83 #endif 78 84 … … 82 88 #include <hal_data.h> 83 89 90 91 92 93 84 94 QT_BEGIN_NAMESPACE 95 96 97 98 85 99 86 100 #if defined(QT_DEBUG) … … 101 115 { 102 116 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 103 168 } 104 169 … … 198 263 199 264 200 QHash<TInt, TUint> QApplicationPrivate::scanCodeCache;201 202 265 static Qt::KeyboardModifiers mapToQtModifiers(TUint s60Modifiers) 203 266 { … … 346 409 if (!desktop) 347 410 { 348 if (isWindowOwning or!qwidget->parentWidget())411 if (isWindowOwning !qwidget->parentWidget()) 349 412 CreateWindowL(S60->windowGroup()); 350 413 else … … 365 428 SetFocusing(true); 366 429 m_longTapDetector = QLongTapTimer::NewL(this); 430 367 431 368 432 DrawableWindow()->SetPointerGrab(ETrue); 369 433 } 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 370 462 } 371 463 372 464 QSymbianControl::~QSymbianControl() 373 465 { 466 467 468 469 374 470 if (S60->curWin == this) 375 471 S60->curWin = 0; … … 408 504 { 409 505 QApplicationPrivate *d = QApplicationPrivate::instance(); 506 410 507 qreal pressure; 411 508 if(d->pressureSupported … … 414 511 else 415 512 pressure = qreal(1.0); 416 513 processTouchEvent(event->PointerNumber(), event->iType, screenPos, pressure); 514 } 515 #endif 516 517 void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure) 518 { 417 519 QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget); 418 520 521 522 419 523 QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints; 420 while (points.count() <= event->PointerNumber())524 while (points.count() <= ) 421 525 points.append(QTouchEvent::TouchPoint(points.count())); 422 526 … … 425 529 QTouchEvent::TouchPoint &touchPoint = points[i]; 426 530 427 if (touchPoint.id() == event->PointerNumber()) {531 if (touchPoint.id() == ) { 428 532 Qt::TouchPointStates state; 429 switch ( event->iType) {533 switch (ype) { 430 534 case TPointerEvent::EButton1Down: 535 431 536 case TPointerEvent::EEnterHighPressure: 537 432 538 state = Qt::TouchPointPressed; 433 539 break; 434 540 case TPointerEvent::EButton1Up: 541 435 542 case TPointerEvent::EExitCloseProximity: 543 436 544 state = Qt::TouchPointReleased; 437 545 break; … … 444 552 break; 445 553 } 446 if ( event->PointerNumber()== 0)554 if ( == 0) 447 555 state |= Qt::TouchPointPrimary; 448 556 touchPoint.setState(state); 449 557 450 QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY));451 558 touchPoint.setScreenPos(screenPos); 452 559 touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), … … 473 580 points); 474 581 } 475 #endif476 582 477 583 void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) … … 547 653 #endif 548 654 655 656 657 658 659 660 661 549 662 sendMouseEvent(receiver, type, globalPos, button, modifiers); 550 663 } … … 594 707 TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type) 595 708 { 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 782 TKeyResponse 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 } 629 811 } 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 830 TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type) 831 { 634 832 #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) 660 874 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; 762 877 } 763 878 } 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 } 772 984 } 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 777 1005 return EKeyWasNotConsumed; 778 1006 } … … 806 1034 return EKeyWasConsumed; 807 1035 } 808 #endif // !defined(QT_NO_IM) && defined(Q_ WS_S60)1036 #endif // !defined(QT_NO_IM) && defined(Q_) 809 1037 810 1038 if (widget && qt_sendSpontaneousEvent(widget, keyEvent)) … … 844 1072 if (!topExtra->inExpose) { 845 1073 topExtra->inExpose = true; 1074 1075 1076 1077 1078 1079 1080 1081 846 1082 QRect exposeRect = qt_TRect2QRect(controlRect); 847 1083 qwidget->d_func()->syncBackingStore(exposeRect); … … 867 1103 868 1104 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 870 1115 CFbsBitmap *bitmap = s60Surface->symbianBitmap(); 871 1116 CWindowGc &gc = SystemGc(); 872 1117 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) { 874 1123 case QWExtra::Disable: 875 1124 // Do nothing 876 1125 break; 877 878 1126 case QWExtra::Blit: 879 1127 if (qwidget->d_func()->isOpaque) … … 881 1129 gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect); 882 1130 break; 883 884 1131 case QWExtra::ZeroFill: 885 if (Window().DisplayMode() == EColor16MA) { 1132 if (Window().DisplayMode() == EColor16MA 1133 || Window().DisplayMode() == Q_SYMBIAN_ECOLOR16MAP) { 886 1134 gc.SetBrushStyle(CGraphicsContext::ESolidBrush); 887 1135 gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); … … 893 1141 }; 894 1142 break; 895 896 1143 default: 897 1144 Q_ASSERT(false); … … 936 1183 tlwExtra->inTopLevelResize = false; 937 1184 } 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 } 940 1189 } 941 1190 } … … 996 1245 #ifdef Q_WS_S60 997 1246 // 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); 1008 1255 } 1009 1256 #endif 1010 1257 } 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; 1016 1276 } 1017 m_symbianPopupIsOpen = true; 1018 return; 1019 } 1020 1021 QApplication::setActiveWindow(0); 1277 1278 QApplication::setActiveWindow(0); 1279 } 1022 1280 } 1023 1281 // else { We don't touch the active window unless we were explicitly activated or deactivated } … … 1062 1320 { 1063 1321 handleClientAreaChange(); 1322 1323 1324 1064 1325 break; 1065 1326 } … … 1091 1352 // the top of the stack may randomly be assigned focus by Symbian, for example 1092 1353 // when creating new windows (specifically in CCoeAppUi::HandleStackChanged()). 1354 1355 1356 1357 1093 1358 if (focus) { 1094 1359 S60->appUi()->RemoveFromStack(this); … … 1111 1376 } 1112 1377 1378 1379 1380 1381 1382 1113 1383 /*! 1114 1384 \typedef QApplication::QS60MainApplicationFactory … … 1161 1431 TTrapHandler *origTrapHandler = User::TrapHandler(); 1162 1432 1163 // The S60 framework has not been init alized. We need to do it.1433 // The S60 framework has not been initalized. We need to do it. 1164 1434 TApaApplicationFactory factory(S60->s60ApplicationFactory ? 1165 1435 S60->s60ApplicationFactory : newS60Application); … … 1168 1438 // After this construction, CEikonEnv will be available from CEikonEnv::Static(). 1169 1439 // (much like our qApp). 1170 CEikonEnv* coe = new CEikonEnv;1440 EikonEnv; 1171 1441 //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there. 1172 1442 if(err == KErrNone) … … 1275 1545 } 1276 1546 } 1277 #endif 1278 1547 delete repository; 1548 repository = 0; 1549 #endif 1550 1551 #ifdef QT_KEYPAD_NAVIGATION 1279 1552 if (touch) { 1280 1553 QApplicationPrivate::navigationMode = Qt::NavigationModeNone; … … 1282 1555 QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional; 1283 1556 } 1557 1284 1558 1285 1559 #ifndef QT_NO_CURSOR … … 1314 1588 QApplicationPrivate::setSystemFont(systemFont); 1315 1589 1590 1591 1592 1593 1316 1594 /* 1317 1595 ### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag … … 1337 1615 1338 1616 // Register WId with the metatype system. This is to enable 1339 // QWidgetPrivate::create_sys to used delayed slot invo kation in order1617 // QWidgetPrivate::create_sys to used delayed slot invoation in order 1340 1618 // to destroy WId objects during reparenting. 1341 1619 qRegisterMetaType<WId>("WId"); 1342 1620 } 1621 1622 1343 1623 1344 1624 /***************************************************************************** … … 1352 1632 } 1353 1633 QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles 1634 1635 1636 1354 1637 // S60 structure and window server session are freed in eventdispatcher destructor as they are needed there 1355 1638 … … 1363 1646 S60->wsSession().SetPointerCursorMode(EPointerCursorNone); 1364 1647 1648 1649 1650 1651 1652 1653 1654 1365 1655 if (S60->qtOwnsS60Environment) { 1366 1656 // Restore the S60 framework trap handler. See qt_init(). … … 1398 1688 void QApplicationPrivate::enterModal_sys(QWidget *widget) 1399 1689 { 1690 1691 1692 1400 1693 if (widget) { 1401 1694 static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(ETrue); … … 1413 1706 void QApplicationPrivate::leaveModal_sys(QWidget *widget) 1414 1707 { 1708 1709 1710 1415 1711 if (widget) { 1416 1712 static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse); … … 1703 1999 return 1; 1704 2000 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); 1720 2005 return 1; 1721 2006 } … … 1735 2020 } 1736 2021 #endif 2022 2023 2024 1737 2025 break; 1738 2026 case EEventFocusLost: … … 1751 2039 #endif 1752 2040 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 1753 2091 default: 1754 2092 break; … … 1817 2155 break; 1818 2156 default: 2157 1819 2158 bool handled = QSoftKeyManager::handleCommand(command); 1820 2159 if (handled) 1821 2160 ret = 1; 1822 #ifdef Q_WS_S601823 2161 else 1824 2162 ret = QMenuBarPrivate::symbianCommands(command); … … 1916 2254 TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) 1917 2255 { 2256 2257 2258 2259 2260 1918 2261 if (keysym) { 1919 2262 // If keysym is specified, cache it. 1920 scanCodeCache.insert(scanCode, keysym);2263 scanCodeCache.insert(scanCode, keysym); 1921 2264 return keysym; 1922 2265 } else { 1923 2266 // If not, retrieve the cached version. 1924 return scanCodeCache[scanCode];2267 return scanCodeCache[scanCode]; 1925 2268 } 1926 2269 } … … 1933 2276 if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone) 1934 2277 maxTouchPressure = KMaxTInt; 2278 2279 2280 1935 2281 #endif 1936 2282 } … … 2039 2385 #endif // QT_NO_CURSOR 2040 2386 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 2041 2420 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.