ANDROID: Try to sync Android backend
This commit is contained in:
parent
d5304e2568
commit
1884ccaa3a
7 changed files with 154 additions and 74 deletions
|
@ -152,7 +152,18 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
|
||||||
|
|
||||||
OSystem_Android::~OSystem_Android() {
|
OSystem_Android::~OSystem_Android() {
|
||||||
ENTER();
|
ENTER();
|
||||||
|
// _audiocdManager should be deleted before _mixer!
|
||||||
|
// It is normally deleted in proper order in the OSystem destructor.
|
||||||
|
// However, currently _mixer is deleted here (OSystem_Android)
|
||||||
|
// and in the ModularBackend destructor,
|
||||||
|
// hence unless _audiocdManager is deleted here first,
|
||||||
|
// it will cause a crash for the Android app (arm64 v8a) upon exit
|
||||||
|
// -- when the audio cd manager was actually used eg. audio cd test of the testbed
|
||||||
|
// FIXME: A more proper fix would probably be to:
|
||||||
|
// - delete _mixer in the base class (OSystem) after _audiocdManager (this is already the current behavior)
|
||||||
|
// - remove its deletion from OSystem_Android and ModularBackend (this is what needs to be fixed).
|
||||||
|
delete _audiocdManager;
|
||||||
|
_audiocdManager = 0;
|
||||||
delete _mixer;
|
delete _mixer;
|
||||||
_mixer = 0;
|
_mixer = 0;
|
||||||
delete _fsFactory;
|
delete _fsFactory;
|
||||||
|
@ -326,11 +337,11 @@ void OSystem_Android::initBackend() {
|
||||||
|
|
||||||
_main_thread = pthread_self();
|
_main_thread = pthread_self();
|
||||||
|
|
||||||
ConfMan.set("fullscreen", "true");
|
ConfMan.registerDefault("fullscreen", true);
|
||||||
ConfMan.registerDefault("aspect_ratio", true);
|
ConfMan.registerDefault("aspect_ratio", true);
|
||||||
ConfMan.registerDefault("touchpad_mouse_mode", true);
|
ConfMan.registerDefault("touchpad_mouse_mode", true);
|
||||||
|
|
||||||
ConfMan.setInt("autosave_period", 0);
|
ConfMan.registerDefault("autosave_period", 0);
|
||||||
ConfMan.setBool("FM_high_quality", false);
|
ConfMan.setBool("FM_high_quality", false);
|
||||||
ConfMan.setBool("FM_medium_quality", true);
|
ConfMan.setBool("FM_medium_quality", true);
|
||||||
ConfMan.set("browser_lastpath", ConfMan.get("path"));
|
ConfMan.set("browser_lastpath", ConfMan.get("path"));
|
||||||
|
@ -348,10 +359,13 @@ void OSystem_Android::initBackend() {
|
||||||
// screen. Passing the savepath in this way makes it stick
|
// screen. Passing the savepath in this way makes it stick
|
||||||
// (via ConfMan.registerDefault)
|
// (via ConfMan.registerDefault)
|
||||||
_savefileManager = new DefaultSaveFileManager(ConfMan.get("savepath"));
|
_savefileManager = new DefaultSaveFileManager(ConfMan.get("savepath"));
|
||||||
|
// TODO remove the debug message eventually
|
||||||
|
LOGD("Setting DefaultSaveFileManager path to: %s", ConfMan.get("savepath").c_str());
|
||||||
|
|
||||||
_mutexManager = new PthreadMutexManager();
|
_mutexManager = new PthreadMutexManager();
|
||||||
_timerManager = new DefaultTimerManager();
|
_timerManager = new DefaultTimerManager();
|
||||||
|
|
||||||
_event_queue_lock = createMutex();
|
_event_queue_lock = new Common::Mutex();
|
||||||
|
|
||||||
gettimeofday(&_startTime, 0);
|
gettimeofday(&_startTime, 0);
|
||||||
|
|
||||||
|
@ -374,6 +388,9 @@ void OSystem_Android::initBackend() {
|
||||||
|
|
||||||
JNI::setReadyForEvents(true);
|
JNI::setReadyForEvents(true);
|
||||||
|
|
||||||
|
_eventManager = new DefaultEventManager(this);
|
||||||
|
_audiocdManager = new DefaultAudioCDManager();
|
||||||
|
|
||||||
BaseBackend::initBackend();
|
BaseBackend::initBackend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +405,7 @@ bool OSystem_Android::hasFeature(Feature f) {
|
||||||
f == kFeatureClipboardSupport) {
|
f == kFeatureClipboardSupport) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return ModularBackend::hasFeature(f);
|
return ModularGraphicsBackend::hasFeature(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::setFeatureState(Feature f, bool enable) {
|
void OSystem_Android::setFeatureState(Feature f, bool enable) {
|
||||||
|
@ -408,7 +425,7 @@ void OSystem_Android::setFeatureState(Feature f, bool enable) {
|
||||||
JNI::showKeyboardControl(enable);
|
JNI::showKeyboardControl(enable);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ModularBackend::setFeatureState(f, enable);
|
ModularGraphicsBackend::setFeatureState(f, enable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,10 +439,30 @@ bool OSystem_Android::getFeatureState(Feature f) {
|
||||||
case kFeatureOnScreenControl:
|
case kFeatureOnScreenControl:
|
||||||
return ConfMan.getBool("onscreen_control");
|
return ConfMan.getBool("onscreen_control");
|
||||||
default:
|
default:
|
||||||
return ModularBackend::getFeatureState(f);
|
return ModularGraphicsBackend::getFeatureState(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::KeymapperDefaultBindings *OSystem_Android::getKeymapperDefaultBindings() {
|
||||||
|
Common::KeymapperDefaultBindings *keymapperDefaultBindings = new Common::KeymapperDefaultBindings();
|
||||||
|
|
||||||
|
// The swap_menu_and_back is a legacy configuration key
|
||||||
|
// It is only checked here for compatibility with old config files
|
||||||
|
// where it may have been set as "true"
|
||||||
|
// TODO Why not just ignore it entirely anyway?
|
||||||
|
if (ConfMan.hasKey("swap_menu_and_back") && ConfMan.getBool("swap_menu_and_back")) {
|
||||||
|
keymapperDefaultBindings->setDefaultBinding(Common::kGlobalKeymapName, "MENU", "AC_BACK");
|
||||||
|
keymapperDefaultBindings->setDefaultBinding("engine-default", Common::kStandardActionSkip, "MENU");
|
||||||
|
keymapperDefaultBindings->setDefaultBinding(Common::kGuiKeymapName, "CLOS", "MENU");
|
||||||
|
} else {
|
||||||
|
keymapperDefaultBindings->setDefaultBinding(Common::kGlobalKeymapName, "MENU", "MENU");
|
||||||
|
keymapperDefaultBindings->setDefaultBinding("engine-default", Common::kStandardActionSkip, "AC_BACK");
|
||||||
|
keymapperDefaultBindings->setDefaultBinding(Common::kGuiKeymapName, "CLOS", "AC_BACK");
|
||||||
|
}
|
||||||
|
|
||||||
|
return keymapperDefaultBindings;
|
||||||
|
}
|
||||||
|
|
||||||
// ResidualVM specific method
|
// ResidualVM specific method
|
||||||
void OSystem_Android::launcherInitSize(uint w, uint h) {
|
void OSystem_Android::launcherInitSize(uint w, uint h) {
|
||||||
dynamic_cast<AndroidGraphicsManager *>(_graphicsManager)->setupScreen(w, h, true, true, false);
|
dynamic_cast<AndroidGraphicsManager *>(_graphicsManager)->setupScreen(w, h, true, true, false);
|
||||||
|
@ -464,7 +501,6 @@ void OSystem_Android::setWindowCaption(const char *caption) {
|
||||||
JNI::setWindowCaption(caption);
|
JNI::setWindowCaption(caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSystem_Android::showVirtualKeyboard(bool enable) {
|
void OSystem_Android::showVirtualKeyboard(bool enable) {
|
||||||
ENTER("%d", enable);
|
ENTER("%d", enable);
|
||||||
|
|
||||||
|
@ -523,18 +559,18 @@ Common::String OSystem_Android::getSystemLanguage() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSystem_Android::openUrl(const Common::String &url) {
|
bool OSystem_Android::openUrl(const Common::String &url) {
|
||||||
return JNI::openUrl(url.c_str());
|
return JNI::openUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSystem_Android::hasTextInClipboard() {
|
bool OSystem_Android::hasTextInClipboard() {
|
||||||
return JNI::hasTextInClipboard();
|
return JNI::hasTextInClipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::String OSystem_Android::getTextFromClipboard() {
|
Common::U32String OSystem_Android::getTextFromClipboard() {
|
||||||
return JNI::getTextFromClipboard();
|
return JNI::getTextFromClipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSystem_Android::setTextInClipboard(const Common::String &text) {
|
bool OSystem_Android::setTextInClipboard(const Common::U32String &text) {
|
||||||
return JNI::setTextInClipboard(text);
|
return JNI::setTextInClipboard(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,4 +586,8 @@ Common::String OSystem_Android::getSystemProperty(const char *name) const {
|
||||||
return Common::String(value, len);
|
return Common::String(value, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *OSystem_Android::convertEncoding(const char *to, const char *from, const char *string, size_t length) {
|
||||||
|
return JNI::convertEncoding(to, from, string, length);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "backends/platform/android/portdefs.h"
|
#include "backends/platform/android/portdefs.h"
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
#include "common/archive.h"
|
#include "common/archive.h"
|
||||||
|
#include "common/mutex.h"
|
||||||
|
#include "common/ustr.h"
|
||||||
#include "audio/mixer_intern.h"
|
#include "audio/mixer_intern.h"
|
||||||
#include "graphics/palette.h"
|
#include "graphics/palette.h"
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
|
@ -100,7 +102,7 @@ extern void checkGlError(const char *expr, const char *file, int line);
|
||||||
#define GLTHREADCHECK do { } while (false)
|
#define GLTHREADCHECK do { } while (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class OSystem_Android : public ModularBackend, Common::EventSource {
|
class OSystem_Android : public ModularMutexBackend, public ModularGraphicsBackend, Common::EventSource {
|
||||||
private:
|
private:
|
||||||
// passed from the dark side
|
// passed from the dark side
|
||||||
int _audio_sample_rate;
|
int _audio_sample_rate;
|
||||||
|
@ -127,9 +129,6 @@ private:
|
||||||
|
|
||||||
void setupKeymapper();
|
void setupKeymapper();
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual Common::EventSource *getDefaultEventSource() { return this; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSystem_Android(int audio_sample_rate, int audio_buffer_size);
|
OSystem_Android(int audio_sample_rate, int audio_buffer_size);
|
||||||
virtual ~OSystem_Android();
|
virtual ~OSystem_Android();
|
||||||
|
@ -140,10 +139,6 @@ public:
|
||||||
virtual void setFeatureState(OSystem::Feature f, bool enable);
|
virtual void setFeatureState(OSystem::Feature f, bool enable);
|
||||||
virtual bool getFeatureState(OSystem::Feature f);
|
virtual bool getFeatureState(OSystem::Feature f);
|
||||||
|
|
||||||
virtual PaletteManager *getPaletteManager() override {
|
|
||||||
return dynamic_cast<AndroidGraphicsManager *>(_graphicsManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void pushEvent(int type, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
|
void pushEvent(int type, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
|
||||||
bool shouldGenerateMouseEvents();
|
bool shouldGenerateMouseEvents();
|
||||||
|
@ -152,7 +147,7 @@ private:
|
||||||
Common::Queue<Common::Event> _event_queue;
|
Common::Queue<Common::Event> _event_queue;
|
||||||
Common::Event _queuedEvent;
|
Common::Event _queuedEvent;
|
||||||
uint32 _queuedEventTime;
|
uint32 _queuedEventTime;
|
||||||
MutexRef _event_queue_lock;
|
Common::Mutex *_event_queue_lock;
|
||||||
|
|
||||||
Common::Point _touch_pt_down, _touch_pt_scroll, _touch_pt_dt;
|
Common::Point _touch_pt_down, _touch_pt_scroll, _touch_pt_dt;
|
||||||
int _eventScaleX;
|
int _eventScaleX;
|
||||||
|
@ -174,6 +169,8 @@ public:
|
||||||
virtual void pushEvent(const Common::Event &event);
|
virtual void pushEvent(const Common::Event &event);
|
||||||
virtual void pushKeyPressEvent(Common::Event &event);
|
virtual void pushKeyPressEvent(Common::Event &event);
|
||||||
virtual bool pollEvent(Common::Event &event);
|
virtual bool pollEvent(Common::Event &event);
|
||||||
|
virtual Common::KeymapperDefaultBindings *getKeymapperDefaultBindings();
|
||||||
|
|
||||||
virtual uint32 getMillis(bool skipRecord = false);
|
virtual uint32 getMillis(bool skipRecord = false);
|
||||||
virtual void delayMillis(uint msecs);
|
virtual void delayMillis(uint msecs);
|
||||||
|
|
||||||
|
@ -189,10 +186,11 @@ public:
|
||||||
int priority = 0);
|
int priority = 0);
|
||||||
virtual bool openUrl(const Common::String &url);
|
virtual bool openUrl(const Common::String &url);
|
||||||
virtual bool hasTextInClipboard();
|
virtual bool hasTextInClipboard();
|
||||||
virtual Common::String getTextFromClipboard();
|
virtual Common::U32String getTextFromClipboard();
|
||||||
virtual bool setTextInClipboard(const Common::String &text);
|
virtual bool setTextInClipboard(const Common::U32String &text);
|
||||||
virtual bool isConnectionLimited();
|
virtual bool isConnectionLimited();
|
||||||
virtual Common::String getSystemLanguage() const;
|
virtual Common::String getSystemLanguage() const;
|
||||||
|
virtual char *convertEncoding(const char *to, const char *from, const char *string, size_t length);
|
||||||
|
|
||||||
// ResidualVM specific method
|
// ResidualVM specific method
|
||||||
virtual void launcherInitSize(uint w, uint h);
|
virtual void launcherInitSize(uint w, uint h);
|
||||||
|
|
|
@ -71,6 +71,9 @@ AssetInputStream::AssetInputStream(AAssetManager *as, const Common::String &path
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetInputStream::~AssetInputStream() {
|
AssetInputStream::~AssetInputStream() {
|
||||||
|
if (_asset != NULL) {
|
||||||
|
AAsset_close(_asset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetInputStream::close() {
|
void AssetInputStream::close() {
|
||||||
|
@ -134,7 +137,7 @@ int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) con
|
||||||
dirs.push_back("shaders");
|
dirs.push_back("shaders");
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (const auto& currentDir : dirs) {
|
for (const auto& currentDir : dirs) {
|
||||||
AAssetDir *dir = AAssetManager_openDir(_am, currentDir.c_str());
|
AAssetDir *dir = AAssetManager_openDir(_am, "");
|
||||||
const char *file = AAssetDir_getNextFileName(dir);
|
const char *file = AAssetDir_getNextFileName(dir);
|
||||||
|
|
||||||
while (file) {
|
while (file) {
|
||||||
|
|
|
@ -40,8 +40,8 @@
|
||||||
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
|
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
|
||||||
|
|
||||||
#include "backends/platform/android/android.h"
|
#include "backends/platform/android/android.h"
|
||||||
#include "backends/platform/android/events.h"
|
|
||||||
#include "backends/platform/android/graphics.h"
|
#include "backends/platform/android/graphics.h"
|
||||||
|
#include "backends/platform/android/events.h"
|
||||||
#include "backends/platform/android/jni-android.h"
|
#include "backends/platform/android/jni-android.h"
|
||||||
|
|
||||||
#include "engines/engine.h"
|
#include "engines/engine.h"
|
||||||
|
@ -755,9 +755,9 @@ bool OSystem_Android::shouldGenerateMouseEvents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::pushEvent(const Common::Event &event) {
|
void OSystem_Android::pushEvent(const Common::Event &event) {
|
||||||
lockMutex(_event_queue_lock);
|
_event_queue_lock->lock();
|
||||||
_event_queue.push(event);
|
_event_queue.push(event);
|
||||||
unlockMutex(_event_queue_lock);
|
_event_queue_lock->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::pushKeyPressEvent(Common::Event &event) {
|
void OSystem_Android::pushKeyPressEvent(Common::Event &event) {
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
|
|
||||||
void updateScreen() override;
|
void updateScreen() override;
|
||||||
|
|
||||||
void displayMessageOnOSD(const char *msg);
|
void displayMessageOnOSD(const Common::U32String &msg);
|
||||||
|
|
||||||
bool notifyMousePosition(Common::Point &mouse);
|
bool notifyMousePosition(Common::Point &mouse);
|
||||||
Common::Point getMousePosition() { return Common::Point(_cursorX, _cursorY); }
|
Common::Point getMousePosition() { return Common::Point(_cursorX, _cursorY); }
|
||||||
|
|
|
@ -87,6 +87,7 @@ jmethodID JNI::_MID_setWindowCaption = 0;
|
||||||
jmethodID JNI::_MID_showVirtualKeyboard = 0;
|
jmethodID JNI::_MID_showVirtualKeyboard = 0;
|
||||||
jmethodID JNI::_MID_showKeyboardControl = 0;
|
jmethodID JNI::_MID_showKeyboardControl = 0;
|
||||||
jmethodID JNI::_MID_getSysArchives = 0;
|
jmethodID JNI::_MID_getSysArchives = 0;
|
||||||
|
jmethodID JNI::_MID_convertEncoding = 0;
|
||||||
jmethodID JNI::_MID_getAllStorageLocations = 0;
|
jmethodID JNI::_MID_getAllStorageLocations = 0;
|
||||||
jmethodID JNI::_MID_initSurface = 0;
|
jmethodID JNI::_MID_initSurface = 0;
|
||||||
jmethodID JNI::_MID_deinitSurface = 0;
|
jmethodID JNI::_MID_deinitSurface = 0;
|
||||||
|
@ -116,9 +117,7 @@ const JNINativeMethod JNI::_natives[] = {
|
||||||
{ "pushEvent", "(IIIIIII)V",
|
{ "pushEvent", "(IIIIIII)V",
|
||||||
(void *)JNI::pushEvent },
|
(void *)JNI::pushEvent },
|
||||||
{ "setPause", "(Z)V",
|
{ "setPause", "(Z)V",
|
||||||
(void *)JNI::setPause },
|
(void *)JNI::setPause }
|
||||||
{ "getCurrentCharset", "()Ljava/lang/String;",
|
|
||||||
(void *)JNI::getCurrentCharset }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
JNI::JNI() {
|
JNI::JNI() {
|
||||||
|
@ -227,24 +226,16 @@ void JNI::getDPI(float *values) {
|
||||||
env->DeleteLocalRef(array);
|
env->DeleteLocalRef(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JNI::displayMessageOnOSD(const char *msg) {
|
void JNI::displayMessageOnOSD(const Common::U32String &msg) {
|
||||||
// called from common/osd_message_queue, method: OSDMessageQueue::pollEvent()
|
// called from common/osd_message_queue, method: OSDMessageQueue::pollEvent()
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
Common::String fromEncoding = "ISO-8859-1";
|
|
||||||
#ifdef USE_TRANSLATION
|
|
||||||
if (TransMan.getCurrentCharset() != "ASCII") {
|
|
||||||
fromEncoding = TransMan.getCurrentCharset();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Common::Encoding converter("UTF-8", fromEncoding.c_str());
|
|
||||||
|
|
||||||
const char *utf8Msg = converter.convert(msg, converter.stringLength(msg, fromEncoding) );
|
jstring java_msg = convertToJString(env, msg.encode(), "UTF-8");
|
||||||
if (utf8Msg == nullptr) {
|
if (java_msg == nullptr) {
|
||||||
// Show a placeholder indicative of the translation error instead of silent failing
|
// Show a placeholder indicative of the translation error instead of silent failing
|
||||||
utf8Msg = "?";
|
java_msg = env->NewStringUTF("?");
|
||||||
LOGE("Failed to convert message to UTF-8 for OSD!");
|
LOGE("Failed to convert message to UTF-8 for OSD!");
|
||||||
}
|
}
|
||||||
jstring java_msg = env->NewStringUTF(utf8Msg);
|
|
||||||
|
|
||||||
env->CallVoidMethod(_jobj, _MID_displayMessageOnOSD, java_msg);
|
env->CallVoidMethod(_jobj, _MID_displayMessageOnOSD, java_msg);
|
||||||
|
|
||||||
|
@ -258,10 +249,10 @@ void JNI::displayMessageOnOSD(const char *msg) {
|
||||||
env->DeleteLocalRef(java_msg);
|
env->DeleteLocalRef(java_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JNI::openUrl(const char *url) {
|
bool JNI::openUrl(const Common::String &url) {
|
||||||
bool success = true;
|
bool success = true;
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
jstring javaUrl = env->NewStringUTF(url);
|
jstring javaUrl = env->NewStringUTF(url.c_str());
|
||||||
|
|
||||||
env->CallVoidMethod(_jobj, _MID_openUrl, javaUrl);
|
env->CallVoidMethod(_jobj, _MID_openUrl, javaUrl);
|
||||||
|
|
||||||
|
@ -292,10 +283,10 @@ bool JNI::hasTextInClipboard() {
|
||||||
return hasText;
|
return hasText;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::String JNI::getTextFromClipboard() {
|
Common::U32String JNI::getTextFromClipboard() {
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
jbyteArray javaText = (jbyteArray)env->CallObjectMethod(_jobj, _MID_getTextFromClipboard);
|
jstring javaText = (jstring)env->CallObjectMethod(_jobj, _MID_getTextFromClipboard);
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
if (env->ExceptionCheck()) {
|
||||||
LOGE("Failed to retrieve text from the clipboard");
|
LOGE("Failed to retrieve text from the clipboard");
|
||||||
|
@ -303,23 +294,18 @@ Common::String JNI::getTextFromClipboard() {
|
||||||
env->ExceptionDescribe();
|
env->ExceptionDescribe();
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
|
|
||||||
return Common::String();
|
return Common::U32String();
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = env->GetArrayLength(javaText);
|
Common::String text = convertFromJString(env, javaText, "UTF-8");
|
||||||
char* buf = new char[len];
|
env->DeleteLocalRef(javaText);
|
||||||
env->GetByteArrayRegion(javaText, 0, len, reinterpret_cast<jbyte*>(buf));
|
|
||||||
Common::String text(buf, len);
|
|
||||||
delete[] buf;
|
|
||||||
|
|
||||||
return text;
|
return text.decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JNI::setTextInClipboard(const Common::String &text) {
|
bool JNI::setTextInClipboard(const Common::U32String &text) {
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
jstring javaText = convertToJString(env, text.encode(), "UTF-8");
|
||||||
jbyteArray javaText = env->NewByteArray(text.size());
|
|
||||||
env->SetByteArrayRegion(javaText, 0, text.size(), reinterpret_cast<const jbyte*>(text.c_str()));
|
|
||||||
|
|
||||||
bool success = env->CallBooleanMethod(_jobj, _MID_setTextInClipboard, javaText);
|
bool success = env->CallBooleanMethod(_jobj, _MID_setTextInClipboard, javaText);
|
||||||
|
|
||||||
|
@ -350,9 +336,9 @@ bool JNI::isConnectionLimited() {
|
||||||
return limited;
|
return limited;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JNI::setWindowCaption(const char *caption) {
|
void JNI::setWindowCaption(const Common::String &caption) {
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
jstring java_caption = env->NewStringUTF(caption);
|
jstring java_caption = convertToJString(env, caption, "ISO-8859-1");
|
||||||
|
|
||||||
env->CallVoidMethod(_jobj, _MID_setWindowCaption, java_caption);
|
env->CallVoidMethod(_jobj, _MID_setWindowCaption, java_caption);
|
||||||
|
|
||||||
|
@ -423,6 +409,36 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *JNI::convertEncoding(const char *to, const char *from, const char *string, size_t length) {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
jstring javaTo = env->NewStringUTF(to);
|
||||||
|
jstring javaFrom = env->NewStringUTF(from);
|
||||||
|
jbyteArray javaString = env->NewByteArray(length);
|
||||||
|
env->SetByteArrayRegion(javaString, 0, length, reinterpret_cast<const jbyte*>(string));
|
||||||
|
|
||||||
|
jbyteArray javaOut = (jbyteArray)env->CallObjectMethod(_jobj, _MID_convertEncoding, javaTo, javaFrom, javaString);
|
||||||
|
|
||||||
|
if (!javaOut || env->ExceptionCheck()) {
|
||||||
|
LOGE("Failed to convert text from %s to %s", from, to);
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int outLength = env->GetArrayLength(javaOut);
|
||||||
|
char *buf = (char *)malloc(outLength + 1);
|
||||||
|
if (!buf)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
env->GetByteArrayRegion(javaOut, 0, outLength, reinterpret_cast<jbyte *>(buf));
|
||||||
|
buf[outLength] = 0;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
bool JNI::initSurface() {
|
bool JNI::initSurface() {
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
@ -544,13 +560,14 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||||
FIND_METHOD(, displayMessageOnOSD, "(Ljava/lang/String;)V");
|
FIND_METHOD(, displayMessageOnOSD, "(Ljava/lang/String;)V");
|
||||||
FIND_METHOD(, openUrl, "(Ljava/lang/String;)V");
|
FIND_METHOD(, openUrl, "(Ljava/lang/String;)V");
|
||||||
FIND_METHOD(, hasTextInClipboard, "()Z");
|
FIND_METHOD(, hasTextInClipboard, "()Z");
|
||||||
FIND_METHOD(, getTextFromClipboard, "()[B");
|
FIND_METHOD(, getTextFromClipboard, "()Ljava/lang/String;");
|
||||||
FIND_METHOD(, setTextInClipboard, "([B)Z");
|
FIND_METHOD(, setTextInClipboard, "(Ljava/lang/String;)Z");
|
||||||
FIND_METHOD(, isConnectionLimited, "()Z");
|
FIND_METHOD(, isConnectionLimited, "()Z");
|
||||||
FIND_METHOD(, showVirtualKeyboard, "(Z)V");
|
FIND_METHOD(, showVirtualKeyboard, "(Z)V");
|
||||||
FIND_METHOD(, showKeyboardControl, "(Z)V");
|
FIND_METHOD(, showKeyboardControl, "(Z)V");
|
||||||
FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
|
FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
|
||||||
FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
|
FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
|
||||||
|
FIND_METHOD(, convertEncoding, "(Ljava/lang/String;Ljava/lang/String;[B)[B");
|
||||||
FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
|
FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
|
||||||
FIND_METHOD(, deinitSurface, "()V");
|
FIND_METHOD(, deinitSurface, "()V");
|
||||||
|
|
||||||
|
@ -711,13 +728,31 @@ void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring JNI::getCurrentCharset(JNIEnv *env, jobject self) {
|
jstring JNI::convertToJString(JNIEnv *env, const Common::String &str, const Common::String &from) {
|
||||||
#ifdef USE_TRANSLATION
|
Common::Encoding converter("UTF-8", from.c_str());
|
||||||
if (TransMan.getCurrentCharset() != "ASCII") {
|
char *utf8Str = converter.convert(str.c_str(), converter.stringLength(str.c_str(), from));
|
||||||
return env->NewStringUTF(TransMan.getCurrentCharset().c_str());
|
if (utf8Str == nullptr)
|
||||||
}
|
return nullptr;
|
||||||
#endif
|
|
||||||
return env->NewStringUTF("ISO-8859-1");
|
jstring jstr = env->NewStringUTF(utf8Str);
|
||||||
|
free(utf8Str);
|
||||||
|
|
||||||
|
return jstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String JNI::convertFromJString(JNIEnv *env, const jstring &jstr, const Common::String &to) {
|
||||||
|
const char *utf8Str = env->GetStringUTFChars(jstr, 0);
|
||||||
|
if (!utf8Str)
|
||||||
|
return Common::String();
|
||||||
|
|
||||||
|
Common::Encoding converter(to.c_str(), "UTF-8");
|
||||||
|
char *asciiStr = converter.convert(utf8Str, env->GetStringUTFLength(jstr));
|
||||||
|
env->ReleaseStringUTFChars(jstr, utf8Str);
|
||||||
|
|
||||||
|
Common::String str(asciiStr);
|
||||||
|
free(asciiStr);
|
||||||
|
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Array<Common::String> JNI::getAllStorageLocations() {
|
Common::Array<Common::String> JNI::getAllStorageLocations() {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
#include "common/archive.h"
|
#include "common/archive.h"
|
||||||
#include "common/array.h"
|
#include "common/array.h"
|
||||||
|
#include "common/ustr.h"
|
||||||
#include "engines/engine.h"
|
#include "engines/engine.h"
|
||||||
|
|
||||||
class OSystem_Android;
|
class OSystem_Android;
|
||||||
|
@ -57,17 +58,18 @@ public:
|
||||||
|
|
||||||
static void setReadyForEvents(bool ready);
|
static void setReadyForEvents(bool ready);
|
||||||
|
|
||||||
static void setWindowCaption(const char *caption);
|
static void setWindowCaption(const Common::String &caption);
|
||||||
static void getDPI(float *values);
|
static void getDPI(float *values);
|
||||||
static void displayMessageOnOSD(const char *msg);
|
static void displayMessageOnOSD(const Common::U32String &msg);
|
||||||
static bool openUrl(const char *url);
|
static bool openUrl(const Common::String &url);
|
||||||
static bool hasTextInClipboard();
|
static bool hasTextInClipboard();
|
||||||
static Common::String getTextFromClipboard();
|
static Common::U32String getTextFromClipboard();
|
||||||
static bool setTextInClipboard(const Common::String &text);
|
static bool setTextInClipboard(const Common::U32String &text);
|
||||||
static bool isConnectionLimited();
|
static bool isConnectionLimited();
|
||||||
static void showVirtualKeyboard(bool enable);
|
static void showVirtualKeyboard(bool enable);
|
||||||
static void showKeyboardControl(bool enable);
|
static void showKeyboardControl(bool enable);
|
||||||
static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
|
static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
|
||||||
|
static char *convertEncoding(const char *to, const char *from, const char *string, size_t length);
|
||||||
|
|
||||||
static inline bool haveSurface();
|
static inline bool haveSurface();
|
||||||
static inline bool swapBuffers();
|
static inline bool swapBuffers();
|
||||||
|
@ -108,6 +110,7 @@ private:
|
||||||
static jmethodID _MID_showVirtualKeyboard;
|
static jmethodID _MID_showVirtualKeyboard;
|
||||||
static jmethodID _MID_showKeyboardControl;
|
static jmethodID _MID_showKeyboardControl;
|
||||||
static jmethodID _MID_getSysArchives;
|
static jmethodID _MID_getSysArchives;
|
||||||
|
static jmethodID _MID_convertEncoding;
|
||||||
static jmethodID _MID_getAllStorageLocations;
|
static jmethodID _MID_getAllStorageLocations;
|
||||||
static jmethodID _MID_initSurface;
|
static jmethodID _MID_initSurface;
|
||||||
static jmethodID _MID_deinitSurface;
|
static jmethodID _MID_deinitSurface;
|
||||||
|
@ -139,7 +142,8 @@ private:
|
||||||
int arg2, int arg3, int arg4, int arg5, int arg6);
|
int arg2, int arg3, int arg4, int arg5, int arg6);
|
||||||
static void setPause(JNIEnv *env, jobject self, jboolean value);
|
static void setPause(JNIEnv *env, jobject self, jboolean value);
|
||||||
|
|
||||||
static jstring getCurrentCharset(JNIEnv *env, jobject self);
|
static jstring convertToJString(JNIEnv *env, const Common::String &str, const Common::String &from);
|
||||||
|
static Common::String convertFromJString(JNIEnv *env, const jstring &jstr, const Common::String &to);
|
||||||
|
|
||||||
static PauseToken _pauseToken;
|
static PauseToken _pauseToken;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue