Add QScreenOrientationChangeEvent and rotation support to wayland client

Qt Compositor propagates screen orientation changes to wayland, which
are then picked up by the wayland client. The wayland client then sends
a QScreenOrientationChangeEvent to QApplication, which can handle the
orientation change.

Change-Id: Ieb2225e52b7e3c318648f2cb21dab7937f301505
Reviewed-on: http://codereview.qt.nokia.com/1063
Reviewed-by: Matthias Ettrich
This commit is contained in:
Lasse Holmstedt 2011-07-04 12:08:38 +02:00 committed by Qt by Nokia
parent 85869920bb
commit a77ce3301c
8 changed files with 172 additions and 22 deletions

View File

@ -273,6 +273,8 @@ public:
ScrollPrepare = 204, ScrollPrepare = 204,
Scroll = 205, Scroll = 205,
OrientationChange = 206, // Screen orientation has changed
// 512 reserved for Qt Jambi's MetaCall event // 512 reserved for Qt Jambi's MetaCall event
// 513 reserved for Qt Jambi's DeleteOnMainThread event // 513 reserved for Qt Jambi's DeleteOnMainThread event

View File

@ -53,6 +53,7 @@
#include "qevent_p.h" #include "qevent_p.h"
#include "qgesture.h" #include "qgesture.h"
#include "qgesture_p.h" #include "qgesture_p.h"
#include "qmath.h"
#ifdef Q_OS_SYMBIAN #ifdef Q_OS_SYMBIAN
#include "private/qcore_symbian_p.h" #include "private/qcore_symbian_p.h"
@ -4818,4 +4819,101 @@ const QScrollEventPrivate *QScrollEvent::d_func() const
return reinterpret_cast<const QScrollEventPrivate *>(d); return reinterpret_cast<const QScrollEventPrivate *>(d);
} }
/*!
\enum QScreenOrientationChangeEvent::Orientation
This enum describes the orientations that a device can have.
\value Portrait The device is in a position where its top edge is pointing up.
\value Landscape The device is rotated clockwise 90 degrees, so that its left edge is pointing up.
\value PortraitInverted The device is rotated 180 degrees, so that its bottom edge is pointing up.
\value LandscapeInverted The device is counterclockwise 90 degrees, so that its right edge is pointing up.
\sa QScreenOrientationChangeEvent::orientation()
\sa QScreenOrientationChangeEvent::orientationInDegrees()
*/
/*!
Creates a new QScreenOrientationChangeEvent
\a screenOrientationInDegrees is the new screen orientation, expressed in degrees.
The orientation must be expressed in steps of 90 degrees.
*/
QScreenOrientationChangeEvent::QScreenOrientationChangeEvent(qint32 screenOrientationInDegrees)
: QEvent(QEvent::OrientationChange)
{
d = reinterpret_cast<QEventPrivate *>(new QScreenOrientationChangeEventPrivate());
d_func()->orientationInDegrees = screenOrientationInDegrees;
qint32 orientationIndex = (qAbs(screenOrientationInDegrees) % 360) / 90;
// flip around the negative coords to correct order.
if (screenOrientationInDegrees < 0) {
if (orientationIndex == 1)
orientationIndex = 3;
else if (orientationIndex == 3)
orientationIndex = 1;
}
orientationIndex = qPow(2, orientationIndex);
d_func()->orientation = (QScreenOrientationChangeEvent::Orientation)(orientationIndex);
d_func()->isValid = (screenOrientationInDegrees % 90 == 0);
}
/*!
Creates a new QScreenOrientationChangeEvent
\a orientation is the new orientation of the screen.
*/
QScreenOrientationChangeEvent::QScreenOrientationChangeEvent(QScreenOrientationChangeEvent::Orientation screenOrientation)
: QEvent(QEvent::OrientationChange)
{
d = reinterpret_cast<QEventPrivate *>(new QScreenOrientationChangeEventPrivate());
d_func()->orientation = screenOrientation;
d_func()->orientationInDegrees = 90 * ((uint)screenOrientation);
d_func()->isValid = true;
}
/*!
Destroys QScreenOrientationChangeEvent.
*/
QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent()
{
delete reinterpret_cast<QScrollEventPrivate *>(d);
}
/*!
Returns the orientation of the screen.
*/
QScreenOrientationChangeEvent::Orientation QScreenOrientationChangeEvent::orientation() const
{
return d_func()->orientation;
}
/*!
Returns the screen orientation in degrees.
The orientation is expressed in steps of 90 degrees and depends on the previous value of the orientation.
This is intended to allow for smooth animations from one orientation to the other.
*/
qint32 QScreenOrientationChangeEvent::orientationInDegrees() const
{
return d_func()->orientationInDegrees;
}
/*!
\internal
*/
QScreenOrientationChangeEventPrivate *QScreenOrientationChangeEvent::d_func()
{
return reinterpret_cast<QScreenOrientationChangeEventPrivate *>(d);
}
/*!
\internal
*/
const QScreenOrientationChangeEventPrivate *QScreenOrientationChangeEvent::d_func() const
{
return reinterpret_cast<const QScreenOrientationChangeEventPrivate *>(d);
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -938,6 +938,30 @@ private:
const QScrollEventPrivate *d_func() const; const QScrollEventPrivate *d_func() const;
}; };
class QScreenOrientationChangeEventPrivate;
class Q_GUI_EXPORT QScreenOrientationChangeEvent : public QEvent
{
public:
enum Orientation {
Portrait = 1,
Landscape = 2,
PortraitInverted = 4,
LandscapeInverted = 8
};
QScreenOrientationChangeEvent(qint32 screenOrientationInDegrees);
QScreenOrientationChangeEvent(Orientation screenOrientation);
~QScreenOrientationChangeEvent();
bool isValid() const;
qint32 orientationInDegrees() const;
Orientation orientation() const;
private:
QScreenOrientationChangeEventPrivate *d_func();
const QScreenOrientationChangeEventPrivate *d_func() const;
};
QT_END_NAMESPACE QT_END_NAMESPACE
QT_END_HEADER QT_END_HEADER

View File

@ -200,6 +200,17 @@ public:
QScrollEvent::ScrollState state; QScrollEvent::ScrollState state;
}; };
class QScreenOrientationChangeEventPrivate
{
public:
inline QScreenOrientationChangeEventPrivate()
{
}
QScreenOrientationChangeEvent::Orientation orientation;
qint32 orientationInDegrees;
bool isValid;
};
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QEVENT_P_H #endif // QEVENT_P_H

View File

@ -39,17 +39,20 @@ struct wl_windowmanager;
extern const struct wl_interface wl_windowmanager_interface; extern const struct wl_interface wl_windowmanager_interface;
struct wl_windowmanager_listener { struct wl_windowmanager_listener {
void (*client_onscreen_visibility)(void *data, void (*client_onscreen_visibility)(void *data,
struct wl_windowmanager *wl_windowmanager, struct wl_windowmanager *wl_windowmanager,
int visible); int visible);
void (*set_screen_rotation)(void *data,
struct wl_windowmanager *wl_windowmanager,
int rotation);
}; };
static inline int static inline int
wl_windowmanager_add_listener(struct wl_windowmanager *wl_windowmanager, wl_windowmanager_add_listener(struct wl_windowmanager *wl_windowmanager,
const struct wl_windowmanager_listener *listener, void *data) const struct wl_windowmanager_listener *listener, void *data)
{ {
return wl_proxy_add_listener((struct wl_proxy *) wl_windowmanager, return wl_proxy_add_listener((struct wl_proxy *) wl_windowmanager,
(void (**)(void)) listener, data); (void (**)(void)) listener, data);
} }
#define WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS 0 #define WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS 0
@ -58,42 +61,42 @@ wl_windowmanager_add_listener(struct wl_windowmanager *wl_windowmanager,
static inline struct wl_windowmanager * static inline struct wl_windowmanager *
wl_windowmanager_create(struct wl_display *display, uint32_t id, uint32_t version) wl_windowmanager_create(struct wl_display *display, uint32_t id, uint32_t version)
{ {
wl_display_bind(display, id, "wl_windowmanager", version); wl_display_bind(display, id, "wl_windowmanager", version);
return (struct wl_windowmanager *) return (struct wl_windowmanager *)
wl_proxy_create_for_id(display, &wl_windowmanager_interface, id); wl_proxy_create_for_id(display, &wl_windowmanager_interface, id);
} }
static inline void static inline void
wl_windowmanager_set_user_data(struct wl_windowmanager *wl_windowmanager, void *user_data) wl_windowmanager_set_user_data(struct wl_windowmanager *wl_windowmanager, void *user_data)
{ {
wl_proxy_set_user_data((struct wl_proxy *) wl_windowmanager, user_data); wl_proxy_set_user_data((struct wl_proxy *) wl_windowmanager, user_data);
} }
static inline void * static inline void *
wl_windowmanager_get_user_data(struct wl_windowmanager *wl_windowmanager) wl_windowmanager_get_user_data(struct wl_windowmanager *wl_windowmanager)
{ {
return wl_proxy_get_user_data((struct wl_proxy *) wl_windowmanager); return wl_proxy_get_user_data((struct wl_proxy *) wl_windowmanager);
} }
static inline void static inline void
wl_windowmanager_destroy(struct wl_windowmanager *wl_windowmanager) wl_windowmanager_destroy(struct wl_windowmanager *wl_windowmanager)
{ {
wl_proxy_destroy((struct wl_proxy *) wl_windowmanager); wl_proxy_destroy((struct wl_proxy *) wl_windowmanager);
} }
static inline void static inline void
wl_windowmanager_map_client_to_process(struct wl_windowmanager *wl_windowmanager, uint32_t processid) wl_windowmanager_map_client_to_process(struct wl_windowmanager *wl_windowmanager, uint32_t processid)
{ {
wl_proxy_marshal((struct wl_proxy *) wl_windowmanager, wl_proxy_marshal((struct wl_proxy *) wl_windowmanager,
WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS, processid); WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS, processid);
} }
static inline void static inline void
wl_windowmanager_authenticate_with_token(struct wl_windowmanager *wl_windowmanager, const char *processid) wl_windowmanager_authenticate_with_token(struct wl_windowmanager *wl_windowmanager, const char *processid)
{ {
wl_proxy_marshal((struct wl_proxy *) wl_windowmanager, wl_proxy_marshal((struct wl_proxy *) wl_windowmanager,
WL_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN, processid); WL_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN, processid);
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -43,13 +43,14 @@
#include "qwaylandwindowmanager-client-protocol.h" #include "qwaylandwindowmanager-client-protocol.h"
#include <stdint.h> #include <stdint.h>
#include <QDebug> #include <QDebug>
#include <QEvent> #include <QEvent>
#include <QtGui/QtEvents>
#include <QCoreApplication> #include <QCoreApplication>
const struct wl_windowmanager_listener QWaylandWindowManagerIntegration::mWindowManagerListener = { const struct wl_windowmanager_listener QWaylandWindowManagerIntegration::mWindowManagerListener = {
QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange, QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange,
QWaylandWindowManagerIntegration::wlHandleScreenOrientationChange,
}; };
QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::createIntegration(QWaylandDisplay *waylandDisplay) QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::createIntegration(QWaylandDisplay *waylandDisplay)
@ -78,6 +79,7 @@ struct wl_windowmanager *QWaylandWindowManagerIntegration::windowManager() const
void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
{ {
Q_UNUSED(version);
if (strcmp(interface, "wl_windowmanager") == 0) { if (strcmp(interface, "wl_windowmanager") == 0) {
QWaylandWindowManagerIntegration *integration = static_cast<QWaylandWindowManagerIntegration *>(data); QWaylandWindowManagerIntegration *integration = static_cast<QWaylandWindowManagerIntegration *>(data);
integration->mWaylandWindowManager = wl_windowmanager_create(display, id, 1); integration->mWaylandWindowManager = wl_windowmanager_create(display, id, 1);
@ -103,11 +105,19 @@ void QWaylandWindowManagerIntegration::authenticateWithToken(const QByteArray &t
void QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible) void QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible)
{ {
QWaylandWindowManagerIntegration *integration = (QWaylandWindowManagerIntegration *)data; Q_UNUSED(data);
Q_UNUSED(wl_windowmanager);
QEvent evt(visible != 0 ? QEvent::ApplicationActivated : QEvent::ApplicationDeactivated); QEvent evt(visible != 0 ? QEvent::ApplicationActivated : QEvent::ApplicationDeactivated);
QCoreApplication::sendEvent(QCoreApplication::instance(), &evt); QCoreApplication::sendEvent(QCoreApplication::instance(), &evt);
qDebug() << "OnScreenVisibility" << (visible != 0); qDebug() << "OnScreenVisibility" << (visible != 0);
} }
void QWaylandWindowManagerIntegration::wlHandleScreenOrientationChange(void *data, struct wl_windowmanager *wl_windowmanager, int screenOrientation)
{
Q_UNUSED(data);
Q_UNUSED(wl_windowmanager);
QScreenOrientationChangeEvent event(screenOrientation);
QCoreApplication::sendEvent(QCoreApplication::instance(), &event);
}

View File

@ -63,6 +63,7 @@ private:
const char *interface, uint32_t version, void *data); const char *interface, uint32_t version, void *data);
static void wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible); static void wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible);
static void wlHandleScreenOrientationChange(void *data, struct wl_windowmanager *wl_windowmanager, int screenOrientation);
private: private:
QWaylandDisplay *mWaylandDisplay; QWaylandDisplay *mWaylandDisplay;

View File

@ -26,12 +26,13 @@
#include "wayland-util.h" #include "wayland-util.h"
static const struct wl_message wl_windowmanager_requests[] = { static const struct wl_message wl_windowmanager_requests[] = {
{ "map_client_to_process", "u", NULL }, { "map_client_to_process", "u", NULL },
{ "authenticate_with_token", "s", NULL }, { "authenticate_with_token", "s", NULL },
}; };
static const struct wl_message wl_windowmanager_events[] = { static const struct wl_message wl_windowmanager_events[] = {
{ "client_onscreen_visibility", "i", NULL }, { "client_onscreen_visibility", "i", NULL },
{ "set_screen_rotation", "i", NULL },
}; };
WL_EXPORT const struct wl_interface wl_windowmanager_interface = { WL_EXPORT const struct wl_interface wl_windowmanager_interface = {