summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/android/android.pro3
-rw-r--r--src/plugins/platforms/android/opengl/opengl.pro30
-rw-r--r--src/plugins/platforms/android/raster/raster.pro19
-rw-r--r--src/plugins/platforms/android/src/android.json3
-rw-r--r--src/plugins/platforms/android/src/androidjniclipboard.cpp120
-rw-r--r--src/plugins/platforms/android/src/androidjniclipboard.h61
-rw-r--r--src/plugins/platforms/android/src/androidjniinput.cpp480
-rw-r--r--src/plugins/platforms/android/src/androidjniinput.h59
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp839
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.h120
-rw-r--r--src/plugins/platforms/android/src/androidjnimenu.cpp405
-rw-r--r--src/plugins/platforms/android/src/androidjnimenu.h69
-rw-r--r--src/plugins/platforms/android/src/androidplatformplugin.cpp66
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp78
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h68
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp72
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h73
-rw-r--r--src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp132
-rw-r--r--src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp288
-rw-r--r--src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h60
-rw-r--r--src/plugins/platforms/android/src/qandroidinputcontext.cpp644
-rw-r--r--src/plugins/platforms/android/src/qandroidinputcontext.h130
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformclipboard.cpp79
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformclipboard.h63
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp79
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformfontdatabase.h58
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.cpp283
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.h158
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenu.cpp167
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenu.h91
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenubar.cpp109
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenubar.h74
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp180
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenuitem.h99
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformservices.cpp83
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformservices.h61
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformtheme.cpp78
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformtheme.h56
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp71
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformscreen.h59
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp56
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformwindow.h60
-rw-r--r--src/plugins/platforms/android/src/raster/raster.pri7
-rw-r--r--src/plugins/platforms/android/src/src.pri47
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp4
-rw-r--r--src/plugins/platforms/platforms.pro2
46 files changed, 5841 insertions, 2 deletions
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
new file mode 100644
index 0000000000..aa5ab4ddbd
--- /dev/null
+++ b/src/plugins/platforms/android/android.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+
+SUBDIRS += raster opengl
diff --git a/src/plugins/platforms/android/opengl/opengl.pro b/src/plugins/platforms/android/opengl/opengl.pro
new file mode 100644
index 0000000000..301c8e6e4c
--- /dev/null
+++ b/src/plugins/platforms/android/opengl/opengl.pro
@@ -0,0 +1,30 @@
+TARGET = qtforandroidGL
+
+PLUGIN_TYPE = platforms
+load(qt_plugin)
+
+# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
+# Yes, the plugin imports itself statically
+DEFINES += QT_STATICPLUGIN ANDROID_PLUGIN_OPENGL
+
+!equals(ANDROID_PLATFORM, android-9) {
+ INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
+ LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
+} else {
+ LIBS += -ljnigraphics -landroid
+}
+
+EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/../src/opengl/qeglfshooks_android.cpp
+
+INCLUDEPATH += $$PWD/../src/opengl/
+
+HEADERS += \
+ $$PWD/../src/opengl/qandroidopenglcontext.h \
+ $$PWD/../src/opengl/qandroidopenglplatformwindow.h
+
+SOURCES += \
+ $$PWD/../src/opengl/qandroidopenglcontext.cpp \
+ $$PWD/../src/opengl/qandroidopenglplatformwindow.cpp
+
+include($$PWD/../../eglfs/eglfs.pri)
+include($$PWD/../src/src.pri)
diff --git a/src/plugins/platforms/android/raster/raster.pro b/src/plugins/platforms/android/raster/raster.pro
new file mode 100644
index 0000000000..53d8ee7a2b
--- /dev/null
+++ b/src/plugins/platforms/android/raster/raster.pro
@@ -0,0 +1,19 @@
+TARGET = qtforandroid
+
+PLUGIN_TYPE = platforms
+
+# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
+# Yes, the plugin imports itself statically
+DEFINES += QT_STATICPLUGIN
+
+load(qt_plugin)
+
+!contains(ANDROID_PLATFORM, android-9) {
+ INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
+ LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
+} else {
+ LIBS += -ljnigraphics -landroid
+}
+
+include($$PWD/../src/src.pri)
+include($$PWD/../src/raster/raster.pri)
diff --git a/src/plugins/platforms/android/src/android.json b/src/plugins/platforms/android/src/android.json
new file mode 100644
index 0000000000..6843bd3301
--- /dev/null
+++ b/src/plugins/platforms/android/src/android.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "android" ]
+}
diff --git a/src/plugins/platforms/android/src/androidjniclipboard.cpp b/src/plugins/platforms/android/src/androidjniclipboard.cpp
new file mode 100644
index 0000000000..05270ac374
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjniclipboard.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidjniclipboard.h"
+#include "androidjnimain.h"
+
+using namespace QtAndroid;
+namespace QtAndroidClipboard
+{
+ // Clipboard support
+ static jmethodID m_registerClipboardManagerMethodID = 0;
+ static jmethodID m_setClipboardTextMethodID = 0;
+ static jmethodID m_hasClipboardTextMethodID = 0;
+ static jmethodID m_getClipboardTextMethodID = 0;
+ // Clipboard support
+
+ void setClipboardListener(QAndroidPlatformClipboard *listener)
+ {
+ Q_UNUSED(listener);
+
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), m_registerClipboardManagerMethodID);
+ }
+
+ void setClipboardText(const QString &text)
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ jstring jtext = env.jniEnv->NewString(reinterpret_cast<const jchar *>(text.data()),
+ text.length());
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), m_setClipboardTextMethodID, jtext);
+ env.jniEnv->DeleteLocalRef(jtext);
+ }
+
+ bool hasClipboardText()
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return false;
+
+ return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_hasClipboardTextMethodID);
+ }
+
+ QString clipboardText()
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return QString();
+
+ jstring text = reinterpret_cast<jstring>(env.jniEnv->CallStaticObjectMethod(applicationClass(),
+ m_getClipboardTextMethodID));
+ const jchar *jstr = env.jniEnv->GetStringChars(text, 0);
+ QString str(reinterpret_cast<const QChar *>(jstr), env.jniEnv->GetStringLength(text));
+ env.jniEnv->ReleaseStringChars(text, jstr);
+ return str;
+ }
+
+
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
+ return false; \
+ }
+
+ bool registerNatives(JNIEnv *env)
+ {
+ jclass appClass = QtAndroid::applicationClass();
+
+ GET_AND_CHECK_STATIC_METHOD(m_registerClipboardManagerMethodID, appClass, "registerClipboardManager", "()V");
+ GET_AND_CHECK_STATIC_METHOD(m_setClipboardTextMethodID, appClass, "setClipboardText", "(Ljava/lang/String;)V");
+ GET_AND_CHECK_STATIC_METHOD(m_hasClipboardTextMethodID, appClass, "hasClipboardText", "()Z");
+ GET_AND_CHECK_STATIC_METHOD(m_getClipboardTextMethodID, appClass, "getClipboardText", "()Ljava/lang/String;");
+
+ return true;
+ }
+}
diff --git a/src/plugins/platforms/android/src/androidjniclipboard.h b/src/plugins/platforms/android/src/androidjniclipboard.h
new file mode 100644
index 0000000000..15cd93202e
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjniclipboard.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDJNICLIPBOARD_H
+#define ANDROIDJNICLIPBOARD_H
+
+#include <jni.h>
+#include <QString>
+
+class QAndroidPlatformClipboard;
+namespace QtAndroidClipboard
+{
+ // Clipboard support
+ void setClipboardListener(QAndroidPlatformClipboard *listener);
+ void setClipboardText(const QString &text);
+ bool hasClipboardText();
+ QString clipboardText();
+ // Clipboard support
+
+ bool registerNatives(JNIEnv *env);
+}
+
+#endif // ANDROIDJNICLIPBOARD_H
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp
new file mode 100644
index 0000000000..6a3dd1f349
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjniinput.cpp
@@ -0,0 +1,480 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidjniinput.h"
+#include "androidjnimain.h"
+
+#include <qpa/qwindowsysteminterface.h>
+#include <QTouchEvent>
+#include <QPointer>
+
+using namespace QtAndroid;
+
+namespace QtAndroidInput
+{
+ static jmethodID m_showSoftwareKeyboardMethodID = 0;
+ static jmethodID m_resetSoftwareKeyboardMethodID = 0;
+ static jmethodID m_hideSoftwareKeyboardMethodID = 0;
+ static jmethodID m_isSoftwareKeyboardVisibleMethodID = 0;
+ static jmethodID m_updateSelectionMethodID = 0;
+
+ static bool m_ignoreMouseEvents = false;
+
+ static QList<QWindowSystemInterface::TouchPoint> m_touchPoints;
+
+ static QPointer<QWindow> m_mouseGrabber;
+
+ void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID,
+ selStart, selEnd, candidatesStart, candidatesEnd);
+ }
+
+ void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints)
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ env.jniEnv->CallStaticVoidMethod(applicationClass(),
+ m_showSoftwareKeyboardMethodID,
+ left,
+ top,
+ width,
+ height,
+ inputHints);
+ }
+
+ void resetSoftwareKeyboard()
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), m_resetSoftwareKeyboardMethodID);
+ }
+
+ void hideSoftwareKeyboard()
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), m_hideSoftwareKeyboardMethodID);
+ }
+
+ bool isSoftwareKeyboardVisible()
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return false;
+
+ return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_isSoftwareKeyboardVisibleMethodID);
+ }
+
+
+ static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
+ {
+ if (m_ignoreMouseEvents)
+ return;
+
+ QPoint globalPos(x,y);
+ QWindow *tlw = topLevelWindowAt(globalPos);
+ m_mouseGrabber = tlw;
+ QPoint localPos = tlw ? (globalPos - tlw->position()) : globalPos;
+ QWindowSystemInterface::handleMouseEvent(tlw,
+ localPos,
+ globalPos,
+ Qt::MouseButtons(Qt::LeftButton));
+ }
+
+ static void mouseUp(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
+ {
+ QPoint globalPos(x,y);
+ QWindow *tlw = m_mouseGrabber.data();
+ if (!tlw)
+ tlw = topLevelWindowAt(globalPos);
+ QPoint localPos = tlw ? (globalPos -tlw->position()) : globalPos;
+ QWindowSystemInterface::handleMouseEvent(tlw, localPos, globalPos
+ , Qt::MouseButtons(Qt::NoButton));
+ m_ignoreMouseEvents = false;
+ m_mouseGrabber = 0;
+ }
+
+ static void mouseMove(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
+ {
+
+ if (m_ignoreMouseEvents)
+ return;
+
+ QPoint globalPos(x,y);
+ QWindow *tlw = m_mouseGrabber.data();
+ if (!tlw)
+ tlw = topLevelWindowAt(globalPos);
+ QPoint localPos = tlw ? (globalPos-tlw->position()) : globalPos;
+ QWindowSystemInterface::handleMouseEvent(tlw,
+ localPos,
+ globalPos,
+ Qt::MouseButtons(Qt::LeftButton));
+ }
+
+ static void longPress(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
+ {
+ m_ignoreMouseEvents = true;
+ QPoint globalPos(x,y);
+ QWindow *tlw = topLevelWindowAt(globalPos);
+ QPoint localPos = tlw ? (globalPos-tlw->position()) : globalPos;
+
+ // Release left button
+ QWindowSystemInterface::handleMouseEvent(tlw,
+ localPos,
+ globalPos,
+ Qt::MouseButtons(Qt::NoButton));
+
+ // Press right button
+ QWindowSystemInterface::handleMouseEvent(tlw,
+ localPos,
+ globalPos,
+ Qt::MouseButtons(Qt::RightButton));
+ }
+
+ static void touchBegin(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/)
+ {
+ m_touchPoints.clear();
+ }
+
+ static void touchAdd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint id, jint action, jboolean /*primary*/, jint x, jint y, jfloat size, jfloat pressure)
+ {
+ Qt::TouchPointState state = Qt::TouchPointStationary;
+ switch (action) {
+ case 0:
+ state = Qt::TouchPointPressed;
+ break;
+ case 1:
+ state = Qt::TouchPointMoved;
+ break;
+ case 2:
+ state = Qt::TouchPointStationary;
+ break;
+ case 3:
+ state = Qt::TouchPointReleased;
+ break;
+ }
+
+ const int dw = desktopWidthPixels();
+ const int dh = desktopHeightPixels();
+ QWindowSystemInterface::TouchPoint touchPoint;
+ touchPoint.id = id;
+ touchPoint.pressure = pressure;
+ touchPoint.normalPosition = QPointF(double(x / dw), double(y / dh));
+ touchPoint.state = state;
+ touchPoint.area = QRectF(x - double(dw*size) / 2.0,
+ y - double(dh*size) / 2.0,
+ double(dw*size),
+ double(dh*size));
+ m_touchPoints.push_back(touchPoint);
+ }
+
+ static void touchEnd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint action)
+ {
+ QEvent::Type eventType = QEvent::None;
+ switch (action) {
+ case 0:
+ eventType = QEvent::TouchBegin;
+ break;
+ case 1:
+ eventType = QEvent::TouchUpdate;
+ break;
+ case 2:
+ eventType = QEvent::TouchEnd;
+ break;
+ }
+
+ // FIXME
+ // QWindowSystemInterface::handleTouchEvent(0, 0, eventType, QTouchEvent::TouchScreen, m_touchPoints);
+ }
+
+ static int mapAndroidKey(int key)
+ {
+ // 0--9 0x00000007 -- 0x00000010
+ if (key >= 0x00000007 && key <= 0x00000010)
+ return Qt::Key_0 + key - 0x00000007;
+
+ // A--Z 0x0000001d -- 0x00000036
+ if (key >= 0x0000001d && key <= 0x00000036)
+ return Qt::Key_A + key - 0x0000001d;
+
+ switch (key) {
+ case 0x00000039:
+ case 0x0000003a:
+ return Qt::Key_Alt;
+
+ case 0x0000004b:
+ return Qt::Key_Apostrophe;
+
+ case 0x00000004: // KEYCODE_BACK
+ return Qt::Key_Back;
+
+ case 0x00000049:
+ return Qt::Key_Backslash;
+
+ case 0x00000005:
+ return Qt::Key_Call;
+
+ case 0x0000001b:
+ return Qt::Key_WebCam;
+
+ case 0x0000001c:
+ return Qt::Key_Clear;
+
+ case 0x00000037:
+ return Qt::Key_Comma;
+
+ case 0x00000043:
+ return Qt::Key_Backspace;
+
+ case 0x00000017: // KEYCODE_DPAD_CENTER
+ return Qt::Key_Enter;
+
+ case 0x00000014: // KEYCODE_DPAD_DOWN
+ return Qt::Key_Down;
+
+ case 0x00000015: //KEYCODE_DPAD_LEFT
+ return Qt::Key_Left;
+
+ case 0x00000016: //KEYCODE_DPAD_RIGHT
+ return Qt::Key_Right;
+
+ case 0x00000013: //KEYCODE_DPAD_UP
+ return Qt::Key_Up;
+
+ case 0x00000006: //KEYCODE_ENDCALL
+ return Qt::Key_Hangup;
+
+ case 0x00000042:
+ return Qt::Key_Return;
+
+ case 0x00000041: //KEYCODE_ENVELOPE
+ return Qt::Key_LaunchMail;
+
+ case 0x00000046:
+ return Qt::Key_Equal;
+
+ case 0x00000040:
+ return Qt::Key_Explorer;
+
+ case 0x00000003:
+ return Qt::Key_Home;
+
+ case 0x00000047:
+ return Qt::Key_BracketLeft;
+
+ case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD
+ return Qt::Key_Forward;
+
+ case 0x00000057:
+ return Qt::Key_MediaNext;
+
+ case 0x00000055:
+ return Qt::Key_MediaPlay;
+
+ case 0x00000058:
+ return Qt::Key_MediaPrevious;
+
+ case 0x00000059:
+ return Qt::Key_AudioRewind;
+
+ case 0x00000056:
+ return Qt::Key_MediaStop;
+
+ case 0x00000052: //KEYCODE_MENU
+ return Qt::Key_Menu;
+
+ case 0x00000045:
+ return Qt::Key_Minus;
+
+ case 0x0000005b:
+ return Qt::Key_VolumeMute;
+
+ case 0x0000004e:
+ return Qt::Key_NumLock;
+
+ case 0x00000038:
+ return Qt::Key_Period;
+
+ case 0x00000051:
+ return Qt::Key_Plus;
+
+ case 0x0000001a:
+ return Qt::Key_PowerOff;
+
+ case 0x00000048:
+ return Qt::Key_BracketRight;
+
+ case 0x00000054:
+ return Qt::Key_Search;
+
+ case 0x0000004a:
+ return Qt::Key_Semicolon;
+
+ case 0x0000003b:
+ case 0x0000003c:
+ return Qt::Key_Shift;
+
+ case 0x0000004c:
+ return Qt::Key_Slash;
+
+ case 0x00000001:
+ return Qt::Key_Left;
+
+ case 0x00000002:
+ return Qt::Key_Right;
+
+ case 0x0000003e:
+ return Qt::Key_Space;
+
+ case 0x0000003f: // KEYCODE_SYM
+ return Qt::Key_Meta;
+
+ case 0x0000003d:
+ return Qt::Key_Tab;
+
+ case 0x00000019:
+ return Qt::Key_VolumeDown;
+
+ case 0x00000018:
+ return Qt::Key_VolumeUp;
+
+ case 0x00000000: // KEYCODE_UNKNOWN
+ case 0x00000011: // KEYCODE_STAR ?!?!?
+ case 0x00000012: // KEYCODE_POUND ?!?!?
+ case 0x00000053: // KEYCODE_NOTIFICATION ?!?!?
+ case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!?
+ case 0x00000044: // KEYCODE_GRAVE ?!?!?
+ case 0x00000050: // KEYCODE_FOCUS ?!?!?
+ return Qt::Key_Any;
+
+ default:
+ return 0;
+ }
+ }
+
+ static void keyDown(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier)
+ {
+ Qt::KeyboardModifiers modifiers;
+ if (modifier & 1)
+ modifiers |= Qt::ShiftModifier;
+
+ if (modifier & 2)
+ modifiers |= Qt::AltModifier;
+
+ if (modifier & 4)
+ modifiers |= Qt::MetaModifier;
+
+ QWindowSystemInterface::handleKeyEvent(0,
+ QEvent::KeyPress,
+ mapAndroidKey(key),
+ modifiers,
+ QChar(unicode),
+ true);
+ }
+
+ static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier)
+ {
+ Qt::KeyboardModifiers modifiers;
+ if (modifier & 1)
+ modifiers |= Qt::ShiftModifier;
+
+ if (modifier & 2)
+ modifiers |= Qt::AltModifier;
+
+ if (modifier & 4)
+ modifiers |= Qt::MetaModifier;
+
+ QWindowSystemInterface::handleKeyEvent(0,
+ QEvent::KeyRelease,
+ mapAndroidKey(key),
+ modifiers,
+ QChar(unicode),
+ true);
+ }
+
+
+ static JNINativeMethod methods[] = {
+ {"touchBegin","(I)V",(void*)touchBegin},
+ {"touchAdd","(IIIZIIFF)V",(void*)touchAdd},
+ {"touchEnd","(II)V",(void*)touchEnd},
+ {"mouseDown", "(III)V", (void *)mouseDown},
+ {"mouseUp", "(III)V", (void *)mouseUp},
+ {"mouseMove", "(III)V", (void *)mouseMove},
+ {"longPress", "(III)V", (void *)longPress},
+ {"keyDown", "(III)V", (void *)keyDown},
+ {"keyUp", "(III)V", (void *)keyUp}
+ };
+
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
+ return false; \
+ }
+
+ bool registerNatives(JNIEnv *env)
+ {
+ jclass appClass = QtAndroid::applicationClass();
+
+ if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
+ return false;
+ }
+
+ GET_AND_CHECK_STATIC_METHOD(m_showSoftwareKeyboardMethodID, appClass, "showSoftwareKeyboard", "(IIIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_resetSoftwareKeyboardMethodID, appClass, "resetSoftwareKeyboard", "()V");
+ GET_AND_CHECK_STATIC_METHOD(m_hideSoftwareKeyboardMethodID, appClass, "hideSoftwareKeyboard", "()V");
+ GET_AND_CHECK_STATIC_METHOD(m_isSoftwareKeyboardVisibleMethodID, appClass, "isSoftwareKeyboardVisible", "()Z");
+ GET_AND_CHECK_STATIC_METHOD(m_updateSelectionMethodID, appClass, "updateSelection", "(IIII)V");
+ return true;
+ }
+}
diff --git a/src/plugins/platforms/android/src/androidjniinput.h b/src/plugins/platforms/android/src/androidjniinput.h
new file mode 100644
index 0000000000..a78c7519db
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjniinput.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDJNIINPUT_H
+#define ANDROIDJNIINPUT_H
+#include <jni.h>
+
+namespace QtAndroidInput
+{
+ // Software keyboard support
+ void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints);
+ void resetSoftwareKeyboard();
+ void hideSoftwareKeyboard();
+ bool isSoftwareKeyboardVisible();
+ void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd);
+ // Software keyboard support
+
+ bool registerNatives(JNIEnv *env);
+}
+
+#endif // ANDROIDJNIINPUT_H
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
new file mode 100644
index 0000000000..2a4c48df3c
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -0,0 +1,839 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <qcoreapplication.h>
+#include <qimage.h>
+#include <qpoint.h>
+#include <qplugin.h>
+#include <qsemaphore.h>
+#include <qmutex.h>
+#include <qdebug.h>
+#include <qglobal.h>
+#include <qobjectdefs.h>
+#include <stdlib.h>
+
+#include "androidjnimain.h"
+#include "androidjniinput.h"
+#include "androidjniclipboard.h"
+#include "androidjnimenu.h"
+#include "qandroidplatformintegration.h"
+#include <QtWidgets/QApplication>
+
+#include <qabstracteventdispatcher.h>
+
+#include <android/bitmap.h>
+#include <android/asset_manager_jni.h>
+#include "qandroidassetsfileenginehandler.h"
+#include <android/api-level.h>
+
+#include <qpa/qwindowsysteminterface.h>
+
+#ifdef ANDROID_PLUGIN_OPENGL
+# include "qandroidopenglplatformwindow.h"
+#endif
+
+#if __ANDROID_API__ > 8
+# include <android/native_window_jni.h>
+#endif
+
+static jmethodID m_redrawSurfaceMethodID = 0;
+
+Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
+
+static JavaVM *m_javaVM = NULL;
+static jclass m_applicationClass = NULL;
+static jobject m_classLoaderObject = NULL;
+static jmethodID m_loadClassMethodID = NULL;
+static AAssetManager *m_assetManager = NULL;
+static jobject m_resourcesObj;
+static jobject m_activityObject = NULL;
+
+static jclass m_bitmapClass = 0;
+static jmethodID m_createBitmapMethodID = 0;
+static jobject m_ARGB_8888_BitmapConfigValue = 0;
+static jobject m_RGB_565_BitmapConfigValue = 0;
+
+static jclass m_bitmapDrawableClass = 0;
+static jmethodID m_bitmapDrawableConstructorMethodID = 0;
+
+extern "C" typedef int (*Main)(int, char **); //use the standard main method to start the application
+static Main m_main = NULL;
+static void *m_mainLibraryHnd = NULL;
+static QList<QByteArray> m_applicationParams;
+
+#ifndef ANDROID_PLUGIN_OPENGL
+static jobject m_surface = NULL;
+#else
+static EGLNativeWindowType m_nativeWindow = 0;
+static QSemaphore m_waitForWindowSemaphore;
+static bool m_waitForWindow = false;
+
+static jfieldID m_surfaceFieldID = 0;
+#endif
+
+
+static QSemaphore m_quitAppSemaphore;
+static QMutex m_surfaceMutex(QMutex::Recursive);
+static QSemaphore m_pauseApplicationSemaphore;
+static QMutex m_pauseApplicationMutex;
+
+static QAndroidPlatformIntegration *m_androidPlatformIntegration = 0;
+
+static int m_desktopWidthPixels = 0;
+static int m_desktopHeightPixels = 0;
+
+static volatile bool m_pauseApplication;
+
+static jmethodID m_setFullScreenMethodID = 0;
+
+static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = 0;
+
+
+
+static const char m_qtTag[] = "Qt";
+static const char m_classErrorMsg[] = "Can't find class \"%s\"";
+static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
+
+static inline void checkPauseApplication()
+{
+ m_pauseApplicationMutex.lock();
+ if (m_pauseApplication) {
+ m_pauseApplicationMutex.unlock();
+ m_pauseApplicationSemaphore.acquire(); // wait until surface is created
+
+ m_pauseApplicationMutex.lock();
+ m_pauseApplication = false;
+ m_pauseApplicationMutex.unlock();
+
+ //FIXME
+// QWindowSystemInterface::handleScreenAvailableGeometryChange(0);
+// QWindowSystemInterface::handleScreenGeometryChange(0);
+ } else {
+ m_pauseApplicationMutex.unlock();
+ }
+}
+
+namespace QtAndroid
+{
+#ifndef ANDROID_PLUGIN_OPENGL
+ void flushImage(const QPoint &pos, const QImage &image, const QRect &destinationRect)
+ {
+ checkPauseApplication();
+ QMutexLocker locker(&m_surfaceMutex);
+ if (!m_surface)
+ return;
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ int bpp = 2;
+ AndroidBitmapInfo info;
+ int ret;
+
+ if ((ret = AndroidBitmap_getInfo(env.jniEnv, m_surface, &info)) < 0) {
+ qWarning() << "AndroidBitmap_getInfo() failed ! error=" << ret;
+ m_javaVM->DetachCurrentThread();
+ return;
+ }
+
+ if (info.format != ANDROID_BITMAP_FORMAT_RGB_565) {
+ qWarning() << "Bitmap format is not RGB_565!";
+ m_javaVM->DetachCurrentThread();
+ return;
+ }
+
+ void *pixels;
+ unsigned char *screenBits;
+ if ((ret = AndroidBitmap_lockPixels(env.jniEnv, m_surface, &pixels)) < 0) {
+ qWarning() << "AndroidBitmap_lockPixels() failed! error=" << ret;
+ m_javaVM->DetachCurrentThread();
+ return;
+ }
+
+ screenBits = static_cast<unsigned char *>(pixels);
+ int sbpl = info.stride;
+ int swidth = info.width;
+ int sheight = info.height;
+
+ unsigned sposx = pos.x() + destinationRect.x();
+ unsigned sposy = pos.y() + destinationRect.y();
+
+ screenBits += sposy * sbpl;
+
+ unsigned ibpl = image.bytesPerLine();
+ unsigned iposx = destinationRect.x();
+ unsigned iposy = destinationRect.y();
+
+ const unsigned char *imageBits = static_cast<const unsigned char *>(image.bits());
+ imageBits += iposy * ibpl;
+
+ unsigned width = swidth - sposx < unsigned(destinationRect.width())
+ ? (swidth-sposx)
+ : destinationRect.width();
+ unsigned height = sheight - sposy < unsigned(destinationRect.height())
+ ? (sheight - sposy)
+ : destinationRect.height();
+
+ for (unsigned y = 0; y < height; y++) {
+ memcpy(screenBits + y*sbpl + sposx*bpp,
+ imageBits + y*ibpl + iposx*bpp,
+ width*bpp);
+ }
+ AndroidBitmap_unlockPixels(env.jniEnv, m_surface);
+
+ env.jniEnv->CallStaticVoidMethod(m_applicationClass,
+ m_redrawSurfaceMethodID,
+ jint(destinationRect.left()),
+ jint(destinationRect.top()),
+ jint(destinationRect.right() + 1),
+ jint(destinationRect.bottom() + 1));
+#warning FIXME dirty hack, figure out why it needs to add 1 to right and bottom !!!!
+ }
+
+#else // for #ifndef ANDROID_PLUGIN_OPENGL
+ EGLNativeWindowType nativeWindow(bool waitForWindow)
+ {
+ m_surfaceMutex.lock();
+ if (!m_nativeWindow && waitForWindow) {
+ m_waitForWindow = true;
+ m_surfaceMutex.unlock();
+ m_waitForWindowSemaphore.acquire();
+ m_waitForWindow = false;
+ return m_nativeWindow;
+ }
+ m_surfaceMutex.unlock();
+ return m_nativeWindow;
+ }
+
+ QSize nativeWindowSize()
+ {
+ if (m_nativeWindow == 0)
+ return QAndroidPlatformIntegration::defaultDesktopSize();
+
+ int width = ANativeWindow_getWidth(m_nativeWindow);
+ int height = ANativeWindow_getHeight(m_nativeWindow);
+
+ return QSize(width, height);
+ }
+#endif
+
+ void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration)
+ {
+ m_surfaceMutex.lock();
+ m_androidPlatformIntegration = androidPlatformIntegration;
+ m_surfaceMutex.unlock();
+ }
+
+ void setFullScreen(QWidget *widget)
+ {
+ AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return;
+
+ bool fullScreen = widget->isFullScreen();
+ if (!fullScreen) {
+ foreach (QWidget *w, qApp->topLevelWidgets()) {
+ fullScreen |= w->isFullScreen();
+ if (fullScreen)
+ break;
+ }
+ }
+
+ env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, fullScreen);
+ }
+
+ QWindow *topLevelWindowAt(const QPoint &globalPos)
+ {
+ return m_androidPlatformIntegration
+ ? m_androidPlatformIntegration->screen()->topLevelAt(globalPos)
+ : 0;
+ }
+
+ int desktopWidthPixels()
+ {
+ return m_desktopWidthPixels;
+ }
+
+ int desktopHeightPixels()
+ {
+ return m_desktopHeightPixels;
+ }
+
+ JavaVM *javaVM()
+ {
+ return m_javaVM;
+ }
+
+ jclass findClass(const QString &className, JNIEnv *env)
+ {
+ return static_cast<jclass>(env->CallObjectMethod(m_classLoaderObject,
+ m_loadClassMethodID,
+ env->NewString(reinterpret_cast<const jchar *>(className.constData()),
+ jsize(className.length()))));
+ }
+
+ AAssetManager *assetManager()
+ {
+ return m_assetManager;
+ }
+
+ jclass applicationClass()
+ {
+ return m_applicationClass;
+ }
+
+ jobject activity()
+ {
+ return m_activityObject;
+ }
+
+ jobject createBitmap(QImage img, JNIEnv *env)
+ {
+ if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16)
+ img = img.convertToFormat(QImage::Format_ARGB32);
+
+ jobject bitmap = env->CallStaticObjectMethod(m_bitmapClass,
+ m_createBitmapMethodID,
+ img.width(),
+ img.height(),
+ img.format() == QImage::Format_ARGB32
+ ? m_ARGB_8888_BitmapConfigValue
+ : m_RGB_565_BitmapConfigValue);
+ if (!bitmap)
+ return 0;
+
+ AndroidBitmapInfo info;
+ if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) {
+ env->DeleteLocalRef(bitmap);
+ return 0;
+ }
+
+ void *pixels;
+ if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
+ env->DeleteLocalRef(bitmap);
+ return 0;
+ }
+
+ if (info.stride == uint(img.bytesPerLine())
+ && info.width == uint(img.width())
+ && info.height == uint(img.height())) {
+ memcpy(pixels, img.constBits(), info.stride * info.height);
+ } else {
+ uchar *bmpPtr = static_cast<uchar *>(pixels);
+ const unsigned width = qMin(info.width, (uint)img.width()); //should be the same
+ const unsigned height = qMin(info.height, (uint)img.height()); //should be the same
+ for (unsigned y = 0; y < height; y++, bmpPtr += info.stride)
+ memcpy(bmpPtr, img.constScanLine(y), width);
+ }
+ AndroidBitmap_unlockPixels(env, bitmap);
+ return bitmap;
+ }
+
+ jobject createBitmapDrawable(jobject bitmap, JNIEnv *env)
+ {
+ if (!bitmap)
+ return 0;
+
+ return env->NewObject(m_bitmapDrawableClass,
+ m_bitmapDrawableConstructorMethodID,
+ m_resourcesObj,
+ bitmap);
+ }
+
+ const char *classErrorMsgFmt()
+ {
+ return m_classErrorMsg;
+ }
+
+ const char *methodErrorMsgFmt()
+ {
+ return m_methodErrorMsg;
+ }
+
+ const char *qtTagText()
+ {
+ return m_qtTag;
+ }
+}
+
+static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/)
+{
+#ifndef ANDROID_PLUGIN_OPENGL
+ m_surface = 0;
+#else
+ m_nativeWindow = 0;
+ m_waitForWindow = false;
+#endif
+
+ m_androidPlatformIntegration = 0;
+ m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler();
+
+#ifdef ANDROID_PLUGIN_OPENGL
+ return true;
+#else
+ return false;
+#endif
+}
+
+static void *startMainMethod(void */*data*/)
+{
+ char const **params;
+ params = static_cast<char const **>(malloc(m_applicationParams.length() * sizeof(char *)));
+ for (int i = 0; i < m_applicationParams.size(); i++)
+ params[i] = static_cast<const char *>(m_applicationParams[i].constData());
+
+ int ret = m_main(m_applicationParams.length(), const_cast<char **>(params));
+
+ free(params);
+ Q_UNUSED(ret);
+
+ if (m_mainLibraryHnd) {
+ int res = dlclose(m_mainLibraryHnd);
+ if (res < 0)
+ qWarning() << "dlclose failed:" << dlerror();
+ }
+
+ QtAndroid::AttachedJNIEnv env;
+ if (!env.jniEnv)
+ return 0;
+
+ if (m_applicationClass) {
+ jmethodID quitApp = env.jniEnv->GetStaticMethodID(m_applicationClass, "quitApp", "()V");
+ env.jniEnv->CallStaticVoidMethod(m_applicationClass, quitApp);
+ }
+
+ return 0;
+}
+
+static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring paramsString, jstring environmentString)
+{
+ m_mainLibraryHnd = NULL;
+ const char *nativeString = env->GetStringUTFChars(environmentString, 0);
+ QByteArray string = nativeString;
+ env->ReleaseStringUTFChars(environmentString, nativeString);
+ m_applicationParams=string.split('\t');
+ foreach (string, m_applicationParams) {
+ if (putenv(string.constData()))
+ qWarning() << "Can't set environment" << string;
+ }
+
+ nativeString = env->GetStringUTFChars(paramsString, 0);
+ string = nativeString;
+ env->ReleaseStringUTFChars(paramsString, nativeString);
+
+ m_applicationParams=string.split('\t');
+
+ // Go home
+ QDir::setCurrent(QDir::homePath());
+
+ //look for main()
+ if (m_applicationParams.length()) {
+ // Obtain a handle to the main library (the library that contains the main() function).
+ // This library should already be loaded, and calling dlopen() will just return a reference to it.
+ m_mainLibraryHnd = dlopen(m_applicationParams.first().data(), 0);
+ if (m_mainLibraryHnd == NULL) {
+ qCritical() << "dlopen failed:" << dlerror();
+ return false;
+ }
+ m_main = (Main)dlsym(m_mainLibraryHnd, "main");
+ } else {
+ qWarning() << "No main library was specified; searching entire process (this is slow!)";
+ m_main = (Main)dlsym(RTLD_DEFAULT, "main");
+ }
+
+ if (!m_main) {
+ qCritical() << "dlsym failed:" << dlerror();
+ qCritical() << "Could not find main method";
+ return false;
+ }
+
+ pthread_t appThread;
+ return pthread_create(&appThread, NULL, startMainMethod, NULL) == 0;
+}
+
+static void pauseQtApp(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ m_surfaceMutex.lock();
+ m_pauseApplicationMutex.lock();
+
+ if (m_androidPlatformIntegration)
+ m_androidPlatformIntegration->pauseApp();
+ m_pauseApplication = true;
+
+ m_pauseApplicationMutex.unlock();
+ m_surfaceMutex.unlock();
+}
+
+static void resumeQtApp(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ m_surfaceMutex.lock();
+ m_pauseApplicationMutex.lock();
+ if (m_androidPlatformIntegration)
+ m_androidPlatformIntegration->resumeApp();
+
+ if (m_pauseApplication)
+ m_pauseApplicationSemaphore.release();
+
+ m_pauseApplicationMutex.unlock();
+ m_surfaceMutex.unlock();
+}
+
+static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/)
+{
+#ifndef ANDROID_PLUGIN_OPENGL
+ if (m_surface) {
+ env->DeleteGlobalRef(m_surface);
+ m_surface = 0;
+ }
+#else
+ Q_UNUSED(env);
+#endif
+
+ m_androidPlatformIntegration = 0;
+ delete m_androidAssetsFileEngineHandler;
+}
+
+static void terminateQt(JNIEnv *env, jclass /*clazz*/)
+{
+#ifndef ANDROID_PLUGIN_OPENGL
+ if (m_surface)
+ env->DeleteGlobalRef(m_surface);
+#endif
+ env->DeleteGlobalRef(m_applicationClass);
+ env->DeleteGlobalRef(m_classLoaderObject);
+ env->DeleteGlobalRef(m_resourcesObj);
+ env->DeleteGlobalRef(m_activityObject);
+ env->DeleteGlobalRef(m_bitmapClass);
+ env->DeleteGlobalRef(m_ARGB_8888_BitmapConfigValue);
+ env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue);
+ env->DeleteGlobalRef(m_bitmapDrawableClass);
+}
+
+#ifdef ANDROID_PLUGIN_OPENGL
+#if __ANDROID_API__ < 9
+struct FakeNativeWindow
+{
+ long long dummyNativeWindow;// force 64 bits alignment
+};
+
+class FakeSurface: public FakeNativeWindow
+{
+public:
+ virtual void FakeSurfaceMethod()
+ {
+ fakeSurface = 0;
+ }
+
+ int fakeSurface;
+};
+
+EGLNativeWindowType ANativeWindow_fromSurface(JNIEnv *env, jobject jSurface)
+{
+ FakeSurface *surface = static_cast<FakeSurface *>(env->GetIntField(jSurface, m_surfaceFieldID));
+ return static_cast<EGLNativeWindowType>(static_cast<FakeNativeWindow*>(surface));
+}
+#endif // __ANDROID_API__ < 9
+#endif // ANDROID_PLUGIN_OPENGL
+
+static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
+{
+#ifndef ANDROID_PLUGIN_OPENGL
+ if (m_surface)
+ env->DeleteGlobalRef(m_surface);
+ m_surface = env->NewGlobalRef(jSurface);
+#else
+ m_surfaceMutex.lock();
+ EGLNativeWindowType nativeWindow = ANativeWindow_fromSurface(env, jSurface);
+ bool sameNativeWindow = (nativeWindow != 0 && nativeWindow == m_nativeWindow);
+
+ m_nativeWindow = nativeWindow;
+ if (m_waitForWindow)
+ m_waitForWindowSemaphore.release();
+ if (m_androidPlatformIntegration && !sameNativeWindow) {
+ m_surfaceMutex.unlock();
+ m_androidPlatformIntegration->surfaceChanged();
+ } else if (m_androidPlatformIntegration && sameNativeWindow) {
+ QAndroidOpenGLPlatformWindow *window = m_androidPlatformIntegration->primaryWindow();
+ QPlatformScreen *screen = m_androidPlatformIntegration->screen();
+ QSize size = QtAndroid::nativeWindowSize();
+
+ QRect geometry(QPoint(0, 0), size);
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry);
+ QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry);
+
+ if (window != 0) {
+ window->lock();
+ window->scheduleResize(size);
+
+ QWindowSystemInterface::handleExposeEvent(window->window(),
+ QRegion(window->window()->geometry()));
+ window->unlock();
+ }
+
+ m_surfaceMutex.unlock();
+ } else {
+ m_surfaceMutex.unlock();
+ }
+#endif // for #ifndef ANDROID_PLUGIN_OPENGL
+}
+
+static void destroySurface(JNIEnv *env, jobject /*thiz*/)
+{
+#ifndef ANDROID_PLUGIN_OPENGL
+ if (m_surface) {
+ env->DeleteGlobalRef(m_surface);
+ m_surface = 0;
+ }
+#else
+ Q_UNUSED(env);
+ m_nativeWindow = 0;
+ if (m_androidPlatformIntegration != 0)
+ m_androidPlatformIntegration->invalidateNativeSurface();
+#endif
+}
+
+static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
+ jint /*widthPixels*/, jint /*heightPixels*/,
+ jint desktopWidthPixels, jint desktopHeightPixels,
+ jdouble xdpi, jdouble ydpi)
+{
+ m_desktopWidthPixels = desktopWidthPixels;
+ m_desktopHeightPixels = desktopHeightPixels;
+
+ if (!m_androidPlatformIntegration) {
+ QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,desktopHeightPixels,
+ qRound(double(desktopWidthPixels) / xdpi * 25.4),
+ qRound(double(desktopHeightPixels) / ydpi * 25.4));
+ } else {
+ m_androidPlatformIntegration->setDisplayMetrics(qRound(double(desktopWidthPixels) / xdpi * 25.4),
+ qRound(double(desktopHeightPixels) / ydpi * 25.4));
+ m_androidPlatformIntegration->setDesktopSize(desktopWidthPixels, desktopHeightPixels);
+ }
+}
+
+static void lockSurface(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ m_surfaceMutex.lock();
+}
+
+static void unlockSurface(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ m_surfaceMutex.unlock();
+}
+
+static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidPlatformIntegration)
+ return;
+
+ if (qApp != 0) {
+ foreach (QWidget *w, qApp->topLevelWidgets())
+ w->update();
+ }
+
+#ifndef ANDROID_PLUGIN_OPENGL
+ QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
+ QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry()));
+#else
+ qWarning("updateWindow: Dirty screen not implemented yet on OpenGL");
+#endif
+}
+
+static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation)
+{
+ if (m_androidPlatformIntegration == 0)
+ return;
+
+ Qt::ScreenOrientation screenOrientation = newOrientation == 1
+ ? Qt::PortraitOrientation
+ : Qt::LandscapeOrientation;
+ QPlatformScreen *screen = m_androidPlatformIntegration->screen();
+ QWindowSystemInterface::handleScreenOrientationChange(screen->screen(),
+ screenOrientation);
+}
+
+static JNINativeMethod methods[] = {
+ {"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin},
+ {"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
+ {"pauseQtApp", "()V", (void *)pauseQtApp},
+ {"resumeQtApp", "()V", (void *)resumeQtApp},
+ {"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin},
+ {"terminateQt", "()V", (void *)terminateQt},
+ {"setDisplayMetrics", "(IIIIDD)V", (void *)setDisplayMetrics},
+ {"setSurface", "(Ljava/lang/Object;)V", (void *)setSurface},
+ {"destroySurface", "()V", (void *)destroySurface},
+ {"lockSurface", "()V", (void *)lockSurface},
+ {"unlockSurface", "()V", (void *)unlockSurface},
+ {"updateWindow", "()V", (void *)updateWindow},
+ {"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged}
+};
+
+#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
+clazz = env->FindClass(CLASS_NAME); \
+if (!clazz) { \
+ __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_classErrorMsg, CLASS_NAME); \
+ return JNI_FALSE; \
+}
+
+#define GET_AND_CHECK_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
+ return JNI_FALSE; \
+}
+
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
+ return JNI_FALSE; \
+}
+
+#define GET_AND_CHECK_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \
+VAR = env->GetFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \
+if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, FIELD_NAME, FIELD_SIGNATURE); \
+ return JNI_FALSE; \
+}
+
+#define GET_AND_CHECK_STATIC_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \
+VAR = env->GetStaticFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \
+if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, FIELD_NAME, FIELD_SIGNATURE); \
+ return JNI_FALSE; \
+}
+
+static int registerNatives(JNIEnv *env)
+{
+ jclass clazz;
+ FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative");
+ m_applicationClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+
+ if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
+ return JNI_FALSE;
+ }
+
+ GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V");
+
+#ifdef ANDROID_PLUGIN_OPENGL
+ FIND_AND_CHECK_CLASS("android/view/Surface");
+#if __ANDROID_API__ < 9
+# define ANDROID_VIEW_SURFACE_JNI_ID "mSurface"
+#else
+# define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface"
+#endif
+ GET_AND_CHECK_FIELD(m_surfaceFieldID, clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I");
+#endif
+
+ jmethodID methodID;
+ GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;");
+ jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID);
+ m_activityObject = env->NewGlobalRef(activityObject);
+ GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "classLoader", "()Ljava/lang/ClassLoader;");
+ m_classLoaderObject = env->NewGlobalRef(env->CallStaticObjectMethod(m_applicationClass, methodID));
+
+ clazz = env->GetObjectClass(m_classLoaderObject);
+ GET_AND_CHECK_METHOD(m_loadClassMethodID, clazz, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+
+ FIND_AND_CHECK_CLASS("android/content/ContextWrapper");
+ GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;");
+ m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(activityObject, methodID));
+
+ GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;");
+ m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(activityObject, methodID));
+
+ FIND_AND_CHECK_CLASS("android/graphics/Bitmap");
+ m_bitmapClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ GET_AND_CHECK_STATIC_METHOD(m_createBitmapMethodID, m_bitmapClass
+ , "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
+
+ FIND_AND_CHECK_CLASS("android/graphics/Bitmap$Config");
+ jfieldID fieldId;
+ GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
+ m_ARGB_8888_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
+ GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "RGB_565", "Landroid/graphics/Bitmap$Config;");
+ m_RGB_565_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
+
+ FIND_AND_CHECK_CLASS("android/graphics/drawable/BitmapDrawable");
+ m_bitmapDrawableClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ GET_AND_CHECK_METHOD(m_bitmapDrawableConstructorMethodID,
+ m_bitmapDrawableClass,
+ "<init>",
+ "(Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V");
+
+ return JNI_TRUE;
+}
+
+Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
+{
+ typedef union {
+ JNIEnv *nativeEnvironment;
+ void *venv;
+ } UnionJNIEnvToVoid;
+
+ __android_log_print(ANDROID_LOG_INFO, "Qt", "qt start");
+ UnionJNIEnvToVoid uenv;
+ uenv.venv = NULL;
+ m_javaVM = 0;
+
+ if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
+ __android_log_print(ANDROID_LOG_FATAL, "Qt", "GetEnv failed");
+ return -1;
+ }
+
+ JNIEnv *env = uenv.nativeEnvironment;
+ if (!registerNatives(env)
+ || !QtAndroidInput::registerNatives(env)
+ || !QtAndroidClipboard::registerNatives(env)
+ || !QtAndroidMenu::registerNatives(env)) {
+ __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
+ return -1;
+ }
+
+ m_javaVM = vm;
+ return JNI_VERSION_1_4;
+}
diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h
new file mode 100644
index 0000000000..36699f15b8
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjnimain.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROID_APP_H
+#define ANDROID_APP_H
+
+#include <android/log.h>
+
+#ifdef ANDROID_PLUGIN_OPENGL
+# include <EGL/eglplatform.h>
+#endif
+
+#include <QtCore/qsize.h>
+
+#include <jni.h>
+#include <android/asset_manager.h>
+
+class QImage;
+class QRect;
+class QPoint;
+class QThread;
+class QAndroidPlatformIntegration;
+class QWidget;
+class QString;
+class QWindow;
+
+namespace QtAndroid
+{
+ void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
+ void setQtThread(QThread *thread);
+
+ void setFullScreen(QWidget *widget);
+
+#ifndef ANDROID_PLUGIN_OPENGL
+ void flushImage(const QPoint &pos, const QImage &image, const QRect &rect);
+#else
+ EGLNativeWindowType nativeWindow(bool waitToCreate = true);
+ QSize nativeWindowSize();
+#endif
+
+ QWindow *topLevelWindowAt(const QPoint &globalPos);
+ int desktopWidthPixels();
+ int desktopHeightPixels();
+ JavaVM *javaVM();
+ jclass findClass(const QString &className, JNIEnv *env);
+ AAssetManager *assetManager();
+ jclass applicationClass();
+ jobject activity();
+
+ jobject createBitmap(QImage img, JNIEnv *env = 0);
+ jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
+
+ struct AttachedJNIEnv
+ {
+ AttachedJNIEnv()
+ {
+ attached = false;
+ if (QtAndroid::javaVM()->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
+ if (QtAndroid::javaVM()->AttachCurrentThread(&jniEnv, NULL) < 0) {
+ __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed");
+ jniEnv = 0;
+ return;
+ }
+ attached = true;
+ }
+ }
+
+ ~AttachedJNIEnv()
+ {
+ if (attached)
+ QtAndroid::javaVM()->DetachCurrentThread();
+ }
+ bool attached;
+ JNIEnv *jniEnv;
+ };
+ const char *classErrorMsgFmt();
+ const char *methodErrorMsgFmt();
+ const char *qtTagText();
+
+}
+#endif // ANDROID_APP_H
diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp
new file mode 100644
index 0000000000..e49af0fdac
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjnimenu.cpp
@@ -0,0 +1,405 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidjnimenu.h"
+#include "androidjnimain.h"
+#include <qmutex.h>
+#include <qset.h>
+#include <qqueue.h>
+#include <android/log.h>
+#include "qandroidplatformmenubar.h"
+#include "qandroidplatformmenu.h"
+#include <qandroidplatformmenuitem.h>
+
+using namespace QtAndroid;
+
+namespace QtAndroidMenu
+{
+ static QQueue<QAndroidPlatformMenu *> pendingContextMenus;
+ static QAndroidPlatformMenu *visibleMenu = 0;
+ static QMutex visibleMenuMutex(QMutex::Recursive);
+
+ static QSet<QAndroidPlatformMenuBar *> menuBars;
+ static QAndroidPlatformMenuBar *visibleMenuBar = 0;
+ static QWindow *activeTopLevelWindow = 0;
+ static QMutex menuBarMutex(QMutex::Recursive);
+
+ static jmethodID openContextMenuMethodID = 0;
+ static jmethodID closeContextMenuMethodID = 0;
+ static jmethodID resetOptionsMenuMethodID = 0;
+
+ static jmethodID clearMenuMethodID = 0;
+ static jmethodID addMenuItemMethodID = 0;
+ static int menuNoneValue = 0;
+ static jmethodID setHeaderTitleContextMenuMethodID = 0;
+
+ static jmethodID setCheckableMenuItemMethodID = 0;
+ static jmethodID setCheckedMenuItemMethodID = 0;
+ static jmethodID setEnabledMenuItemMethodID = 0;
+ static jmethodID setIconMenuItemMethodID = 0;
+ static jmethodID setVisibleMenuItemMethodID = 0;
+
+ void resetMenuBar()
+ {
+ AttachedJNIEnv env;
+ if (env.jniEnv)
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), resetOptionsMenuMethodID);
+ }
+
+ void showContextMenu(QAndroidPlatformMenu *menu, JNIEnv *env)
+ {
+ QMutexLocker lock(&visibleMenuMutex);
+ if (visibleMenu) {
+ pendingContextMenus.enqueue(menu);
+ } else {
+ visibleMenu = menu;
+ menu->aboutToShow();
+ if (env) {
+ env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID);
+ } else {
+ AttachedJNIEnv aenv;
+ if (aenv.jniEnv)
+ aenv.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID);
+ }
+ }
+ }
+
+ void hideContextMenu(QAndroidPlatformMenu *menu)
+ {
+ QMutexLocker lock(&visibleMenuMutex);
+ if (visibleMenu == menu) {
+ AttachedJNIEnv env;
+ if (env.jniEnv)
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID);
+ } else {
+ pendingContextMenus.removeOne(menu);
+ }
+ }
+
+ void syncMenu(QAndroidPlatformMenu */*menu*/)
+ {
+// QMutexLocker lock(&visibleMenuMutex);
+// if (visibleMenu == menu)
+// {
+// hideContextMenu(menu);
+// showContextMenu(menu);
+// }
+ }
+
+ void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu)
+ {
+ QMutexLocker lock(&visibleMenuMutex);
+ if (visibleMenu == menu)
+ visibleMenu = 0;
+ }
+
+ void setMenuBar(QAndroidPlatformMenuBar *menuBar, QWindow *window)
+ {
+ if (activeTopLevelWindow == window && visibleMenuBar != menuBar) {
+ visibleMenuBar = menuBar;
+ resetMenuBar();
+ }
+ }
+
+ void setActiveTopLevelWindow(QWindow *window)
+ {
+ QMutexLocker lock(&menuBarMutex);
+ if (activeTopLevelWindow == window)
+ return;
+
+ visibleMenuBar = 0;
+ activeTopLevelWindow = window;
+#ifdef ANDROID_PLUGIN_OPENGL
+ //only one toplevel window, so the menu bar always belongs to us
+ if (menuBars.size() == 1) {
+ visibleMenuBar = *menuBars.constBegin(); //since QSet doesn't have first()
+ } else
+#endif
+ foreach (QAndroidPlatformMenuBar *menuBar, menuBars) {
+ if (menuBar->parentWindow() == window) {
+ visibleMenuBar = menuBar;
+ break;
+ }
+ }
+
+ resetMenuBar();
+ }
+
+ void addMenuBar(QAndroidPlatformMenuBar *menuBar)
+ {
+ QMutexLocker lock(&menuBarMutex);
+ menuBars.insert(menuBar);
+ }
+
+ void removeMenuBar(QAndroidPlatformMenuBar *menuBar)
+ {
+ QMutexLocker lock(&menuBarMutex);
+ menuBars.remove(menuBar);
+ if (visibleMenuBar == menuBar)
+ resetMenuBar();
+ }
+
+ static void fillMenuItem(JNIEnv *env, jobject menuItem, bool checkable, bool checked, bool enabled, bool visible, const QIcon &icon=QIcon())
+ {
+ env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable);
+ env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked);
+ env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled);
+
+ if (!icon.isNull()) {
+ int sz = qMax(36, qgetenv("QT_ANDROID_APP_ICON_SIZE").toInt());
+ QImage img = icon.pixmap(QSize(sz,sz),
+ enabled
+ ? QIcon::Normal
+ : QIcon::Disabled,
+ QIcon::On).toImage();
+ env->CallObjectMethod(menuItem,
+ setIconMenuItemMethodID,
+ createBitmapDrawable(createBitmap(img, env), env));
+ }
+
+ env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible);
+ }
+
+ static int addAllMenuItemsToMenu(JNIEnv *env, jobject menu, QAndroidPlatformMenu *platformMenu) {
+ int order = 0;
+ QMutexLocker lock(platformMenu->menuItemsMutex());
+ foreach (QAndroidPlatformMenuItem *item, platformMenu->menuItems()) {
+ if (item->isSeparator())
+ continue;
+ jstring jtext = env->NewString(reinterpret_cast<const jchar *>(item->text().data()),
+ item->text().length());
+ jobject menuItem = env->CallObjectMethod(menu,
+ addMenuItemMethodID,
+ menuNoneValue,
+ int(item->tag()),
+ order++,
+ jtext);
+ env->DeleteLocalRef(jtext);
+ fillMenuItem(env,
+ menuItem,
+ item->isCheckable(),
+ item->isChecked(),
+ item->isEnabled(),
+ item->isVisible(),
+ item->icon());
+ }
+
+ return order;
+ }
+
+ static jboolean onPrepareOptionsMenu(JNIEnv *env, jobject /*thiz*/, jobject menu)
+ {
+ env->CallVoidMethod(menu, clearMenuMethodID);
+ QMutexLocker lock(&menuBarMutex);
+ if (!visibleMenuBar)
+ return JNI_FALSE;
+
+ const QAndroidPlatformMenuBar::PlatformMenusType &menus = visibleMenuBar->menus();
+ int order = 0;
+ QMutexLocker lockMenuBarMutex(visibleMenuBar->menusListMutex());
+ if (menus.size() == 1) { // Expand the menu
+ order = addAllMenuItemsToMenu(env, menu, static_cast<QAndroidPlatformMenu *>(menus.front()));
+ } else {
+ foreach (QAndroidPlatformMenu *item, menus) {
+ jstring jtext = env->NewString(reinterpret_cast<const jchar *>(item->text().data()),
+ item->text().length());
+ jobject menuItem = env->CallObjectMethod(menu,
+ addMenuItemMethodID,
+ menuNoneValue,
+ int(item->tag()),
+ order++,
+ jtext);
+ env->DeleteLocalRef(jtext);
+
+ fillMenuItem(env,
+ menuItem,
+ false,
+ false,
+ item->isEnabled(),
+ item->isVisible(),
+ item->icon());
+ }
+ }
+ return order ? JNI_TRUE : JNI_FALSE;
+ }
+
+ static jboolean onOptionsItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked)
+ {
+ QMutexLocker lock(&menuBarMutex);
+ if (!visibleMenuBar)
+ return JNI_FALSE;
+
+ const QAndroidPlatformMenuBar::PlatformMenusType &menus = visibleMenuBar->menus();
+ if (menus.size() == 1) { // Expanded menu
+ QAndroidPlatformMenuItem *item = static_cast<QAndroidPlatformMenuItem *>(menus.front()->menuItemForTag(menuId));
+ if (item) {
+ if (item->menu()) {
+ showContextMenu(item->menu(), env);
+ } else {
+ if (item->isCheckable())
+ item->setChecked(checked);
+ item->activated();
+ }
+ }
+ } else {
+ QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForTag(menuId));
+ if (menu)
+ showContextMenu(menu, env);
+ }
+
+ return JNI_TRUE;
+ }
+
+ static void onOptionsMenuClosed(JNIEnv */*env*/, jobject /*thiz*/, jobject /*menu*/)
+ {
+ }
+
+ static void onCreateContextMenu(JNIEnv *env, jobject /*thiz*/, jobject menu)
+ {
+ env->CallVoidMethod(menu, clearMenuMethodID);
+ QMutexLocker lock(&visibleMenuMutex);
+ if (!visibleMenu)
+ return;
+
+ jstring jtext = env->NewString(reinterpret_cast<const jchar*>(visibleMenu->text().data()),
+ visibleMenu->text().length());
+ env->CallObjectMethod(menu, setHeaderTitleContextMenuMethodID, jtext);
+ env->DeleteLocalRef(jtext);
+ addAllMenuItemsToMenu(env, menu, visibleMenu);
+ }
+
+ static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked)
+ {
+ QMutexLocker lock(&visibleMenuMutex);
+ QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForTag(menuId));
+ if (item) {
+ if (item->menu()) {
+ showContextMenu(item->menu(), env);
+ } else {
+ if (item->isCheckable())
+ item->setChecked(checked);
+ item->activated();
+ }
+ }
+ return JNI_TRUE;
+ }
+
+ static void onContextMenuClosed(JNIEnv *env, jobject /*thiz*/, jobject /*menu*/)
+ {
+ QMutexLocker lock(&visibleMenuMutex);
+ if (!visibleMenu)
+ return;
+ visibleMenu->aboutToHide();
+ visibleMenu = 0;
+ if (!pendingContextMenus.empty())
+ showContextMenu(pendingContextMenus.dequeue(), env);
+ }
+
+ static JNINativeMethod methods[] = {
+ {"onPrepareOptionsMenu", "(Landroid/view/Menu;)Z", (void *)onPrepareOptionsMenu},
+ {"onOptionsItemSelected", "(IZ)Z", (void *)onOptionsItemSelected},
+ {"onOptionsMenuClosed", "(Landroid/view/Menu;)V", (void*)onOptionsMenuClosed},
+ {"onCreateContextMenu", "(Landroid/view/ContextMenu;)V", (void *)onCreateContextMenu},
+ {"onContextItemSelected", "(IZ)Z", (void *)onContextItemSelected},
+ {"onContextMenuClosed", "(Landroid/view/Menu;)V", (void*)onContextMenuClosed},
+ };
+
+#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
+ clazz = env->FindClass(CLASS_NAME); \
+ if (!clazz) { \
+ __android_log_print(ANDROID_LOG_FATAL, qtTagText(), classErrorMsgFmt(), CLASS_NAME); \
+ return false; \
+ }
+
+#define GET_AND_CHECK_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
+ return false; \
+ }
+
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
+ return false; \
+ }
+
+#define GET_AND_CHECK_STATIC_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \
+ VAR = env->GetStaticFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \
+ if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), FIELD_NAME, FIELD_SIGNATURE); \
+ return false; \
+ }
+
+ bool registerNatives(JNIEnv *env)
+ {
+ jclass appClass = applicationClass();
+
+ if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
+ return false;
+ }
+
+ GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "()V");
+ GET_AND_CHECK_STATIC_METHOD(closeContextMenuMethodID, appClass, "closeContextMenu", "()V");
+ GET_AND_CHECK_STATIC_METHOD(resetOptionsMenuMethodID, appClass, "resetOptionsMenu", "()V");
+
+ jclass clazz;
+ FIND_AND_CHECK_CLASS("android/view/Menu");
+ GET_AND_CHECK_METHOD(clearMenuMethodID, clazz, "clear", "()V");
+ GET_AND_CHECK_METHOD(addMenuItemMethodID, clazz, "add", "(IIILjava/lang/CharSequence;)Landroid/view/MenuItem;");
+ jfieldID menuNoneFiledId;
+ GET_AND_CHECK_STATIC_FIELD(menuNoneFiledId, clazz, "NONE", "I");
+ menuNoneValue = env->GetStaticIntField(clazz, menuNoneFiledId);
+
+ FIND_AND_CHECK_CLASS("android/view/ContextMenu");
+ GET_AND_CHECK_METHOD(setHeaderTitleContextMenuMethodID, clazz, "setHeaderTitle","(Ljava/lang/CharSequence;)Landroid/view/ContextMenu;");
+
+ FIND_AND_CHECK_CLASS("android/view/MenuItem");
+ GET_AND_CHECK_METHOD(setCheckableMenuItemMethodID, clazz, "setCheckable", "(Z)Landroid/view/MenuItem;");
+ GET_AND_CHECK_METHOD(setCheckedMenuItemMethodID, clazz, "setChecked", "(Z)Landroid/view/MenuItem;");
+ GET_AND_CHECK_METHOD(setEnabledMenuItemMethodID, clazz, "setEnabled", "(Z)Landroid/view/MenuItem;");
+ GET_AND_CHECK_METHOD(setIconMenuItemMethodID, clazz, "setIcon", "(Landroid/graphics/drawable/Drawable;)Landroid/view/MenuItem;");
+ GET_AND_CHECK_METHOD(setVisibleMenuItemMethodID, clazz, "setVisible", "(Z)Landroid/view/MenuItem;");
+ return true;
+ }
+}
diff --git a/src/plugins/platforms/android/src/androidjnimenu.h b/src/plugins/platforms/android/src/androidjnimenu.h
new file mode 100644
index 0000000000..7c5422f67b
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjnimenu.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDJNIMENU_H
+#define ANDROIDJNIMENU_H
+
+#include <jni.h>
+
+class QAndroidPlatformMenuBar;
+class QAndroidPlatformMenu;
+class QAndroidPlatformMenuItem;
+class QWindow;
+
+namespace QtAndroidMenu
+{
+ // Menu support
+ void showContextMenu(QAndroidPlatformMenu *menu, JNIEnv *env = 0);
+ void hideContextMenu(QAndroidPlatformMenu *menu);
+ void syncMenu(QAndroidPlatformMenu *menu);
+ void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu);
+
+ void setMenuBar(QAndroidPlatformMenuBar *menuBar, QWindow *window);
+ void setActiveTopLevelWindow(QWindow *window);
+ void addMenuBar(QAndroidPlatformMenuBar *menuBar);
+ void removeMenuBar(QAndroidPlatformMenuBar *menuBar);
+
+ // Menu support
+ bool registerNatives(JNIEnv *env);
+}
+
+#endif // ANDROIDJNIMENU_H
diff --git a/src/plugins/platforms/android/src/androidplatformplugin.cpp b/src/plugins/platforms/android/src/androidplatformplugin.cpp
new file mode 100644
index 0000000000..71c5096e16
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidplatformplugin.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qplatformintegrationplugin.h>
+#include "qandroidplatformintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformIntegrationPlugin: public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "android.json")
+public:
+ QPlatformIntegration *create(const QString &key, const QStringList &paramList);
+};
+
+
+QPlatformIntegration *QAndroidPlatformIntegrationPlugin::create(const QString &key, const QStringList &paramList)
+{
+ Q_UNUSED(paramList);
+ if (key.toLower() == "android")
+ return new QAndroidPlatformIntegration(paramList);
+ return 0;
+}
+
+QT_END_NAMESPACE
+#include "androidplatformplugin.moc"
+
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
new file mode 100644
index 0000000000..aa8ee57341
--- /dev/null
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidopenglcontext.h"
+#include "qandroidopenglplatformwindow.h"
+#include "qandroidplatformintegration.h"
+
+#include <QtCore/qdebug.h>
+#include <qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidOpenGLContext::QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
+ const QSurfaceFormat &format,
+ QPlatformOpenGLContext *share,
+ EGLDisplay display,
+ EGLenum eglApi)
+ : QEglFSContext(format, share, display, eglApi)
+ , m_platformIntegration(integration)
+{
+}
+
+void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ QEglFSContext::swapBuffers(surface);
+
+ QAndroidOpenGLPlatformWindow *primaryWindow = m_platformIntegration->primaryWindow();
+ if (primaryWindow == surface) {
+ primaryWindow->lock();
+ QSize size = primaryWindow->scheduledResize();
+ if (size.isValid()) {
+ QRect geometry(QPoint(0, 0), size);
+ primaryWindow->setGeometry(geometry);
+ primaryWindow->scheduleResize(QSize());
+ }
+ primaryWindow->unlock();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h
new file mode 100644
index 0000000000..c4c5a430ad
--- /dev/null
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDOPENGLCONTEXT_H
+#define QANDROIDOPENGLCONTEXT_H
+
+#include <QtCore/qreadwritelock.h>
+#include "qeglfscontext.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformIntegration;
+class QAndroidOpenGLContext : public QEglFSContext
+{
+public:
+ QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
+ const QSurfaceFormat &format,
+ QPlatformOpenGLContext *share,
+ EGLDisplay display,
+ EGLenum eglApi = EGL_OPENGL_ES_API);
+
+ void swapBuffers(QPlatformSurface *surface);
+
+private:
+ const QAndroidPlatformIntegration *m_platformIntegration;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDOPENGLCONTEXT_H
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
new file mode 100644
index 0000000000..15c6559157
--- /dev/null
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidopenglplatformwindow.h"
+#include "androidjnimain.h"
+#include <qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
+ : QEglFSWindow(window)
+{
+}
+
+bool QAndroidOpenGLPlatformWindow::isExposed() const
+{
+ return QtAndroid::nativeWindow(false) != 0 && QEglFSWindow::isExposed();
+}
+
+void QAndroidOpenGLPlatformWindow::invalidateSurface()
+{
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
+ QWindowSystemInterface::flushWindowSystemEvents();
+ QEglFSWindow::invalidateSurface();
+}
+
+void QAndroidOpenGLPlatformWindow::resetSurface()
+{
+ QEglFSWindow::resetSurface();
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
+ QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
new file mode 100644
index 0000000000..b835cb3246
--- /dev/null
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDOPENGLPLATFORMWINDOW_H
+#define QANDROIDOPENGLPLATFORMWINDOW_H
+
+#include "qeglfswindow.h"
+#include <QtCore/qmutex.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidOpenGLPlatformWindow : public QEglFSWindow
+{
+public:
+ QAndroidOpenGLPlatformWindow(QWindow *window);
+
+ QSize scheduledResize() const { return m_scheduledResize; }
+ void scheduleResize(const QSize &size) { m_scheduledResize = size; }
+
+ void lock() { m_lock.lock(); }
+ void unlock() { m_lock.unlock(); }
+
+ bool isExposed() const;
+
+ void invalidateSurface();
+ void resetSurface();
+
+private:
+ QSize m_scheduledResize;
+ QMutex m_lock;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDOPENGLPLATFORMWINDOW_H
diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
new file mode 100644
index 0000000000..cd415843a7
--- /dev/null
+++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfshooks.h"
+#include "androidjnimain.h"
+#include "qandroidplatformintegration.h"
+
+#include <android/native_window.h>
+#include <jni.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSAndroidHooks: public QEglFSHooks
+{
+public:
+ void platformInit();
+ void platformDestroy();
+ EGLNativeDisplayType platformDisplay() const;
+ QSize screenSize() const;
+ QSizeF physicalScreenSize() const;
+ int screenDepth() const;
+ QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
+ EGLNativeWindowType createNativeWindow(const QSize &size, const QSurfaceFormat &format);
+ void destroyNativeWindow(EGLNativeWindowType window);
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+};
+
+void QEglFSAndroidHooks::platformInit()
+{
+}
+
+void QEglFSAndroidHooks::platformDestroy()
+{
+}
+
+EGLNativeDisplayType QEglFSAndroidHooks::platformDisplay() const
+{
+ return EGL_DEFAULT_DISPLAY;
+}
+
+QSize QEglFSAndroidHooks::screenSize() const
+{
+ return QtAndroid::nativeWindowSize();
+}
+
+QSizeF QEglFSAndroidHooks::physicalScreenSize() const
+{
+ return QSizeF(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth, QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
+}
+
+
+EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format)
+{
+ ANativeWindow *window = QtAndroid::nativeWindow();
+ if (window != 0)
+ ANativeWindow_acquire(window);
+
+ return window;
+}
+
+void QEglFSAndroidHooks::destroyNativeWindow(EGLNativeWindowType window)
+{
+ ANativeWindow_release(window);
+}
+
+bool QEglFSAndroidHooks::hasCapability(QPlatformIntegration::Capability capability) const
+{
+ switch (capability) {
+ case QPlatformIntegration::OpenGL: return true;
+ case QPlatformIntegration::ThreadedOpenGL: return true;
+ default: return false;
+ };
+}
+
+int QEglFSAndroidHooks::screenDepth() const
+{
+ // ### Hardcoded
+ return 32;
+}
+
+QSurfaceFormat QEglFSAndroidHooks::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
+{
+ QSurfaceFormat ret(inputFormat);
+ ret.setAlphaBufferSize(8);
+ ret.setRedBufferSize(8);
+ ret.setGreenBufferSize(8);
+ ret.setBlueBufferSize(8);
+ return ret;
+}
+
+static QEglFSAndroidHooks eglFSAndroidHooks;
+QEglFSHooks *platformHooks = &eglFSAndroidHooks;
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp
new file mode 100644
index 0000000000..f3cb2586cc
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidassetsfileenginehandler.h"
+#include "androidjnimain.h"
+
+#include <QCoreApplication>
+
+class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator
+{
+public:
+ AndroidAbstractFileEngineIterator(QDir::Filters filters,
+ const QStringList &nameFilters,
+ AAssetDir *asset,
+ const QString &path)
+ : QAbstractFileEngineIterator(filters, nameFilters)
+ {
+ AAssetDir_rewind(asset);
+ const char *fileName;
+ while ((fileName = AAssetDir_getNextFileName(asset)))
+ m_items << fileName;
+ m_index = -1;
+ m_path = path;
+ }
+
+ virtual QFileInfo currentFileInfo() const
+ {
+ return QFileInfo(currentFilePath());
+ }
+
+ virtual QString currentFileName() const
+ {
+ if (m_index < 0 || m_index >= m_items.size())
+ return QString();
+ return m_items[m_index];
+ }
+
+ virtual QString currentFilePath() const
+ {
+ return m_path + currentFileName();
+ }
+
+ virtual bool hasNext() const
+ {
+ return m_items.size() && (m_index < m_items.size() - 1);
+ }
+
+ virtual QString next()
+ {
+ if (!hasNext())
+ return QString();
+ m_index++;
+ return currentFileName();
+ }
+
+private:
+ QString m_path;
+ QStringList m_items;
+ int m_index;
+};
+
+class AndroidAbstractFileEngine: public QAbstractFileEngine
+{
+public:
+ explicit AndroidAbstractFileEngine(AAsset *asset, const QString &fileName)
+ {
+ m_assetDir = 0;
+ m_assetFile = asset;
+ m_fileName = fileName;
+ }
+
+ explicit AndroidAbstractFileEngine(AAssetDir *asset, const QString &fileName)
+ {
+ m_assetFile = 0;
+ m_assetDir = asset;
+ m_fileName = fileName;
+ if (!m_fileName.endsWith(QChar(QLatin1Char('/'))))
+ m_fileName += "/";
+ }
+
+ ~AndroidAbstractFileEngine()
+ {
+ close();
+ if (m_assetDir)
+ AAssetDir_close(m_assetDir);
+ }
+
+ virtual bool open(QIODevice::OpenMode openMode)
+ {
+ if (m_assetFile)
+ return openMode & QIODevice::ReadOnly;
+ return false;
+ }
+
+ virtual bool close()
+ {
+ if (m_assetFile) {
+ AAsset_close(m_assetFile);
+ m_assetFile = 0;
+ return true;
+ }
+ return false;
+ }
+
+ virtual qint64 size() const
+ {
+ if (m_assetFile)
+ return AAsset_getLength(m_assetFile);
+ return -1;
+ }
+
+ virtual qint64 pos() const
+ {
+ if (m_assetFile)
+ return AAsset_seek(m_assetFile, 0, SEEK_CUR);
+ return -1;
+ }
+
+ virtual bool seek(qint64 pos)
+ {
+ if (m_assetFile)
+ return pos == AAsset_seek(m_assetFile, pos, SEEK_SET);
+ return false;
+ }
+
+ virtual qint64 read(char *data, qint64 maxlen)
+ {
+ if (m_assetFile)
+ return AAsset_read(m_assetFile, data, maxlen);
+ return -1;
+ }
+
+ virtual bool isSequential() const
+ {
+ return false;
+ }
+
+ virtual bool caseSensitive() const
+ {
+ return true;
+ }
+
+ virtual bool isRelativePath() const
+ {
+ return false;
+ }
+
+ virtual FileFlags fileFlags(FileFlags type = FileInfoAll) const
+ {
+ FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
+ if (m_assetFile)
+ flags |= FileType;
+ if (m_assetDir)
+ flags |= DirectoryType;
+
+ return type & flags;
+ }
+
+ virtual QString fileName(FileName file = DefaultName) const
+ {
+ int pos;
+ switch (file) {
+ case DefaultName:
+ case AbsoluteName:
+ case CanonicalName:
+ return m_fileName;
+ case BaseName:
+ if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1)
+ return m_fileName.mid(pos);
+ else
+ return m_fileName;
+ case PathName:
+ case AbsolutePathName:
+ case CanonicalPathName:
+ if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1)
+ return m_fileName.left(pos);
+ else
+ return m_fileName;
+ default:
+ return QString();
+ }
+ }
+
+ virtual void setFileName(const QString &file)
+ {
+ if (file == m_fileName)
+ return;
+
+ m_fileName = file;
+ if (!m_fileName.endsWith(QChar(QLatin1Char('/'))))
+ m_fileName += "/";
+
+ close();
+ }
+
+ virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames)
+ {
+ if (m_assetDir)
+ return new AndroidAbstractFileEngineIterator(filters, filterNames, m_assetDir, m_fileName);
+ return 0;
+ }
+
+private:
+ AAsset *m_assetFile;
+ AAssetDir *m_assetDir;
+ QString m_fileName;
+};
+
+
+AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler()
+{
+ m_assetManager = QtAndroid::assetManager();
+}
+
+AndroidAssetsFileEngineHandler::~AndroidAssetsFileEngineHandler()
+{
+}
+
+QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &fileName) const
+{
+ if (fileName.isEmpty())
+ return 0;
+
+ if (!fileName.startsWith(QLatin1String("assets:/")))
+ return 0;
+
+ int prefixSize=8;
+
+ m_path.clear();
+ if (!fileName.endsWith(QLatin1Char('/'))) {
+ m_path = fileName.toUtf8();
+ AAsset *asset = AAssetManager_open(m_assetManager,
+ m_path.constData() + prefixSize,
+ AASSET_MODE_BUFFER);
+ if (asset)
+ return new AndroidAbstractFileEngine(asset, fileName);
+ }
+
+ if (!m_path.size())
+ m_path = fileName.left(fileName.length() - 1).toUtf8();
+
+ AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, m_path.constData() + prefixSize);
+ if (assetDir) {
+ if (AAssetDir_getNextFileName(assetDir))
+ return new AndroidAbstractFileEngine(assetDir, fileName);
+ else
+ AAssetDir_close(assetDir);
+ }
+ return 0;
+}
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h
new file mode 100644
index 0000000000..9bff6a012e
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDASSETSFILEENGINEHANDLER_H
+#define QANDROIDASSETSFILEENGINEHANDLER_H
+
+#include <QtCore/private/qabstractfileengine_p.h>
+#include <android/asset_manager.h>
+
+class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler
+{
+public:
+ AndroidAssetsFileEngineHandler();
+ virtual ~AndroidAssetsFileEngineHandler();
+ QAbstractFileEngine *create(const QString &fileName) const;
+
+private:
+ AAssetManager *m_assetManager;
+ mutable QByteArray m_path;
+};
+
+#endif // QANDROIDASSETSFILEENGINEHANDLER_H
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.cpp b/src/plugins/platforms/android/src/qandroidinputcontext.cpp
new file mode 100644
index 0000000000..37fb605ea8
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidinputcontext.cpp
@@ -0,0 +1,644 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <android/log.h>
+
+#include "qandroidinputcontext.h"
+#include "androidjnimain.h"
+#include "androidjniinput.h"
+#include <QDebug>
+#include <qevent.h>
+#include <qguiapplication.h>
+#include <qsharedpointer.h>
+#include <qthread.h>
+#include <qinputmethod.h>
+#include <qwindow.h>
+
+#include <QTextCharFormat>
+
+QT_BEGIN_NAMESPACE
+
+static QAndroidInputContext *m_androidInputContext = 0;
+static char const *const QtNativeInputConnectionClassName = "org/qtproject/qt5/android/QtNativeInputConnection";
+static char const *const QtExtractedTextClassName = "org/qtproject/qt5/android/QtExtractedText";
+static jclass m_extractedTextClass = 0;
+static jmethodID m_classConstructorMethodID = 0;
+static jfieldID m_partialEndOffsetFieldID = 0;
+static jfieldID m_partialStartOffsetFieldID = 0;
+static jfieldID m_selectionEndFieldID = 0;
+static jfieldID m_selectionStartFieldID = 0;
+static jfieldID m_startOffsetFieldID = 0;
+static jfieldID m_textFieldID = 0;
+
+static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ jboolean isCopy;
+ const jchar *jstr = env->GetStringChars(text, &isCopy);
+ QString str(reinterpret_cast<const QChar *>(jstr), env->GetStringLength(text));
+ env->ReleaseStringChars(text, jstr);
+
+ return m_androidInputContext->commitText(str, newCursorPosition);
+}
+
+static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint leftLength, jint rightLength)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->deleteSurroundingText(leftLength, rightLength);
+}
+
+static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->finishComposingText();
+}
+
+static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes)
+{
+ if (!m_androidInputContext)
+ return 0;
+
+ return m_androidInputContext->getCursorCapsMode(reqModes);
+}
+
+static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars, int hintMaxLines, jint flags)
+{
+ if (!m_androidInputContext)
+ return 0;
+
+ const QAndroidInputContext::ExtractedText &extractedText =
+ m_androidInputContext->getExtractedText(hintMaxChars, hintMaxLines, flags);
+
+ jobject object = env->NewObject(m_extractedTextClass, m_classConstructorMethodID);
+ env->SetIntField(object, m_partialStartOffsetFieldID, extractedText.partialStartOffset);
+ env->SetIntField(object, m_partialEndOffsetFieldID, extractedText.partialEndOffset);
+ env->SetIntField(object, m_selectionStartFieldID, extractedText.selectionStart);
+ env->SetIntField(object, m_selectionEndFieldID, extractedText.selectionEnd);
+ env->SetIntField(object, m_startOffsetFieldID, extractedText.startOffset);
+ env->SetObjectField(object,
+ m_textFieldID,
+ env->NewString(reinterpret_cast<const jchar *>(extractedText.text.constData()),
+ jsize(extractedText.text.length())));
+
+ return object;
+}
+
+static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags)
+{
+ if (!m_androidInputContext)
+ return 0;
+
+ const QString &text = m_androidInputContext->getSelectedText(flags);
+ return env->NewString(reinterpret_cast<const jchar *>(text.constData()), jsize(text.length()));
+}
+
+static jstring getTextAfterCursor(JNIEnv *env, jobject /*thiz*/, jint length, jint flags)
+{
+ if (!m_androidInputContext)
+ return 0;
+
+ const QString &text = m_androidInputContext->getTextAfterCursor(length, flags);
+ return env->NewString(reinterpret_cast<const jchar *>(text.constData()), jsize(text.length()));
+}
+
+static jstring getTextBeforeCursor(JNIEnv *env, jobject /*thiz*/, jint length, jint flags)
+{
+ if (!m_androidInputContext)
+ return 0;
+
+ const QString &text = m_androidInputContext->getTextBeforeCursor(length, flags);
+ return env->NewString(reinterpret_cast<const jchar *>(text.constData()), jsize(text.length()));
+}
+
+static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ jboolean isCopy;
+ const jchar *jstr = env->GetStringChars(text, &isCopy);
+ QString str(reinterpret_cast<const QChar *>(jstr), env->GetStringLength(text));
+ env->ReleaseStringChars(text, jstr);
+
+ return m_androidInputContext->setComposingText(str, newCursorPosition);
+}
+
+static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint end)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->setSelection(start, end);
+}
+
+static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->selectAll();
+}
+
+static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->cut();
+}
+
+static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->copy();
+}
+
+static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->copyURL();
+}
+
+static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+ return m_androidInputContext->paste();
+}
+
+
+static JNINativeMethod methods[] = {
+ {"commitText", "(Ljava/lang/String;I)Z", (void *)commitText},
+ {"deleteSurroundingText", "(II)Z", (void *)deleteSurroundingText},
+ {"finishComposingText", "()Z", (void *)finishComposingText},
+ {"getCursorCapsMode", "(I)I", (void *)getCursorCapsMode},
+ {"getExtractedText", "(III)Lorg/qtproject/qt5/android/QtExtractedText;", (void *)getExtractedText},
+ {"getSelectedText", "(I)Ljava/lang/String;", (void *)getSelectedText},
+ {"getTextAfterCursor", "(II)Ljava/lang/String;", (void *)getTextAfterCursor},
+ {"getTextBeforeCursor", "(II)Ljava/lang/String;", (void *)getTextBeforeCursor},
+ {"setComposingText", "(Ljava/lang/String;I)Z", (void *)setComposingText},
+ {"setSelection", "(II)Z", (void *)setSelection},
+ {"selectAll", "()Z", (void *)selectAll},
+ {"cut", "()Z", (void *)cut},
+ {"copy", "()Z", (void *)copy},
+ {"copyURL", "()Z", (void *)copyURL},
+ {"paste", "()Z", (void *)paste}
+};
+
+
+QAndroidInputContext::QAndroidInputContext():QPlatformInputContext()
+{
+ JNIEnv *env = 0;
+ if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) {
+ qCritical() << "AttachCurrentThread failed";
+ return;
+ }
+
+ jclass clazz = QtAndroid::findClass(QtNativeInputConnectionClassName, env);
+ if (clazz == NULL) {
+ qCritical() << "Native registration unable to find class '"
+ << QtNativeInputConnectionClassName
+ << "'";
+ return;
+ }
+
+ if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ qCritical() << "RegisterNatives failed for '"
+ << QtNativeInputConnectionClassName
+ << "'";
+ return;
+ }
+
+ clazz = QtAndroid::findClass(QtExtractedTextClassName, env);
+ if (clazz == NULL) {
+ qCritical() << "Native registration unable to find class '"
+ << QtExtractedTextClassName
+ << "'";
+ return;
+ }
+
+ m_extractedTextClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ m_classConstructorMethodID = env->GetMethodID(m_extractedTextClass, "<init>", "()V");
+ if (m_classConstructorMethodID == NULL) {
+ qCritical() << "GetMethodID failed";
+ return;
+ }
+
+ m_partialEndOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialEndOffset", "I");
+ if (m_partialEndOffsetFieldID == NULL) {
+ qCritical() << "Can't find field partialEndOffset";
+ return;
+ }
+
+ m_partialStartOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialStartOffset", "I");
+ if (m_partialStartOffsetFieldID == NULL) {
+ qCritical() << "Can't find field partialStartOffset";
+ return;
+ }
+
+ m_selectionEndFieldID = env->GetFieldID(m_extractedTextClass, "selectionEnd", "I");
+ if (m_selectionEndFieldID == NULL) {
+ qCritical() << "Can't find field selectionEnd";
+ return;
+ }
+
+ m_selectionStartFieldID = env->GetFieldID(m_extractedTextClass, "selectionStart", "I");
+ if (m_selectionStartFieldID == NULL) {
+ qCritical() << "Can't find field selectionStart";
+ return;
+ }
+
+ m_startOffsetFieldID = env->GetFieldID(m_extractedTextClass, "startOffset", "I");
+ if (m_startOffsetFieldID == NULL) {
+ qCritical() << "Can't find field startOffset";
+ return;
+ }
+
+ m_textFieldID = env->GetFieldID(m_extractedTextClass, "text", "Ljava/lang/String;");
+ if (m_textFieldID == NULL) {
+ qCritical() << "Can't find field text";
+ return;
+ }
+ qRegisterMetaType<QInputMethodEvent *>("QInputMethodEvent*");
+ qRegisterMetaType<QInputMethodQueryEvent *>("QInputMethodQueryEvent*");
+ m_androidInputContext = this;
+}
+
+QAndroidInputContext::~QAndroidInputContext()
+{
+ m_androidInputContext = 0;
+ m_extractedTextClass = 0;
+ m_partialEndOffsetFieldID = 0;
+ m_partialStartOffsetFieldID = 0;
+ m_selectionEndFieldID = 0;
+ m_selectionStartFieldID = 0;
+ m_startOffsetFieldID = 0;
+ m_textFieldID = 0;
+}
+
+void QAndroidInputContext::reset()
+{
+ clear();
+ if (qGuiApp->focusObject())
+ QtAndroidInput::resetSoftwareKeyboard();
+ else
+ QtAndroidInput::hideSoftwareKeyboard();
+}
+
+void QAndroidInputContext::commit()
+{
+ finishComposingText();
+
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (!query.isNull()) {
+ const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ QtAndroidInput::updateSelection(cursorPos, cursorPos, -1, -1); //selection empty and no pre-edit text
+ }
+}
+
+void QAndroidInputContext::update(Qt::InputMethodQueries queries)
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(queries);
+ if (query.isNull())
+ return;
+#warning TODO extract the needed data from query
+}
+
+void QAndroidInputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
+{
+#warning TODO Handle at least QInputMethod::ContextMenu action
+ Q_UNUSED(action)
+ Q_UNUSED(cursorPosition)
+
+ if (action == QInputMethod::Click)
+ commit();
+}
+
+QRectF QAndroidInputContext::keyboardRect() const
+{
+ return QPlatformInputContext::keyboardRect();
+}
+
+bool QAndroidInputContext::isAnimating() const
+{
+ return false;
+}
+
+void QAndroidInputContext::showInputPanel()
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return;
+ QRectF itemRect = qGuiApp->inputMethod()->inputItemRectangle();
+ QRect rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(itemRect).toRect();
+ QWindow *window = qGuiApp->focusWindow();
+ if (window)
+ rect = QRect(window->mapToGlobal(rect.topLeft()), rect.size());
+
+ QtAndroidInput::showSoftwareKeyboard(rect.left(),
+ rect.top(),
+ rect.width(),
+ rect.height(),
+ query->value(Qt::ImHints).toUInt());
+}
+
+void QAndroidInputContext::hideInputPanel()
+{
+ QtAndroidInput::hideSoftwareKeyboard();
+}
+
+bool QAndroidInputContext::isInputPanelVisible() const
+{
+ return QtAndroidInput::isSoftwareKeyboardVisible();
+}
+
+bool QAndroidInputContext::isComposing() const
+{
+ return m_composingText.length();
+}
+
+void QAndroidInputContext::clear()
+{
+ m_composingText.clear();
+ m_extractedText.clear();
+}
+
+void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodEvent *event)
+{
+ QCoreApplication::sendEvent(receiver, event);
+}
+
+void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodQueryEvent *event)
+{
+ QCoreApplication::sendEvent(receiver, event);
+}
+
+jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/)
+{
+ m_composingText = text;
+ return finishComposingText();
+}
+
+jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint rightLength)
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return JNI_TRUE;
+
+ m_composingText.clear();
+
+ QInputMethodEvent event;
+ event.setCommitString(QString(), -leftLength, leftLength+rightLength);
+ sendInputMethodEvent(&event);
+ clear();
+
+ return JNI_TRUE;
+}
+
+jboolean QAndroidInputContext::finishComposingText()
+{
+ QInputMethodEvent event;
+ event.setCommitString(m_composingText);
+ sendInputMethodEvent(&event);
+ clear();
+
+ return JNI_TRUE;
+}
+
+jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
+{
+ jint res = 0;
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return res;
+
+ const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt();
+
+ if (qtInputMethodHints & Qt::ImhPreferUppercase)
+ res = CAP_MODE_SENTENCES;
+
+ if (qtInputMethodHints & Qt::ImhUppercaseOnly)
+ res = CAP_MODE_CHARACTERS;
+
+ return res;
+}
+
+const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint hintMaxChars, jint /*hintMaxLines*/, jint /*flags*/)
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return m_extractedText;
+
+ if (hintMaxChars)
+ m_extractedText.text = query->value(Qt::ImSurroundingText).toString().right(hintMaxChars);
+
+ m_extractedText.startOffset = query->value(Qt::ImCursorPosition).toInt();
+ const QString &selection = query->value(Qt::ImCurrentSelection).toString();
+ const int selLen = selection.length();
+ if (selLen) {
+ m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt();
+ m_extractedText.selectionEnd = m_extractedText.startOffset;
+ }
+
+ return m_extractedText;
+}
+
+QString QAndroidInputContext::getSelectedText(jint /*flags*/)
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return QString();
+
+ return query->value(Qt::ImCurrentSelection).toString();
+}
+
+QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return QString();
+
+ QString text = query->value(Qt::ImSurroundingText).toString();
+ if (!text.length())
+ return text;
+
+ int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ return text.mid(cursorPos, length);
+}
+
+QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return QString();
+
+ QString text = query->value(Qt::ImSurroundingText).toString();
+ if (!text.length())
+ return text;
+
+ int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ const int wordLeftPos = cursorPos - length;
+ return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos);
+}
+
+jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition)
+{
+ if (newCursorPosition > 0)
+ newCursorPosition += text.length() - 1;
+ m_composingText = text;
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ newCursorPosition,
+ 1,
+ QVariant()));
+ // Show compose text underlined
+ QTextCharFormat underlined;
+ underlined.setFontUnderline(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,0, text.length(),
+ QVariant(underlined)));
+
+ QInputMethodEvent event(m_composingText, attributes);
+ sendInputMethodEvent(&event);
+
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (!query.isNull()) {
+ int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ int preeditLength = text.length();
+ QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, cursorPos, cursorPos+preeditLength);
+ }
+
+ return JNI_TRUE;
+}
+
+jboolean QAndroidInputContext::setSelection(jint start, jint end)
+{
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
+ start,
+ end - start,
+ QVariant()));
+
+ QInputMethodEvent event(QString(), attributes);
+ sendInputMethodEvent(&event);
+ return JNI_TRUE;
+}
+
+jboolean QAndroidInputContext::selectAll()
+{
+#warning TODO
+ return JNI_FALSE;
+}
+
+jboolean QAndroidInputContext::cut()
+{
+#warning TODO
+ return JNI_FALSE;
+}
+
+jboolean QAndroidInputContext::copy()
+{
+#warning TODO
+ return JNI_FALSE;
+}
+
+jboolean QAndroidInputContext::copyURL()
+{
+#warning TODO
+ return JNI_FALSE;
+}
+
+jboolean QAndroidInputContext::paste()
+{
+#warning TODO
+ return JNI_FALSE;
+}
+
+QSharedPointer<QInputMethodQueryEvent> QAndroidInputContext::focusObjectInputMethodQuery(Qt::InputMethodQueries queries)
+{
+#warning TODO make qGuiApp->focusObject() thread safe !!!
+ QObject *focusObject = qGuiApp->focusObject();
+ if (!focusObject)
+ return QSharedPointer<QInputMethodQueryEvent>();
+
+ QSharedPointer<QInputMethodQueryEvent> ret = QSharedPointer<QInputMethodQueryEvent>(new QInputMethodQueryEvent(queries));
+ if (qGuiApp->thread()==QThread::currentThread()) {
+ QCoreApplication::sendEvent(focusObject, ret.data());
+ } else {
+ QMetaObject::invokeMethod(this,
+ "sendEvent",
+ Qt::BlockingQueuedConnection,
+ Q_ARG(QObject*, focusObject),
+ Q_ARG(QInputMethodQueryEvent*, ret.data()));
+ }
+
+ return ret;
+}
+
+void QAndroidInputContext::sendInputMethodEvent(QInputMethodEvent *event)
+{
+#warning TODO make qGuiApp->focusObject() thread safe !!!
+ QObject *focusObject = qGuiApp->focusObject();
+ if (!focusObject)
+ return;
+
+ if (qGuiApp->thread() == QThread::currentThread()) {
+ QCoreApplication::sendEvent(focusObject, event);
+ } else {
+ QMetaObject::invokeMethod(this,
+ "sendEvent",
+ Qt::BlockingQueuedConnection,
+ Q_ARG(QObject*, focusObject),
+ Q_ARG(QInputMethodEvent*, event));
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.h b/src/plugins/platforms/android/src/qandroidinputcontext.h
new file mode 100644
index 0000000000..e2b8107044
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidinputcontext.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDINPUTCONTEXT_H
+#define ANDROIDINPUTCONTEXT_H
+
+#include <qpa/qplatforminputcontext.h>
+#include <jni.h>
+#include <qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidInputContext: public QPlatformInputContext
+{
+ Q_OBJECT
+ enum CapsMode
+ {
+ CAP_MODE_CHARACTERS = 0x00001000,
+ CAP_MODE_SENTENCES = 0x00004000,
+ CAP_MODE_WORDS = 0x00002000
+ };
+
+public:
+ struct ExtractedText
+ {
+ ExtractedText() { clear(); }
+
+ void clear()
+ {
+ partialEndOffset = partialStartOffset = selectionEnd = selectionStart = startOffset = -1;
+ text.clear();
+ }
+
+ int partialEndOffset;
+ int partialStartOffset;
+ int selectionEnd;
+ int selectionStart;
+ int startOffset;
+ QString text;
+ };
+
+public:
+ QAndroidInputContext();
+ ~QAndroidInputContext();
+ bool isValid() const { return true; }
+
+ void reset();
+ void commit();
+ void update(Qt::InputMethodQueries queries);
+ void invokeAction(QInputMethod::Action action, int cursorPosition);
+ QRectF keyboardRect() const;
+ bool isAnimating() const;
+ void showInputPanel();
+ void hideInputPanel();
+ bool isInputPanelVisible() const;
+
+ bool isComposing() const;
+ void clear();
+
+ //---------------//
+ jboolean commitText(const QString &text, jint newCursorPosition);
+ jboolean deleteSurroundingText(jint leftLength, jint rightLength);
+ jboolean finishComposingText();
+ jint getCursorCapsMode(jint reqModes);
+ const ExtractedText &getExtractedText(jint hintMaxChars, jint hintMaxLines, jint flags);
+ QString getSelectedText(jint flags);
+ QString getTextAfterCursor(jint length, jint flags);
+ QString getTextBeforeCursor(jint length, jint flags);
+ jboolean setComposingText(const QString &text, jint newCursorPosition);
+ jboolean setSelection(jint start, jint end);
+ jboolean selectAll();
+ jboolean cut();
+ jboolean copy();
+ jboolean copyURL();
+ jboolean paste();
+
+private:
+ QSharedPointer<QInputMethodQueryEvent> focusObjectInputMethodQuery(Qt::InputMethodQueries queries = Qt::ImQueryAll);
+ void sendInputMethodEvent(QInputMethodEvent *event);
+
+private slots:
+ virtual void sendEvent(QObject *receiver, QInputMethodEvent *event);
+ virtual void sendEvent(QObject *receiver, QInputMethodQueryEvent *event);
+
+private:
+ ExtractedText m_extractedText;
+ QString m_composingText;
+};
+
+QT_END_NAMESPACE
+
+#endif // ANDROIDINPUTCONTEXT_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp
new file mode 100644
index 0000000000..bc48b4935b
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformclipboard.h"
+#include "androidjniclipboard.h"
+#ifndef QT_NO_CLIPBOARD
+#include <QMimeData>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformClipboard::QAndroidPlatformClipboard()
+{
+ QtAndroidClipboard::setClipboardListener(this);
+}
+
+QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (QClipboard::Clipboard != mode || !QtAndroidClipboard::hasClipboardText())
+ return 0;
+
+ QMimeData *mimeData = new QMimeData();
+ mimeData->setText(QtAndroidClipboard::clipboardText());
+ return mimeData;
+}
+
+void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
+{
+ if (!data || !data->hasText() || QClipboard::Clipboard != mode)
+ return;
+
+ QtAndroidClipboard::setClipboardText(data->text());
+}
+
+bool QAndroidPlatformClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ return QClipboard::Clipboard == mode;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_CLIPBOARD
diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.h b/src/plugins/platforms/android/src/qandroidplatformclipboard.h
new file mode 100644
index 0000000000..644f326934
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformclipboard.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMCLIPBOARD_H
+#define QANDROIDPLATFORMCLIPBOARD_H
+
+#include <qpa/qplatformclipboard.h>
+
+#ifndef QT_NO_CLIPBOARD
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformClipboard: public QPlatformClipboard
+{
+public:
+ QAndroidPlatformClipboard();
+
+ virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
+ virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
+ virtual bool supportsMode(QClipboard::Mode mode) const;
+};
+
+QT_END_NAMESPACE
+#endif // QT_NO_CLIPBOARD
+
+#endif // QANDROIDPLATFORMCLIPBOARD_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp
new file mode 100644
index 0000000000..7f68b44ed8
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDir>
+
+#include "qandroidplatformfontdatabase.h"
+
+QString QAndroidPlatformFontDatabase::fontDir() const
+{
+ return QLatin1String("/system/fonts");
+}
+
+void QAndroidPlatformFontDatabase::populateFontDatabase()
+{
+ QString fontpath = fontDir();
+
+ if (!QFile::exists(fontpath)) {
+ qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
+ qPrintable(fontpath));
+ }
+
+ QDir dir(fontpath, QLatin1String("*.ttf"));
+ for (int i = 0; i < int(dir.count()); ++i) {
+ const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
+ addTTFile(QByteArray(), file);
+ }
+}
+
+QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QChar::Script script) const
+{
+ Q_UNUSED(family);
+ Q_UNUSED(style);
+ Q_UNUSED(script);
+ if (styleHint == QFont::Monospace)
+ return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";");
+
+ return QString(qgetenv("QT_ANDROID_FONTS")).split(";");
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h
new file mode 100644
index 0000000000..3cbfe95d36
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMFONTDATABASE_H
+#define QANDROIDPLATFORMFONTDATABASE_H
+
+#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
+
+class QAndroidPlatformFontDatabase: public QBasicFontDatabase
+{
+public:
+ QString fontDir() const;
+ void populateFontDatabase();
+ QStringList fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QChar::Script script) const;
+};
+
+#endif // QANDROIDPLATFORMFONTDATABASE_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
new file mode 100644
index 0000000000..1091416ccc
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformintegration.h"
+#include "qabstracteventdispatcher.h"
+#include "androidjnimain.h"
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <QThread>
+#include <qpa/qplatformwindow.h>
+#include "qandroidplatformservices.h"
+#include "qandroidplatformfontdatabase.h"
+#include "qandroidplatformclipboard.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+#ifndef ANDROID_PLUGIN_OPENGL
+# include "qandroidplatformscreen.h"
+# include "qandroidplatformwindow.h"
+# include <QtPlatformSupport/private/qfbbackingstore_p.h>
+#else
+# include "qeglfswindow.h"
+# include "androidjnimenu.h"
+# include "qandroidopenglcontext.h"
+# include "qandroidopenglplatformwindow.h"
+# include "qeglfshooks.h"
+# include <QtGui/qopenglcontext.h>
+#endif
+
+#include "qandroidplatformtheme.h"
+
+QT_BEGIN_NAMESPACE
+
+int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320;
+int QAndroidPlatformIntegration::m_defaultGeometryHeight = 455;
+int QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth = 50;
+int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71;
+
+void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
+{
+ if (resource=="JavaVM")
+ return QtAndroid::javaVM();
+ if (resource == "QtActivity")
+ return QtAndroid::activity();
+
+ return 0;
+}
+
+QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &paramList)
+#ifdef ANDROID_PLUGIN_OPENGL
+ : m_primaryWindow(0)
+#endif
+{
+ Q_UNUSED(paramList);
+
+#ifndef ANDROID_PLUGIN_OPENGL
+ m_eventDispatcher = createUnixEventDispatcher();
+#endif
+
+ m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
+
+#ifndef ANDROID_PLUGIN_OPENGL
+ m_primaryScreen = new QAndroidPlatformScreen();
+ screenAdded(m_primaryScreen);
+ m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
+ m_primaryScreen->setGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
+#endif
+
+ m_mainThread = QThread::currentThread();
+ QtAndroid::setAndroidPlatformIntegration(this);
+
+ m_androidFDB = new QAndroidPlatformFontDatabase();
+ m_androidPlatformServices = new QAndroidPlatformServices();
+ m_androidPlatformClipboard = new QAndroidPlatformClipboard();
+}
+
+bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ default:
+#ifndef ANDROID_PLUGIN_OPENGL
+ return QPlatformIntegration::hasCapability(cap);
+#else
+ return QEglFSIntegration::hasCapability(cap);
+#endif
+ }
+}
+
+#ifndef ANDROID_PLUGIN_OPENGL
+QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QFbBackingStore(window);
+}
+
+QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QAndroidPlatformWindow(window);
+}
+
+QAbstractEventDispatcher *QAndroidPlatformIntegration::guiThreadEventDispatcher() const
+{
+ return m_eventDispatcher;
+}
+#else // !ANDROID_PLUGIN_OPENGL
+QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
+{
+ if (m_primaryWindow != 0) {
+ qWarning("QAndroidPlatformIntegration::createPlatformWindow: Unsupported case: More than "
+ "one top-level window created.");
+ }
+
+ m_primaryWindow = new QAndroidOpenGLPlatformWindow(window);
+ m_primaryWindow->requestActivateWindow();
+ QtAndroidMenu::setActiveTopLevelWindow(window);
+
+ return m_primaryWindow;
+}
+
+void QAndroidPlatformIntegration::invalidateNativeSurface()
+{
+ if (m_primaryWindow != 0)
+ m_primaryWindow->invalidateSurface();
+}
+
+void QAndroidPlatformIntegration::surfaceChanged()
+{
+ if (m_primaryWindow != 0)
+ m_primaryWindow->resetSurface();
+}
+
+QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ return new QAndroidOpenGLContext(this,
+ QEglFSHooks::hooks()->surfaceFormatFor(context->format()),
+ context->shareHandle(),
+ display());
+}
+#endif // ANDROID_PLUGIN_OPENGL
+
+QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
+{
+ delete m_androidPlatformNativeInterface;
+ delete m_androidFDB;
+ QtAndroid::setAndroidPlatformIntegration(NULL);
+}
+QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const
+{
+ return m_androidFDB;
+}
+
+#ifndef QT_NO_CLIPBOARD
+QPlatformClipboard *QAndroidPlatformIntegration::clipboard() const
+{
+static QAndroidPlatformClipboard *clipboard = 0;
+ if (!clipboard)
+ clipboard = new QAndroidPlatformClipboard;
+
+ return clipboard;
+}
+#endif
+
+QPlatformInputContext *QAndroidPlatformIntegration::inputContext() const
+{
+ return &m_platformInputContext;
+}
+
+QPlatformNativeInterface *QAndroidPlatformIntegration::nativeInterface() const
+{
+ return m_androidPlatformNativeInterface;
+}
+
+QPlatformServices *QAndroidPlatformIntegration::services() const
+{
+ return m_androidPlatformServices;
+}
+
+static const QLatin1String androidThemeName("android");
+QStringList QAndroidPlatformIntegration::themeNames() const
+{
+ return QStringList(QString(androidThemeName));
+}
+
+QPlatformTheme *QAndroidPlatformIntegration::createPlatformTheme(const QString &name) const
+{
+ if (androidThemeName == name)
+ return new QAndroidPlatformTheme;
+
+ return 0;
+}
+
+void QAndroidPlatformIntegration::setDefaultDisplayMetrics(int gw, int gh, int sw, int sh)
+{
+ m_defaultGeometryWidth = gw;
+ m_defaultGeometryHeight = gh;
+ m_defaultPhysicalSizeWidth = sw;
+ m_defaultPhysicalSizeHeight = sh;
+}
+
+void QAndroidPlatformIntegration::setDefaultDesktopSize(int gw, int gh)
+{
+ m_defaultGeometryWidth = gw;
+ m_defaultGeometryHeight = gh;
+}
+
+
+#ifndef ANDROID_PLUGIN_OPENGL
+void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
+{
+ if (m_primaryScreen)
+ QMetaObject::invokeMethod(m_primaryScreen, "setGeometry", Qt::AutoConnection, Q_ARG(QRect, QRect(0,0,width, height)));
+}
+
+void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
+{
+ if (m_primaryScreen)
+ QMetaObject::invokeMethod(m_primaryScreen, "setPhysicalSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height)));
+}
+#else
+void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
+{
+ m_defaultGeometryWidth = width;
+ m_defaultGeometryHeight = height;
+}
+
+void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
+{
+ m_defaultPhysicalSizeWidth = width;
+ m_defaultPhysicalSizeHeight = height;
+}
+
+#endif
+
+void QAndroidPlatformIntegration::pauseApp()
+{
+ if (QAbstractEventDispatcher::instance(m_mainThread))
+ QAbstractEventDispatcher::instance(m_mainThread)->interrupt();
+}
+
+void QAndroidPlatformIntegration::resumeApp()
+{
+ if (QAbstractEventDispatcher::instance(m_mainThread))
+ QAbstractEventDispatcher::instance(m_mainThread)->wakeUp();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h
new file mode 100644
index 0000000000..7dde277d25
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMINTERATION_H
+#define QANDROIDPLATFORMINTERATION_H
+
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformmenu.h>
+#include <qpa/qplatformnativeinterface.h>
+#include <QtWidgets/QAction>
+
+#include <jni.h>
+#include "qandroidinputcontext.h"
+
+#ifndef ANDROID_PLUGIN_OPENGL
+# include "qandroidplatformscreen.h"
+#else
+# include "qeglfsintegration.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QDesktopWidget;
+class QAndroidPlatformServices;
+
+#ifdef ANDROID_PLUGIN_OPENGL
+class QAndroidOpenGLPlatformWindow;
+#endif
+
+class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
+{
+public:
+ void *nativeResourceForIntegration(const QByteArray &resource);
+};
+
+class QAndroidPlatformIntegration
+#ifndef ANDROID_PLUGIN_OPENGL
+ : public QPlatformIntegration
+#else
+ : public QEglFSIntegration
+#endif
+{
+ friend class QAndroidPlatformScreen;
+
+public:
+ QAndroidPlatformIntegration(const QStringList &paramList);
+ ~QAndroidPlatformIntegration();
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+
+#ifndef ANDROID_PLUGIN_OPENGL
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+ QAndroidPlatformScreen *screen() { return m_primaryScreen; }
+#else
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ void invalidateNativeSurface();
+ void surfaceChanged();
+ QAndroidOpenGLPlatformWindow *primaryWindow() const { return m_primaryWindow; }
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+#endif
+
+ virtual void setDesktopSize(int width, int height);
+ virtual void setDisplayMetrics(int width, int height);
+ bool isVirtualDesktop() { return true; }
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+#ifndef QT_NO_CLIPBOARD
+ QPlatformClipboard *clipboard() const;
+#endif
+
+ QPlatformInputContext *inputContext() const;
+ QPlatformNativeInterface *nativeInterface() const;
+ QPlatformServices *services() const;
+
+ QStringList themeNames() const;
+ QPlatformTheme *createPlatformTheme(const QString &name) const;
+
+ void pauseApp();
+ void resumeApp();
+ static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh);
+ static void setDefaultDesktopSize(int gw, int gh);
+
+ static QSize defaultDesktopSize()
+ {
+ return QSize(m_defaultGeometryWidth, m_defaultGeometryHeight);
+ }
+
+private:
+
+ friend class QEglFSAndroidHooks;
+#ifndef ANDROID_PLUGIN_OPENGL
+ QAbstractEventDispatcher *m_eventDispatcher;
+ QAndroidPlatformScreen *m_primaryScreen;
+#else
+ mutable QAndroidOpenGLPlatformWindow *m_primaryWindow;
+#endif
+
+ QThread *m_mainThread;
+
+ static int m_defaultGeometryWidth;
+ static int m_defaultGeometryHeight;
+ static int m_defaultPhysicalSizeWidth;
+ static int m_defaultPhysicalSizeHeight;
+
+ QPlatformFontDatabase *m_androidFDB;
+ QImage *m_FbScreenImage;
+ QPainter *m_compositePainter;
+ QAndroidPlatformNativeInterface *m_androidPlatformNativeInterface;
+ QAndroidPlatformServices *m_androidPlatformServices;
+ QPlatformClipboard *m_androidPlatformClipboard;
+
+ mutable QAndroidInputContext m_platformInputContext;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
new file mode 100644
index 0000000000..36247e86f9
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformmenu.h"
+#include "qandroidplatformmenuitem.h"
+#include "androidjnimenu.h"
+
+QAndroidPlatformMenu::QAndroidPlatformMenu()
+{
+ m_tag = reinterpret_cast<quintptr>(this); // QMenu will overwrite this later, but we need a unique ID for QtQuick
+ m_enabled = true;
+ m_isVisible = true;
+}
+
+QAndroidPlatformMenu::~QAndroidPlatformMenu()
+{
+ QtAndroidMenu::androidPlatformMenuDestroyed(this);
+}
+
+void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
+{
+ QMutexLocker lock(&m_menuItemsMutex);
+ m_menuItems.insert(qFind(m_menuItems.begin(),
+ m_menuItems.end(),
+ static_cast<QAndroidPlatformMenuItem *>(before)),
+ static_cast<QAndroidPlatformMenuItem *>(menuItem));
+}
+
+void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
+{
+ QMutexLocker lock(&m_menuItemsMutex);
+ m_menuItems.erase(qFind(m_menuItems.begin(),
+ m_menuItems.end(),
+ static_cast<QAndroidPlatformMenuItem *>(menuItem)));
+}
+
+void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
+{
+ PlatformMenuItemsType::iterator it;
+ for (it = m_menuItems.begin(); it != m_menuItems.end(); ++it) {
+ if ((*it)->tag() == menuItem->tag())
+ break;
+ }
+
+ if (it != m_menuItems.end())
+ QtAndroidMenu::syncMenu(this);
+}
+
+void QAndroidPlatformMenu::syncSeparatorsCollapsible(bool enable)
+{
+ Q_UNUSED(enable)
+}
+
+void QAndroidPlatformMenu::setTag(quintptr tag)
+{
+ m_tag = tag;
+}
+
+quintptr QAndroidPlatformMenu::tag() const
+{
+ return m_tag;
+}
+
+void QAndroidPlatformMenu::setText(const QString &text)
+{
+ m_text = text;
+}
+
+QString QAndroidPlatformMenu::text() const
+{
+ return m_text;
+}
+
+void QAndroidPlatformMenu::setIcon(const QIcon &icon)
+{
+ m_icon = icon;
+}
+
+QIcon QAndroidPlatformMenu::icon() const
+{
+ return m_icon;
+}
+
+void QAndroidPlatformMenu::setEnabled(bool enabled)
+{
+ m_enabled = enabled;
+}
+
+bool QAndroidPlatformMenu::isEnabled() const
+{
+ return m_enabled;
+}
+
+void QAndroidPlatformMenu::setVisible(bool visible)
+{
+ m_isVisible = visible;
+}
+
+bool QAndroidPlatformMenu::isVisible() const
+{
+ return m_isVisible;
+}
+
+QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const
+{
+ if (position < m_menuItems.size())
+ return m_menuItems[position];
+ return 0;
+}
+
+QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const
+{
+ foreach (QPlatformMenuItem *menuItem, m_menuItems) {
+ if (menuItem->tag() == tag)
+ return menuItem;
+ }
+
+ return 0;
+}
+
+QAndroidPlatformMenu::PlatformMenuItemsType QAndroidPlatformMenu::menuItems() const
+{
+ return m_menuItems;
+}
+
+QMutex *QAndroidPlatformMenu::menuItemsMutex()
+{
+ return &m_menuItemsMutex;
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.h b/src/plugins/platforms/android/src/qandroidplatformmenu.h
new file mode 100644
index 0000000000..20236cb636
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformmenu.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMMENU_H
+#define QANDROIDPLATFORMMENU_H
+
+#include <qpa/qplatformmenu.h>
+#include <qvector.h>
+#include <qmutex.h>
+
+class QAndroidPlatformMenuItem;
+class QAndroidPlatformMenu: public QPlatformMenu
+{
+public:
+ typedef QVector<QAndroidPlatformMenuItem *> PlatformMenuItemsType;
+
+public:
+ QAndroidPlatformMenu();
+ ~QAndroidPlatformMenu();
+
+ void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before);
+ void removeMenuItem(QPlatformMenuItem *menuItem);
+ void syncMenuItem(QPlatformMenuItem *menuItem);
+ void syncSeparatorsCollapsible(bool enable);
+
+ void setTag(quintptr tag);
+ quintptr tag() const;
+ void setText(const QString &text);
+ QString text() const;
+ void setIcon(const QIcon &icon);
+ QIcon icon() const;
+ void setEnabled(bool enabled);
+ bool isEnabled() const;
+ void setVisible(bool visible);
+ bool isVisible() const;
+
+ QPlatformMenuItem *menuItemAt(int position) const;
+ QPlatformMenuItem *menuItemForTag(quintptr tag) const;
+
+ PlatformMenuItemsType menuItems() const;
+ QMutex *menuItemsMutex();
+
+private:
+ PlatformMenuItemsType m_menuItems;
+ quintptr m_tag;
+ QString m_text;
+ QIcon m_icon;
+ bool m_enabled;
+ bool m_isVisible;
+ QMutex m_menuItemsMutex;
+};
+
+#endif // QANDROIDPLATFORMMENU_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp
new file mode 100644
index 0000000000..ef1ac61356
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformmenubar.h"
+#include "qandroidplatformmenu.h"
+#include "androidjnimenu.h"
+
+
+QAndroidPlatformMenuBar::QAndroidPlatformMenuBar()
+{
+ m_parentWindow = 0;
+ QtAndroidMenu::addMenuBar(this);
+}
+
+QAndroidPlatformMenuBar::~QAndroidPlatformMenuBar()
+{
+ QtAndroidMenu::removeMenuBar(this);
+}
+
+void QAndroidPlatformMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before)
+{
+ QMutexLocker lock(&m_menusListMutex);
+ m_menus.insert(qFind(m_menus.begin(),
+ m_menus.end(),
+ static_cast<QAndroidPlatformMenu *>(before)),
+ static_cast<QAndroidPlatformMenu *>(menu));
+}
+
+void QAndroidPlatformMenuBar::removeMenu(QPlatformMenu *menu)
+{
+ QMutexLocker lock(&m_menusListMutex);
+ m_menus.erase(qFind(m_menus.begin(),
+ m_menus.end(),
+ static_cast<QAndroidPlatformMenu *>(menu)));
+}
+
+void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu)
+{
+ QtAndroidMenu::syncMenu(static_cast<QAndroidPlatformMenu *>(menu));
+}
+
+void QAndroidPlatformMenuBar::handleReparent(QWindow *newParentWindow)
+{
+ m_parentWindow = newParentWindow;
+ QtAndroidMenu::setMenuBar(this, newParentWindow);
+}
+
+QPlatformMenu *QAndroidPlatformMenuBar::menuForTag(quintptr tag) const
+{
+ foreach (QPlatformMenu *menu, m_menus) {
+ if (menu->tag() == tag)
+ return menu;
+ }
+
+ return 0;
+}
+
+QWindow *QAndroidPlatformMenuBar::parentWindow() const
+{
+ return m_parentWindow;
+}
+
+QAndroidPlatformMenuBar::PlatformMenusType QAndroidPlatformMenuBar::menus() const
+{
+ return m_menus;
+}
+
+QMutex *QAndroidPlatformMenuBar::menusListMutex()
+{
+ return &m_menusListMutex;
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.h b/src/plugins/platforms/android/src/qandroidplatformmenubar.h
new file mode 100644
index 0000000000..56915335c2
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformmenubar.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMMENUBAR_H
+#define QANDROIDPLATFORMMENUBAR_H
+
+#include <qpa/qplatformmenu.h>
+#include <qvector.h>
+#include <qmutex.h>
+
+class QAndroidPlatformMenu;
+class QAndroidPlatformMenuBar: public QPlatformMenuBar
+{
+public:
+ typedef QVector<QAndroidPlatformMenu *> PlatformMenusType;
+public:
+ QAndroidPlatformMenuBar();
+ ~QAndroidPlatformMenuBar();
+
+ void insertMenu(QPlatformMenu *menu, QPlatformMenu *before);
+ void removeMenu(QPlatformMenu *menu);
+ void syncMenu(QPlatformMenu *menu);
+ void handleReparent(QWindow *newParentWindow);
+ QPlatformMenu *menuForTag(quintptr tag) const;
+
+ QWindow *parentWindow() const;
+ PlatformMenusType menus() const;
+ QMutex *menusListMutex();
+
+private:
+ PlatformMenusType m_menus;
+ QWindow *m_parentWindow;
+ QMutex m_menusListMutex;
+};
+
+#endif // QANDROIDPLATFORMMENUBAR_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp b/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp
new file mode 100644
index 0000000000..bd37834d2a
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformmenuitem.h"
+#include "qandroidplatformmenu.h"
+
+QAndroidPlatformMenuItem::QAndroidPlatformMenuItem()
+{
+ m_tag = reinterpret_cast<quintptr>(this); // QMenu will overwrite this later, but we need a unique ID for QtQuick
+ m_menu = 0;
+ m_isVisible = true;
+ m_isSeparator = false;
+ m_role = NoRole;
+ m_isCheckable = false;
+ m_isChecked = false;
+ m_isEnabled = true;
+}
+
+void QAndroidPlatformMenuItem::setTag(quintptr tag)
+{
+ m_tag = tag;
+}
+
+quintptr QAndroidPlatformMenuItem::tag() const
+{
+ return m_tag;
+}
+
+void QAndroidPlatformMenuItem::setText(const QString &text)
+{
+ m_text = text;
+ if (m_menu)
+ m_menu->setText(m_text);
+}
+
+QString QAndroidPlatformMenuItem::text() const
+{
+ return m_text;
+}
+
+void QAndroidPlatformMenuItem::setIcon(const QIcon &icon)
+{
+ m_icon = icon;
+ if (m_menu)
+ m_menu->setIcon(m_icon);
+}
+
+QIcon QAndroidPlatformMenuItem::icon() const
+{
+ return m_icon;
+}
+
+void QAndroidPlatformMenuItem::setMenu(QPlatformMenu *menu)
+{
+ m_menu = static_cast<QAndroidPlatformMenu *>(menu);
+ if (!m_menu)
+ return;
+
+ m_menu->setText(m_text);
+ m_menu->setIcon(m_icon);
+ m_menu->setVisible(m_isVisible);
+ m_menu->setEnabled(m_isEnabled);
+}
+
+QAndroidPlatformMenu *QAndroidPlatformMenuItem::menu() const
+{
+ return m_menu;
+}
+
+void QAndroidPlatformMenuItem::setVisible(bool isVisible)
+{
+ m_isVisible = isVisible;
+ if (m_menu)
+ m_menu->setVisible(m_isVisible);
+}
+
+bool QAndroidPlatformMenuItem::isVisible() const
+{
+ return m_isVisible;
+}
+
+void QAndroidPlatformMenuItem::setIsSeparator(bool isSeparator)
+{
+ m_isSeparator = isSeparator;
+}
+
+bool QAndroidPlatformMenuItem::isSeparator() const
+{
+ return m_isSeparator;
+}
+
+void QAndroidPlatformMenuItem::setFont(const QFont &font)
+{
+ Q_UNUSED(font)
+}
+
+void QAndroidPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role)
+{
+ m_role = role;
+}
+
+QPlatformMenuItem::MenuRole QAndroidPlatformMenuItem::role() const
+{
+ return m_role;
+}
+
+void QAndroidPlatformMenuItem::setCheckable(bool checkable)
+{
+ m_isCheckable = checkable;
+}
+
+bool QAndroidPlatformMenuItem::isCheckable() const
+{
+ return m_isCheckable;
+}
+
+void QAndroidPlatformMenuItem::setChecked(bool isChecked)
+{
+ m_isChecked = isChecked;
+}
+
+bool QAndroidPlatformMenuItem::isChecked() const
+{
+ return m_isChecked;
+}
+
+void QAndroidPlatformMenuItem::setShortcut(const QKeySequence &shortcut)
+{
+ Q_UNUSED(shortcut)
+}
+
+void QAndroidPlatformMenuItem::setEnabled(bool enabled)
+{
+ m_isEnabled = enabled;
+ if (m_menu)
+ m_menu->setEnabled(m_isEnabled);
+}
+
+bool QAndroidPlatformMenuItem::isEnabled() const
+{
+ return m_isEnabled;
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.h b/src/plugins/platforms/android/src/qandroidplatformmenuitem.h
new file mode 100644
index 0000000000..5861e8e195
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformmenuitem.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMMENUITEM_H
+#define QANDROIDPLATFORMMENUITEM_H
+#include <qpa/qplatformmenu.h>
+
+class QAndroidPlatformMenu;
+
+class QAndroidPlatformMenuItem: public QPlatformMenuItem
+{
+public:
+ QAndroidPlatformMenuItem();
+ void setTag(quintptr tag);
+ quintptr tag() const;
+
+ void setText(const QString &text);
+ QString text() const;
+
+ void setIcon(const QIcon &icon);
+ QIcon icon() const;
+
+ void setMenu(QPlatformMenu *menu);
+ QAndroidPlatformMenu *menu() const;
+
+ void setVisible(bool isVisible);
+ bool isVisible() const;
+
+ void setIsSeparator(bool isSeparator);
+ bool isSeparator() const;
+
+ void setFont(const QFont &font);
+
+ void setRole(MenuRole role);
+ MenuRole role() const;
+
+ void setCheckable(bool checkable);
+ bool isCheckable() const;
+
+ void setChecked(bool isChecked);
+ bool isChecked() const;
+
+ void setShortcut(const QKeySequence &shortcut);
+
+ void setEnabled(bool enabled);
+ bool isEnabled() const;
+
+private:
+ quintptr m_tag;
+ QString m_text;
+ QIcon m_icon;
+ QAndroidPlatformMenu *m_menu;
+ bool m_isVisible;
+ bool m_isSeparator;
+ MenuRole m_role;
+ bool m_isCheckable;
+ bool m_isChecked;
+ bool m_isEnabled;
+};
+
+#endif // QANDROIDPLATFORMMENUITEM_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.cpp b/src/plugins/platforms/android/src/qandroidplatformservices.cpp
new file mode 100644
index 0000000000..841a9d4d51
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformservices.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformservices.h"
+#include <QUrl>
+#include <QDir>
+#include <QDebug>
+
+QAndroidPlatformServices::QAndroidPlatformServices()
+{
+ JNIEnv *env;
+ if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) {
+ qCritical() << "AttachCurrentThread failed";
+ return;
+ }
+
+ m_openURIMethodID = env->GetStaticMethodID(QtAndroid::applicationClass(),
+ "openURL",
+ "(Ljava/lang/String;)V");
+}
+
+bool QAndroidPlatformServices::openUrl(const QUrl &url)
+{
+ JNIEnv *env;
+ if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) {
+ qCritical() << "AttachCurrentThread failed";
+ return false;
+ }
+
+ jstring string = env->NewString(reinterpret_cast<const jchar *>(url.toString().constData()),
+ url.toString().length());
+ env->CallStaticVoidMethod(QtAndroid::applicationClass(), m_openURIMethodID, string);
+ env->DeleteLocalRef(string);
+ return true;
+}
+
+bool QAndroidPlatformServices::openDocument(const QUrl &url)
+{
+ return openUrl(url);
+}
+
+QByteArray QAndroidPlatformServices::desktopEnvironment() const
+{
+ return QByteArray("Android");
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.h b/src/plugins/platforms/android/src/qandroidplatformservices.h
new file mode 100644
index 0000000000..8368b19043
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformservices.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDPLATFORMDESKTOPSERVICE_H
+#define ANDROIDPLATFORMDESKTOPSERVICE_H
+
+#include <qpa/qplatformservices.h>
+#include "androidjnimain.h"
+#include <jni.h>
+
+class QAndroidPlatformServices: public QPlatformServices
+{
+public:
+ QAndroidPlatformServices();
+ bool openUrl(const QUrl &url);
+ bool openDocument(const QUrl &url);
+ QByteArray desktopEnvironment() const;
+private:
+ jmethodID m_openURIMethodID;
+
+};
+
+#endif // ANDROIDPLATFORMDESKTOPSERVICE_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp
new file mode 100644
index 0000000000..25f2ade11a
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformtheme.h"
+#include "qandroidplatformmenubar.h"
+#include "qandroidplatformmenu.h"
+#include "qandroidplatformmenuitem.h"
+#include <QVariant>
+#include <QFileInfo>
+
+QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const
+{
+ return new QAndroidPlatformMenuBar;
+}
+
+QPlatformMenu *QAndroidPlatformTheme::createPlatformMenu() const
+{
+ return new QAndroidPlatformMenu;
+}
+
+QPlatformMenuItem *QAndroidPlatformTheme::createPlatformMenuItem() const
+{
+ return new QAndroidPlatformMenuItem;
+}
+
+QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
+{
+ switch (hint) {
+ case StyleNames:
+ if (qgetenv("QT_USE_ANDROID_NATIVE_STYLE").toInt()
+ && (!qgetenv("MINISTRO_ANDROID_STYLE_PATH").isEmpty()
+ || QFileInfo("/data/data/org.kde.necessitas.ministro/files/qt/style/style.json").exists())) {
+ return QStringList("android");
+ }
+ return QStringList("fusion");
+ break;
+ default:
+ return QPlatformTheme::themeHint(hint);
+ }
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.h b/src/plugins/platforms/android/src/qandroidplatformtheme.h
new file mode 100644
index 0000000000..263878ee16
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformtheme.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMTHEME_H
+#define QANDROIDPLATFORMTHEME_H
+
+#include <qpa/qplatformtheme.h>
+
+class QAndroidPlatformTheme: public QPlatformTheme
+{
+public:
+ virtual QPlatformMenuBar *createPlatformMenuBar() const;
+ virtual QPlatformMenu *createPlatformMenu() const;
+ virtual QPlatformMenuItem *createPlatformMenuItem() const;
+ virtual QVariant themeHint(ThemeHint hint) const;
+};
+
+#endif // QANDROIDPLATFORMTHEME_H
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
new file mode 100644
index 0000000000..2779d7cffd
--- /dev/null
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformscreen.h"
+#include "qandroidplatformintegration.h"
+#include "androidjnimain.h"
+#include "androidjnimenu.h"
+
+QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
+{
+ mGeometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
+ mFormat = QImage::Format_RGB16;
+ mDepth = 16;
+ mPhysicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
+ mPhysicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth);
+ initializeCompositor();
+}
+
+void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
+{
+ QtAndroidMenu::setActiveTopLevelWindow(w);
+}
+
+QRegion QAndroidPlatformScreen::doRedraw()
+{
+ QRegion touched;
+ touched = QFbScreen::doRedraw();
+ if (touched.isEmpty())
+ return touched;
+
+ QtAndroid::flushImage(mGeometry.topLeft(), *mScreenImage, touched.boundingRect());
+ return touched;
+}
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h
new file mode 100644
index 0000000000..df08e43af4
--- /dev/null
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMSCREEN_H
+#define QANDROIDPLATFORMSCREEN_H
+
+#include <QtPlatformSupport/private/qfbscreen_p.h>
+
+class QAndroidPlatformScreen: public QFbScreen
+{
+ Q_OBJECT
+public:
+ QAndroidPlatformScreen();
+ void topWindowChanged(QWindow *w);
+
+public slots:
+ QRegion doRedraw();
+
+};
+
+#endif
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
new file mode 100644
index 0000000000..94a69c10c7
--- /dev/null
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformwindow.h"
+
+QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window)
+{
+}
+
+void QAndroidPlatformWindow::setGeometry(const QRect &rect)
+{
+ QFbWindow::setGeometry(rect);
+}
+
+void QAndroidPlatformWindow::propagateSizeHints()
+{
+ //shut up warning from default implementation
+}
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
new file mode 100644
index 0000000000..3ee815fd69
--- /dev/null
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDPLATFORMWINDOW_H
+#define ANDROIDPLATFORMWINDOW_H
+#include <qobject.h>
+#include <QtPlatformSupport/private/qfbwindow_p.h>
+
+class QAndroidPlatformWindow: public QObject, public QFbWindow
+{
+ Q_OBJECT
+public:
+ explicit QAndroidPlatformWindow(QWindow *window);
+
+ void propagateSizeHints();
+
+public slots:
+ void setGeometry(const QRect &rect);
+
+};
+
+#endif // ANDROIDPLATFORMWINDOW_H
diff --git a/src/plugins/platforms/android/src/raster/raster.pri b/src/plugins/platforms/android/src/raster/raster.pri
new file mode 100644
index 0000000000..86e5aa235f
--- /dev/null
+++ b/src/plugins/platforms/android/src/raster/raster.pri
@@ -0,0 +1,7 @@
+INCLUDEPATH += $$PWD
+
+SOURCES += $$PWD/qandroidplatformscreen.cpp \
+ $$PWD/qandroidplatformwindow.cpp
+
+HEADERS += $$PWD/qandroidplatformscreen.h \
+ $$PWD/qandroidplatformwindow.h
diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri
new file mode 100644
index 0000000000..9bf36b2337
--- /dev/null
+++ b/src/plugins/platforms/android/src/src.pri
@@ -0,0 +1,47 @@
+load(qt_plugin)
+
+QT += core-private gui-private widgets-private platformsupport-private
+
+CONFIG += qpa/genericunixfontdatabase
+
+OTHER_FILES += $$PWD/android.json
+
+INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD/../../../../3rdparty/android/src
+
+SOURCES += $$PWD/androidplatformplugin.cpp \
+ $$PWD/androidjnimain.cpp \
+ $$PWD/androidjniinput.cpp \
+ $$PWD/androidjnimenu.cpp \
+ $$PWD/androidjniclipboard.cpp \
+ $$PWD/qandroidplatformintegration.cpp \
+ $$PWD/qandroidplatformservices.cpp \
+ $$PWD/qandroidassetsfileenginehandler.cpp \
+ $$PWD/qandroidinputcontext.cpp \
+ $$PWD/qandroidplatformfontdatabase.cpp \
+ $$PWD/qandroidplatformclipboard.cpp \
+ $$PWD/qandroidplatformtheme.cpp \
+ $$PWD/qandroidplatformmenubar.cpp \
+ $$PWD/qandroidplatformmenu.cpp \
+ $$PWD/qandroidplatformmenuitem.cpp
+
+
+HEADERS += $$PWD/qandroidplatformintegration.h \
+ $$PWD/androidjnimain.h \
+ $$PWD/androidjniinput.h \
+ $$PWD/androidjnimenu.h \
+ $$PWD/androidjniclipboard.h \
+ $$PWD/qandroidplatformservices.h \
+ $$PWD/qandroidassetsfileenginehandler.h \
+ $$PWD/qandroidinputcontext.h \
+ $$PWD/qandroidplatformfontdatabase.h \
+ $$PWD/qandroidplatformclipboard.h \
+ $$PWD/qandroidplatformtheme.h \
+ $$PWD/qandroidplatformmenubar.h \
+ $$PWD/qandroidplatformmenu.h \
+ $$PWD/qandroidplatformmenuitem.h
+
+
+#Non-standard install directory, QTBUG-29859
+DESTDIR = $$DESTDIR/android
+target.path = $${target.path}/android
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 0fc4c44629..8cebe16775 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -53,7 +53,7 @@
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
-#if !defined(QT_NO_EVDEV)
+#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID)
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
#include <QtPlatformSupport/private/qevdevtouch_p.h>
@@ -77,7 +77,7 @@ QEglFSIntegration::QEglFSIntegration()
{
QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
-#if !defined(QT_NO_EVDEV)
+#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID)
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index a60a3626fa..92664826ab 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -1,5 +1,7 @@
TEMPLATE = subdirs
+android:!android-no-sdk: SUBDIRS += android
+
SUBDIRS += minimal offscreen
contains(QT_CONFIG, xcb) {