Support multiple native surfaces on Android.
Support for multiple native surfaces is needed by applications that need to mix raster windows with GL windows. Rework the raster and opengl implementation, get rid of eglfs and fbconvenience dependencies. Create a single android platform plugin. [ChangeLog][Android] Rework the raster and opengl implementation. [ChangeLog][Android] Create a single android platform plugin. Task-number: QTBUG-34650 Change-Id: I9b1ab51554823329dda8cfbf8fef27c38f917c7b Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
This commit is contained in:
parent
338f4c9246
commit
8a9bd001c9
@ -1,4 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="org.qtproject.qt5.android">
|
||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||
<uses-sdk android:minSdkVersion="9" />
|
||||
</manifest>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 Android port of the Qt Toolkit.
|
||||
@ -73,6 +73,7 @@ import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class QtActivityDelegate
|
||||
@ -105,7 +106,7 @@ public class QtActivityDelegate
|
||||
private int m_lastChar = 0;
|
||||
private boolean m_fullScreen = false;
|
||||
private boolean m_started = false;
|
||||
private QtSurface m_surface = null;
|
||||
private HashMap<Integer, QtSurface> m_surfaces = null;
|
||||
private QtLayout m_layout = null;
|
||||
private QtEditText m_editText = null;
|
||||
private InputMethodManager m_imm = null;
|
||||
@ -116,21 +117,6 @@ public class QtActivityDelegate
|
||||
public boolean m_backKeyPressedSent = false;
|
||||
|
||||
|
||||
public QtLayout getQtLayout()
|
||||
{
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
public QtSurface getQtSurface()
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
public void redrawWindow(int left, int top, int right, int bottom)
|
||||
{
|
||||
m_surface.drawBitmap(new Rect(left, top, right, bottom));
|
||||
}
|
||||
|
||||
public void setFullScreen(boolean enterFullScreen)
|
||||
{
|
||||
if (m_fullScreen == enterFullScreen)
|
||||
@ -175,6 +161,7 @@ public class QtActivityDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
m_layout.requestLayout();
|
||||
}
|
||||
|
||||
|
||||
@ -233,7 +220,8 @@ public class QtActivityDelegate
|
||||
{
|
||||
if (m_imm == null)
|
||||
return;
|
||||
if (height > m_surface.getHeight()*2/3)
|
||||
|
||||
if (height > m_layout.getHeight() * 2 / 3)
|
||||
m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||
else
|
||||
m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
|
||||
@ -330,7 +318,7 @@ public class QtActivityDelegate
|
||||
{
|
||||
if (m_imm == null)
|
||||
return;
|
||||
m_imm.hideSoftInputFromWindow(m_editText.getWindowToken(), 0, new ResultReceiver( new Handler()){
|
||||
m_imm.hideSoftInputFromWindow(m_editText.getWindowToken(), 0, new ResultReceiver(new Handler()) {
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
switch (resultCode) {
|
||||
@ -358,7 +346,7 @@ public class QtActivityDelegate
|
||||
if (size < 36 || size > 512) { // check size sanity
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
a.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
size = metrics.densityDpi/10*3;
|
||||
size = metrics.densityDpi / 10 * 3;
|
||||
if (size < 36)
|
||||
size = 36;
|
||||
|
||||
@ -626,13 +614,13 @@ public class QtActivityDelegate
|
||||
m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
|
||||
}
|
||||
|
||||
if (null == m_surface)
|
||||
if (null == m_surfaces)
|
||||
onCreate(null);
|
||||
String nativeLibraryDir = QtNativeLibrariesDir.nativeLibrariesDir(m_activity);
|
||||
m_surface.applicationStarted( QtNative.startApplication(m_applicationParameters,
|
||||
QtNative.startApplication(m_applicationParameters,
|
||||
m_environmentVariables,
|
||||
m_mainLib,
|
||||
nativeLibraryDir));
|
||||
nativeLibraryDir);
|
||||
m_started = true;
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
@ -657,14 +645,12 @@ public class QtActivityDelegate
|
||||
metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
|
||||
}
|
||||
m_layout = new QtLayout(m_activity);
|
||||
m_surface = new QtSurface(m_activity, 0);
|
||||
m_editText = new QtEditText(m_activity, this);
|
||||
m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
m_layout.addView(m_surface, 0);
|
||||
m_surfaces = new HashMap<Integer, QtSurface>();
|
||||
m_activity.setContentView(m_layout,
|
||||
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||
ViewGroup.LayoutParams.FILL_PARENT));
|
||||
m_layout.bringChildToFront(m_surface);
|
||||
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
m_activity.registerForContextMenu(m_layout);
|
||||
|
||||
int orientation = m_activity.getResources().getConfiguration().orientation;
|
||||
@ -704,18 +690,6 @@ public class QtActivityDelegate
|
||||
}
|
||||
}
|
||||
|
||||
public void onRestoreInstanceState(Bundle savedInstanceState)
|
||||
{
|
||||
try {
|
||||
m_super_onRestoreInstanceState.invoke(m_activity, savedInstanceState);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
m_started = savedInstanceState.getBoolean("Started");
|
||||
if (m_started)
|
||||
m_surface.applicationStarted(true);
|
||||
}
|
||||
|
||||
public void onPause()
|
||||
{
|
||||
QtNative.updateApplicationState(ApplicationInactive);
|
||||
@ -768,6 +742,19 @@ public class QtActivityDelegate
|
||||
}
|
||||
outState.putBoolean("FullScreen", m_fullScreen);
|
||||
outState.putBoolean("Started", m_started);
|
||||
// It should never
|
||||
}
|
||||
|
||||
public void onRestoreInstanceState(Bundle savedInstanceState)
|
||||
{
|
||||
try {
|
||||
m_super_onRestoreInstanceState.invoke(m_activity, savedInstanceState);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
m_started = savedInstanceState.getBoolean("Started");
|
||||
// FIXME restore all surfaces
|
||||
|
||||
}
|
||||
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
@ -967,4 +954,39 @@ public class QtActivityDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createSurface(int id, boolean onTop, int x, int y, int w, int h) {
|
||||
if (m_surfaces.containsKey(id))
|
||||
m_layout.removeView(m_surfaces.remove(id));
|
||||
|
||||
QtSurface surface = new QtSurface(m_activity, id, onTop);
|
||||
if (w < 0 || h < 0) {
|
||||
surface.setLayoutParams( new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
} else {
|
||||
surface.setLayoutParams( new QtLayout.LayoutParams(w, h, x, y));
|
||||
}
|
||||
|
||||
m_layout.addView(surface);
|
||||
if (onTop)
|
||||
m_layout.bringChildToFront(surface);
|
||||
m_surfaces.put(id, surface);
|
||||
}
|
||||
|
||||
public void setSurfaceGeometry(int id, int x, int y, int w, int h) {
|
||||
if (!m_surfaces.containsKey(id)) {
|
||||
Log.e(QtNative.QtTAG, "Surface " + id +" not found!");
|
||||
return;
|
||||
}
|
||||
QtSurface surface = m_surfaces.get(id);
|
||||
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
m_layout.requestLayout();
|
||||
}
|
||||
|
||||
public void destroySurface(int id) {
|
||||
if (m_surfaces.containsKey(id))
|
||||
m_layout.removeView(m_surfaces.remove(id));
|
||||
else
|
||||
Log.e(QtNative.QtTAG, "Surface " + id +" not found!");
|
||||
}
|
||||
}
|
||||
|
@ -42,8 +42,10 @@
|
||||
|
||||
package org.qtproject.qt5.android;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
@ -64,6 +66,15 @@ public class QtLayout extends ViewGroup
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged (int w, int h, int oldw, int oldh)
|
||||
{
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
|
||||
metrics.heightPixels, w, h, metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 Android port of the Qt Toolkit.
|
||||
@ -250,29 +250,10 @@ public class QtNative
|
||||
}
|
||||
}
|
||||
|
||||
public static void pauseApplication()
|
||||
{
|
||||
synchronized (m_mainActivityMutex) {
|
||||
if (m_started)
|
||||
pauseQtApp();
|
||||
}
|
||||
}
|
||||
|
||||
public static void resumeApplication()
|
||||
{
|
||||
synchronized (m_mainActivityMutex) {
|
||||
if (m_started) {
|
||||
resumeQtApp();
|
||||
updateWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// application methods
|
||||
public static native void startQtApplication(String params, String env);
|
||||
public static native void startQtApp(String params, String env);
|
||||
public static native void pauseQtApp();
|
||||
public static native void resumeQtApp();
|
||||
public static native boolean startQtAndroidPlugin();
|
||||
public static native void quitQtAndroidPlugin();
|
||||
public static native void terminateQt();
|
||||
@ -283,16 +264,6 @@ public class QtNative
|
||||
m_activity.finish();
|
||||
}
|
||||
|
||||
private static void redrawSurface(final int left, final int top, final int right, final int bottom )
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activityDelegate.redrawWindow(left, top, right, bottom);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//@ANDROID-9
|
||||
static private int getAction(int index, MotionEvent event)
|
||||
{
|
||||
@ -539,6 +510,36 @@ public class QtNative
|
||||
return certificateArray;
|
||||
}
|
||||
|
||||
private static void createSurface(final int id, final boolean onTop, final int x, final int y, final int w, final int h)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activityDelegate.createSurface(id, onTop, x, y, w, h);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void setSurfaceGeometry(final int id, final int x, final int y, final int w, final int h)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activityDelegate.setSurfaceGeometry(id, x, y, w, h);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void destroySurface(final int id)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activityDelegate.destroySurface(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// screen methods
|
||||
public static native void setDisplayMetrics(int screenWidthPixels,
|
||||
int screenHeightPixels,
|
||||
@ -567,10 +568,7 @@ public class QtNative
|
||||
// keyboard methods
|
||||
|
||||
// surface methods
|
||||
public static native void destroySurface();
|
||||
public static native void setSurface(Object surface);
|
||||
public static native void lockSurface();
|
||||
public static native void unlockSurface();
|
||||
public static native void setSurface(int id, Object surface, int w, int h);
|
||||
// surface methods
|
||||
|
||||
// window methods
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 Android port of the Qt Toolkit.
|
||||
@ -44,11 +44,7 @@ package org.qtproject.qt5.android;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
@ -60,61 +56,34 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
|
||||
{
|
||||
private Bitmap m_bitmap = null;
|
||||
private boolean m_started = false;
|
||||
private boolean m_usesGL = false;
|
||||
private GestureDetector m_gestureDetector;
|
||||
private Object m_accessibilityDelegate = null;
|
||||
private boolean m_onTop;
|
||||
|
||||
public QtSurface(Context context, int id)
|
||||
public QtSurface(Context context, int id, boolean onTop)
|
||||
{
|
||||
super(context);
|
||||
setFocusable(false);
|
||||
setFocusableInTouchMode(false);
|
||||
|
||||
m_onTop = onTop;
|
||||
setZOrderMediaOverlay(onTop);
|
||||
getHolder().addCallback(this);
|
||||
getHolder().setFormat(PixelFormat.RGBA_8888);
|
||||
getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
|
||||
setId(id);
|
||||
m_gestureDetector =
|
||||
new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
|
||||
public void onLongPress(MotionEvent event) {
|
||||
if (!m_started)
|
||||
return;
|
||||
QtNative.longPress(getId(), (int) event.getX(), (int) event.getY());
|
||||
}
|
||||
});
|
||||
m_gestureDetector.setIsLongpressEnabled(true);
|
||||
}
|
||||
|
||||
public void applicationStarted(boolean usesGL)
|
||||
{
|
||||
m_started = true;
|
||||
m_usesGL = usesGL;
|
||||
if (getWidth() < 1 || getHeight() < 1)
|
||||
return;
|
||||
if (m_usesGL) {
|
||||
QtNative.setSurface(getHolder().getSurface());
|
||||
} else {
|
||||
QtNative.lockSurface();
|
||||
QtNative.setSurface(null);
|
||||
m_bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.RGB_565);
|
||||
QtNative.setSurface(m_bitmap);
|
||||
QtNative.unlockSurface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder)
|
||||
{
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
|
||||
metrics.heightPixels, getWidth(), getHeight(), metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
|
||||
|
||||
if (m_usesGL)
|
||||
holder.setFormat(PixelFormat.RGBA_8888);
|
||||
|
||||
|
||||
QtNative.setSurface(getId(), holder.getSurface(), getWidth(), getHeight());
|
||||
// Initialize Accessibility
|
||||
// The accessibility code depends on android API level 16, so dynamically resolve it
|
||||
if (android.os.Build.VERSION.SDK_INT >= 16) {
|
||||
@ -158,71 +127,21 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
|
||||
{
|
||||
if (width<1 || height<1)
|
||||
if (width < 1 || height < 1)
|
||||
return;
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
|
||||
metrics.heightPixels,
|
||||
width,
|
||||
height,
|
||||
metrics.xdpi,
|
||||
metrics.ydpi,
|
||||
metrics.scaledDensity);
|
||||
|
||||
if (!m_started)
|
||||
return;
|
||||
|
||||
if (m_usesGL) {
|
||||
QtNative.setSurface(holder.getSurface());
|
||||
} else {
|
||||
QtNative.lockSurface();
|
||||
QtNative.setSurface(null);
|
||||
m_bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
QtNative.setSurface(m_bitmap);
|
||||
QtNative.unlockSurface();
|
||||
QtNative.updateWindow();
|
||||
}
|
||||
QtNative.setSurface(getId(), holder.getSurface(), width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder)
|
||||
{
|
||||
if (m_usesGL) {
|
||||
QtNative.destroySurface();
|
||||
} else {
|
||||
if (!m_started)
|
||||
return;
|
||||
|
||||
QtNative.lockSurface();
|
||||
QtNative.setSurface(null);
|
||||
QtNative.unlockSurface();
|
||||
}
|
||||
}
|
||||
|
||||
public void drawBitmap(Rect rect)
|
||||
{
|
||||
if (!m_started)
|
||||
return;
|
||||
QtNative.lockSurface();
|
||||
if (null != m_bitmap) {
|
||||
try {
|
||||
Canvas cv = getHolder().lockCanvas(rect);
|
||||
cv.drawBitmap(m_bitmap, rect, rect, null);
|
||||
getHolder().unlockCanvasAndPost(cv);
|
||||
} catch (Exception e) {
|
||||
Log.e(QtNative.QtTAG, "Can't create main activity", e);
|
||||
}
|
||||
}
|
||||
QtNative.unlockSurface();
|
||||
QtNative.setSurface(getId(), null, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event)
|
||||
{
|
||||
if (!m_started)
|
||||
return false;
|
||||
QtNative.sendTouchEvent(event, getId());
|
||||
m_gestureDetector.onTouchEvent(event);
|
||||
return true;
|
||||
@ -231,8 +150,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
|
||||
@Override
|
||||
public boolean onTrackballEvent(MotionEvent event)
|
||||
{
|
||||
if (!m_started)
|
||||
return false;
|
||||
QtNative.sendTrackballEvent(event, getId());
|
||||
return true;
|
||||
}
|
||||
|
@ -871,7 +871,7 @@ static void android_default_message_handler(QtMsgType type,
|
||||
const QMessageLogContext &context,
|
||||
const QString &message)
|
||||
{
|
||||
android_LogPriority priority;
|
||||
android_LogPriority priority = ANDROID_LOG_DEBUG;
|
||||
switch (type) {
|
||||
case QtDebugMsg: priority = ANDROID_LOG_DEBUG; break;
|
||||
case QtWarningMsg: priority = ANDROID_LOG_WARN; break;
|
||||
|
@ -178,12 +178,14 @@ public:
|
||||
jobject jobj = static_cast<jobject>(o);
|
||||
if (!isSameObject(jobj)) {
|
||||
d = QSharedPointer<QJNIObjectData>(new QJNIObjectData());
|
||||
if (jobj) {
|
||||
QJNIEnvironmentPrivate env;
|
||||
d->m_jobject = env->NewGlobalRef(jobj);
|
||||
jclass objectClass = env->GetObjectClass(jobj);
|
||||
d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
|
||||
env->DeleteLocalRef(objectClass);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -8,9 +8,6 @@ irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
|
||||
|
||||
QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf
|
||||
|
||||
ANDROID_LIB_DEPENDENCY_REPLACEMENTS = \
|
||||
"plugins/platforms/android/libqtforandroid.so:plugins/platforms/android/libqtforandroidGL.so"
|
||||
|
||||
load(qt_module)
|
||||
|
||||
contains(QT_CONFIG, opengl):CONFIG += opengl
|
||||
|
@ -1,3 +1,80 @@
|
||||
TEMPLATE = subdirs
|
||||
TARGET = qtforandroid
|
||||
|
||||
SUBDIRS += raster opengl
|
||||
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
|
||||
}
|
||||
|
||||
QT += core-private gui-private platformsupport-private
|
||||
|
||||
CONFIG += qpa/genericunixfontdatabase
|
||||
|
||||
OTHER_FILES += $$PWD/android.json
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
SOURCES += $$PWD/androidplatformplugin.cpp \
|
||||
$$PWD/androidjnimain.cpp \
|
||||
$$PWD/androidjniaccessibility.cpp \
|
||||
$$PWD/androidjniinput.cpp \
|
||||
$$PWD/androidjnimenu.cpp \
|
||||
$$PWD/androidjniclipboard.cpp \
|
||||
$$PWD/qandroidplatformintegration.cpp \
|
||||
$$PWD/qandroidplatformservices.cpp \
|
||||
$$PWD/qandroidassetsfileenginehandler.cpp \
|
||||
$$PWD/qandroidinputcontext.cpp \
|
||||
$$PWD/qandroidplatformaccessibility.cpp \
|
||||
$$PWD/qandroidplatformfontdatabase.cpp \
|
||||
$$PWD/qandroidplatformdialoghelpers.cpp \
|
||||
$$PWD/qandroidplatformclipboard.cpp \
|
||||
$$PWD/qandroidplatformtheme.cpp \
|
||||
$$PWD/qandroidplatformmenubar.cpp \
|
||||
$$PWD/qandroidplatformmenu.cpp \
|
||||
$$PWD/qandroidplatformmenuitem.cpp \
|
||||
$$PWD/qandroidsystemlocale.cpp \
|
||||
$$PWD/qandroidplatformscreen.cpp \
|
||||
$$PWD/qandroidplatformwindow.cpp \
|
||||
$$PWD/qandroidplatformopenglwindow.cpp \
|
||||
$$PWD/qandroidplatformrasterwindow.cpp \
|
||||
$$PWD/qandroidplatformbackingstore.cpp \
|
||||
$$PWD/qandroidplatformopenglcontext.cpp
|
||||
|
||||
HEADERS += $$PWD/qandroidplatformintegration.h \
|
||||
$$PWD/androidjnimain.h \
|
||||
$$PWD/androidjniaccessibility.h \
|
||||
$$PWD/androidjniinput.h \
|
||||
$$PWD/androidjnimenu.h \
|
||||
$$PWD/androidjniclipboard.h \
|
||||
$$PWD/qandroidplatformservices.h \
|
||||
$$PWD/qandroidassetsfileenginehandler.h \
|
||||
$$PWD/qandroidinputcontext.h \
|
||||
$$PWD/qandroidplatformaccessibility.h \
|
||||
$$PWD/qandroidplatformfontdatabase.h \
|
||||
$$PWD/qandroidplatformclipboard.h \
|
||||
$$PWD/qandroidplatformdialoghelpers.h \
|
||||
$$PWD/qandroidplatformtheme.h \
|
||||
$$PWD/qandroidplatformmenubar.h \
|
||||
$$PWD/qandroidplatformmenu.h \
|
||||
$$PWD/qandroidplatformmenuitem.h \
|
||||
$$PWD/qandroidsystemlocale.h \
|
||||
$$PWD/androidsurfaceclient.h \
|
||||
$$PWD/qandroidplatformscreen.h \
|
||||
$$PWD/qandroidplatformwindow.h \
|
||||
$$PWD/qandroidplatformopenglwindow.h \
|
||||
$$PWD/qandroidplatformrasterwindow.h \
|
||||
$$PWD/qandroidplatformbackingstore.h \
|
||||
$$PWD/qandroidplatformopenglcontext.h
|
||||
|
||||
#Non-standard install directory, QTBUG-29859
|
||||
DESTDIR = $$DESTDIR/android
|
||||
target.path = $${target.path}/android
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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.
|
||||
@ -53,6 +53,7 @@
|
||||
#include <qdebug.h>
|
||||
#include <qglobal.h>
|
||||
#include <qobjectdefs.h>
|
||||
#include <QtCore/private/qjni_p.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "androidjnimain.h"
|
||||
@ -73,14 +74,6 @@
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#ifdef ANDROID_PLUGIN_OPENGL
|
||||
# include "qandroidopenglplatformwindow.h"
|
||||
#endif
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
static jmethodID m_redrawSurfaceMethodID = 0;
|
||||
|
||||
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
|
||||
|
||||
static JavaVM *m_javaVM = NULL;
|
||||
@ -90,6 +83,9 @@ static jmethodID m_loadClassMethodID = NULL;
|
||||
static AAssetManager *m_assetManager = NULL;
|
||||
static jobject m_resourcesObj;
|
||||
static jobject m_activityObject = NULL;
|
||||
static jmethodID m_createSurfaceMethodID = 0;
|
||||
static jmethodID m_setSurfaceGeometryMethodID = 0;
|
||||
static jmethodID m_destroySurfaceMethodID = 0;
|
||||
|
||||
static bool m_activityActive = true; // defaults to true because when the platform plugin is
|
||||
// initialized, QtActivity::onResume() has already been called
|
||||
@ -110,17 +106,19 @@ 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;
|
||||
#endif
|
||||
struct SurfaceData
|
||||
{
|
||||
~SurfaceData() { delete surface; }
|
||||
QJNIObjectPrivate *surface = 0;
|
||||
AndroidSurfaceClient *client = 0;
|
||||
};
|
||||
|
||||
QHash<int, AndroidSurfaceClient *> m_surfaces;
|
||||
|
||||
static QMutex m_surfacesMutex;
|
||||
static int m_surfaceId = 1;
|
||||
|
||||
static QSemaphore m_quitAppSemaphore;
|
||||
static QMutex m_surfaceMutex(QMutex::Recursive);
|
||||
static QSemaphore m_pauseApplicationSemaphore;
|
||||
static QMutex m_pauseApplicationMutex;
|
||||
|
||||
@ -140,128 +138,18 @@ 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;
|
||||
}
|
||||
#endif
|
||||
|
||||
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration)
|
||||
{
|
||||
m_surfaceMutex.lock();
|
||||
m_surfacesMutex.lock();
|
||||
m_androidPlatformIntegration = androidPlatformIntegration;
|
||||
m_surfaceMutex.unlock();
|
||||
m_surfacesMutex.unlock();
|
||||
}
|
||||
|
||||
QAndroidPlatformIntegration *androidPlatformIntegration()
|
||||
{
|
||||
QMutexLocker locker(&m_surfaceMutex);
|
||||
QMutexLocker locker(&m_surfacesMutex);
|
||||
return m_androidPlatformIntegration;
|
||||
}
|
||||
|
||||
@ -353,14 +241,14 @@ namespace QtAndroid
|
||||
|
||||
jobject createBitmap(QImage img, JNIEnv *env)
|
||||
{
|
||||
if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16)
|
||||
img = img.convertToFormat(QImage::Format_ARGB32);
|
||||
if (img.format() != QImage::Format_RGBA8888 && img.format() != QImage::Format_RGB16)
|
||||
img = img.convertToFormat(QImage::Format_RGBA8888);
|
||||
|
||||
jobject bitmap = env->CallStaticObjectMethod(m_bitmapClass,
|
||||
m_createBitmapMethodID,
|
||||
img.width(),
|
||||
img.height(),
|
||||
img.format() == QImage::Format_ARGB32
|
||||
img.format() == QImage::Format_RGBA8888
|
||||
? m_ARGB_8888_BitmapConfigValue
|
||||
: m_RGB_565_BitmapConfigValue);
|
||||
if (!bitmap)
|
||||
@ -393,6 +281,21 @@ namespace QtAndroid
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env)
|
||||
{
|
||||
if (format != QImage::Format_RGBA8888
|
||||
&& format != QImage::Format_RGB16)
|
||||
return 0;
|
||||
|
||||
return env->CallStaticObjectMethod(m_bitmapClass,
|
||||
m_createBitmapMethodID,
|
||||
width,
|
||||
height,
|
||||
format == QImage::Format_RGB16
|
||||
? m_RGB_565_BitmapConfigValue
|
||||
: m_ARGB_8888_BitmapConfigValue);
|
||||
}
|
||||
|
||||
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env)
|
||||
{
|
||||
if (!bitmap)
|
||||
@ -418,25 +321,74 @@ namespace QtAndroid
|
||||
{
|
||||
return m_qtTag;
|
||||
}
|
||||
|
||||
int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop)
|
||||
{
|
||||
QJNIEnvironmentPrivate env;
|
||||
if (!env)
|
||||
return 0;
|
||||
|
||||
m_surfacesMutex.lock();
|
||||
int surfaceId = m_surfaceId++;
|
||||
m_surfaces[surfaceId] = client;
|
||||
m_surfacesMutex.unlock();
|
||||
|
||||
jint x = 0, y = 0, w = -1, h = -1;
|
||||
if (!geometry.isNull()) {
|
||||
x = geometry.x();
|
||||
y = geometry.y();
|
||||
w = std::max(geometry.width(), 1);
|
||||
h = std::max(geometry.height(), 1);
|
||||
}
|
||||
env->CallStaticVoidMethod(m_applicationClass,
|
||||
m_createSurfaceMethodID,
|
||||
surfaceId,
|
||||
jboolean(onTop),
|
||||
x, y, w, h);
|
||||
return surfaceId;
|
||||
}
|
||||
|
||||
void setSurfaceGeometry(int surfaceId, const QRect &geometry)
|
||||
{
|
||||
QJNIEnvironmentPrivate env;
|
||||
if (!env)
|
||||
return;
|
||||
jint x = 0, y = 0, w = -1, h = -1;
|
||||
if (!geometry.isNull()) {
|
||||
x = geometry.x();
|
||||
y = geometry.y();
|
||||
w = geometry.width();
|
||||
h = geometry.height();
|
||||
}
|
||||
env->CallStaticVoidMethod(m_applicationClass,
|
||||
m_setSurfaceGeometryMethodID,
|
||||
surfaceId,
|
||||
x, y, w, h);
|
||||
}
|
||||
|
||||
void destroySurface(int surfaceId)
|
||||
{
|
||||
QMutexLocker lock(&m_surfacesMutex);
|
||||
const auto &it = m_surfaces.find(surfaceId);
|
||||
if (it == m_surfaces.end())
|
||||
return;
|
||||
|
||||
m_surfaces.remove(surfaceId);
|
||||
QJNIEnvironmentPrivate env;
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
env->CallStaticVoidMethod(m_applicationClass,
|
||||
m_destroySurfaceMethodID,
|
||||
surfaceId);
|
||||
}
|
||||
}
|
||||
|
||||
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*/)
|
||||
@ -512,54 +464,16 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
|
||||
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);
|
||||
@ -568,76 +482,19 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
|
||||
env->DeleteGlobalRef(m_ARGB_8888_BitmapConfigValue);
|
||||
env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue);
|
||||
env->DeleteGlobalRef(m_bitmapDrawableClass);
|
||||
m_androidPlatformIntegration = 0;
|
||||
delete m_androidAssetsFileEngineHandler;
|
||||
}
|
||||
|
||||
static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
|
||||
static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h)
|
||||
{
|
||||
#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) {
|
||||
// Use the desktop size.
|
||||
// On some devices, the getters for the native window size gives wrong values
|
||||
QSize size = QAndroidPlatformIntegration::defaultDesktopSize();
|
||||
|
||||
QPlatformScreen *screen = m_androidPlatformIntegration->screen();
|
||||
QRect geometry(QPoint(0, 0), size);
|
||||
if (screen) {
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry);
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry);
|
||||
QMutexLocker lock(&m_surfacesMutex);
|
||||
const auto &it = m_surfaces.find(id);
|
||||
if (it == m_surfaces.end()) {
|
||||
qWarning()<<"Can't find surface" << id;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sameNativeWindow) {
|
||||
m_surfaceMutex.unlock();
|
||||
m_androidPlatformIntegration->surfaceChanged();
|
||||
} else {
|
||||
// Resize all top level windows, since they share the same surface
|
||||
foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
|
||||
QAndroidOpenGLPlatformWindow *window =
|
||||
static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
|
||||
|
||||
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
|
||||
it.value()->surfaceChanged(env, jSurface, w, h);
|
||||
}
|
||||
|
||||
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
|
||||
@ -660,16 +517,6 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -680,12 +527,8 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
|
||||
QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
|
||||
}
|
||||
|
||||
#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 updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
|
||||
@ -734,15 +577,10 @@ static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint new
|
||||
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", "(IIIIDDD)V", (void *)setDisplayMetrics},
|
||||
{"setSurface", "(Ljava/lang/Object;)V", (void *)setSurface},
|
||||
{"destroySurface", "()V", (void *)destroySurface},
|
||||
{"lockSurface", "()V", (void *)lockSurface},
|
||||
{"unlockSurface", "()V", (void *)unlockSurface},
|
||||
{"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
|
||||
{"updateWindow", "()V", (void *)updateWindow},
|
||||
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
|
||||
{"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged}
|
||||
@ -795,7 +633,9 @@ static int registerNatives(JNIEnv *env)
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_createSurfaceMethodID, m_applicationClass, "createSurface", "(IZIIII)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setSurfaceGeometryMethodID, m_applicationClass, "setSurfaceGeometry", "(IIIII)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_destroySurfaceMethodID, m_applicationClass, "destroySurface", "(I)V");
|
||||
|
||||
jmethodID methodID;
|
||||
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;");
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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.
|
||||
@ -45,16 +45,11 @@
|
||||
|
||||
#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;
|
||||
#include <QImage>
|
||||
|
||||
class QRect;
|
||||
class QPoint;
|
||||
class QThread;
|
||||
@ -62,6 +57,7 @@ class QAndroidPlatformIntegration;
|
||||
class QWidget;
|
||||
class QString;
|
||||
class QWindow;
|
||||
class AndroidSurfaceClient;
|
||||
|
||||
namespace QtAndroid
|
||||
{
|
||||
@ -69,11 +65,10 @@ namespace QtAndroid
|
||||
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
|
||||
void setQtThread(QThread *thread);
|
||||
|
||||
#ifndef ANDROID_PLUGIN_OPENGL
|
||||
void flushImage(const QPoint &pos, const QImage &image, const QRect &rect);
|
||||
#else
|
||||
EGLNativeWindowType nativeWindow(bool waitToCreate = true);
|
||||
#endif
|
||||
|
||||
int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop);
|
||||
void setSurfaceGeometry(int surfaceId, const QRect &geometry);
|
||||
void destroySurface(int surfaceId);
|
||||
|
||||
QWindow *topLevelWindowAt(const QPoint &globalPos);
|
||||
int desktopWidthPixels();
|
||||
@ -91,6 +86,7 @@ namespace QtAndroid
|
||||
void hideStatusBar();
|
||||
|
||||
jobject createBitmap(QImage img, JNIEnv *env = 0);
|
||||
jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env);
|
||||
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
|
||||
|
||||
struct AttachedJNIEnv
|
@ -143,6 +143,9 @@ namespace QtAndroidMenu
|
||||
void setActiveTopLevelWindow(QWindow *window)
|
||||
{
|
||||
Qt::WindowFlags flags = window ? window->flags() : Qt::WindowFlags();
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
bool isNonRegularWindow = flags & (Qt::Desktop | Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
|
||||
if (isNonRegularWindow)
|
||||
return;
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
@ -39,22 +39,20 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QANDROIDOPENGLPLATFORMSCREEN_H
|
||||
#define QANDROIDOPENGLPLATFORMSCREEN_H
|
||||
#ifndef ANDROIDSURFACECLIENT_H
|
||||
#define ANDROIDSURFACECLIENT_H
|
||||
#include <QMutex>
|
||||
#include <jni.h>
|
||||
|
||||
#include "qeglfsscreen.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidOpenGLPlatformScreen : public QEglFSScreen
|
||||
class AndroidSurfaceClient
|
||||
{
|
||||
public:
|
||||
QAndroidOpenGLPlatformScreen(EGLDisplay display);
|
||||
virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) = 0;
|
||||
void lockSurface() { m_surfaceMutex.lock(); }
|
||||
void unlockSurface() { m_surfaceMutex.unlock(); }
|
||||
|
||||
protected:
|
||||
void topWindowChanged(QPlatformWindow *window);
|
||||
QMutex m_surfaceMutex;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDOPENGLPLATFORMSCREEN_H
|
||||
#endif // ANDROIDSURFACECLIENT_H
|
@ -1,32 +0,0 @@
|
||||
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 \
|
||||
$$PWD/../src/opengl/qandroidopenglplatformscreen.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/../src/opengl/qandroidopenglcontext.cpp \
|
||||
$$PWD/../src/opengl/qandroidopenglplatformwindow.cpp \
|
||||
$$PWD/../src/opengl/qandroidopenglplatformscreen.cpp
|
||||
|
||||
include($$PWD/../../eglfs/eglfs.pri)
|
||||
include($$PWD/../src/src.pri)
|
@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 "qandroidplatformbackingstore.h"
|
||||
#include "qandroidplatformscreen.h"
|
||||
#include "qandroidplatformrasterwindow.h"
|
||||
#include <qpa/qplatformscreen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidPlatformBackingStore::QAndroidPlatformBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window)
|
||||
{
|
||||
Q_ASSERT(window->handle());
|
||||
(static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->setBackingStore(this);
|
||||
}
|
||||
|
||||
QPaintDevice *QAndroidPlatformBackingStore::paintDevice()
|
||||
{
|
||||
return &m_image;
|
||||
}
|
||||
|
||||
void QAndroidPlatformBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
Q_UNUSED(window);
|
||||
Q_UNUSED(offset);
|
||||
|
||||
(static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->repaint(region);
|
||||
}
|
||||
|
||||
void QAndroidPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
||||
{
|
||||
Q_UNUSED(staticContents);
|
||||
|
||||
if (m_image.size() != size)
|
||||
m_image = QImage(size, window()->screen()->handle()->format());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
@ -39,23 +40,27 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qandroidopenglplatformscreen.h"
|
||||
#include "qandroidopenglplatformwindow.h"
|
||||
#include "androidjnimenu.h"
|
||||
#ifndef QANDROIDPLATFORMBACKINGSTORE_H
|
||||
#define QANDROIDPLATFORMBACKINGSTORE_H
|
||||
|
||||
#include <qpa/qplatformbackingstore.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display)
|
||||
: QEglFSScreen(display)
|
||||
class QAndroidPlatformBackingStore : public QPlatformBackingStore
|
||||
{
|
||||
}
|
||||
public:
|
||||
explicit QAndroidPlatformBackingStore(QWindow *window);
|
||||
virtual QPaintDevice *paintDevice();
|
||||
virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset);
|
||||
virtual void resize(const QSize &size, const QRegion &staticContents);
|
||||
const QImage image() { return m_image; }
|
||||
|
||||
void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window)
|
||||
{
|
||||
QtAndroidMenu::setActiveTopLevelWindow(window->window());
|
||||
QAndroidOpenGLPlatformWindow *platformWindow = static_cast<QAndroidOpenGLPlatformWindow *>(window);
|
||||
if (platformWindow != 0)
|
||||
platformWindow->updateStatusBarVisibility();
|
||||
}
|
||||
protected:
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDPLATFORMBACKINGSTORE_H
|
@ -40,35 +40,32 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qandroidplatformintegration.h"
|
||||
#include "qabstracteventdispatcher.h"
|
||||
#include "androidjnimain.h"
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QOpenGLContext>
|
||||
#include <QThread>
|
||||
|
||||
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <qpa/qplatformwindow.h>
|
||||
|
||||
#warning sort the headers
|
||||
#include "androidjnimain.h"
|
||||
#include "qabstracteventdispatcher.h"
|
||||
#include "qandroidplatformrasterwindow.h"
|
||||
#include "qandroidplatformopenglwindow.h"
|
||||
#include "qandroidplatformbackingstore.h"
|
||||
#include "qandroidplatformservices.h"
|
||||
#include "qandroidplatformfontdatabase.h"
|
||||
#include "qandroidplatformclipboard.h"
|
||||
#include "qandroidplatformaccessibility.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 "qandroidopenglplatformscreen.h"
|
||||
# include "qeglfshooks.h"
|
||||
# include <QtGui/qopenglcontext.h>
|
||||
#endif
|
||||
|
||||
#include "qandroidplatformopenglcontext.h"
|
||||
#include "qandroidplatformscreen.h"
|
||||
#include "qandroidplatformtheme.h"
|
||||
#include "qandroidsystemlocale.h"
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320;
|
||||
@ -102,12 +99,21 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶
|
||||
|
||||
m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
|
||||
|
||||
#ifndef ANDROID_PLUGIN_OPENGL
|
||||
if (!eglBindAPI(EGL_OPENGL_ES_API))
|
||||
qFatal("Could not bind GL_ES API");
|
||||
|
||||
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (m_eglDisplay == EGL_NO_DISPLAY)
|
||||
qFatal("Could not open egl display");
|
||||
|
||||
EGLint major, minor;
|
||||
if (!eglInitialize(m_eglDisplay, &major, &minor))
|
||||
qFatal("Could not initialize egl display");
|
||||
|
||||
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);
|
||||
@ -124,83 +130,53 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
|
||||
switch (cap) {
|
||||
case ThreadedPixmaps: return true;
|
||||
case ApplicationState: return true;
|
||||
case NativeWidgets: return false;
|
||||
case NativeWidgets: return true;
|
||||
case OpenGL: return true;
|
||||
case ThreadedOpenGL: 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);
|
||||
return new QAndroidPlatformBackingStore(window);
|
||||
}
|
||||
|
||||
QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
|
||||
{
|
||||
QSurfaceFormat format(context->format());
|
||||
format.setAlphaBufferSize(8);
|
||||
format.setRedBufferSize(8);
|
||||
format.setGreenBufferSize(8);
|
||||
format.setBlueBufferSize(8);
|
||||
return new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay);
|
||||
}
|
||||
|
||||
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
|
||||
{
|
||||
QAndroidPlatformWindow *platformWindow = new QAndroidPlatformWindow(window);
|
||||
platformWindow->setWindowState(window->windowState());
|
||||
|
||||
return platformWindow;
|
||||
if (window->surfaceType() == QSurface::RasterSurface)
|
||||
return new QAndroidPlatformRasterWindow(window);
|
||||
else
|
||||
return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
|
||||
}
|
||||
|
||||
QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
|
||||
{
|
||||
return createUnixEventDispatcher();
|
||||
}
|
||||
#else // !ANDROID_PLUGIN_OPENGL
|
||||
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
|
||||
{
|
||||
QAndroidOpenGLPlatformWindow *platformWindow = new QAndroidOpenGLPlatformWindow(window);
|
||||
platformWindow->create();
|
||||
platformWindow->requestActivateWindow();
|
||||
platformWindow->setWindowState(window->windowState());
|
||||
QtAndroidMenu::setActiveTopLevelWindow(window);
|
||||
|
||||
return platformWindow;
|
||||
}
|
||||
|
||||
void QAndroidPlatformIntegration::invalidateNativeSurface()
|
||||
{
|
||||
foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
|
||||
QAndroidOpenGLPlatformWindow *window =
|
||||
static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
|
||||
if (window != 0)
|
||||
window->invalidateSurface();
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidPlatformIntegration::surfaceChanged()
|
||||
{
|
||||
QAndroidOpenGLPlatformWindow::updateStaticNativeWindow();
|
||||
foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
|
||||
QAndroidOpenGLPlatformWindow *window =
|
||||
static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
|
||||
if (window != 0)
|
||||
window->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()
|
||||
{
|
||||
if (m_eglDisplay != EGL_NO_DISPLAY)
|
||||
eglTerminate(m_eglDisplay);
|
||||
|
||||
delete m_androidPlatformNativeInterface;
|
||||
delete m_androidFDB;
|
||||
delete m_androidSystemLocale;
|
||||
QtAndroid::setAndroidPlatformIntegration(NULL);
|
||||
}
|
||||
|
||||
QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const
|
||||
{
|
||||
return m_androidFDB;
|
||||
@ -295,8 +271,6 @@ QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ANDROID_PLUGIN_OPENGL
|
||||
void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
|
||||
{
|
||||
if (m_primaryScreen)
|
||||
@ -308,36 +282,5 @@ 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;
|
||||
}
|
||||
|
||||
QEglFSScreen *QAndroidPlatformIntegration::createScreen() const
|
||||
{
|
||||
return new QAndroidOpenGLPlatformScreen(display());
|
||||
}
|
||||
|
||||
#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
|
@ -47,14 +47,11 @@
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <QtWidgets/QAction>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <jni.h>
|
||||
#include "qandroidinputcontext.h"
|
||||
|
||||
#ifndef ANDROID_PLUGIN_OPENGL
|
||||
# include "qandroidplatformscreen.h"
|
||||
#else
|
||||
# include "qeglfsintegration.h"
|
||||
#endif
|
||||
#include "qandroidplatformscreen.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -63,10 +60,6 @@ class QAndroidPlatformServices;
|
||||
class QAndroidSystemLocale;
|
||||
class QPlatformAccessibility;
|
||||
|
||||
#ifdef ANDROID_PLUGIN_OPENGL
|
||||
class QAndroidOpenGLPlatformWindow;
|
||||
#endif
|
||||
|
||||
class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
|
||||
{
|
||||
public:
|
||||
@ -75,12 +68,7 @@ public:
|
||||
QHash<int, QFont> m_fonts;
|
||||
};
|
||||
|
||||
class QAndroidPlatformIntegration
|
||||
#ifndef ANDROID_PLUGIN_OPENGL
|
||||
: public QPlatformIntegration
|
||||
#else
|
||||
: public QEglFSIntegration
|
||||
#endif
|
||||
class QAndroidPlatformIntegration : public QPlatformIntegration
|
||||
{
|
||||
friend class QAndroidPlatformScreen;
|
||||
|
||||
@ -90,17 +78,11 @@ public:
|
||||
|
||||
bool hasCapability(QPlatformIntegration::Capability cap) const;
|
||||
|
||||
#ifndef ANDROID_PLUGIN_OPENGL
|
||||
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const;
|
||||
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
|
||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
|
||||
QAbstractEventDispatcher *createEventDispatcher() const;
|
||||
QAndroidPlatformScreen *screen() { return m_primaryScreen; }
|
||||
#else
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const;
|
||||
void invalidateNativeSurface();
|
||||
void surfaceChanged();
|
||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
|
||||
#endif
|
||||
|
||||
virtual void setDesktopSize(int width, int height);
|
||||
virtual void setDisplayMetrics(int width, int height);
|
||||
@ -121,13 +103,11 @@ public:
|
||||
#endif
|
||||
|
||||
QVariant styleHint(StyleHint hint) const;
|
||||
Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const Q_DECL_OVERRIDE;
|
||||
Qt::WindowState defaultWindowState(Qt::WindowFlags flags) 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 void setScreenOrientation(Qt::ScreenOrientation currentOrientation,
|
||||
@ -141,19 +121,12 @@ public:
|
||||
QTouchDevice *touchDevice() const { return m_touchDevice; }
|
||||
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
|
||||
|
||||
#ifdef ANDROID_PLUGIN_OPENGL
|
||||
QEglFSScreen *createScreen() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
friend class QEglFSAndroidHooks;
|
||||
EGLDisplay m_eglDisplay;
|
||||
|
||||
QTouchDevice *m_touchDevice;
|
||||
|
||||
#ifndef ANDROID_PLUGIN_OPENGL
|
||||
QAndroidPlatformScreen *m_primaryScreen;
|
||||
#endif
|
||||
|
||||
QThread *m_mainThread;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
@ -39,49 +40,30 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qandroidopenglcontext.h"
|
||||
#include "qandroidopenglplatformwindow.h"
|
||||
#include "qandroidplatformintegration.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include "qandroidplatformopenglcontext.h"
|
||||
#include "qandroidplatformopenglwindow.h"
|
||||
|
||||
#include <QSurface>
|
||||
#include <QtGui/private/qopenglcontext_p.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)
|
||||
QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
|
||||
:QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API)
|
||||
{
|
||||
}
|
||||
|
||||
void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
|
||||
void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface)
|
||||
{
|
||||
QEglFSContext::swapBuffers(surface);
|
||||
QEGLPlatformContext::swapBuffers(surface);
|
||||
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window) {
|
||||
QAndroidOpenGLPlatformWindow *window = static_cast<QAndroidOpenGLPlatformWindow *>(surface);
|
||||
window->lock();
|
||||
QSize size = window->scheduledResize();
|
||||
if (size.isValid()) {
|
||||
QRect geometry(QPoint(0, 0), size);
|
||||
window->setGeometry(geometry);
|
||||
QWindowSystemInterface::handleGeometryChange(window->window(), geometry);
|
||||
QWindowSystemInterface::handleExposeEvent(window->window(), QRegion(geometry));
|
||||
window->scheduleResize(QSize());
|
||||
}
|
||||
window->unlock();
|
||||
}
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window)
|
||||
static_cast<QAndroidPlatformOpenGLWindow *>(surface)->checkNativeSurface(eglConfig());
|
||||
}
|
||||
|
||||
bool QAndroidOpenGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
{
|
||||
bool ret = QEglFSContext::makeCurrent(surface);
|
||||
bool ret = QEGLPlatformContext::makeCurrent(surface);
|
||||
|
||||
const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
|
||||
if (rendererString != 0 && qstrncmp(rendererString, "Android Emulator", 16) == 0) {
|
||||
@ -92,4 +74,11 @@ bool QAndroidOpenGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
return ret;
|
||||
}
|
||||
|
||||
EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
||||
{
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window)
|
||||
return static_cast<QAndroidPlatformOpenGLWindow *>(surface)->eglSurface(eglConfig());
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
@ -39,31 +40,24 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QANDROIDOPENGLCONTEXT_H
|
||||
#define QANDROIDOPENGLCONTEXT_H
|
||||
#ifndef QANDROIDPLATFORMOPENGLCONTEXT_H
|
||||
#define QANDROIDPLATFORMOPENGLCONTEXT_H
|
||||
|
||||
#include <QtCore/qreadwritelock.h>
|
||||
#include "qeglfscontext.h"
|
||||
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidPlatformIntegration;
|
||||
class QAndroidOpenGLContext : public QEglFSContext
|
||||
class QAndroidPlatformOpenGLContext : public QEGLPlatformContext
|
||||
{
|
||||
public:
|
||||
QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
|
||||
const QSurfaceFormat &format,
|
||||
QPlatformOpenGLContext *share,
|
||||
EGLDisplay display,
|
||||
EGLenum eglApi = EGL_OPENGL_ES_API);
|
||||
|
||||
QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display);
|
||||
void swapBuffers(QPlatformSurface *surface);
|
||||
bool makeCurrent(QPlatformSurface *surface);
|
||||
|
||||
private:
|
||||
const QAndroidPlatformIntegration *m_platformIntegration;
|
||||
virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDOPENGLCONTEXT_H
|
||||
#endif // QANDROIDPLATFORMOPENGLCONTEXT_H
|
160
src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
Normal file
160
src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 "qandroidplatformopenglwindow.h"
|
||||
|
||||
#include "androidjnimain.h"
|
||||
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#warning remove me
|
||||
#include <QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidPlatformOpenGLWindow::QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display)
|
||||
:QAndroidPlatformWindow(window), m_eglDisplay(display)
|
||||
{
|
||||
lockSurface();
|
||||
m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), bool(window->flags() & Qt::WindowStaysOnTopHint));
|
||||
m_surfaceWaitCondition.wait(&m_surfaceMutex);
|
||||
unlockSurface();
|
||||
}
|
||||
|
||||
QAndroidPlatformOpenGLWindow::~QAndroidPlatformOpenGLWindow()
|
||||
{
|
||||
m_surfaceWaitCondition.wakeOne();
|
||||
lockSurface();
|
||||
if (m_nativeSurfaceId != -1)
|
||||
QtAndroid::destroySurface(m_nativeSurfaceId);
|
||||
clearEgl();
|
||||
unlockSurface();
|
||||
}
|
||||
|
||||
void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
if (rect == geometry())
|
||||
return;
|
||||
|
||||
qDebug() << rect;
|
||||
QAndroidPlatformWindow::setGeometry(rect);
|
||||
QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
|
||||
}
|
||||
|
||||
EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
|
||||
{
|
||||
QMutexLocker lock(&m_surfaceMutex);
|
||||
if (m_eglSurface == EGL_NO_SURFACE) {
|
||||
m_surfaceMutex.unlock();
|
||||
checkNativeSurface(config);
|
||||
m_surfaceMutex.lock();
|
||||
}
|
||||
return m_eglSurface;
|
||||
}
|
||||
|
||||
void QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
|
||||
{
|
||||
QMutexLocker lock(&m_surfaceMutex);
|
||||
qDebug() << geometry() << m_changedAndroidSurface.isValid();
|
||||
if (m_nativeSurfaceId == -1 || !m_changedAndroidSurface.isValid())
|
||||
return;
|
||||
|
||||
createEgl(config);
|
||||
|
||||
// we've create another surface, the window should be repainted
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
|
||||
}
|
||||
|
||||
void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
|
||||
{
|
||||
clearEgl();
|
||||
m_androidSurface = QJNIObjectPrivate();
|
||||
m_androidSurface = m_changedAndroidSurface;
|
||||
m_changedAndroidSurface = QJNIObjectPrivate();
|
||||
QJNIEnvironmentPrivate env;
|
||||
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurface.object());
|
||||
if (m_nativeWindow)
|
||||
ANativeWindow_acquire(m_nativeWindow);
|
||||
|
||||
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
|
||||
if (m_eglSurface == EGL_NO_SURFACE) {
|
||||
EGLint error = eglGetError();
|
||||
eglTerminate(m_eglDisplay);
|
||||
qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidPlatformOpenGLWindow::clearEgl()
|
||||
{
|
||||
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (m_eglSurface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(m_eglDisplay, m_eglSurface);
|
||||
m_eglSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (m_nativeWindow) {
|
||||
ANativeWindow_release(m_nativeWindow);
|
||||
m_nativeWindow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h)
|
||||
{
|
||||
Q_UNUSED(jniEnv);
|
||||
Q_UNUSED(w);
|
||||
Q_UNUSED(h);
|
||||
qDebug() << w << h;
|
||||
lockSurface();
|
||||
m_changedAndroidSurface = surface;
|
||||
m_surfaceWaitCondition.wakeOne();
|
||||
unlockSurface();
|
||||
|
||||
// repaint the window
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
@ -39,53 +40,44 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QANDROIDOPENGLPLATFORMWINDOW_H
|
||||
#define QANDROIDOPENGLPLATFORMWINDOW_H
|
||||
#ifndef QANDROIDPLATFORMOPENGLWINDOW_H
|
||||
#define QANDROIDPLATFORMOPENGLWINDOW_H
|
||||
|
||||
#include "qeglfswindow.h"
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qreadwritelock.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <QWaitCondition>
|
||||
#include <QtCore/private/qjni_p.h>
|
||||
|
||||
#include "androidsurfaceclient.h"
|
||||
#include "qandroidplatformwindow.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidOpenGLPlatformWindow : public QEglFSWindow
|
||||
class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
|
||||
{
|
||||
public:
|
||||
QAndroidOpenGLPlatformWindow(QWindow *window);
|
||||
~QAndroidOpenGLPlatformWindow();
|
||||
explicit QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display);
|
||||
~QAndroidPlatformOpenGLWindow();
|
||||
|
||||
QSize scheduledResize() const { return m_scheduledResize; }
|
||||
void scheduleResize(const QSize &size) { m_scheduledResize = size; }
|
||||
void setGeometry(const QRect &rect);
|
||||
EGLSurface eglSurface(EGLConfig config);
|
||||
|
||||
void lock() { m_lock.lock(); }
|
||||
void unlock() { m_lock.unlock(); }
|
||||
void checkNativeSurface(EGLConfig config);
|
||||
|
||||
bool isExposed() const;
|
||||
|
||||
void raise();
|
||||
|
||||
void invalidateSurface();
|
||||
void resetSurface();
|
||||
void setWindowState(Qt::WindowState state);
|
||||
|
||||
void setVisible(bool visible);
|
||||
|
||||
void destroy();
|
||||
|
||||
static void updateStaticNativeWindow();
|
||||
void updateStatusBarVisibility();
|
||||
protected:
|
||||
virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h);
|
||||
void createEgl(EGLConfig config);
|
||||
void clearEgl();
|
||||
|
||||
private:
|
||||
QSize m_scheduledResize;
|
||||
QMutex m_lock;
|
||||
Qt::WindowState m_state;
|
||||
EGLDisplay m_eglDisplay;
|
||||
EGLSurface m_eglSurface = EGL_NO_SURFACE;
|
||||
EGLNativeWindowType m_nativeWindow = nullptr;
|
||||
|
||||
static QReadWriteLock m_staticSurfaceLock;
|
||||
static EGLSurface m_staticSurface;
|
||||
static EGLNativeWindowType m_staticNativeWindow;
|
||||
static QBasicAtomicInt m_referenceCount;
|
||||
int m_nativeSurfaceId = -1;
|
||||
QJNIObjectPrivate m_androidSurface;
|
||||
QJNIObjectPrivate m_changedAndroidSurface;
|
||||
QWaitCondition m_surfaceWaitCondition;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDOPENGLPLATFORMWINDOW_H
|
||||
#endif // QANDROIDPLATFORMOPENGLWINDOW_H
|
@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 "qandroidplatformrasterwindow.h"
|
||||
|
||||
#include "qandroidplatformscreen.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidPlatformRasterWindow::QAndroidPlatformRasterWindow(QWindow *window)
|
||||
:QAndroidPlatformWindow(window)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QAndroidPlatformRasterWindow::repaint(const QRegion ®ion)
|
||||
{
|
||||
QRect currentGeometry = geometry();
|
||||
|
||||
QRect dirtyClient = region.boundingRect();
|
||||
QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
|
||||
currentGeometry.top() + dirtyClient.top(),
|
||||
dirtyClient.width(),
|
||||
dirtyClient.height());
|
||||
QRect mOldGeometryLocal = m_oldGeometry;
|
||||
m_oldGeometry = currentGeometry;
|
||||
// If this is a move, redraw the previous location
|
||||
if (mOldGeometryLocal != currentGeometry)
|
||||
platformScreen()->setDirty(mOldGeometryLocal);
|
||||
platformScreen()->setDirty(dirtyRegion);
|
||||
}
|
||||
|
||||
void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
m_oldGeometry = geometry();
|
||||
QAndroidPlatformWindow::setGeometry(rect);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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.
|
||||
@ -39,24 +40,31 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QANDROIDPLATFORMSCREEN_H
|
||||
#define QANDROIDPLATFORMSCREEN_H
|
||||
#ifndef QANDROIDPLATFORMRASTERWINDOW_H
|
||||
#define QANDROIDPLATFORMRASTERWINDOW_H
|
||||
|
||||
#include <QtPlatformSupport/private/qfbscreen_p.h>
|
||||
#include "qandroidplatformwindow.h"
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidPlatformScreen: public QFbScreen
|
||||
class QAndroidPlatformBackingStore;
|
||||
class QAndroidPlatformRasterWindow : public QObject, public QAndroidPlatformWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QAndroidPlatformScreen();
|
||||
void topWindowChanged(QWindow *w);
|
||||
QDpi logicalDpi() const;
|
||||
Qt::ScreenOrientation orientation() const;
|
||||
Qt::ScreenOrientation nativeOrientation() const;
|
||||
QAndroidPlatformRasterWindow(QWindow *window);
|
||||
|
||||
void setBackingStore(QAndroidPlatformBackingStore *store) { m_backingStore = store; }
|
||||
QAndroidPlatformBackingStore *backingStore() const { return m_backingStore; }
|
||||
void repaint(const QRegion®ion);
|
||||
|
||||
public slots:
|
||||
QRegion doRedraw();
|
||||
void setGeometry(const QRect &rect);
|
||||
|
||||
private:
|
||||
QAndroidPlatformBackingStore *m_backingStore = nullptr;
|
||||
QRect m_oldGeometry;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
QT_END_NAMESPACE
|
||||
#endif // QANDROIDPLATFORMRASTERWINDOW_H
|
352
src/plugins/platforms/android/qandroidplatformscreen.cpp
Normal file
352
src/plugins/platforms/android/qandroidplatformscreen.cpp
Normal file
@ -0,0 +1,352 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 <QDebug>
|
||||
#include <QTime>
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include "qandroidplatformscreen.h"
|
||||
#include "qandroidplatformbackingstore.h"
|
||||
#include "qandroidplatformintegration.h"
|
||||
#include "androidjnimain.h"
|
||||
#include "androidjnimenu.h"
|
||||
#include "qandroidplatformrasterwindow.h"
|
||||
|
||||
#include <android/bitmap.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#warning REMOVE ME
|
||||
class ScopedProfiler
|
||||
{
|
||||
public:
|
||||
ScopedProfiler(const QString &msg)
|
||||
{
|
||||
m_msg = msg;
|
||||
}
|
||||
~ScopedProfiler()
|
||||
{
|
||||
qDebug() << m_msg << m_timer.elapsed();
|
||||
}
|
||||
|
||||
private:
|
||||
QTime m_timer;
|
||||
QString m_msg;
|
||||
};
|
||||
|
||||
#define PROFILE_SCOPE ScopedProfiler ___sp___(__func__)
|
||||
|
||||
QAndroidPlatformScreen::QAndroidPlatformScreen():QObject(),QPlatformScreen()
|
||||
{
|
||||
m_geometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
|
||||
// Raster only apps should set QT_ANDROID_RASTER_IMAGE_DEPTH to 16
|
||||
// is way much faster than 32
|
||||
if (qgetenv("QT_ANDROID_RASTER_IMAGE_DEPTH").toInt() == 16) {
|
||||
m_format = QImage::Format_RGB16;
|
||||
m_depth = 16;
|
||||
} else {
|
||||
m_format = QImage::Format_RGBA8888;
|
||||
m_depth = 32;
|
||||
}
|
||||
m_physicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
|
||||
m_physicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth);
|
||||
m_redrawTimer.setSingleShot(true);
|
||||
m_redrawTimer.setInterval(0);
|
||||
connect(&m_redrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw()));
|
||||
}
|
||||
|
||||
QAndroidPlatformScreen::~QAndroidPlatformScreen()
|
||||
{
|
||||
if (m_id != -1) {
|
||||
QtAndroid::destroySurface(m_id);
|
||||
m_surfaceWaitCondition.wakeOne();
|
||||
if (m_bitmap)
|
||||
QtAndroid::AttachedJNIEnv().jniEnv->DeleteGlobalRef(m_bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
QWindow *QAndroidPlatformScreen::topWindow() const
|
||||
{
|
||||
foreach (QAndroidPlatformWindow *w, m_windowStack)
|
||||
if (w->window()->type() == Qt::Window || w->window()->type() == Qt::Dialog)
|
||||
return w->window();
|
||||
return 0;
|
||||
}
|
||||
|
||||
QWindow *QAndroidPlatformScreen::topLevelAt(const QPoint &p) const
|
||||
{
|
||||
foreach (QAndroidPlatformWindow *w, m_windowStack) {
|
||||
if (w->geometry().contains(p, false) && w->window()->isVisible())
|
||||
return w->window();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
|
||||
{
|
||||
m_windowStack.prepend(window);
|
||||
if (window->isRaster())
|
||||
setDirty(window->geometry());
|
||||
|
||||
QWindow *w = topWindow();
|
||||
QWindowSystemInterface::handleWindowActivated(w);
|
||||
topWindowChanged(w);
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
|
||||
{
|
||||
m_windowStack.removeOne(window);
|
||||
if (window->isRaster()) {
|
||||
setDirty(window->geometry());
|
||||
}
|
||||
QWindow *w = topWindow();
|
||||
QWindowSystemInterface::handleWindowActivated(w);
|
||||
topWindowChanged(w);
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window)
|
||||
{
|
||||
int index = m_windowStack.indexOf(window);
|
||||
if (index <= 0)
|
||||
return;
|
||||
m_windowStack.move(index, 0);
|
||||
if (window->isRaster()) {
|
||||
setDirty(window->geometry());
|
||||
}
|
||||
QWindow *w = topWindow();
|
||||
QWindowSystemInterface::handleWindowActivated(w);
|
||||
topWindowChanged(w);
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window)
|
||||
{
|
||||
int index = m_windowStack.indexOf(window);
|
||||
if (index == -1 || index == (m_windowStack.size() - 1))
|
||||
return;
|
||||
m_windowStack.move(index, m_windowStack.size() - 1);
|
||||
if (window->isRaster()) {
|
||||
setDirty(window->geometry());
|
||||
}
|
||||
QWindow *w = topWindow();
|
||||
QWindowSystemInterface::handleWindowActivated(w);
|
||||
topWindowChanged(w);
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::scheduleUpdate()
|
||||
{
|
||||
if (!m_redrawTimer.isActive())
|
||||
m_redrawTimer.start();
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::setDirty(const QRect &rect)
|
||||
{
|
||||
QRect intersection = rect.intersected(m_geometry);
|
||||
QPoint screenOffset = m_geometry.topLeft();
|
||||
m_repaintRegion += intersection.translated(-screenOffset); // global to local translation
|
||||
scheduleUpdate();
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::setPhysicalSize(const QSize &size)
|
||||
{
|
||||
m_physicalSize = size;
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::setGeometry(const QRect &rect)
|
||||
{
|
||||
QMutexLocker lock(&m_surfaceMutex);
|
||||
if (m_geometry == rect)
|
||||
return;
|
||||
|
||||
m_geometry = rect;
|
||||
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
|
||||
resizeMaximizedWindows();
|
||||
|
||||
if (m_id != -1) {
|
||||
if (m_bitmap) {
|
||||
QtAndroid::AttachedJNIEnv().jniEnv->DeleteGlobalRef(m_bitmap);
|
||||
m_bitmap = 0;
|
||||
}
|
||||
QtAndroid::setSurfaceGeometry(m_id, rect);
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
|
||||
{
|
||||
QtAndroidMenu::setActiveTopLevelWindow(w);
|
||||
|
||||
if (w != 0) {
|
||||
QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
|
||||
if (platformWindow != 0)
|
||||
platformWindow->updateStatusBarVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::doRedraw()
|
||||
{
|
||||
PROFILE_SCOPE;
|
||||
|
||||
if (m_repaintRegion.isEmpty())
|
||||
return;
|
||||
|
||||
QVector<QRect> rects = m_repaintRegion.rects();
|
||||
|
||||
QMutexLocker lock(&m_surfaceMutex);
|
||||
if (m_id == -1) {
|
||||
m_id = QtAndroid::createSurface(this, m_geometry, true);
|
||||
m_surfaceWaitCondition.wait(&m_surfaceMutex);
|
||||
}
|
||||
|
||||
if (!m_bitmap || !m_surface.isValid())
|
||||
return;
|
||||
|
||||
QJNIEnvironmentPrivate env;
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
int ret;
|
||||
void *pixels;
|
||||
|
||||
if ((ret = AndroidBitmap_lockPixels(env, m_bitmap, &pixels)) < 0) {
|
||||
qWarning() << "AndroidBitmap_lockPixels() failed! error=" << ret;
|
||||
return;
|
||||
}
|
||||
|
||||
QImage mScreenImage(reinterpret_cast<uchar *>(pixels), m_bitmapWidth, m_bitmapHeight, m_bitmapStride, m_format);
|
||||
QPainter mCompositePainter(&mScreenImage);
|
||||
|
||||
for (int rectIndex = 0; rectIndex < rects.size(); rectIndex++) {
|
||||
QRegion visibleRegion = rects[rectIndex];
|
||||
foreach (QAndroidPlatformWindow *window, m_windowStack) {
|
||||
if (!window->window()->isVisible()
|
||||
|| !window->isRaster())
|
||||
continue;
|
||||
|
||||
foreach (const QRect &rect, visibleRegion.rects()) {
|
||||
QRect targetRect = window->geometry();
|
||||
targetRect &= rect;
|
||||
|
||||
if (targetRect.isNull())
|
||||
continue;
|
||||
|
||||
visibleRegion -= targetRect;
|
||||
QRect windowRect = targetRect.translated(-window->geometry().topLeft());
|
||||
QAndroidPlatformBackingStore *backingStore = static_cast<QAndroidPlatformRasterWindow *>(window)->backingStore();
|
||||
if (backingStore)
|
||||
mCompositePainter.drawImage(targetRect, backingStore->image(), windowRect);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const QRect &rect, visibleRegion.rects())
|
||||
mCompositePainter.fillRect(rect, Qt::transparent);
|
||||
}
|
||||
|
||||
|
||||
QRect br = m_repaintRegion.boundingRect();
|
||||
m_repaintRegion = QRegion();
|
||||
AndroidBitmap_unlockPixels(env, m_bitmap);
|
||||
|
||||
QJNIObjectPrivate jrect("android.graphics.Rect", "(IIII)V",
|
||||
jint(br.left()),
|
||||
jint(br.top()),
|
||||
jint(br.right() + 1),
|
||||
jint(br.bottom() + 1));
|
||||
|
||||
QJNIObjectPrivate canvas = m_surface.callObjectMethod("lockCanvas",
|
||||
"(Landroid/graphics/Rect;)Landroid/graphics/Canvas;",
|
||||
jrect.object());
|
||||
if (!canvas.isValid()) {
|
||||
qWarning() << "Can't lockCanvas";
|
||||
return;
|
||||
}
|
||||
canvas.callMethod<void>("drawBitmap",
|
||||
"(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Paint;)V",
|
||||
m_bitmap, jrect.object(), jrect.object(), jobject(0));
|
||||
|
||||
m_surface.callMethod<void>("unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", canvas.object());
|
||||
}
|
||||
|
||||
QDpi QAndroidPlatformScreen::logicalDpi() const
|
||||
{
|
||||
qreal lDpi = QtAndroid::scaledDensity() * 72;
|
||||
return QDpi(lDpi, lDpi);
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
|
||||
{
|
||||
return QAndroidPlatformIntegration::m_orientation;
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
|
||||
{
|
||||
return QAndroidPlatformIntegration::m_nativeOrientation;
|
||||
}
|
||||
|
||||
void QAndroidPlatformScreen::surfaceChanged(JNIEnv *env, jobject surface, int w, int h)
|
||||
{
|
||||
lockSurface();
|
||||
m_surface = surface;
|
||||
|
||||
if (surface && w && h) {
|
||||
if (w != m_bitmapWidth || h != m_bitmapHeight) {
|
||||
if (m_bitmap)
|
||||
env->DeleteGlobalRef(m_bitmap);
|
||||
m_bitmap = env->NewGlobalRef(QtAndroid::createBitmap(w, h, m_format, env));
|
||||
AndroidBitmapInfo info;
|
||||
int res = AndroidBitmap_getInfo(env, m_bitmap, &info);
|
||||
Q_ASSERT(res > -1);
|
||||
m_bitmapStride = info.stride;
|
||||
m_bitmapWidth = info.width;
|
||||
m_bitmapHeight = info.height;
|
||||
}
|
||||
} else {
|
||||
if (m_bitmap) {
|
||||
env->DeleteGlobalRef(m_bitmap);
|
||||
m_bitmap = 0;
|
||||
}
|
||||
}
|
||||
unlockSurface();
|
||||
m_surfaceWaitCondition.wakeOne();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
120
src/plugins/platforms/android/qandroidplatformscreen.h
Normal file
120
src/plugins/platforms/android/qandroidplatformscreen.h
Normal file
@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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 QANDROIDPLATFORMSCREEN_H
|
||||
#define QANDROIDPLATFORMSCREEN_H
|
||||
|
||||
#include <qpa/qplatformscreen.h>
|
||||
#include <QList>
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
#include <QWaitCondition>
|
||||
#include <QtCore/private/qjni_p.h>
|
||||
|
||||
#include "androidsurfaceclient.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidPlatformWindow;
|
||||
class QAndroidPlatformBackingStore;
|
||||
|
||||
class QAndroidPlatformScreen: public QObject, public QPlatformScreen, public AndroidSurfaceClient
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QAndroidPlatformScreen();
|
||||
~QAndroidPlatformScreen();
|
||||
|
||||
QRect geometry() const { return m_geometry; }
|
||||
int depth() const { return m_depth; }
|
||||
QImage::Format format() const { return m_format; }
|
||||
QSizeF physicalSize() const { return m_physicalSize; }
|
||||
|
||||
inline QWindow *topWindow() const;
|
||||
QWindow *topLevelAt(const QPoint & p) const;
|
||||
|
||||
// compositor api
|
||||
void addWindow(QAndroidPlatformWindow *window);
|
||||
void removeWindow(QAndroidPlatformWindow *window);
|
||||
void raise(QAndroidPlatformWindow *window);
|
||||
void lower(QAndroidPlatformWindow *window);
|
||||
|
||||
void scheduleUpdate();
|
||||
void topWindowChanged(QWindow *w);
|
||||
|
||||
public slots:
|
||||
void setDirty(const QRect &rect);
|
||||
void setPhysicalSize(const QSize &size);
|
||||
void setGeometry(const QRect &rect);
|
||||
|
||||
protected:
|
||||
typedef QList<QAndroidPlatformWindow *> WindowStackType;
|
||||
WindowStackType m_windowStack;
|
||||
QRegion m_repaintRegion;
|
||||
QTimer m_redrawTimer;
|
||||
|
||||
QRect m_geometry;
|
||||
int m_depth;
|
||||
QImage::Format m_format;
|
||||
QSizeF m_physicalSize;
|
||||
|
||||
private:
|
||||
QDpi logicalDpi() const;
|
||||
Qt::ScreenOrientation orientation() const;
|
||||
Qt::ScreenOrientation nativeOrientation() const;
|
||||
void surfaceChanged(JNIEnv *env, jobject surface, int w, int h);
|
||||
|
||||
private slots:
|
||||
void doRedraw();
|
||||
|
||||
private:
|
||||
int m_id = -1;
|
||||
QJNIObjectPrivate m_surface;
|
||||
jobject m_bitmap = nullptr;
|
||||
QWaitCondition m_surfaceWaitCondition;
|
||||
int m_bitmapStride = -1;
|
||||
int m_bitmapWidth = -1;
|
||||
int m_bitmapHeight = -1;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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.
|
||||
@ -40,52 +41,39 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qandroidplatformwindow.h"
|
||||
#include "qandroidplatformopenglcontext.h"
|
||||
#include "qandroidplatformscreen.h"
|
||||
|
||||
#include "androidjnimain.h"
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
|
||||
: QFbWindow(window)
|
||||
: QPlatformWindow(window)
|
||||
{
|
||||
m_windowFlags = Qt::Widget;
|
||||
m_windowState = Qt::WindowNoState;
|
||||
static QAtomicInt winIdGenerator(1);
|
||||
m_windowId = winIdGenerator.fetchAndAddRelaxed(1);
|
||||
setWindowState(window->windowState());
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::setGeometry(const QRect &rect)
|
||||
void QAndroidPlatformWindow::lower()
|
||||
{
|
||||
QFbWindow::setGeometry(rect);
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::propagateSizeHints()
|
||||
{
|
||||
//shut up warning from default implementation
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::updateStatusBarVisibility()
|
||||
{
|
||||
Qt::WindowFlags flags = window()->flags();
|
||||
bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
|
||||
if (!isNonRegularWindow) {
|
||||
if (mWindowState & Qt::WindowFullScreen)
|
||||
QtAndroid::hideStatusBar();
|
||||
else if (mWindowState & Qt::WindowMaximized)
|
||||
QtAndroid::showStatusBar();
|
||||
}
|
||||
platformScreen()->lower(this);
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::raise()
|
||||
{
|
||||
updateStatusBarVisibility();
|
||||
QFbWindow::raise();
|
||||
platformScreen()->raise(this);
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)
|
||||
void QAndroidPlatformWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
if (mWindowState == state)
|
||||
return;
|
||||
|
||||
if (window()->isVisible())
|
||||
updateStatusBarVisibility();
|
||||
|
||||
QFbWindow::setWindowState(state);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), rect);
|
||||
QPlatformWindow::setGeometry(rect);
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::setVisible(bool visible)
|
||||
@ -93,10 +81,77 @@ void QAndroidPlatformWindow::setVisible(bool visible)
|
||||
if (visible)
|
||||
updateStatusBarVisibility();
|
||||
|
||||
QFbWindow::setVisible(visible);
|
||||
if (visible) {
|
||||
if (m_windowState & Qt::WindowFullScreen)
|
||||
setGeometry(platformScreen()->geometry());
|
||||
else if (m_windowState & Qt::WindowMaximized)
|
||||
setGeometry(platformScreen()->availableGeometry());
|
||||
}
|
||||
|
||||
QPlatformWindow::setVisible(visible);
|
||||
|
||||
if (visible)
|
||||
platformScreen()->addWindow(this);
|
||||
else
|
||||
platformScreen()->removeWindow(this);
|
||||
|
||||
// The Android Activity is activated before Qt is initialized, causing the application state to
|
||||
// never be set to 'active'. We explicitly set this state when the first window becomes visible.
|
||||
if (visible)
|
||||
QtAndroid::setApplicationActive();
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)
|
||||
{
|
||||
if (m_windowState == state)
|
||||
return;
|
||||
|
||||
QPlatformWindow::setWindowState(state);
|
||||
m_windowState = state;
|
||||
|
||||
if (window()->isVisible())
|
||||
updateStatusBarVisibility();
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
|
||||
{
|
||||
if (m_windowFlags == flags)
|
||||
return;
|
||||
|
||||
m_windowFlags = flags;
|
||||
}
|
||||
|
||||
Qt::WindowFlags QAndroidPlatformWindow::windowFlags() const
|
||||
{
|
||||
return m_windowFlags;
|
||||
}
|
||||
|
||||
QAndroidPlatformScreen *QAndroidPlatformWindow::platformScreen() const
|
||||
{
|
||||
return static_cast<QAndroidPlatformScreen *>(window()->screen()->handle());
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::propagateSizeHints()
|
||||
{
|
||||
//shut up warning from default implementation
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::requestActivateWindow()
|
||||
{
|
||||
platformScreen()->topWindowChanged(window());
|
||||
}
|
||||
|
||||
void QAndroidPlatformWindow::updateStatusBarVisibility()
|
||||
{
|
||||
Qt::WindowFlags flags = window()->flags();
|
||||
bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
|
||||
if (!isNonRegularWindow) {
|
||||
if (m_windowState & Qt::WindowFullScreen)
|
||||
QtAndroid::hideStatusBar();
|
||||
else if (m_windowState & Qt::WindowMaximized)
|
||||
QtAndroid::showStatusBar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** 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.
|
||||
@ -42,23 +43,45 @@
|
||||
#ifndef ANDROIDPLATFORMWINDOW_H
|
||||
#define ANDROIDPLATFORMWINDOW_H
|
||||
#include <qobject.h>
|
||||
#include <QtPlatformSupport/private/qfbwindow_p.h>
|
||||
#include <qrect.h>
|
||||
#include <qpa/qplatformwindow.h>
|
||||
|
||||
class QAndroidPlatformWindow: public QObject, public QFbWindow
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidPlatformScreen;
|
||||
|
||||
class QAndroidPlatformWindow: public QPlatformWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QAndroidPlatformWindow(QWindow *window);
|
||||
|
||||
void propagateSizeHints();
|
||||
|
||||
void lower();
|
||||
void raise();
|
||||
void setWindowState(Qt::WindowState state);
|
||||
void setVisible(bool visible);
|
||||
void updateStatusBarVisibility();
|
||||
|
||||
public slots:
|
||||
void setVisible(bool visible);
|
||||
|
||||
void setWindowState(Qt::WindowState state);
|
||||
void setWindowFlags(Qt::WindowFlags flags);
|
||||
Qt::WindowFlags windowFlags() const;
|
||||
|
||||
WId winId() const { return m_windowId; }
|
||||
|
||||
QAndroidPlatformScreen *platformScreen() const;
|
||||
|
||||
void propagateSizeHints();
|
||||
void requestActivateWindow();
|
||||
void updateStatusBarVisibility();
|
||||
inline bool isRaster() const { return window()->surfaceType() == QSurface::RasterSurface; }
|
||||
|
||||
protected:
|
||||
void setGeometry(const QRect &rect);
|
||||
|
||||
protected:
|
||||
Qt::WindowFlags m_windowFlags;
|
||||
Qt::WindowState m_windowState;
|
||||
|
||||
WId m_windowId;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif // ANDROIDPLATFORMWINDOW_H
|
@ -1,19 +0,0 @@
|
||||
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)
|
@ -1,178 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qandroidplatformintegration.h"
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
EGLSurface QAndroidOpenGLPlatformWindow::m_staticSurface = 0;
|
||||
EGLNativeWindowType QAndroidOpenGLPlatformWindow::m_staticNativeWindow = 0;
|
||||
QReadWriteLock QAndroidOpenGLPlatformWindow::m_staticSurfaceLock;
|
||||
QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_INITIALIZER(0);
|
||||
|
||||
QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
|
||||
: QEglFSWindow(window)
|
||||
, m_state(Qt::WindowNoState)
|
||||
{
|
||||
}
|
||||
|
||||
QAndroidOpenGLPlatformWindow::~QAndroidOpenGLPlatformWindow()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool QAndroidOpenGLPlatformWindow::isExposed() const
|
||||
{
|
||||
return QtAndroid::nativeWindow(false) != 0 && QEglFSWindow::isExposed();
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::invalidateSurface()
|
||||
{
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
|
||||
m_window = 0;
|
||||
m_surface = 0;
|
||||
|
||||
if (!m_referenceCount.deref()){
|
||||
QWriteLocker locker(&m_staticSurfaceLock);
|
||||
|
||||
EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
|
||||
eglDestroySurface(display, m_staticSurface);
|
||||
|
||||
m_staticSurface = 0;
|
||||
m_staticNativeWindow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::updateStaticNativeWindow()
|
||||
{
|
||||
QWriteLocker locker(&m_staticSurfaceLock);
|
||||
m_staticNativeWindow = QtAndroid::nativeWindow(false);
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::resetSurface()
|
||||
{
|
||||
// Only add a reference if we're not already holding one, otherwise we're just updating
|
||||
// the native window pointer
|
||||
if (m_window == 0)
|
||||
m_referenceCount.ref();
|
||||
|
||||
if (m_staticSurface == 0) {
|
||||
QWriteLocker locker(&m_staticSurfaceLock);
|
||||
QEglFSWindow::resetSurface();
|
||||
m_staticSurface = m_surface;
|
||||
m_staticNativeWindow = m_window;
|
||||
} else {
|
||||
QReadLocker locker(&m_staticSurfaceLock);
|
||||
m_window = m_staticNativeWindow;
|
||||
m_surface = m_staticSurface;
|
||||
}
|
||||
|
||||
{
|
||||
lock();
|
||||
// Use the desktop size.
|
||||
// On some devices, the getters for the native window size gives wrong values
|
||||
scheduleResize(QAndroidPlatformIntegration::defaultDesktopSize());
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
|
||||
unlock();
|
||||
}
|
||||
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::destroy()
|
||||
{
|
||||
if (!m_referenceCount.deref()) {
|
||||
QEglFSWindow::destroy();
|
||||
} else {
|
||||
m_window = 0;
|
||||
m_surface = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::updateStatusBarVisibility()
|
||||
{
|
||||
Qt::WindowFlags flags = window()->flags();
|
||||
bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
|
||||
if (!isNonRegularWindow) {
|
||||
if (m_state & Qt::WindowFullScreen)
|
||||
QtAndroid::hideStatusBar();
|
||||
else if (m_state & Qt::WindowMaximized)
|
||||
QtAndroid::showStatusBar();
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::raise()
|
||||
{
|
||||
updateStatusBarVisibility();
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::setWindowState(Qt::WindowState state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
|
||||
m_state = state;
|
||||
if (window()->isVisible())
|
||||
updateStatusBarVisibility();
|
||||
}
|
||||
|
||||
void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
updateStatusBarVisibility();
|
||||
|
||||
QEglFSWindow::setVisible(visible);
|
||||
|
||||
// The Android Activity is activated before Qt is initialized, causing the application state to
|
||||
// never be set to 'active'. We explicitly set this state when the first window becomes visible.
|
||||
if (visible)
|
||||
QtAndroid::setApplicationActive();
|
||||
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,161 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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;
|
||||
QDpi logicalDpi() const;
|
||||
Qt::ScreenOrientation orientation() const;
|
||||
Qt::ScreenOrientation nativeOrientation() const;
|
||||
int screenDepth() const;
|
||||
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
|
||||
EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format);
|
||||
void destroyNativeWindow(EGLNativeWindowType window);
|
||||
bool hasCapability(QPlatformIntegration::Capability cap) const;
|
||||
QEglFSCursor *createCursor(QEglFSScreen *screen) const;
|
||||
};
|
||||
|
||||
void QEglFSAndroidHooks::platformInit()
|
||||
{
|
||||
}
|
||||
|
||||
void QEglFSAndroidHooks::platformDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
EGLNativeDisplayType QEglFSAndroidHooks::platformDisplay() const
|
||||
{
|
||||
return EGL_DEFAULT_DISPLAY;
|
||||
}
|
||||
|
||||
QSize QEglFSAndroidHooks::screenSize() const
|
||||
{
|
||||
return QAndroidPlatformIntegration::defaultDesktopSize();
|
||||
}
|
||||
|
||||
QSizeF QEglFSAndroidHooks::physicalScreenSize() const
|
||||
{
|
||||
return QSizeF(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth, QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
|
||||
}
|
||||
|
||||
QDpi QEglFSAndroidHooks::logicalDpi() const
|
||||
{
|
||||
qreal lDpi = QtAndroid::scaledDensity() * 72;
|
||||
return QDpi(lDpi, lDpi);
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QEglFSAndroidHooks::orientation() const
|
||||
{
|
||||
return QAndroidPlatformIntegration::m_orientation;
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QEglFSAndroidHooks::nativeOrientation() const
|
||||
{
|
||||
return QAndroidPlatformIntegration::m_nativeOrientation;
|
||||
}
|
||||
|
||||
EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format)
|
||||
{
|
||||
Q_UNUSED(platformWindow);
|
||||
Q_UNUSED(size);
|
||||
Q_UNUSED(format);
|
||||
ANativeWindow *window = QtAndroid::nativeWindow();
|
||||
if (window != 0)
|
||||
ANativeWindow_acquire(window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void QEglFSAndroidHooks::destroyNativeWindow(EGLNativeWindowType window)
|
||||
{
|
||||
if (window != 0)
|
||||
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;
|
||||
}
|
||||
|
||||
QEglFSCursor *QEglFSAndroidHooks::createCursor(QEglFSScreen *screen) const
|
||||
{
|
||||
Q_UNUSED(screen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QEglFSAndroidHooks eglFSAndroidHooks;
|
||||
QEglFSHooks *platformHooks = &eglFSAndroidHooks;
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,94 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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"
|
||||
#include "qandroidplatformwindow.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);
|
||||
|
||||
if (w != 0) {
|
||||
QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
|
||||
if (platformWindow != 0)
|
||||
platformWindow->updateStatusBarVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
QRegion QAndroidPlatformScreen::doRedraw()
|
||||
{
|
||||
QRegion touched;
|
||||
touched = QFbScreen::doRedraw();
|
||||
if (touched.isEmpty())
|
||||
return touched;
|
||||
|
||||
QtAndroid::flushImage(mGeometry.topLeft(), *mScreenImage, touched.boundingRect());
|
||||
return touched;
|
||||
}
|
||||
|
||||
QDpi QAndroidPlatformScreen::logicalDpi() const
|
||||
{
|
||||
qreal lDpi = QtAndroid::scaledDensity() * 72;
|
||||
return QDpi(lDpi, lDpi);
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
|
||||
{
|
||||
return QAndroidPlatformIntegration::m_orientation;
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
|
||||
{
|
||||
return QAndroidPlatformIntegration::m_nativeOrientation;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
SOURCES += $$PWD/qandroidplatformscreen.cpp \
|
||||
$$PWD/qandroidplatformwindow.cpp
|
||||
|
||||
HEADERS += $$PWD/qandroidplatformscreen.h \
|
||||
$$PWD/qandroidplatformwindow.h
|
@ -1,55 +0,0 @@
|
||||
load(qt_plugin)
|
||||
|
||||
QT += core-private gui-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/androidjniaccessibility.cpp \
|
||||
$$PWD/androidjniinput.cpp \
|
||||
$$PWD/androidjnimenu.cpp \
|
||||
$$PWD/androidjniclipboard.cpp \
|
||||
$$PWD/qandroidplatformintegration.cpp \
|
||||
$$PWD/qandroidplatformservices.cpp \
|
||||
$$PWD/qandroidassetsfileenginehandler.cpp \
|
||||
$$PWD/qandroidinputcontext.cpp \
|
||||
$$PWD/qandroidplatformaccessibility.cpp \
|
||||
$$PWD/qandroidplatformfontdatabase.cpp \
|
||||
$$PWD/qandroidplatformdialoghelpers.cpp \
|
||||
$$PWD/qandroidplatformclipboard.cpp \
|
||||
$$PWD/qandroidplatformtheme.cpp \
|
||||
$$PWD/qandroidplatformmenubar.cpp \
|
||||
$$PWD/qandroidplatformmenu.cpp \
|
||||
$$PWD/qandroidplatformmenuitem.cpp \
|
||||
$$PWD/qandroidsystemlocale.cpp
|
||||
|
||||
|
||||
HEADERS += $$PWD/qandroidplatformintegration.h \
|
||||
$$PWD/androidjnimain.h \
|
||||
$$PWD/androidjniaccessibility.h \
|
||||
$$PWD/androidjniinput.h \
|
||||
$$PWD/androidjnimenu.h \
|
||||
$$PWD/androidjniclipboard.h \
|
||||
$$PWD/qandroidplatformservices.h \
|
||||
$$PWD/qandroidassetsfileenginehandler.h \
|
||||
$$PWD/qandroidinputcontext.h \
|
||||
$$PWD/qandroidplatformaccessibility.h \
|
||||
$$PWD/qandroidplatformfontdatabase.h \
|
||||
$$PWD/qandroidplatformclipboard.h \
|
||||
$$PWD/qandroidplatformdialoghelpers.h \
|
||||
$$PWD/qandroidplatformtheme.h \
|
||||
$$PWD/qandroidplatformmenubar.h \
|
||||
$$PWD/qandroidplatformmenu.h \
|
||||
$$PWD/qandroidplatformmenuitem.h \
|
||||
$$PWD/qandroidsystemlocale.h
|
||||
|
||||
|
||||
#Non-standard install directory, QTBUG-29859
|
||||
DESTDIR = $$DESTDIR/android
|
||||
target.path = $${target.path}/android
|
Loading…
x
Reference in New Issue
Block a user