summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qpixmap_s60.cpp10
-rw-r--r--src/gui/kernel/qapplication.cpp90
-rw-r--r--src/gui/kernel/qapplication.h4
-rw-r--r--src/gui/kernel/qapplication_p.h16
-rw-r--r--src/gui/kernel/qapplication_s60.cpp307
-rw-r--r--src/gui/kernel/qapplication_x11.cpp2
-rw-r--r--src/gui/kernel/qcursor.h18
-rw-r--r--src/gui/kernel/qcursor_p.h14
-rw-r--r--src/gui/kernel/qcursor_qws.cpp2
-rw-r--r--src/gui/kernel/qcursor_s60.cpp471
-rw-r--r--src/gui/kernel/qcursor_win.cpp2
-rw-r--r--src/gui/kernel/qcursor_x11.cpp3
-rw-r--r--src/gui/kernel/qdnd_p.h7
-rw-r--r--src/gui/kernel/qdnd_s60.cpp148
-rw-r--r--src/gui/kernel/qt_s60_p.h23
-rw-r--r--src/gui/kernel/qwidget.cpp1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp77
-rw-r--r--src/gui/kernel/qwidget_win.cpp2
-rw-r--r--src/gui/kernel/symbian.pri1
-rw-r--r--src/gui/symbian/images/blank.pngbin0 -> 91 bytes
-rw-r--r--src/gui/symbian/images/busy12.pngbin0 -> 253 bytes
-rw-r--r--src/gui/symbian/images/busy3.pngbin0 -> 251 bytes
-rw-r--r--src/gui/symbian/images/busy6.pngbin0 -> 253 bytes
-rw-r--r--src/gui/symbian/images/busy9.pngbin0 -> 255 bytes
-rw-r--r--src/gui/symbian/images/closehand.pngbin0 -> 190 bytes
-rw-r--r--src/gui/symbian/images/cross.pngbin0 -> 145 bytes
-rw-r--r--src/gui/symbian/images/forbidden.pngbin0 -> 256 bytes
-rw-r--r--src/gui/symbian/images/handpoint.pngbin0 -> 230 bytes
-rw-r--r--src/gui/symbian/images/ibeam.pngbin0 -> 176 bytes
-rw-r--r--src/gui/symbian/images/openhand.pngbin0 -> 201 bytes
-rw-r--r--src/gui/symbian/images/pointer.pngbin0 -> 222 bytes
-rw-r--r--src/gui/symbian/images/sizeall.pngbin0 -> 188 bytes
-rw-r--r--src/gui/symbian/images/sizebdiag.pngbin0 -> 192 bytes
-rw-r--r--src/gui/symbian/images/sizefdiag.pngbin0 -> 197 bytes
-rw-r--r--src/gui/symbian/images/sizehor.pngbin0 -> 175 bytes
-rw-r--r--src/gui/symbian/images/sizever.pngbin0 -> 171 bytes
-rw-r--r--src/gui/symbian/images/splith.pngbin0 -> 206 bytes
-rw-r--r--src/gui/symbian/images/splitv.pngbin0 -> 205 bytes
-rw-r--r--src/gui/symbian/images/uparrow.pngbin0 -> 157 bytes
-rw-r--r--src/gui/symbian/images/wait1.pngbin0 -> 219 bytes
-rw-r--r--src/gui/symbian/images/wait10.pngbin0 -> 220 bytes
-rw-r--r--src/gui/symbian/images/wait11.pngbin0 -> 220 bytes
-rw-r--r--src/gui/symbian/images/wait12.pngbin0 -> 213 bytes
-rw-r--r--src/gui/symbian/images/wait2.pngbin0 -> 219 bytes
-rw-r--r--src/gui/symbian/images/wait3.pngbin0 -> 210 bytes
-rw-r--r--src/gui/symbian/images/wait4.pngbin0 -> 215 bytes
-rw-r--r--src/gui/symbian/images/wait5.pngbin0 -> 217 bytes
-rw-r--r--src/gui/symbian/images/wait6.pngbin0 -> 213 bytes
-rw-r--r--src/gui/symbian/images/wait7.pngbin0 -> 215 bytes
-rw-r--r--src/gui/symbian/images/wait8.pngbin0 -> 217 bytes
-rw-r--r--src/gui/symbian/images/wait9.pngbin0 -> 209 bytes
-rw-r--r--src/gui/symbian/images/whatsthis.pngbin0 -> 254 bytes
-rw-r--r--src/gui/symbian/symbianresources.qrc37
53 files changed, 1065 insertions, 170 deletions
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index 493e440..666e557 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -178,7 +178,12 @@ CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
return 0;
}
- const QImage converted = img.convertToFormat(destFormat);
+ QImage converted = img.convertToFormat(destFormat);
+
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ if (mode == EGray2)
+ converted.invertPixels();
bitmap->LockHeap();
const uchar *sptr = converted.bits();
@@ -220,6 +225,9 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
image.setNumColors(2);
image.setColor(0, QColor(Qt::color0).rgba());
image.setColor(1, QColor(Qt::color1).rgba());
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ image.invertPixels();
} else if (displayMode == EGray256) {
for (int i=0; i < 256; ++i)
image.setColor(i, qRgb(i, i, i));
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index a19e022..1fd2d39 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -458,10 +458,10 @@ bool QApplicationPrivate::widgetCount = false;
bool QApplicationPrivate::inSizeMove = false;
#endif
#ifdef QT_KEYPAD_NAVIGATION
-# if defined(Q_OS_SYMBIAN)
-bool QApplicationPrivate::keypadNavigation = true;
+# ifdef Q_OS_SYMBIAN
+Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
# else
-bool QApplicationPrivate::keypadNavigation = false;
+Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder;
# endif
QWidget *QApplicationPrivate::oldEditFocus = 0;
#endif
@@ -2521,12 +2521,6 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
Creates the proper Enter/Leave event when widget \a enter is entered and
widget \a leave is left.
*/
-#if defined(Q_WS_WIN)
- extern void qt_win_set_cursor(QWidget *, bool);
-#elif defined(Q_WS_X11)
- extern void qt_x11_enforce_cursor(QWidget *, bool);
-#endif
-
void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
#if 0
if (leave) {
@@ -2676,6 +2670,8 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
qt_win_set_cursor(cursorWidget, true);
#elif defined(Q_WS_X11)
qt_x11_enforce_cursor(cursorWidget, true);
+#elif defined(Q_WS_S60)
+ qt_symbian_set_cursor(cursorWidget, true);
#endif
}
}
@@ -4777,10 +4773,36 @@ void QApplicationPrivate::emitLastWindowClosed()
#ifdef QT_KEYPAD_NAVIGATION
/*!
- Sets whether Qt should use focus navigation suitable for use with a
- minimal keypad.
+ Sets what kind of focus navigation Qt should use.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \note On Symbian, setting the mode to Qt::NavigationModeCursorAuto will enable a
+ virtual mouse cursor on non touchscreen devices, which is controlled
+ by the cursor keys if there is no analog pointer device.
+ On other platforms and on touchscreen devices, it has the same
+ meaning as Qt::NavigationModeNone.
+
+ \since 4.6
+
+ \sa keypadNavigationEnabled()
+*/
+void QApplication::setNavigationMode(Qt::NavigationMode mode)
+{
+#ifdef Q_OS_SYMBIAN
+ QApplicationPrivate::setNavigationMode(mode);
+#else
+ QApplicationPrivate::navigationMode = mode;
+#endif
+}
- If \a enable is true, Qt::Key_Up and Qt::Key_Down are used to change focus.
+/*!
+ Returns what kind of focus navigation Qt is using.
This feature is available in Qt for Embedded Linux, Symbian and Windows CE
only.
@@ -4788,12 +4810,47 @@ void QApplicationPrivate::emitLastWindowClosed()
\note On Windows CE this feature is disabled by default for touch device
mkspecs. To enable keypad navigation, build Qt with
QT_KEYPAD_NAVIGATION defined.
+
+ \note On Symbian, the default mode is Qt::NavigationModeNone for touch
+ devices, and Qt::NavigationModeKeypadDirectional.
+
+ \since 4.6
\sa keypadNavigationEnabled()
*/
+Qt::NavigationMode QApplication::navigationMode()
+{
+ return QApplicationPrivate::navigationMode;
+}
+
+/*!
+ Sets whether Qt should use focus navigation suitable for use with a
+ minimal keypad.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \deprecated
+
+ \sa setNavigationMode()
+*/
void QApplication::setKeypadNavigationEnabled(bool enable)
{
- QApplicationPrivate::keypadNavigation = enable;
+ if (enable) {
+#ifdef Q_OS_SYMBIAN
+ QApplication::setNavigationMode(Qt::NavigationModeKeypadDirectional);
+#else
+ QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder);
+#endif
+ }
+ else {
+ QApplication::setNavigationMode(Qt::NavigationModeNone);
+ }
}
/*!
@@ -4806,12 +4863,15 @@ void QApplication::setKeypadNavigationEnabled(bool enable)
\note On Windows CE this feature is disabled by default for touch device
mkspecs. To enable keypad navigation, build Qt with
QT_KEYPAD_NAVIGATION defined.
+
+ \deprecated
- \sa setKeypadNavigationEnabled()
+ \sa navigationMode()
*/
bool QApplication::keypadNavigationEnabled()
{
- return QApplicationPrivate::keypadNavigation;
+ return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
+ QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
}
#endif
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 216cfff..0562251 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -272,8 +272,10 @@ public:
static bool quitOnLastWindowClosed();
#ifdef QT_KEYPAD_NAVIGATION
- static void setKeypadNavigationEnabled(bool);
+ static Q_DECL_DEPRECATED void setKeypadNavigationEnabled(bool);
static bool keypadNavigationEnabled();
+ static void setNavigationMode(Qt::NavigationMode mode);
+ static Qt::NavigationMode navigationMode();
#endif
Q_SIGNALS:
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index c33eb1a..707caaa 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -71,6 +71,9 @@
#include "QtGui/qscreen_qws.h"
#include <private/qgraphicssystem_qws_p.h>
#endif
+#ifdef Q_OS_SYMBIAN
+#include <w32std.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -492,8 +495,8 @@ public:
static int app_compile_version;
#ifdef QT_KEYPAD_NAVIGATION
- static bool keypadNavigation;
static QWidget *oldEditFocus;
+ static Qt::NavigationMode navigationMode;
#endif
#if defined(Q_WS_MAC) || defined(Q_WS_X11)
@@ -511,7 +514,9 @@ public:
QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
bool spontaneous = true);
#ifdef Q_OS_SYMBIAN
+ static void setNavigationMode(Qt::NavigationMode mode);
static TUint resolveS60ScanCode(TInt scanCode, TUint keysym);
+ QSet<WId> nativeWindows;
#endif
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
void sendSyntheticEnterLeave(QWidget *widget);
@@ -595,6 +600,15 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
QTouchEvent::DeviceType deviceType,
const QList<QTouchEvent::TouchPoint> &touchPoints);
+#if defined(Q_WS_WIN)
+ extern void qt_win_set_cursor(QWidget *, bool);
+#elif defined(Q_WS_X11)
+ extern void qt_x11_enforce_cursor(QWidget *, bool);
+ extern void qt_x11_enforce_cursor(QWidget *);
+#elif defined(Q_OS_SYMBIAN)
+ extern void qt_symbian_set_cursor(QWidget *, bool);
+#endif
+
QT_END_NAMESPACE
#endif // QAPPLICATION_P_H
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 00932a0..fd889fc 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -73,6 +73,9 @@
#include "private/qstylesheetstyle_p.h"
+#include <hal.h>
+#include <hal_data.h>
+
QT_BEGIN_NAMESPACE
#if defined(QT_DEBUG)
@@ -151,21 +154,21 @@ void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
void QS60Beep::Play()
{
- if(iState!=EBeepNotPrepared){
- if(iState==EBeepPlaying) {
+ if (iState != EBeepNotPrepared) {
+ if (iState == EBeepPlaying) {
iToneUtil->CancelPlay();
- iState=EBeepPrepared;
+ iState = EBeepPrepared;
}
}
iToneUtil->Play();
- iState=EBeepPlaying;
+ iState = EBeepPlaying;
}
void QS60Beep::MatoPrepareComplete(TInt aError)
{
- if(aError==KErrNone) {
- iState=EBeepPrepared;
+ if (aError == KErrNone) {
+ iState = EBeepPrepared;
}
}
@@ -320,8 +323,9 @@ void QSymbianControl::ConstructL(bool topLevel, bool desktop)
{
if (!desktop)
{
- if (topLevel)
+ if (topLevel) {
CreateWindowL(S60->windowGroup());
+ }
SetFocusing(true);
m_longTapDetector = QLongTapTimer::NewL(this);
@@ -330,6 +334,8 @@ void QSymbianControl::ConstructL(bool topLevel, bool desktop)
QSymbianControl::~QSymbianControl()
{
+ if (S60->curWin == this)
+ S60->curWin = 0;
S60->appUi()->RemoveFromStack(this);
delete m_longTapDetector;
}
@@ -392,14 +398,15 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
- if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick)
+ if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove)
{
- // get the button press target
+ // get the widget where the event happened
alienWidget = qwidget->childAt(widgetPos);
if (!alienWidget)
alienWidget = qwidget;
S60->mousePressTarget = alienWidget;
}
+
alienWidget = S60->mousePressTarget;
if (alienWidget != S60->lastPointerEventTarget)
@@ -412,12 +419,30 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers));
events.append(Event(S60->lastPointerEventTarget,mEventLeave));
}
- QMouseEvent mEventEnter(QEvent::Enter, alienWidget->mapFromGlobal(globalPos), globalPos,
- button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers));
-
- events.append(Event(alienWidget,mEventEnter));
+ if (alienWidget) {
+ QMouseEvent mEventEnter(QEvent::Enter, alienWidget->mapFromGlobal(globalPos),
+ globalPos, button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(
+ pEvent.iModifiers));
+
+ events.append(Event(alienWidget, mEventEnter));
+#ifndef QT_NO_CURSOR
+ S60->curWin = alienWidget->effectiveWinId();
+ if (!QApplication::overrideCursor()) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_set_pointer_sprite(alienWidget->cursor());
+ else
+#endif
+ qt_symbian_setWindowCursor(alienWidget->cursor(), S60->curWin);
+ }
+#endif
+ }
}
S60->lastCursorPos = globalPos;
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_move_cursor_sprite();
+#endif
S60->lastPointerEventPos = widgetPos;
S60->lastPointerEventTarget = alienWidget;
if (alienWidget)
@@ -494,6 +519,82 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
// Special S60 keys.
keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym);
}
+
+#ifndef QT_NO_CURSOR
+ if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
+ //translate keys to pointer
+ if (keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down || keyCode == Qt::Key_Select) {
+ /*Explanation about virtualMouseAccel:
+ Tapping an arrow key allows precise pixel positioning
+ Holding an arrow key down, acceleration is applied to allow cursor
+ to be quickly moved to another part of the screen by key repeats.
+ */
+ if (S60->virtualMouseLastKey == keyCode) {
+ S60->virtualMouseAccel *= 2;
+ if (S60->virtualMouseAccel > S60->virtualMouseMaxAccel)
+ S60->virtualMouseAccel = S60->virtualMouseMaxAccel;
+ }
+ else
+ S60->virtualMouseAccel = 1;
+ S60->virtualMouseLastKey = keyCode;
+
+ QPoint pos = QCursor::pos();
+ TPointerEvent fakeEvent;
+ TInt x = pos.x();
+ TInt y = pos.y();
+ if (type == EEventKeyUp) {
+ if (keyCode == Qt::Key_Select)
+ fakeEvent.iType = TPointerEvent::EButton1Up;
+ S60->virtualMouseAccel = 1;
+ S60->virtualMouseLastKey = 0;
+ }
+ else if (type == EEventKey) {
+ switch (keyCode) {
+ case Qt::Key_Left:
+ x -= S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Right:
+ x += S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Up:
+ y -= S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Down:
+ y += S60->virtualMouseAccel;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case Qt::Key_Select:
+ fakeEvent.iType = TPointerEvent::EButton1Down;
+ break;
+ }
+ }
+ //clip to screen size (window server allows a sprite hotspot to be outside the screen)
+ if (x < 0)
+ x = 0;
+ else if (x >= S60->screenWidthInPixels)
+ x = S60->screenWidthInPixels - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= S60->screenHeightInPixels)
+ y = S60->screenHeightInPixels - 1;
+ TPoint epos(x, y);
+ TPoint cpos = epos - PositionRelativeToScreen();
+ fakeEvent.iModifiers = keyEvent.iModifiers;
+ fakeEvent.iPosition = cpos;
+ fakeEvent.iParentPosition = epos;
+ HandlePointerEvent(fakeEvent);
+ return EKeyWasConsumed;
+ }
+ else {
+ S60->virtualMouseLastKey = keyCode;
+ S60->virtualMouseAccel = 1;
+ }
+ }
+#endif
+
Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode,
mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
@@ -557,7 +658,7 @@ TKeyResponse QSymbianControl::sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent)
#if !defined(QT_NO_IM) && defined(Q_WS_S60)
if (widget && widget->isEnabled() && widget->testAttribute(Qt::WA_InputMethodEnabled)) {
QInputContext *qic = widget->inputContext();
- if(qic && qic->filterEvent(keyEvent))
+ if (qic && qic->filterEvent(keyEvent))
return EKeyWasConsumed;
}
#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
@@ -574,11 +675,10 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const
{
QWidget *w = 0;
- if(qwidget->hasFocus()) {
+ if (qwidget->hasFocus())
w = qwidget;
- } else {
+ else
w = qwidget->focusWidget();
- }
QCoeFepInputContext *ic;
if (w && w->isEnabled() && w->testAttribute(Qt::WA_InputMethodEnabled)
@@ -749,6 +849,70 @@ void qt_init(QApplicationPrivate * /* priv */, int)
TSecureId securId = me.SecureId();
S60->uid = securId.operator TUid();
+ // enable focus events - used to re-enable mouse after focus changed between mouse and non mouse app,
+ // and for dimming behind modal windows
+ S60->windowGroup().EnableFocusChangeEvents();
+
+ //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
+ const TInt KMachineUidSamsungI8510 = 0x2000C51E;
+ const TInt KMachineUidSamsungI550 = 0x2000A678;
+ TInt machineUID;
+ TInt mouse;
+ TInt touch;
+ TInt err;
+ err = HAL::Get(HALData::EMouse, mouse);
+ if (err != KErrNone)
+ mouse = 0;
+ err = HAL::Get(HALData::EMachineUid, machineUID);
+ if (err != KErrNone)
+ machineUID = 0;
+ err = HAL::Get(HALData::EPen, touch);
+ if (err != KErrNone)
+ touch = 0;
+ if (mouse || machineUID == KMachineUidSamsungI8510) {
+ S60->hasTouchscreen = false;
+ S60->virtualMouseRequired = false;
+ }
+ else if (!touch) {
+ S60->hasTouchscreen = false;
+ S60->virtualMouseRequired = true;
+ }
+ else {
+ S60->hasTouchscreen = true;
+ S60->virtualMouseRequired = false;
+ }
+
+ if (touch) {
+ QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
+ } else {
+ QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
+ }
+
+ //Check if window server pointer cursors are supported or not
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ //In generic binary, use the HAL and OS version
+ //Any other known good phones should be added here.
+ if (machineUID == KMachineUidSamsungI8510 || (QSysInfo::symbianVersion() != QSysInfo::SV_9_4
+ && QSysInfo::symbianVersion() != QSysInfo::SV_9_3 && QSysInfo::symbianVersion()
+ != QSysInfo::SV_9_2)) {
+ S60->brokenPointerCursors = false;
+ qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
+ }
+ else
+ S60->brokenPointerCursors = true;
+#endif
+
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(Qt::ArrowCursor);
+ qt_symbian_show_pointer_sprite();
+ }
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ }
+
/*
### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
int argc = priv->argc;
@@ -785,6 +949,9 @@ void qt_cleanup()
// it dies.
delete QApplicationPrivate::inputContext;
QApplicationPrivate::inputContext = 0;
+
+ //Change mouse pointer back
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
if (S60->qtOwnsS60Environment) {
CEikonEnv* coe = CEikonEnv::Static();
@@ -1016,9 +1183,8 @@ void QApplication::beep()
TTimeIntervalMicroSeconds duration(500000);
QS60Beep* beep=NULL;
TRAPD(err, beep=QS60Beep::NewL(frequency, duration));
- if(!err) {
+ if (!err)
beep->Play();
- }
delete beep;
beep=NULL;
}
@@ -1108,7 +1274,31 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
return 1;
}
break;
- default:
+ case EEventFocusGained:
+ RDebug::Printf("focus gained %x", control);
+ //re-enable mouse interaction
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_show_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ }
+ break;
+ case EEventFocusLost:
+ RDebug::Printf("focus lost %x", control);
+ //disable mouse as may be moving to application that does not support it
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_hide_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
+ }
+ break;
+ default:
break;
}
@@ -1279,4 +1469,81 @@ void QSessionManager::cancel()
}
#endif //QT_NO_SESSIONMANAGER
+
+#ifdef QT_KEYPAD_NAVIGATION
+/*
+ * Show/Hide the mouse cursor depending on phone type and chosen mode
+ */
+void QApplicationPrivate::setNavigationMode(Qt::NavigationMode mode)
+{
+#ifndef QT_NO_CURSOR
+ const bool wasCursorOn = (QApplicationPrivate::navigationMode == Qt::NavigationModeCursorAuto
+ && !S60->hasTouchscreen)
+ || QApplicationPrivate::navigationMode == Qt::NavigationModeCursorForceVisible;
+ const bool isCursorOn = (mode == Qt::NavigationModeCursorAuto
+ && !S60->hasTouchscreen)
+ || mode == Qt::NavigationModeCursorForceVisible;
+
+ if (!wasCursorOn && isCursorOn) {
+ //Show the cursor, when changing from another mode to cursor mode
+ qt_symbian_set_cursor_visible(true);
+ }
+ else if (wasCursorOn && !isCursorOn) {
+ //Hide the cursor, when leaving cursor mode
+ qt_symbian_set_cursor_visible(false);
+ }
+#endif
+ QApplicationPrivate::navigationMode = mode;
+}
+#endif
+
+#ifndef QT_NO_CURSOR
+/*****************************************************************************
+ QApplication cursor stack
+ *****************************************************************************/
+
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qApp->d_func()->cursor_list.prepend(cursor);
+ qt_symbian_setGlobalCursor(cursor);
+}
+
+void QApplication::restoreOverrideCursor()
+{
+ if (qApp->d_func()->cursor_list.isEmpty())
+ return;
+ qApp->d_func()->cursor_list.removeFirst();
+
+ if (!qApp->d_func()->cursor_list.isEmpty()) {
+ qt_symbian_setGlobalCursor(qApp->d_func()->cursor_list.first());
+ }
+ else {
+ //determine which widget has focus
+ QWidget *w = QApplication::widgetAt(QCursor::pos());
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(w ? w->cursor() : Qt::ArrowCursor);
+ }
+ else
+#endif
+ {
+ //because of the internals of window server, we need to force the cursor
+ //to be set in all child windows too, otherwise when the cursor is over
+ //the child window it may show a widget cursor or arrow cursor instead,
+ //depending on construction order.
+ QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
+ while (iter.hasNext()) {
+ CCoeControl *ctrl = iter.next();
+ ctrl->DrawableWindow()->ClearPointerCursor();
+ }
+ if (w)
+ qt_symbian_setWindowCursor(w->cursor(), w->effectiveWinId());
+ else
+ qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
+ }
+ }
+}
+
+#endif // QT_NO_CURSOR
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 1ce799c..601cd11 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -2820,8 +2820,6 @@ void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_wid
QApplication cursor stack
*****************************************************************************/
-extern void qt_x11_enforce_cursor(QWidget * w);
-
void QApplication::setOverrideCursor(const QCursor &cursor)
{
qApp->d_func()->cursor_list.prepend(cursor);
diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h
index 389a110..2b2aa4a 100644
--- a/src/gui/kernel/qcursor.h
+++ b/src/gui/kernel/qcursor.h
@@ -72,13 +72,19 @@ private:
#ifndef QT_NO_CURSOR
-struct QCursorData;
+class QCursorData;
class QBitmap;
class QPixmap;
#if defined(Q_WS_MAC)
void qt_mac_set_cursor(const QCursor *c, const QPoint &p);
#endif
+#if defined(Q_OS_SYMBIAN)
+extern void qt_symbian_show_pointer_sprite();
+extern void qt_symbian_hide_pointer_sprite();
+extern void qt_symbian_set_pointer_sprite(const QCursor& cursor);
+extern void qt_symbian_move_cursor_sprite();
+#endif
class Q_GUI_EXPORT QCursor
{
@@ -103,7 +109,7 @@ public:
static QPoint pos();
static void setPos(int x, int y);
inline static void setPos(const QPoint &p) { setPos(p.x(), p.y()); }
-
+
#ifdef qdoc
HCURSOR_or_HANDLE handle() const;
QCursor(HCURSOR cursor);
@@ -122,6 +128,8 @@ public:
Qt::HANDLE handle() const;
#elif defined(Q_WS_QWS)
int handle() const;
+#elif defined(Q_OS_SYMBIAN)
+ Qt::HANDLE handle() const;
#endif
#endif
@@ -131,6 +139,12 @@ private:
friend void *qt_mac_nsCursorForQCursor(const QCursor &c);
friend void qt_mac_set_cursor(const QCursor *c, const QPoint &p);
#endif
+#if defined(Q_OS_SYMBIAN)
+ friend void qt_symbian_show_pointer_sprite();
+ friend void qt_symbian_hide_pointer_sprite();
+ friend void qt_symbian_set_pointer_sprite(const QCursor& cursor);
+ friend void qt_symbian_move_cursor_sprite();
+#endif
};
#ifdef QT3_SUPPORT
diff --git a/src/gui/kernel/qcursor_p.h b/src/gui/kernel/qcursor_p.h
index aa4f4b2..12166c8 100644
--- a/src/gui/kernel/qcursor_p.h
+++ b/src/gui/kernel/qcursor_p.h
@@ -64,6 +64,8 @@
# include "private/qt_x11_p.h"
# elif defined(Q_WS_WIN)
# include "QtCore/qt_windows.h"
+# elif defined(Q_OS_SYMBIAN)
+# include "private/qt_s60_p.h"
#endif
QT_BEGIN_NAMESPACE
@@ -74,7 +76,8 @@ class QMacAnimateCursor;
#endif
class QBitmap;
-struct QCursorData {
+class QCursorData {
+public:
QCursorData(Qt::CursorShape s = Qt::ArrowCursor);
~QCursorData();
@@ -111,12 +114,21 @@ struct QCursorData {
} curs;
void initCursorFromBitmap();
void initCursorFromPixmap();
+#elif defined Q_OS_SYMBIAN
+ void loadShapeFromResource(RWsSpriteBase& target, QString resource, int hx, int hy, int interval=0);
+ void constructShapeSprite(RWsSpriteBase& target);
+ void constructCursorSprite(RWsSpriteBase& target);
+ RWsPointerCursor pcurs;
+ RWsSprite scurs;
+ RPointerArray<TSpriteMember> nativeSpriteMembers;
#endif
static bool initialized;
void update();
static QCursorData *setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY);
};
+extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
+
QT_END_NAMESPACE
#endif // QCURSOR_P_H
diff --git a/src/gui/kernel/qcursor_qws.cpp b/src/gui/kernel/qcursor_qws.cpp
index eda826b..0eeb187 100644
--- a/src/gui/kernel/qcursor_qws.cpp
+++ b/src/gui/kernel/qcursor_qws.cpp
@@ -78,8 +78,6 @@ QCursorData::~QCursorData()
Global cursors
*****************************************************************************/
-extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
-
int QCursor::handle() const
{
return d->id;
diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp
index b812994..757eaa8 100644
--- a/src/gui/kernel/qcursor_s60.cpp
+++ b/src/gui/kernel/qcursor_s60.cpp
@@ -40,12 +40,22 @@
****************************************************************************/
#include <private/qcursor_p.h>
+#include <private/qwidget_p.h>
+#include <private/qapplication_p.h>
+#include <coecntrl.h>
#include <qcursor.h>
#include <qt_s60_p.h>
+#include <qbitmap.h>
+#include <w32std.h>
+#include <qapplication.h>
+#include <qwidget.h>
-#ifdef QT_NO_CURSOR
QT_BEGIN_NAMESPACE
+static QCursor cursorSprite;
+static int cursorSpriteVisible;
+
+//pos and setpos are required whether cursors are configured or not.
QPoint QCursor::pos()
{
return S60->lastCursorPos;
@@ -53,8 +63,467 @@ QPoint QCursor::pos()
void QCursor::setPos(int x, int y)
{
+ //clip to screen size (window server allows a sprite hotspot to be outside the screen)
+ if (x < 0)
+ x=0;
+ else if (x >= S60->screenWidthInPixels)
+ x = S60->screenWidthInPixels - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= S60->screenHeightInPixels)
+ y = S60->screenHeightInPixels - 1;
+
+#ifndef QT_NO_CURSOR
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors && cursorSpriteVisible)
+ cursorSprite.d->scurs.SetPosition(TPoint(x,y));
+ else
+#endif
+ S60->wsSession().SetPointerCursorPosition(TPoint(x, y));
+#endif
S60->lastCursorPos = QPoint(x, y);
+ //send a fake mouse move event, so that enter/leave events go to the widget hierarchy
+ QWidget *w = QApplication::topLevelAt(S60->lastCursorPos);
+ if (w) {
+ CCoeControl* ctrl = w->effectiveWinId();
+ TPoint epos(x, y);
+ TPoint cpos = epos - ctrl->PositionRelativeToScreen();
+ TPointerEvent fakeEvent;
+ fakeEvent.iType = TPointerEvent::EMove;
+ fakeEvent.iModifiers = 0U;
+ fakeEvent.iPosition = cpos;
+ fakeEvent.iParentPosition = epos;
+ ctrl->HandlePointerEventL(fakeEvent);
+ }
+}
+
+#ifndef QT_NO_CURSOR
+/*
+ * Request cursor to be turned on or off.
+ * Reference counted, so 2 on + 1 off = on, for example
+ */
+void qt_symbian_set_cursor_visible(bool visible) {
+ if (visible)
+ cursorSpriteVisible++;
+ else
+ cursorSpriteVisible--;
+ Q_ASSERT(cursorSpriteVisible >=0);
+
+ if (cursorSpriteVisible && !S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_show_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ } else if (!cursorSpriteVisible && S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_hide_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
+ }
+ S60->mouseInteractionEnabled = ((cursorSpriteVisible > 0) ? true : false);
+}
+
+/*
+ * Check if the cursor is on or off
+ */
+bool qt_symbian_is_cursor_visible() {
+ return S60->mouseInteractionEnabled;
+}
+
+QCursorData::QCursorData(Qt::CursorShape s) :
+ cshape(s), bm(0), bmm(0), hx(0), hy(0), pcurs()
+{
+ ref = 1;
+}
+
+QCursorData::~QCursorData()
+{
+ for(int i=0;i<nativeSpriteMembers.Count();i++) {
+ delete nativeSpriteMembers[i]->iBitmap;
+ delete nativeSpriteMembers[i]->iMaskBitmap;
+ }
+ nativeSpriteMembers.ResetAndDestroy();
+ pcurs.Close();
+ delete bm;
+ delete bmm;
+}
+
+/* Create a bitmap cursor, this is called by public constructors in the
+ * generic QCursor code.
+ */
+QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
+{
+ if (!QCursorData::initialized)
+ QCursorData::initialize();
+ if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
+ qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
+ QCursorData *c = qt_cursorTable[0];
+ c->ref.ref();
+ return c;
+ }
+ QCursorData *d = new QCursorData;
+ d->bm = new QBitmap(bitmap);
+ d->bmm = new QBitmap(mask);
+ d->cshape = Qt::BitmapCursor;
+ d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
+ d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
+ return d;
+}
+
+/*
+ * returns an opaque native handle to a cursor.
+ * It happens to be the address of the native handle, as window server handles
+ * are not POD types. Note there is no QCursor(HANDLE) constructor on Symbian,
+ * Mac or QWS.
+ */
+Qt::HANDLE QCursor::handle() const
+{
+ if (d->pcurs.WsHandle())
+ return reinterpret_cast<Qt::HANDLE> (&(d->pcurs));
+
+#ifdef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+ // don't construct shape cursors, QApplication_s60 will use the system cursor instead
+ if (!(d->bm))
+ return 0;
+#endif
+
+ d->pcurs = RWsPointerCursor(S60->wsSession());
+ d->pcurs.Construct(0);
+ d->constructCursorSprite(d->pcurs);
+ d->pcurs.Activate();
+
+ return reinterpret_cast<Qt::HANDLE> (&(d->pcurs));
+}
+
+#ifndef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+/*
+ * Loads a single cursor shape from resources and appends it to a native sprite.
+ * Animated cursors (e.g. the busy cursor) have multiple members.
+ */
+void QCursorData::loadShapeFromResource(RWsSpriteBase& target, QString resource, int hx, int hy, int interval)
+{
+ QPixmap pix;
+ CFbsBitmap* native;
+ QScopedPointer<TSpriteMember> member(new TSpriteMember);
+ member->iInterval = interval;
+ member->iInvertMask = false;
+ member->iMaskBitmap = 0; // all shapes are RGBA
+ member->iDrawMode = CGraphicsContext::EDrawModePEN;
+ member->iOffset = TPoint(-hx, -hy);
+ QString res(QLatin1String(":/trolltech/symbian/cursors/images/%1.png"));
+ pix.load(res.arg(resource));
+ native = pix.toSymbianCFbsBitmap();
+ member->iBitmap = native;
+ qt_symbian_throwIfError(nativeSpriteMembers.Append(member.data()));
+ target.AppendMember(*(member.take()));
+}
+
+//TODO: after 4.6, connect with style & skins?
+/*
+ * Constructs the native cursor from resources compiled into QtGui
+ * This is needed only when the platform doesn't have system cursors.
+ *
+ * System cursors are higher performance, since they are constructed once
+ * and shared by all applications by specifying the shape number.
+ * Due to symbian platform security considerations, and the fact most
+ * existing phones have a broken RWsPointerCursor, system cursors are not
+ * being used.
+ */
+void QCursorData::constructShapeSprite(RWsSpriteBase& target)
+{
+ int i;
+ switch (cshape) {
+ default:
+ qWarning("QCursorData::constructShapeSprite unknown shape %d", cshape);
+ //fall through and give arrow cursor
+ case Qt::ArrowCursor:
+ loadShapeFromResource(target, QLatin1String("pointer"), 1, 1);
+ break;
+ case Qt::UpArrowCursor:
+ loadShapeFromResource(target, QLatin1String("uparrow"), 4, 0);
+ break;
+ case Qt::CrossCursor:
+ loadShapeFromResource(target, QLatin1String("cross"), 7, 7);
+ break;
+ case Qt::WaitCursor:
+ for (i = 1; i <= 12; i++) {
+ loadShapeFromResource(target, QString(QLatin1String("wait%1")).arg(i), 7, 7, 1000000);
+ }
+ break;
+ case Qt::IBeamCursor:
+ loadShapeFromResource(target, QLatin1String("ibeam"), 3, 10);
+ break;
+ case Qt::SizeVerCursor:
+ loadShapeFromResource(target, QLatin1String("sizever"), 4, 8);
+ break;
+ case Qt::SizeHorCursor:
+ loadShapeFromResource(target, QLatin1String("sizehor"), 8, 4);
+ break;
+ case Qt::SizeBDiagCursor:
+ loadShapeFromResource(target, QLatin1String("sizebdiag"), 8, 8);
+ break;
+ case Qt::SizeFDiagCursor:
+ loadShapeFromResource(target, QLatin1String("sizefdiag"), 8, 8);
+ break;
+ case Qt::SizeAllCursor:
+ loadShapeFromResource(target, QLatin1String("sizeall"), 7, 7);
+ break;
+ case Qt::BlankCursor:
+ loadShapeFromResource(target, QLatin1String("blank"), 0, 0);
+ break;
+ case Qt::SplitVCursor:
+ loadShapeFromResource(target, QLatin1String("splitv"), 7, 7);
+ break;
+ case Qt::SplitHCursor:
+ loadShapeFromResource(target, QLatin1String("splith"), 7, 7);
+ break;
+ case Qt::PointingHandCursor:
+ loadShapeFromResource(target, QLatin1String("handpoint"), 5, 0);
+ break;
+ case Qt::ForbiddenCursor:
+ loadShapeFromResource(target, QLatin1String("forbidden"), 7, 7);
+ break;
+ case Qt::WhatsThisCursor:
+ loadShapeFromResource(target, QLatin1String("whatsthis"), 1, 1);
+ break;
+ case Qt::BusyCursor:
+ loadShapeFromResource(target, QLatin1String("busy3"), 1, 1, 1000000);
+ loadShapeFromResource(target, QLatin1String("busy6"), 1, 1, 1000000);
+ loadShapeFromResource(target, QLatin1String("busy9"), 1, 1, 1000000);
+ loadShapeFromResource(target, QLatin1String("busy12"), 1, 1, 1000000);
+ break;
+ case Qt::OpenHandCursor:
+ loadShapeFromResource(target, QLatin1String("openhand"), 7, 7);
+ break;
+ case Qt::ClosedHandCursor:
+ loadShapeFromResource(target, QLatin1String("closehand"), 7, 7);
+ break;
+ }
+}
+#endif
+
+/*
+ * Common code between the sprite workaround and standard modes of operation.
+ * RWsSpriteBase is the base class for both RWsSprite and RWsPointerCursor.
+ * It is called from both handle() and qt_s60_show_pointer_sprite()
+ */
+void QCursorData::constructCursorSprite(RWsSpriteBase& target)
+{
+ int count = nativeSpriteMembers.Count();
+ if (count) {
+ // already constructed
+ for (int i = 0; i < count; i++)
+ target.AppendMember(*(nativeSpriteMembers[i]));
+
+ return;
+ }
+ if (pixmap.isNull() && !bm) {
+#ifndef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+ //shape cursor
+ constructShapeSprite(target);
+#endif
+ return;
+ }
+ QScopedPointer<TSpriteMember> member(new TSpriteMember);
+ if (pixmap.isNull()) {
+ //construct mono cursor
+ member->iBitmap = bm->toSymbianCFbsBitmap();
+ member->iMaskBitmap = bmm->toSymbianCFbsBitmap();
+ }
+ else {
+ //construct normal cursor
+ member->iBitmap = pixmap.toSymbianCFbsBitmap();
+ if (pixmap.hasAlphaChannel()) {
+ member->iMaskBitmap = 0; //use alpha blending
+ }
+ else if (pixmap.hasAlpha()) {
+ member->iMaskBitmap = pixmap.mask().toSymbianCFbsBitmap();
+ }
+ else {
+ member->iMaskBitmap = pixmap.createHeuristicMask().toSymbianCFbsBitmap();
+ }
+ }
+
+ member->iDrawMode = CGraphicsContext::EDrawModePEN;
+ member->iInvertMask = EFalse;
+ member->iInterval = 0;
+ member->iOffset = TPoint(-(hx), -(hy)); //Symbian hotspot coordinates are negative
+ qt_symbian_throwIfError(nativeSpriteMembers.Append(member.data()));
+ target.AppendMember(*(member.take()));
+}
+
+/*
+ * shows the pointer sprite by constructing a native handle, and registering
+ * it with the window server.
+ * Only used when the sprite workaround is in use.
+ */
+void qt_symbian_show_pointer_sprite()
+{
+ if (cursorSprite.d) {
+ if (cursorSprite.d->scurs.WsHandle())
+ cursorSprite.d->scurs.Close();
+ } else {
+ cursorSprite = QCursor(Qt::ArrowCursor);
+ }
+
+ cursorSprite.d->scurs = RWsSprite(S60->wsSession());
+ QPoint pos = QCursor::pos();
+ cursorSprite.d->scurs.Construct(S60->windowGroup(), TPoint(pos.x(), pos.y()), ESpriteNoChildClip | ESpriteNoShadows);
+
+ cursorSprite.d->constructCursorSprite(cursorSprite.d->scurs);
+ cursorSprite.d->scurs.Activate();
+}
+
+/*
+ * hides the pointer sprite by closing the native handle.
+ * Only used when the sprite workaround is in use.
+ */
+void qt_symbian_hide_pointer_sprite()
+{
+ if (cursorSprite.d) {
+ cursorSprite.d->scurs.Close();
+ }
+}
+
+/*
+ * Changes the cursor sprite to the cursor specified.
+ * Only used when the sprite workaround is in use.
+ */
+void qt_symbian_set_pointer_sprite(const QCursor& cursor)
+{
+ if (S60->mouseInteractionEnabled)
+ qt_symbian_hide_pointer_sprite();
+ cursorSprite = cursor;
+ if (S60->mouseInteractionEnabled)
+ qt_symbian_show_pointer_sprite();
+}
+
+/*
+ * When using sprites as a workaround on phones that have a broken
+ * RWsPointerCursor, this function is called in response to pointer events
+ * and when QCursor::setPos() is called.
+ * Performance is worse than a real pointer cursor, due to extra context
+ * switches vs. the window server moving the cursor by itself.
+ */
+void qt_symbian_move_cursor_sprite()
+{
+ if (S60->mouseInteractionEnabled) {
+ cursorSprite.d->scurs.SetPosition(TPoint(S60->lastCursorPos.x(), S60->lastCursorPos.y()));
+ }
+}
+
+/*
+ * Translate from Qt::CursorShape to OS system pointer cursor list index.
+ * Currently we control the implementation of the system pointer cursor list,
+ * so this function is trivial. That may not always be the case.
+ */
+TInt qt_symbian_translate_cursor_shape(Qt::CursorShape shape)
+{
+ return (TInt) shape;
+}
+
+/*
+ Internal function called from QWidget::setCursor()
+ force is true if this function is called from dispatchEnterLeave, it means that the
+ mouse is actually directly under this widget.
+*/
+void qt_symbian_set_cursor(QWidget *w, bool force)
+{
+ static QPointer<QWidget> lastUnderMouse = 0;
+ if (force) {
+ lastUnderMouse = w;
+ }
+ else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse
+ && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
+ w = lastUnderMouse;
+ }
+
+ if (!S60->curWin && w && w->internalWinId())
+ return;
+ QWidget* cW = w && !w->internalWinId() ? w : QWidget::find(S60->curWin);
+ if (!cW || cW->window() != w->window() || !cW->isVisible() || !cW->underMouse()
+ || QApplication::overrideCursor())
+ return;
+
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_set_pointer_sprite(cW->cursor());
+ else
+#endif
+ qt_symbian_setWindowCursor(cW->cursor(), w->effectiveWinId());
}
+/*
+ * Makes the specified cursor appear above a specific native window group
+ * Called from QSymbianControl and QApplication::restoreOverrideCursor
+ *
+ * Window server is needed for this, so there is no equivalent when using
+ * the sprite workaround.
+ */
+void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &node)
+{
+ Qt::HANDLE handle = cursor.handle();
+ if (handle) {
+ RWsPointerCursor *pcurs = reinterpret_cast<RWsPointerCursor *> (handle);
+ node.SetCustomPointerCursor(*pcurs);
+ }
+#ifdef Q_SYMBIAN_HAS_SYSTEM_CURSORS
+ else {
+ TInt shape = qt_symbian_translate_cursor_shape(cursor.shape());
+ node.SetPointerCursor(shape);
+ }
+#else
+ qWarning("qt_s60_setWindowGroupCursor - null handle");
+#endif
+}
+
+/*
+ * Makes the specified cursor appear above a specific native window
+ * Called from QSymbianControl and QApplication::restoreOverrideCursor
+ *
+ * Window server is needed for this, so there is no equivalent when using
+ * the sprite workaround.
+ */
+void qt_symbian_setWindowCursor(const QCursor &cursor, const CCoeControl* wid)
+{
+ //find the window for this control
+ while (!wid->OwnsWindow()) {
+ wid = wid->Parent();
+ if (!wid)
+ return;
+ }
+ RWindowTreeNode *node = wid->DrawableWindow();
+ qt_symbian_setWindowGroupCursor(cursor, *node);
+}
+
+/*
+ * Makes the specified cursor appear everywhere.
+ * Called from QApplication::setOverrideCursor
+ */
+void qt_symbian_setGlobalCursor(const QCursor &cursor)
+{
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(cursor);
+ } else
+#endif
+ {
+ //because of the internals of window server, we need to force the cursor
+ //to be set in all child windows too, otherwise when the cursor is over
+ //the child window it may show a widget cursor or arrow cursor instead,
+ //depending on construction order.
+ QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
+ while(iter.hasNext())
+ {
+ CCoeControl *ctrl = iter.next();
+ RWindowTreeNode *node = ctrl->DrawableWindow();
+ qt_symbian_setWindowGroupCursor(cursor, *node);
+ }
+ }
+}
QT_END_NAMESPACE
#endif // QT_NO_CURSOR
diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp
index 430f587..26cde1a 100644
--- a/src/gui/kernel/qcursor_win.cpp
+++ b/src/gui/kernel/qcursor_win.cpp
@@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
-extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
-
/*****************************************************************************
Internal QCursorData class
*****************************************************************************/
diff --git a/src/gui/kernel/qcursor_x11.cpp b/src/gui/kernel/qcursor_x11.cpp
index d8cc2fc..3e53f04 100644
--- a/src/gui/kernel/qcursor_x11.cpp
+++ b/src/gui/kernel/qcursor_x11.cpp
@@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE
// Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
// use the ugly X11 cursors.
-extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
-
/*****************************************************************************
Internal QCursorData class
*****************************************************************************/
@@ -100,6 +98,7 @@ QCursor::QCursor(Qt::HANDLE cursor)
d = new QCursorData(Qt::CustomCursor);
d->hcurs = cursor;
}
+
#endif
QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index 4ee484c..b635685 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -58,6 +58,7 @@
#include "QtGui/qmime.h"
#include "QtGui/qdrag.h"
#include "QtGui/qpixmap.h"
+#include "QtGui/qcursor.h"
#include "QtCore/qpoint.h"
#include "private/qobject_p.h"
#ifdef Q_WS_MAC
@@ -265,7 +266,11 @@ private:
#ifdef Q_WS_QWS
Qt::DropAction currentActionForOverrideCursor;
#endif
-
+#ifdef Q_OS_SYMBIAN
+#ifndef QT_NO_CURSOR
+ QCursor overrideCursor;
+#endif
+#endif
QWidget *currentDropTarget;
static QDragManager *instance;
diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/gui/kernel/qdnd_s60.cpp
index fb2e426..2456185 100644
--- a/src/gui/kernel/qdnd_s60.cpp
+++ b/src/gui/kernel/qdnd_s60.cpp
@@ -50,11 +50,14 @@
#include "qevent.h"
#include "qpainter.h"
#include "qdnd_p.h"
+#include "qt_s60_p.h"
#include <COECNTRL.H>
// pointer cursor
#include <w32std.h>
#include <gdi.h>
+#include <QCursor>
+
QT_BEGIN_NAMESPACE
//### artistic impression of Symbians default DnD cursor ?
@@ -89,82 +92,24 @@ static bool qt_symbian_dnd_dragging = false;
static Qt::KeyboardModifiers oldstate;
-class QShapedPixmapWidget
-{
-public:
- QShapedPixmapWidget(RWsSession aWsSession,RWindowTreeNode* aNode)
- {
- sprite = RWsSprite(aWsSession);
- cursorSprite.iBitmap = 0;
- cursorSprite.iMaskBitmap = 0;
- cursorSprite.iInvertMask = EFalse;
- cursorSprite.iOffset = TPoint(0,0);
- cursorSprite.iInterval = TTimeIntervalMicroSeconds32(0);
- cursorSprite.iDrawMode = CGraphicsContext::EDrawModePEN;
- sprite.Construct(*aNode,TPoint(0,0), ESpriteNoShadows | ESpriteNoChildClip);
- sprite.AppendMember(cursorSprite);
- sprite.Activate();
- }
- ~QShapedPixmapWidget()
- {
- sprite.Close();
- cursorSprite.iBitmap = 0;
- delete cursorBitmap;
- cursorBitmap = 0; //redundant...
- }
- void disableCursor()
- {
- cursorSprite.iBitmap = 0;
- sprite.UpdateMember(0,cursorSprite);
- }
- void enableCursor()
- {
- cursorSprite.iBitmap = cursorBitmap;
- sprite.UpdateMember(0,cursorSprite);
- }
- void setPixmap(QPixmap pm)
- {
- //### heaplock centralized.
- QImage temp = pm.toImage();
- QSize size = pm.size();
- temp.bits();
- CFbsBitmap *curbm = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new
- curbm->Create(TSize(size.width(),size.height()),EColor16MA);
- curbm->LockHeap(ETrue);
- memcpy((uchar*)curbm->DataAddress(),temp.bits(),temp.numBytes());
- curbm->UnlockHeap(ETrue);
- delete cursorSprite.iBitmap;
- cursorSprite.iBitmap = curbm;
- cursorBitmap = curbm;
- sprite.UpdateMember(0,cursorSprite);
- }
- CFbsBitmap *cursorBitmap;
- RWsPointerCursor pointerCursor;
- RWsSprite sprite;
- TSpriteMember cursorSprite;
-
-};
-
-
-static QShapedPixmapWidget *qt_symbian_dnd_deco = 0;
-
void QDragManager::updatePixmap()
{
- if (qt_symbian_dnd_deco) {
- QPixmap pm;
- QPoint pm_hot(default_pm_hotx,default_pm_hoty);
- if (drag_object) {
- pm = drag_object->pixmap();
- if (!pm.isNull())
- pm_hot = drag_object->hotSpot();
- }
- if (pm.isNull()) {
- if (!defaultPm)
- defaultPm = new QPixmap(default_pm);
- pm = *defaultPm;
- }
- qt_symbian_dnd_deco->setPixmap(pm);
+ QPixmap pm;
+ QPoint pm_hot(default_pm_hotx,default_pm_hoty);
+ if (drag_object) {
+ pm = drag_object->pixmap();
+ if (!pm.isNull())
+ pm_hot = drag_object->hotSpot();
+ }
+ if (pm.isNull()) {
+ if (!defaultPm)
+ defaultPm = new QPixmap(default_pm);
+ pm = *defaultPm;
}
+#ifndef QT_NO_CURSOR
+ QCursor cursor(pm, pm_hot.x(), pm_hot.y());
+ overrideCursor = cursor;
+#endif
}
void QDragManager::timerEvent(QTimerEvent *) { }
@@ -174,6 +119,16 @@ void QDragManager::move(const QPoint&) {
void QDragManager::updateCursor()
{
+#ifndef QT_NO_CURSOR
+ QCursor cursor = willDrop ? overrideCursor : Qt::ForbiddenCursor;
+ if (!restoreCursor) {
+ QApplication::setOverrideCursor(cursor);
+ restoreCursor = true;
+ }
+ else {
+ QApplication::changeOverrideCursor(cursor);
+ }
+#endif
}
@@ -210,20 +165,19 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
// map the Coords relative to the window.
if (!cw)
return true;
- TPoint windowPos = cw->effectiveWinId()->PositionRelativeToScreen();
- qt_symbian_dnd_deco->sprite.SetPosition(TPoint(me->globalX()- windowPos.iX,me->globalY()- windowPos.iY));
while (cw && !cw->acceptDrops() && !cw->isWindow())
cw = cw->parentWidget();
+ bool oldWillDrop = willDrop;
if (object->target() != cw) {
if (object->target()) {
QDragLeaveEvent dle;
QApplication::sendEvent(object->target(), &dle);
willDrop = false;
global_accepted_action = Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
+ if (oldWillDrop != willDrop)
+ updateCursor();
object->d_func()->target = 0;
}
if (cw && cw->acceptDrops()) {
@@ -233,8 +187,8 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
QApplication::sendEvent(object->target(), &dee);
willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
+ if (oldWillDrop != willDrop)
+ updateCursor();
}
} else if (cw) {
QDragMoveEvent dme(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData,
@@ -246,8 +200,10 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
QApplication::sendEvent(cw, &dme);
willDrop = dme.isAccepted();
global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction;
- updatePixmap();
- updateCursor();
+ if (oldWillDrop != willDrop) {
+ updatePixmap();
+ updateCursor();
+ }
}
if (global_accepted_action != prevAction)
emitActionChanged(global_accepted_action);
@@ -259,7 +215,7 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
{
qApp->removeEventFilter(this);
if (restoreCursor) {
- qt_symbian_dnd_deco->disableCursor();
+ QApplication::restoreOverrideCursor();
willDrop = false;
restoreCursor = false;
}
@@ -305,23 +261,15 @@ Qt::DropAction QDragManager::drag(QDrag *o)
}
object = drag_object = o;
- RWsSession winSession = o->source()->effectiveWinId()->ControlEnv()->WsSession();
- Q_ASSERT(!qt_symbian_dnd_deco);
- qt_symbian_dnd_deco = new QShapedPixmapWidget(winSession, o->source()->effectiveWinId()->DrawableWindow());
oldstate = Qt::NoModifier; // #### Should use state that caused the drag
willDrop = false;
updatePixmap();
updateCursor();
- restoreCursor = true;
- object->d_func()->target = 0;
- TPoint windowPos = source()->effectiveWinId()->PositionRelativeToScreen();
- qt_symbian_dnd_deco->sprite.SetPosition(TPoint(QCursor::pos().x()- windowPos.iX ,QCursor::pos().y() - windowPos.iY));
+ qt_symbian_set_cursor_visible(true); //force cursor on even for touch phone
- QPoint hotspot = drag_object->hotSpot();
- qt_symbian_dnd_deco->cursorSprite.iOffset = TPoint(- hotspot.x(),- hotspot.y());
- qt_symbian_dnd_deco->sprite.UpdateMember(0,qt_symbian_dnd_deco->cursorSprite);
+ object->d_func()->target = 0;
qApp->installEventFilter(this);
@@ -334,11 +282,11 @@ Qt::DropAction QDragManager::drag(QDrag *o)
delete eventLoop;
eventLoop = 0;
- delete qt_symbian_dnd_deco;
- qt_symbian_dnd_deco = 0;
+ qt_symbian_set_cursor_visible(false);
+
+ overrideCursor = QCursor(); //deref the cursor data
qt_symbian_dnd_dragging = false;
-
return global_accepted_action;
}
@@ -358,8 +306,10 @@ void QDragManager::cancel(bool deleteSource)
drag_object = object = 0;
}
- delete qt_symbian_dnd_deco;
- qt_symbian_dnd_deco = 0;
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
global_accepted_action = Qt::IgnoreAction;
}
@@ -367,6 +317,10 @@ void QDragManager::cancel(bool deleteSource)
void QDragManager::drop()
{
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
}
QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index d85023b..794d15a 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -83,6 +83,7 @@ const TInt KInternalStatusPaneChange = 0x50000000;
class QS60Data
{
public:
+ QS60Data();
TUid uid;
int screenDepth;
QPoint lastCursorPos;
@@ -95,6 +96,16 @@ public:
int screenHeightInTwips;
int defaultDpiX;
int defaultDpiY;
+ WId curWin;
+ int virtualMouseLastKey;
+ int virtualMouseAccel;
+ int virtualMouseMaxAccel;
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ bool brokenPointerCursors;
+#endif
+ bool hasTouchscreen;
+ bool mouseInteractionEnabled;
+ bool virtualMouseRequired;
int qtOwnsS60Environment : 1;
static inline void updateScreenSize();
static inline RWsSession& wsSession();
@@ -164,6 +175,11 @@ private:
bool m_previousEventLongTap;
};
+inline QS60Data::QS60Data()
+{
+ memclr(this, sizeof(QS60Data)); //zero init data
+}
+
inline void QS60Data::updateScreenSize()
{
TPixelsTwipsAndRotation params;
@@ -173,6 +189,8 @@ inline void QS60Data::updateScreenSize()
S60->screenHeightInPixels = params.iPixelSize.iHeight;
S60->screenWidthInTwips = params.iTwipsSize.iWidth;
S60->screenHeightInTwips = params.iTwipsSize.iHeight;
+
+ S60->virtualMouseMaxAccel = qMax(S60->screenHeightInPixels, S60->screenWidthInPixels) / 20;
TReal inches = S60->screenHeightInTwips / (TReal)KTwipsPerInch;
S60->defaultDpiY = S60->screenHeightInPixels / inches;
@@ -286,6 +304,11 @@ static inline QImage::Format qt_TDisplayMode2Format(TDisplayMode mode)
return format;
}
+void qt_symbian_setWindowCursor(const QCursor &cursor, const CCoeControl* wid);
+void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &node);
+void qt_symbian_setGlobalCursor(const QCursor &cursor);
+void qt_symbian_set_cursor_visible(bool visible);
+bool qt_symbian_is_cursor_visible();
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index fd89cb9..c86012d 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -3048,7 +3048,6 @@ void QWidgetPrivate::setEnabled_helper(bool enable)
if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
// enforce the windows behavior of clearing the cursor on
// disabled widgets
- extern void qt_x11_enforce_cursor(QWidget * w); // defined in qwidget_x11.cpp
qt_x11_enforce_cursor(q);
}
#endif
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 744d20f..522ce33 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -188,7 +188,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if (isResize)
data.window_state &= ~Qt::WindowMaximized;
- if(q->isWindow()) {
+ if (q->isWindow()) {
if (w == 0 || h == 0) {
q->setAttribute(Qt::WA_OutsideWSRange, true);
if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
@@ -287,7 +287,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
TSize screenSize = S60->screenDevice()->SizeInPixels();
data.crect.setRect(0, 0, screenSize.iWidth, screenSize.iHeight);
q->setAttribute(Qt::WA_DontShowOnScreen);
- } else if(topLevel && !q->testAttribute(Qt::WA_Resized)){
+ } else if (topLevel && !q->testAttribute(Qt::WA_Resized)){
int width = sw;
int height = sh;
if (extra) {
@@ -300,7 +300,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
CCoeControl *destroyw = 0;
createExtra();
- if(window) {
+ if (window) {
if (destroyOldWindow)
destroyw = data.winid;
id = window;
@@ -416,7 +416,7 @@ void QWidgetPrivate::hide_sys()
deactivateWidgetCleanup();
WId id = q->internalWinId();
if (q->isWindow() && id) {
- if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
id->SetFocus(false);
id->MakeVisible(false);
if (QWidgetBackingStore *bs = maybeBackingStore())
@@ -432,7 +432,7 @@ void QWidgetPrivate::setFocus_sys()
{
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup)
- if(!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged()
+ if (!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged()
q->effectiveWinId()->SetFocus(true);
}
@@ -482,7 +482,7 @@ void QWidgetPrivate::lower_sys()
if (q->internalWinId() && tlwExtra) {
tlwExtra->rwindow->SetOrdinalPosition(-1);
}
- if(!q->isWindow())
+ if (!q->isWindow())
invalidateBuffer(q->rect());
}
@@ -499,7 +499,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget* w)
QTLWExtra *tlwExtraSibling = w->d_func()->maybeTopData();
if (q->internalWinId() && tlwExtra && w->internalWinId() && tlwExtraSibling)
tlwExtra->rwindow->SetOrdinalPosition(tlwExtraSibling->rwindow->OrdinalPosition() + 1);
- if(!q->isWindow() || !w->internalWinId())
+ if (!q->isWindow() || !w->internalWinId())
invalidateBuffer(q->rect());
}
@@ -553,7 +553,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
// destroyed when emitting the child remove event below. See QWorkspace.
if (wasCreated && old_winid) {
old_winid->MakeVisible(false);
- if(old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged()
old_winid->SetFocus(false);
old_winid->SetParent(0);
}
@@ -660,7 +660,7 @@ CFbsBitmap* qt_pixmapToNativeBitmap(QPixmap pixmap, bool invert)
fbsBitmap->LockHeap();
QImage image = pixmap.toImage();
- if(invert)
+ if (invert)
image.invertPixels();
int height = pixmap.size().height();
@@ -764,8 +764,8 @@ void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
if (q->isWindow()) {
Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
CAknTitlePane* titlePane = S60->titlePane();
- if(titlePane) {
- if(caption.isEmpty()) {
+ if (titlePane) {
+ if (caption.isEmpty()) {
QT_TRAP_THROWING(titlePane->SetTextToDefaultL());
} else {
QT_TRAP_THROWING(titlePane->SetTextL(qt_QString2TPtrC(caption)));
@@ -996,7 +996,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
// The window decoration visibility has to be changed before doing actual
// window state change since in that order the availableGeometry will return
// directly the right size and we will avoid unnecessarty redraws
- if((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) ||
+ if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) ||
oldstate == Qt::WindowNoState) {
CEikStatusPane* statusPane = S60->statusPane();
CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
@@ -1061,7 +1061,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
if (newstate & Qt::WindowMinimized) {
if (isVisible()) {
WId id = effectiveWinId();
- if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
id->SetFocus(false);
id->MakeVisible(false);
}
@@ -1069,7 +1069,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
if (isVisible()) {
WId id = effectiveWinId();
id->MakeVisible(true);
- if(!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
id->SetFocus(true);
}
const QRect normalGeometry = geometry();
@@ -1111,6 +1111,10 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
}
#endif
+ if (QWidgetPrivate::mouseGrabber == this)
+ releaseMouse();
+ if (QWidgetPrivate::keyboardGrabber == this)
+ releaseKeyboard();
setAttribute(Qt::WA_WState_Created, false);
QObjectList childList = children();
for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
@@ -1119,12 +1123,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
static_cast<QWidget*>(obj)->destroy(destroySubWindows,
destroySubWindows);
}
- if (QWidgetPrivate::mouseGrabber == this)
- releaseMouse();
- if (QWidgetPrivate::keyboardGrabber == this)
- releaseKeyboard();
if (destroyWindow && !(windowType() == Qt::Desktop) && id) {
- if(id->IsFocused()) // Avoid unnecessry calls to FocusChanged()
+ if (id->IsFocused()) // Avoid unnecessry calls to FocusChanged()
id->SetFocus(false);
id->ControlEnv()->AppUi()->RemoveFromStack(id);
@@ -1192,8 +1192,28 @@ void QWidget::grabMouse()
WId id = effectiveWinId();
id->SetPointerCapture(true);
QWidgetPrivate::mouseGrabber = this;
+
+#ifndef QT_NO_CURSOR
+ QApplication::setOverrideCursor(cursor());
+#endif
+ }
+}
+
+#ifndef QT_NO_CURSOR
+void QWidget::grabMouse(const QCursor &cursor)
+{
+ if (!qt_nograb()) {
+ if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
+ QWidgetPrivate::mouseGrabber->releaseMouse();
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ WId id = effectiveWinId();
+ id->SetPointerCapture(true);
+ QWidgetPrivate::mouseGrabber = this;
+
+ QApplication::setOverrideCursor(cursor);
}
}
+#endif
void QWidget::releaseMouse()
{
@@ -1202,6 +1222,8 @@ void QWidget::releaseMouse()
WId id = effectiveWinId();
id->SetPointerCapture(false);
QWidgetPrivate::mouseGrabber = 0;
+
+ QApplication::restoreOverrideCursor();
}
}
@@ -1215,4 +1237,21 @@ void QWidget::activateWindow()
id->SetFocus(true);
}
}
+
+#ifndef QT_NO_CURSOR
+
+void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
+{
+ Q_UNUSED(cursor);
+ Q_Q(QWidget);
+ qt_symbian_set_cursor(q, false);
+}
+
+void QWidgetPrivate::unsetCursor_sys()
+{
+ Q_Q(QWidget);
+ qt_symbian_set_cursor(q, false);
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index c9ebccf..211e9d4 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -722,8 +722,6 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const
void QWidgetPrivate::updateSystemBackground() {}
-extern void qt_win_set_cursor(QWidget *, bool); // qapplication_win.cpp
-
#ifndef QT_NO_CURSOR
void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
{
diff --git a/src/gui/kernel/symbian.pri b/src/gui/kernel/symbian.pri
index d267a53..5497ccb 100644
--- a/src/gui/kernel/symbian.pri
+++ b/src/gui/kernel/symbian.pri
@@ -1,3 +1,4 @@
symbian {
contains(QT_CONFIG, s60): LIBS+= $$QMAKE_LIBS_S60
+ RESOURCES += symbian/symbianresources.qrc
}
diff --git a/src/gui/symbian/images/blank.png b/src/gui/symbian/images/blank.png
new file mode 100644
index 0000000..bd396de
--- /dev/null
+++ b/src/gui/symbian/images/blank.png
Binary files differ
diff --git a/src/gui/symbian/images/busy12.png b/src/gui/symbian/images/busy12.png
new file mode 100644
index 0000000..909e70f
--- /dev/null
+++ b/src/gui/symbian/images/busy12.png
Binary files differ
diff --git a/src/gui/symbian/images/busy3.png b/src/gui/symbian/images/busy3.png
new file mode 100644
index 0000000..983f5d8
--- /dev/null
+++ b/src/gui/symbian/images/busy3.png
Binary files differ
diff --git a/src/gui/symbian/images/busy6.png b/src/gui/symbian/images/busy6.png
new file mode 100644
index 0000000..b2e8780
--- /dev/null
+++ b/src/gui/symbian/images/busy6.png
Binary files differ
diff --git a/src/gui/symbian/images/busy9.png b/src/gui/symbian/images/busy9.png
new file mode 100644
index 0000000..e093d01
--- /dev/null
+++ b/src/gui/symbian/images/busy9.png
Binary files differ
diff --git a/src/gui/symbian/images/closehand.png b/src/gui/symbian/images/closehand.png
new file mode 100644
index 0000000..05534f5
--- /dev/null
+++ b/src/gui/symbian/images/closehand.png
Binary files differ
diff --git a/src/gui/symbian/images/cross.png b/src/gui/symbian/images/cross.png
new file mode 100644
index 0000000..50da7aa
--- /dev/null
+++ b/src/gui/symbian/images/cross.png
Binary files differ
diff --git a/src/gui/symbian/images/forbidden.png b/src/gui/symbian/images/forbidden.png
new file mode 100644
index 0000000..a3a0fd6
--- /dev/null
+++ b/src/gui/symbian/images/forbidden.png
Binary files differ
diff --git a/src/gui/symbian/images/handpoint.png b/src/gui/symbian/images/handpoint.png
new file mode 100644
index 0000000..a221548
--- /dev/null
+++ b/src/gui/symbian/images/handpoint.png
Binary files differ
diff --git a/src/gui/symbian/images/ibeam.png b/src/gui/symbian/images/ibeam.png
new file mode 100644
index 0000000..ace2fad
--- /dev/null
+++ b/src/gui/symbian/images/ibeam.png
Binary files differ
diff --git a/src/gui/symbian/images/openhand.png b/src/gui/symbian/images/openhand.png
new file mode 100644
index 0000000..6f232f0
--- /dev/null
+++ b/src/gui/symbian/images/openhand.png
Binary files differ
diff --git a/src/gui/symbian/images/pointer.png b/src/gui/symbian/images/pointer.png
new file mode 100644
index 0000000..677404e
--- /dev/null
+++ b/src/gui/symbian/images/pointer.png
Binary files differ
diff --git a/src/gui/symbian/images/sizeall.png b/src/gui/symbian/images/sizeall.png
new file mode 100644
index 0000000..2950067
--- /dev/null
+++ b/src/gui/symbian/images/sizeall.png
Binary files differ
diff --git a/src/gui/symbian/images/sizebdiag.png b/src/gui/symbian/images/sizebdiag.png
new file mode 100644
index 0000000..f565a3a
--- /dev/null
+++ b/src/gui/symbian/images/sizebdiag.png
Binary files differ
diff --git a/src/gui/symbian/images/sizefdiag.png b/src/gui/symbian/images/sizefdiag.png
new file mode 100644
index 0000000..9493f12
--- /dev/null
+++ b/src/gui/symbian/images/sizefdiag.png
Binary files differ
diff --git a/src/gui/symbian/images/sizehor.png b/src/gui/symbian/images/sizehor.png
new file mode 100644
index 0000000..217bf39
--- /dev/null
+++ b/src/gui/symbian/images/sizehor.png
Binary files differ
diff --git a/src/gui/symbian/images/sizever.png b/src/gui/symbian/images/sizever.png
new file mode 100644
index 0000000..2c99038
--- /dev/null
+++ b/src/gui/symbian/images/sizever.png
Binary files differ
diff --git a/src/gui/symbian/images/splith.png b/src/gui/symbian/images/splith.png
new file mode 100644
index 0000000..343bed5
--- /dev/null
+++ b/src/gui/symbian/images/splith.png
Binary files differ
diff --git a/src/gui/symbian/images/splitv.png b/src/gui/symbian/images/splitv.png
new file mode 100644
index 0000000..69ee416
--- /dev/null
+++ b/src/gui/symbian/images/splitv.png
Binary files differ
diff --git a/src/gui/symbian/images/uparrow.png b/src/gui/symbian/images/uparrow.png
new file mode 100644
index 0000000..92dd933
--- /dev/null
+++ b/src/gui/symbian/images/uparrow.png
Binary files differ
diff --git a/src/gui/symbian/images/wait1.png b/src/gui/symbian/images/wait1.png
new file mode 100644
index 0000000..5aebaab
--- /dev/null
+++ b/src/gui/symbian/images/wait1.png
Binary files differ
diff --git a/src/gui/symbian/images/wait10.png b/src/gui/symbian/images/wait10.png
new file mode 100644
index 0000000..3b549b0
--- /dev/null
+++ b/src/gui/symbian/images/wait10.png
Binary files differ
diff --git a/src/gui/symbian/images/wait11.png b/src/gui/symbian/images/wait11.png
new file mode 100644
index 0000000..24a943f
--- /dev/null
+++ b/src/gui/symbian/images/wait11.png
Binary files differ
diff --git a/src/gui/symbian/images/wait12.png b/src/gui/symbian/images/wait12.png
new file mode 100644
index 0000000..15afd4d
--- /dev/null
+++ b/src/gui/symbian/images/wait12.png
Binary files differ
diff --git a/src/gui/symbian/images/wait2.png b/src/gui/symbian/images/wait2.png
new file mode 100644
index 0000000..f2022b2
--- /dev/null
+++ b/src/gui/symbian/images/wait2.png
Binary files differ
diff --git a/src/gui/symbian/images/wait3.png b/src/gui/symbian/images/wait3.png
new file mode 100644
index 0000000..5b73e57
--- /dev/null
+++ b/src/gui/symbian/images/wait3.png
Binary files differ
diff --git a/src/gui/symbian/images/wait4.png b/src/gui/symbian/images/wait4.png
new file mode 100644
index 0000000..17a0339
--- /dev/null
+++ b/src/gui/symbian/images/wait4.png
Binary files differ
diff --git a/src/gui/symbian/images/wait5.png b/src/gui/symbian/images/wait5.png
new file mode 100644
index 0000000..16a5c23
--- /dev/null
+++ b/src/gui/symbian/images/wait5.png
Binary files differ
diff --git a/src/gui/symbian/images/wait6.png b/src/gui/symbian/images/wait6.png
new file mode 100644
index 0000000..2870093
--- /dev/null
+++ b/src/gui/symbian/images/wait6.png
Binary files differ
diff --git a/src/gui/symbian/images/wait7.png b/src/gui/symbian/images/wait7.png
new file mode 100644
index 0000000..54f75a1
--- /dev/null
+++ b/src/gui/symbian/images/wait7.png
Binary files differ
diff --git a/src/gui/symbian/images/wait8.png b/src/gui/symbian/images/wait8.png
new file mode 100644
index 0000000..1d370c7
--- /dev/null
+++ b/src/gui/symbian/images/wait8.png
Binary files differ
diff --git a/src/gui/symbian/images/wait9.png b/src/gui/symbian/images/wait9.png
new file mode 100644
index 0000000..c28096f
--- /dev/null
+++ b/src/gui/symbian/images/wait9.png
Binary files differ
diff --git a/src/gui/symbian/images/whatsthis.png b/src/gui/symbian/images/whatsthis.png
new file mode 100644
index 0000000..3386ef0
--- /dev/null
+++ b/src/gui/symbian/images/whatsthis.png
Binary files differ
diff --git a/src/gui/symbian/symbianresources.qrc b/src/gui/symbian/symbianresources.qrc
new file mode 100644
index 0000000..0a4fc36
--- /dev/null
+++ b/src/gui/symbian/symbianresources.qrc
@@ -0,0 +1,37 @@
+<RCC>
+ <qresource prefix="/trolltech/symbian/cursors" >
+ <file>images/blank.png</file>
+ <file>images/busy3.png</file>
+ <file>images/busy6.png</file>
+ <file>images/busy9.png</file>
+ <file>images/busy12.png</file>
+ <file>images/closehand.png</file>
+ <file>images/cross.png</file>
+ <file>images/forbidden.png</file>
+ <file>images/handpoint.png</file>
+ <file>images/ibeam.png</file>
+ <file>images/openhand.png</file>
+ <file>images/pointer.png</file>
+ <file>images/sizeall.png</file>
+ <file>images/sizebdiag.png</file>
+ <file>images/sizefdiag.png</file>
+ <file>images/sizehor.png</file>
+ <file>images/sizever.png</file>
+ <file>images/splith.png</file>
+ <file>images/splitv.png</file>
+ <file>images/uparrow.png</file>
+ <file>images/wait1.png</file>
+ <file>images/wait2.png</file>
+ <file>images/wait3.png</file>
+ <file>images/wait4.png</file>
+ <file>images/wait5.png</file>
+ <file>images/wait6.png</file>
+ <file>images/wait7.png</file>
+ <file>images/wait8.png</file>
+ <file>images/wait9.png</file>
+ <file>images/wait10.png</file>
+ <file>images/wait11.png</file>
+ <file>images/wait12.png</file>
+ <file>images/whatsthis.png</file>
+ </qresource>
+</RCC>