diff --git a/build/macOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj b/build/macOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj index 486181df7..94384e3f9 100644 --- a/build/macOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj +++ b/build/macOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj @@ -124,6 +124,13 @@ 847C6D4B25D6F483008F5FC8 /* lutf8lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 847C6D4A25D6F483008F5FC8 /* lutf8lib.c */; }; 848ADEF427BD68AE001C60F3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 848ADEF627BD68AE001C60F3 /* Localizable.strings */; }; 848CE6E527778E38001D3E0F /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 848CE6E427778E30001D3E0F /* libz.tbd */; }; + 8495BD1628B80B14009FCF4D /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8495BD1528B80B00009FCF4D /* libSDL2.a */; }; + 8495BD1E28B80F0B009FCF4D /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8495BD1D28B80F0B009FCF4D /* ForceFeedback.framework */; }; + 8495BD2028B80F21009FCF4D /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8495BD1F28B80F21009FCF4D /* Metal.framework */; }; + 8495BD2228B80F4D009FCF4D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8495BD2128B80F4D009FCF4D /* AudioToolbox.framework */; }; + 8495BD2628B80FD1009FCF4D /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8495BD2528B80FD1009FCF4D /* CoreAudio.framework */; }; + 8495BD2828B810AD009FCF4D /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8495BD2728B810AD009FCF4D /* CoreVideo.framework */; }; + 8495BD2A28B81170009FCF4D /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8495BD2928B81170009FCF4D /* Carbon.framework */; }; 849D0847278AC1B200471354 /* lchacha.c in Sources */ = {isa = PBXBuildFile; fileRef = 849D0845278AC1B200471354 /* lchacha.c */; }; 849D0848278AC1B200471354 /* chacha.c in Sources */ = {isa = PBXBuildFile; fileRef = 849D0846278AC1B200471354 /* chacha.c */; }; 84A1F9B2252E616B00000717 /* semaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A1F9AC252E616B00000717 /* semaphore.cpp */; }; @@ -565,6 +572,13 @@ 848ADF0927BD69C8001C60F3 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 848ADF0A27BD69CB001C60F3 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; }; 848CE6E427778E30001D3E0F /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + 8495BD1528B80B00009FCF4D /* libSDL2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL2.a; path = ../deps/SDL2/libSDL2.a; sourceTree = ""; }; + 8495BD1D28B80F0B009FCF4D /* ForceFeedback.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ForceFeedback.framework; path = System/Library/Frameworks/ForceFeedback.framework; sourceTree = SDKROOT; }; + 8495BD1F28B80F21009FCF4D /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + 8495BD2128B80F4D009FCF4D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 8495BD2528B80FD1009FCF4D /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + 8495BD2728B810AD009FCF4D /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + 8495BD2928B81170009FCF4D /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; 849D0841278AC1B200471354 /* ecrypt-config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ecrypt-config.h"; path = "../../../../lib/luachacha/ecrypt-config.h"; sourceTree = ""; }; 849D0842278AC1B200471354 /* ecrypt-sync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ecrypt-sync.h"; path = "../../../../lib/luachacha/ecrypt-sync.h"; sourceTree = ""; }; 849D0843278AC1B200471354 /* ecrypt-portable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ecrypt-portable.h"; path = "../../../../lib/luachacha/ecrypt-portable.h"; sourceTree = ""; }; @@ -896,6 +910,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8495BD2628B80FD1009FCF4D /* CoreAudio.framework in Frameworks */, + 8495BD2228B80F4D009FCF4D /* AudioToolbox.framework in Frameworks */, 84585C0724B134900040BA4F /* libcurl.tbd in Frameworks */, 848CE6E527778E38001D3E0F /* libz.tbd in Frameworks */, 84EEE5E72782729B00F61929 /* libintl.a in Frameworks */, @@ -906,9 +922,14 @@ 8458616924B1B7DC0040BA4F /* libfreetype.a in Frameworks */, 84C8E20B257804A200C1E5D0 /* libopenal.1.dylib in Frameworks */, 84463B9924B258B50099DFBD /* OpenGL.framework in Frameworks */, + 8495BD1628B80B14009FCF4D /* libSDL2.a in Frameworks */, + 8495BD2A28B81170009FCF4D /* Carbon.framework in Frameworks */, 8458616A24B1B7E20040BA4F /* libIrrlicht.a in Frameworks */, 84463B9324B258B00099DFBD /* IOKit.framework in Frameworks */, + 8495BD2828B810AD009FCF4D /* CoreVideo.framework in Frameworks */, 846F883B27A59704007B6210 /* libluajit.a in Frameworks */, + 8495BD2028B80F21009FCF4D /* Metal.framework in Frameworks */, + 8495BD1E28B80F0B009FCF4D /* ForceFeedback.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1100,6 +1121,13 @@ 84585BFF24B1347B0040BA4F /* Frameworks */ = { isa = PBXGroup; children = ( + 8495BD2928B81170009FCF4D /* Carbon.framework */, + 8495BD2728B810AD009FCF4D /* CoreVideo.framework */, + 8495BD2528B80FD1009FCF4D /* CoreAudio.framework */, + 8495BD2128B80F4D009FCF4D /* AudioToolbox.framework */, + 8495BD1F28B80F21009FCF4D /* Metal.framework */, + 8495BD1D28B80F0B009FCF4D /* ForceFeedback.framework */, + 8495BD1528B80B00009FCF4D /* libSDL2.a */, 846F883A27A596F9007B6210 /* libluajit.a */, 84EEE5E62782728E00F61929 /* libintl.a */, 848CE6E427778E30001D3E0F /* libz.tbd */, @@ -2243,6 +2271,7 @@ "${SRCROOT}/../deps/freetype/include/freetype2", "${SRCROOT}/../deps/gettext/include", "${SRCROOT}/../deps/irrlicht/include", + "${SRCROOT}/../deps/SDL2/include", "${SRCROOT}/../deps/luajit/include", ); INFOPLIST_FILE = MultiCraft/Info.plist; @@ -2252,6 +2281,10 @@ ); MACOSX_DEPLOYMENT_TARGET = 10.11; MARKETING_VERSION = 2.0.1; + OTHER_CFLAGS = ( + "$(inherited)", + "-D_IRR_COMPILE_WITH_SDL_DEVICE_", + ); OTHER_LDFLAGS = ( "$(inherited)", "-L${SRCROOT}/../deps/freetype/lib", @@ -2259,6 +2292,7 @@ "-L${SRCROOT}/../deps/irrlicht", "-L${SRCROOT}/../deps/luajit/lib", "-L${SRCROOT}/../deps/openal", + "-L${SRCROOT}/../deps/SDL2", "-Wl,-dead_strip", ); PRODUCT_BUNDLE_IDENTIFIER = mobi.MultiCraft; @@ -2307,6 +2341,7 @@ "${SRCROOT}/../deps/freetype/include/freetype2", "${SRCROOT}/../deps/gettext/include", "${SRCROOT}/../deps/irrlicht/include", + "${SRCROOT}/../deps/SDL2/include", "${SRCROOT}/../deps/luajit/include", ); INFOPLIST_FILE = MultiCraft/Info.plist; @@ -2316,6 +2351,10 @@ ); MACOSX_DEPLOYMENT_TARGET = 10.11; MARKETING_VERSION = 2.0.1; + OTHER_CFLAGS = ( + "$(inherited)", + "-D_IRR_COMPILE_WITH_SDL_DEVICE_", + ); OTHER_LDFLAGS = ( "$(inherited)", "-L${SRCROOT}/../deps/freetype/lib", @@ -2323,6 +2362,7 @@ "-L${SRCROOT}/../deps/irrlicht", "-L${SRCROOT}/../deps/luajit/lib", "-L${SRCROOT}/../deps/openal", + "-L${SRCROOT}/../deps/SDL2", "-Wl,-dead_strip", ); PRODUCT_BUNDLE_IDENTIFIER = mobi.MultiCraft; diff --git a/build/macOS/MultiCraft/MultiCraft/MultiCraft.entitlements b/build/macOS/MultiCraft/MultiCraft/MultiCraft.entitlements index 0770415d2..1ed8ac75d 100644 --- a/build/macOS/MultiCraft/MultiCraft/MultiCraft.entitlements +++ b/build/macOS/MultiCraft/MultiCraft/MultiCraft.entitlements @@ -8,6 +8,8 @@ com.apple.security.cs.allow-unsigned-executable-memory + com.apple.security.device.usb + com.apple.security.files.user-selected.read-only com.apple.security.network.client diff --git a/build/macOS/deps/SDL2.diff b/build/macOS/deps/SDL2.diff new file mode 100755 index 000000000..3c4d47646 --- /dev/null +++ b/build/macOS/deps/SDL2.diff @@ -0,0 +1,16 @@ +diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m +index bca8eb4dd..2e444947d 100644 +--- a/SDL2-src/src/video/cocoa/SDL_cocoawindow.m ++++ b/SDL2-src/src/video/cocoa/SDL_cocoawindow.m +@@ -764,6 +764,11 @@ - (void)windowDidResize:(NSNotification *)aNotification + return; + } + ++ if (focusClickPending) { ++ focusClickPending = 0; ++ [self onMovingOrFocusClickPendingStateCleared]; ++ } ++ + SDL_Window *window = _data->window; + NSWindow *nswindow = _data->nswindow; + int x, y, w, h; diff --git a/build/macOS/deps/SDL2.sh b/build/macOS/deps/SDL2.sh new file mode 100755 index 000000000..ec04f2425 --- /dev/null +++ b/build/macOS/deps/SDL2.sh @@ -0,0 +1,34 @@ +#!/bin/bash -e + +. sdk.sh +SDL2_VERSION=2.0.22 + +if [ ! -d SDL2-src ]; then + wget https://github.com/libsdl-org/SDL/archive/release-$SDL2_VERSION.tar.gz + tar -xzvf release-$SDL2_VERSION.tar.gz + mv SDL-release-$SDL2_VERSION SDL2-src + rm release-$SDL2_VERSION.tar.gz + # patch SDL2 + patch -p1 < SDL2.diff +fi + +cd SDL2-src + +xcodebuild build \ + ARCHS="$OSX_ARCHES" \ + -project Xcode/SDL/SDL.xcodeproj \ + -configuration Release \ + -scheme "Static Library" + +BUILD_FOLDER=$(xcodebuild \ + -project Xcode/SDL/SDL.xcodeproj \ + -configuration Release \ + -scheme "Static Library" \ + -showBuildSettings | \ + grep TARGET_BUILD_DIR | sed -n -e 's/^.*TARGET_BUILD_DIR = //p') + +mkdir -p ../SDL2 +cp -a "${BUILD_FOLDER}/libSDL2.a" ../SDL2 +cp -a include ../SDL2 + +echo "SDL2 build successful" diff --git a/build/macOS/deps/irrlicht.sh b/build/macOS/deps/irrlicht.sh index 3353ecbf5..5c28d2d59 100755 --- a/build/macOS/deps/irrlicht.sh +++ b/build/macOS/deps/irrlicht.sh @@ -3,7 +3,7 @@ . sdk.sh [ ! -d irrlicht-src ] && \ - git clone --depth 1 -b ogl-es https://github.com/MoNTE48/Irrlicht irrlicht-src + git clone --depth 1 -b SDL2 https://github.com/MoNTE48/Irrlicht irrlicht-src cd irrlicht-src/source/Irrlicht xcodebuild build \ diff --git a/build/macOS/deps/libraries.sh b/build/macOS/deps/libraries.sh index 0928db6fb..0d50486be 100755 --- a/build/macOS/deps/libraries.sh +++ b/build/macOS/deps/libraries.sh @@ -1,5 +1,6 @@ #!/bin/bash -e +sh SDL2.sh sh irrlicht.sh sh gettext.sh sh freetype.sh diff --git a/build/macOS/locale.sh b/build/macOS/locale.sh index 45710cc49..3bfa61905 100755 --- a/build/macOS/locale.sh +++ b/build/macOS/locale.sh @@ -5,12 +5,12 @@ if [ ! -d MultiCraft/MultiCraft.xcodeproj ]; then exit 1 fi -DEST=$(pwd) +DEST=$(pwd)/locale pushd ../../po for lang in *; do [ ${#lang} -ne 2 ] && continue - mopath=$DEST/locale/$lang/LC_MESSAGES + mopath=$DEST/$lang/LC_MESSAGES mkdir -p $mopath pushd $lang for fn in *.po; do @@ -21,10 +21,9 @@ for lang in *; do done popd -find $DEST -type d -name '.git' -print0 | xargs -0 -- rm -rf -find $DEST -type f -name '.*' -delete +find $DEST -type d,f -name '.*' -print0 | xargs -0 -- rm -rf # remove broken languages for broken_lang in ar he hi ky ms_Arab th; do - find $DEST -type d -name $broken_lang -print0 | xargs -0 -- rm -rf + rm -rf $DEST/$broken_lang done diff --git a/src/client/game.cpp b/src/client/game.cpp index 4b767b0ec..cd94410ab 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2022,7 +2022,7 @@ void Game::processKeyInput() toggleDebug(); } else if (wasKeyDown(KeyType::TOGGLE_PROFILER)) { m_game_ui->toggleProfiler(); - } else if (wasKeyDown(KeyType::INCREASE_VIEWING_RANGE) || wasKeyDown(KeyType::INCREASE_VIEWING_RANGE2)) { + } else if (wasKeyDown(KeyType::INCREASE_VIEWING_RANGE)) { increaseViewRange(); } else if (wasKeyDown(KeyType::DECREASE_VIEWING_RANGE)) { decreaseViewRange(); diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index ec618b00e..3e535efc4 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -74,9 +74,6 @@ void KeyCache::populate() key[KeyType::CAMERA_MODE] = getKeySetting("keymap_camera_mode"); key[KeyType::INCREASE_VIEWING_RANGE] = getKeySetting("keymap_increase_viewing_range_min"); -#if defined(__MACH__) && defined(__APPLE__) - key[KeyType::INCREASE_VIEWING_RANGE2] = "="; -#endif key[KeyType::DECREASE_VIEWING_RANGE] = getKeySetting("keymap_decrease_viewing_range_min"); key[KeyType::RANGESELECT] = getKeySetting("keymap_rangeselect"); diff --git a/src/client/keys.h b/src/client/keys.h index d4924a9d4..9853c090a 100644 --- a/src/client/keys.h +++ b/src/client/keys.h @@ -67,7 +67,6 @@ public: TOGGLE_PROFILER, CAMERA_MODE, INCREASE_VIEWING_RANGE, - INCREASE_VIEWING_RANGE2, DECREASE_VIEWING_RANGE, RANGESELECT, ZOOM, diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 96d197b4a..1f84a1a8d 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -508,7 +508,6 @@ void set_default_settings() #if defined(__MACH__) && defined(__APPLE__) && !defined(__IOS__) settings->setDefault("screen_w", "0"); settings->setDefault("screen_h", "0"); - settings->setDefault("keymap_sneak", "KEY_SHIFT"); settings->setDefault("keymap_camera_mode", "KEY_KEY_C"); settings->setDefault("vsync", "true"); diff --git a/src/gettext.cpp b/src/gettext.cpp index 75b2b0a16..7503c74d9 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -26,6 +26,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "porting.h" +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +#include +#endif + #ifdef __APPLE__ #ifdef __IOS__ #import @@ -216,12 +220,23 @@ void init_gettext(const char *path, const std::string &configured_language, } else { /* set current system default locale */ -#ifdef __ANDROID__ +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + SDL_Locale* locale = SDL_GetPreferredLocales(); + + if (locale) { + if (locale[0].language) { + char lang[3] = {0}; + strncpy(lang, locale[0].language, 2); + setenv("LANG", lang, 1); + } + + SDL_free(locale); + } +#elif defined(__ANDROID__) char lang[3] = {0}; AConfiguration_getLanguage(porting::app_global->config, lang); setenv("LANG", lang, 1); -#endif -#ifdef __APPLE__ +#elif defined(__IOS__) char lang[3] = {0}; NSString *syslang = [[NSLocale preferredLanguages] firstObject]; [syslang getBytes:lang maxLength:2 usedLength:nil encoding:NSASCIIStringEncoding options:0 range:NSMakeRange(0, 2) remainingRange:nil]; diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 1b2ddf85e..990f357f5 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -36,6 +36,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlicht_changes/CGUITTFont.h" #endif +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +#include +#endif + inline u32 clamp_u8(s32 value) { return (u32) MYMIN(MYMAX(value, 0), 255); @@ -95,6 +99,11 @@ GUIChatConsole::GUIChatConsole( GUIChatConsole::~GUIChatConsole() { +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (porting::hasRealKeyboard() && SDL_IsTextInputActive()) + SDL_StopTextInput(); +#endif + if (m_font) m_font->drop(); } @@ -111,6 +120,11 @@ void GUIChatConsole::openConsole(f32 scale) IGUIElement::setVisible(true); Environment->setFocus(this); m_menumgr->createdMenu(this); + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (porting::hasRealKeyboard()) + SDL_StartTextInput(); +#endif } bool GUIChatConsole::isOpen() const @@ -128,6 +142,11 @@ void GUIChatConsole::closeConsole() m_open = false; Environment->removeFocus(this); m_menumgr->deletingMenu(this); + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (porting::hasRealKeyboard() && SDL_IsTextInputActive()) + SDL_StopTextInput(); +#endif } void GUIChatConsole::closeConsoleAtOnce() @@ -620,6 +639,20 @@ bool GUIChatConsole::OnEvent(const SEvent& event) return true; } } +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + else if(event.EventType == EET_SDL_TEXT_EVENT) + { + if (event.SDLTextEvent.Type == ESDLET_TEXTINPUT) + { + std::wstring text = utf8_to_wide(event.SDLTextEvent.Text); + + for (u32 i = 0; i < text.size(); i++) + prompt.input(text[i]); + + return true; + } + } +#endif else if(event.EventType == EET_MOUSE_INPUT_EVENT) { if(event.MouseInput.Event == EMIE_MOUSE_WHEEL) diff --git a/src/gui/guiEditBox.cpp b/src/gui/guiEditBox.cpp index 839a89e87..259c26be2 100644 --- a/src/gui/guiEditBox.cpp +++ b/src/gui/guiEditBox.cpp @@ -26,6 +26,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "util/string.h" +#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) +#include +#endif + GUIEditBox::~GUIEditBox() { if (m_override_font) @@ -209,6 +213,19 @@ bool GUIEditBox::OnEvent(const SEvent &event) } } break; +#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + case EET_SDL_TEXT_EVENT: + if (event.SDLTextEvent.Type == irr::ESDLET_TEXTINPUT) { + core::stringw text = + utf8_to_stringw(event.SDLTextEvent.Text); + + for (size_t i = 0; i < text.size(); i++) + inputChar(text[i]); + + return true; + } + break; +#endif case EET_KEY_INPUT_EVENT: { #if (defined(__linux__) || defined(__FreeBSD__)) || defined(__DragonFly__) // ################################################################ @@ -259,8 +276,18 @@ bool GUIEditBox::processKey(const SEvent &event) s32 new_mark_begin = m_mark_begin; s32 new_mark_end = m_mark_end; + // On Windows right alt simulates additional control press/release events. + // It causes unexpected bahavior, for example right alt + A would clear text + // in the edit box. At least for SDL we can easily check if alt key is + // pressed + bool altPressed = false; +#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + SDL_Keymod keymod = SDL_GetModState(); + altPressed = keymod & KMOD_ALT; +#endif + // control shortcut handling - if (event.KeyInput.Control) { + if (event.KeyInput.Control && !altPressed) { // german backlash '\' entered with control + '?' if (event.KeyInput.Char == '\\') { diff --git a/src/gui/guiEditBoxWithScrollbar.cpp b/src/gui/guiEditBoxWithScrollbar.cpp index c72070787..f42dc14c4 100644 --- a/src/gui/guiEditBoxWithScrollbar.cpp +++ b/src/gui/guiEditBoxWithScrollbar.cpp @@ -94,6 +94,10 @@ void GUIEditBoxWithScrollBar::draw() default_bg_color = m_writable ? skin->getColor(EGDC_WINDOW) : video::SColor(0); bg_color = m_bg_color_used ? m_bg_color : default_bg_color; + if (IsEnabled && m_writable) { + bg_color = focus ? skin->getColor(EGDC_FOCUSED_EDITABLE) : skin->getColor(EGDC_EDITABLE); + } + if (!m_border && m_background) { skin->draw2DRectangle(this, bg_color, AbsoluteRect, &AbsoluteClippingRect); } diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 615edbd75..4c2924ba1 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -69,6 +69,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiHyperText.h" #include "guiScene.h" +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +#include +#endif + #define MY_CHECKPOS(a,b) \ if (v_pos.size() != 2) { \ errorstream<< "Invalid pos for element " << a << " specified: \"" \ @@ -211,6 +215,10 @@ void GUIFormSpecMenu::setInitialFocus() if (it->getType() == gui::EGUIET_EDIT_BOX && it->getText()[0] == 0) { Environment->setFocus(it); +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (porting::hasRealKeyboard()) + SDL_StartTextInput(); +#endif return; } } @@ -219,6 +227,10 @@ void GUIFormSpecMenu::setInitialFocus() for (gui::IGUIElement *it : children) { if (it->getType() == gui::EGUIET_EDIT_BOX) { Environment->setFocus(it); +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (porting::hasRealKeyboard()) + SDL_StartTextInput(); +#endif return; } } diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp index ef3c3bace..e492baed9 100644 --- a/src/gui/modalMenu.cpp +++ b/src/gui/modalMenu.cpp @@ -29,6 +29,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/renderingengine.h" #endif +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +#include +#endif + // clang-format off GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, bool remap_dbl_click) : @@ -59,6 +63,10 @@ GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, GUIModalMenu::~GUIModalMenu() { +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (porting::hasRealKeyboard() && SDL_IsTextInputActive()) + SDL_StopTextInput(); +#endif m_menumgr->deletingMenu(this); } @@ -242,8 +250,26 @@ void GUIModalMenu::leave() bool GUIModalMenu::preprocessEvent(const SEvent &event) { -#if defined(__ANDROID__) || defined(__IOS__) // clang-format off +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + // Enable text input events when edit box is focused + if (event.EventType == EET_GUI_EVENT) { + if (event.GUIEvent.EventType == irr::gui::EGET_ELEMENT_FOCUSED && + event.GUIEvent.Caller && + event.GUIEvent.Caller->getType() == irr::gui::EGUIET_EDIT_BOX) { + if (porting::hasRealKeyboard()) + SDL_StartTextInput(); + } + else if (event.GUIEvent.EventType == irr::gui::EGET_ELEMENT_FOCUS_LOST && + event.GUIEvent.Caller && + event.GUIEvent.Caller->getType() == irr::gui::EGUIET_EDIT_BOX) { + if (porting::hasRealKeyboard() && SDL_IsTextInputActive()) + SDL_StopTextInput(); + } + } +#endif + +#if defined(__ANDROID__) || defined(__IOS__) // display software keyboard when clicking edit boxes if (event.EventType == EET_MOUSE_INPUT_EVENT && event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { diff --git a/src/porting.cpp b/src/porting.cpp index f3f52a2c9..9db8a6e26 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -623,11 +623,11 @@ void initializePaths() #endif // USE_GETTEXT } -#ifndef __ANDROID__ -// Dummy for other OS with a touchscreen +#if !defined(__ANDROID__) && !defined(__IOS__) +// Dummy for other OS bool hasRealKeyboard() { - return false; + return true; } #endif diff --git a/src/porting.h b/src/porting.h index a9a653d0c..4e34452c3 100644 --- a/src/porting.h +++ b/src/porting.h @@ -40,6 +40,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "constants.h" #include "gettime.h" +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +#include +#endif + #ifdef _MSC_VER #define SWPRINTF_CHARSTRING L"%S" #else @@ -95,7 +99,9 @@ with this program; if not, write to the Free Software Foundation, Inc., defined(__APPLE__) || \ defined(__sun) || defined(sun) || \ defined(__QNX__) || defined(__QNXNTO__) - #define HAVE_STRLCPY + #ifndef HAVE_STRLCPY + #define HAVE_STRLCPY + #endif #endif // So we need to define our own. diff --git a/src/util/string.cpp b/src/util/string.cpp index d2f524d52..0a5189c25 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -32,7 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -#ifndef _WIN32 +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + #include +#elif !defined(_WIN32) #include #else #define _WIN32_WINNT 0x0501 @@ -48,7 +50,56 @@ static bool parseHexColorString(const std::string &value, video::SColor &color, unsigned char default_alpha = 0xff); static bool parseNamedColorString(const std::string &value, video::SColor &color); -#ifndef _WIN32 +#if defined(__ANDROID__) || defined(__APPLE__) +// Android need manual caring to support the full character set possible with wchar_t +const char *DEFAULT_ENCODING = "UTF-32LE"; +#else +const char *DEFAULT_ENCODING = "WCHAR_T"; +#endif + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + +std::wstring utf8_to_wide(const std::string &input) +{ +#if defined(__ANDROID__) || defined(__APPLE__) + SANITY_CHECK(sizeof(wchar_t) == 4); +#endif + + const char *inbuf = input.c_str(); + size_t inbuf_size = input.size() + 1; + + char *outbuf = SDL_iconv_string(DEFAULT_ENCODING, "UTF-8", inbuf, inbuf_size); + + if (!outbuf) + return L""; + + std::wstring out((wchar_t*)outbuf); + SDL_free(outbuf); + + return out; +} + +std::string wide_to_utf8(const std::wstring &input) +{ +#if defined(__ANDROID__) || defined(__APPLE__) + SANITY_CHECK(sizeof(wchar_t) == 4); +#endif + + const char *inbuf = (const char*)(input.c_str()); + size_t inbuf_size = (input.size() + 1) * sizeof(wchar_t); + + char *outbuf = SDL_iconv_string("UTF-8", DEFAULT_ENCODING, inbuf, inbuf_size); + + if (!outbuf) + return ""; + + std::string out(outbuf); + SDL_free(outbuf); + + return out; +} + +#elif !defined(_WIN32) static bool convert(const char *to, const char *from, char *outbuf, size_t *outbuf_size, char *inbuf, size_t inbuf_size) @@ -80,13 +131,6 @@ static bool convert(const char *to, const char *from, char *outbuf, return true; } -#if defined(__ANDROID__) || defined(__APPLE__) -// Android need manual caring to support the full character set possible with wchar_t -const char *DEFAULT_ENCODING = "UTF-32LE"; -#else -const char *DEFAULT_ENCODING = "WCHAR_T"; -#endif - std::wstring utf8_to_wide(const std::string &input) { const size_t inbuf_size = input.length();