From 8a0d911d10475c187fb24a0f32476cd4b6c25adb Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 9 Nov 2016 12:28:23 +0800 Subject: [PATCH 01/10] Allow using input method (for CJK) in linux --- .../source/Irrlicht/CIrrDeviceLinux.cpp | 171 +++++++++++++++--- .../source/Irrlicht/CIrrDeviceLinux.h | 7 + src/guiengine/widgets/CGUIEditBox.cpp | 28 +++ src/guiengine/widgets/CGUIEditBox.hpp | 2 + 4 files changed, 182 insertions(+), 26 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index b84a5cfcc..49a3fb026 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -86,7 +86,8 @@ CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param) : CIrrDeviceStub(param), #ifdef _IRR_COMPILE_WITH_X11_ display(0), visual(0), screennr(0), window(0), StdHints(0), SoftwareImage(0), - XInputMethod(0), XInputContext(0), numlock_mask(0), + XInputMethod(0), XInputContext(0), m_font_set(0), numlock_mask(0), + m_ime_enabled(false), #ifdef _IRR_COMPILE_WITH_OPENGL_ glxWin(0), Context(0), @@ -139,8 +140,12 @@ CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param) return; #ifdef _IRR_COMPILE_WITH_X11_ + m_ime_position.x = 0; + m_ime_position.y = 0; createInputContext(); numlock_mask = getNumlockMask(display); + // Get maximum 16 characters from input method + m_ime_char_holder.reallocate(16); #endif createGUIAndScene(); @@ -1183,12 +1188,15 @@ void CIrrDeviceLinux::createDriver() #ifdef _IRR_COMPILE_WITH_X11_ bool CIrrDeviceLinux::createInputContext() { + if (!display) + return false; + // One one side it would be nicer to let users do that - on the other hand // not setting the environment locale will not work when using i18n X11 functions. // So users would have to call it always or their input is broken badly. // We can restore immediately - so won't mess with anything in users apps. core::stringc oldLocale(setlocale(LC_CTYPE, NULL)); - setlocale(LC_CTYPE, ""); // use environment locale + setlocale(LC_CTYPE, ""); // use environment locale if ( !XSupportsLocale() ) { @@ -1197,31 +1205,56 @@ bool CIrrDeviceLinux::createInputContext() return false; } - XInputMethod = XOpenIM(display, NULL, NULL, NULL); - if ( !XInputMethod ) + char* p = XSetLocaleModifiers(""); + if (p == NULL) { + os::Printer::log("Could not set locale modifiers. Falling back to non-i18n input.", ELL_WARNING); setlocale(LC_CTYPE, oldLocale.c_str()); - os::Printer::log("XOpenIM failed to create an input method. Falling back to non-i18n input.", ELL_WARNING); return false; } - XIMStyles *im_supported_styles; - XGetIMValues(XInputMethod, XNQueryInputStyle, &im_supported_styles, (char*)NULL); - XIMStyle bestStyle = 0; - // TODO: If we want to support languages like chinese or japanese as well we probably have to work with callbacks here. - XIMStyle supportedStyle = XIMPreeditNone | XIMStatusNone; - for (int i=0; i < im_supported_styles->count_styles; ++i) + XInputMethod = XOpenIM(display, NULL, NULL, NULL); + if ( !XInputMethod ) { - XIMStyle style = im_supported_styles->supported_styles[i]; - if ((style & supportedStyle) == style) /* if we can handle it */ + os::Printer::log("XOpenIM failed to create an input method. Falling back to non-i18n input.", ELL_WARNING); + setlocale(LC_CTYPE, oldLocale.c_str()); + return false; + } + + XIMStyles *im_supported_styles = NULL; + XGetIMValues(XInputMethod, XNQueryInputStyle, &im_supported_styles, (void*)NULL); + if (!im_supported_styles) + { + os::Printer::log("XGetIMValues failed to get supported styles. Falling back to non-i18n input.", ELL_WARNING); + setlocale(LC_CTYPE, oldLocale.c_str()); + return false; + } + + // Only OverTheSpot and Root pre-edit type are implemented for now + core::array supported_style; + //supported_style.push_back(XIMPreeditPosition | XIMStatusNothing); + supported_style.push_back(XIMPreeditNothing | XIMStatusNothing); + XIMStyle best_style = 0; + bool found = false; + int supported_style_start = -1; + + while (!found && supported_style_start < (int)supported_style.size()) + { + supported_style_start++; + for (int i = 0; i < im_supported_styles->count_styles; i++) { - bestStyle = style; - break; + XIMStyle cur_style = im_supported_styles->supported_styles[i]; + if (cur_style == supported_style[supported_style_start]) + { + best_style = cur_style; + found = true; + break; + } } } XFree(im_supported_styles); - if ( !bestStyle ) + if (!found) { XDestroyIC(XInputContext); XInputContext = 0; @@ -1231,18 +1264,53 @@ bool CIrrDeviceLinux::createInputContext() return false; } - XInputContext = XCreateIC(XInputMethod, - XNInputStyle, bestStyle, - XNClientWindow, window, - (char*)NULL); + // Only use root preedit type for now + /*if (best_style != (XIMPreeditNothing | XIMStatusNothing)) + { + char **list = NULL; + int count = 0; + m_font_set = XCreateFontSet(display, "fixed", &list, &count, NULL); + if (!m_font_set) + { + os::Printer::log("XInputContext failed to create font set. Falling back to non-i18n input.", ELL_WARNING); + setlocale(LC_CTYPE, oldLocale.c_str()); + return false; + } + if (count > 0) + { + XFreeStringList(list); + } + + XPoint spot = {0, 0}; + XVaNestedList p_list = XVaCreateNestedList(0, XNSpotLocation, &spot, + XNFontSet, m_font_set, (void*)NULL); + XInputContext = XCreateIC(XInputMethod, + XNInputStyle, best_style, + XNClientWindow, window, + XNFocusWindow, window, + XNPreeditAttributes, p_list, + (void*)NULL); + XFree(p_list); + } + else*/ + { + XInputContext = XCreateIC(XInputMethod, + XNInputStyle, best_style, + XNClientWindow, window, + XNFocusWindow, window, + (void*)NULL); + } + if (!XInputContext ) { os::Printer::log("XInputContext failed to create an input context. Falling back to non-i18n input.", ELL_WARNING); setlocale(LC_CTYPE, oldLocale.c_str()); return false; } + XSetICFocus(XInputContext); setlocale(LC_CTYPE, oldLocale.c_str()); + XFree(p); return true; } @@ -1259,6 +1327,34 @@ void CIrrDeviceLinux::destroyInputContext() XCloseIM(XInputMethod); XInputMethod = 0; } + if (display && m_font_set) + { + XFreeFontSet(display, m_font_set); + m_font_set = 0; + } +} + +void CIrrDeviceLinux::setIMELocation(const irr::core::position2di& pos) +{ + if (!XInputContext || !m_ime_enabled) return; + m_ime_position.x = pos.X; + m_ime_position.y = pos.Y; + updateIMELocation(); +} + +void CIrrDeviceLinux::updateIMELocation() +{ + if (!XInputContext || !m_ime_enabled) return; + XVaNestedList list; + list = XVaCreateNestedList(0, XNSpotLocation, &m_ime_position, (void*)NULL); + XSetICValues(XInputContext, XNPreeditAttributes, list, (void*)NULL); + XFree(list); +} + +void CIrrDeviceLinux::setIMEEnable(bool enable) +{ + if (!XInputContext) return; + m_ime_enabled = enable; } int CIrrDeviceLinux::getNumlockMask(Display* display) @@ -1361,12 +1457,30 @@ bool CIrrDeviceLinux::run() while (XPending(display) > 0 && !Close) { + if (!m_ime_char_holder.empty()) + { + irrevent.KeyInput.Char = m_ime_char_holder[0]; + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; + irrevent.KeyInput.PressedDown = true; + irrevent.KeyInput.Control = false; + irrevent.KeyInput.Shift = false; + irrevent.KeyInput.Key = (irr::EKEY_CODE)0; + postEventFromUser(irrevent); + m_ime_char_holder.erase(0); + continue; + } + XEvent event; XNextEvent(display, &event); - + if (m_ime_enabled && XFilterEvent(&event, None)) + { + updateIMELocation(); + continue; + } switch (event.type) { case ConfigureNotify: + updateIMELocation(); // check for changed window size if ((event.xconfigure.width != (int) Width) || (event.xconfigure.height != (int) Height)) @@ -1539,9 +1653,8 @@ bool CIrrDeviceLinux::run() SKeyMap mp; if ( XInputContext ) { - wchar_t buf[8]={0}; Status status; - int strLen = XwcLookupString(XInputContext, &event.xkey, buf, sizeof(buf), &mp.X11Key, &status); + int strLen = XwcLookupString(XInputContext, &event.xkey, m_ime_char_holder.pointer(), 16 * sizeof(wchar_t), &mp.X11Key, &status); if ( status == XBufferOverflow ) { os::Printer::log("XwcLookupString needs a larger buffer", ELL_INFORMATION); @@ -1549,8 +1662,14 @@ bool CIrrDeviceLinux::run() if ( strLen > 0 && (status == XLookupChars || status == XLookupBoth) ) { if ( strLen > 1 ) - os::Printer::log("Additional returned characters dropped", ELL_INFORMATION); - irrevent.KeyInput.Char = buf[0]; + { + m_ime_char_holder.set_used(strLen > 16 ? 16 : strLen); + continue; + } + else + { + irrevent.KeyInput.Char = m_ime_char_holder[0]; + } } else { @@ -1563,7 +1682,7 @@ bool CIrrDeviceLinux::run() { char buf[8]; wchar_t wbuf[2]; - } tmp = {0}; + } tmp = {{0}}; XLookupString(&event.xkey, tmp.buf, sizeof(tmp.buf), &mp.X11Key, NULL); irrevent.KeyInput.Char = tmp.wbuf[0]; } diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h index ea1131aaf..9d1a8688f 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h @@ -129,6 +129,8 @@ namespace irr } #ifdef _IRR_COMPILE_WITH_X11_ + void setIMELocation(const irr::core::position2di& pos); + void setIMEEnable(bool enable); // convert an Irrlicht texture to a X11 cursor Cursor TextureToCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot); Cursor TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot); @@ -158,6 +160,7 @@ namespace irr void destroyInputContext(); int getNumlockMask(Display* display); EKEY_CODE getKeyCode(XEvent &event); + void updateIMELocation(); #endif //! Implementation of the linux cursor control @@ -399,8 +402,12 @@ namespace irr XImage* SoftwareImage; XIM XInputMethod; XIC XInputContext; + XFontSet m_font_set; + core::array m_ime_char_holder; + XPoint m_ime_position; mutable core::stringc Clipboard; int numlock_mask; + bool m_ime_enabled; #ifdef _IRR_LINUX_X11_VIDMODE_ XF86VidModeModeInfo oldVideoMode; #endif diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index cf3b9d7a2..bca0479b7 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -13,10 +13,13 @@ #include "Keycodes.h" #include "graphics/2dutils.hpp" +#include "graphics/irr_driver.hpp" #include "utils/string_utils.hpp" #include "utils/translation.hpp" #include "utils/time.hpp" +#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h" + /* todo: optional scrollbars @@ -101,6 +104,10 @@ CGUIEditBox::~CGUIEditBox() if (Operator) Operator->drop(); +#ifdef _IRR_COMPILE_WITH_X11_ + CIrrDeviceLinux* dl = dynamic_cast(irr_driver->getDevice()); + dl->setIMEEnable(false); +#endif } @@ -241,7 +248,19 @@ bool CGUIEditBox::OnEvent(const SEvent& event) MouseMarking = false; setTextMarkers(0,0); } +#ifdef _IRR_COMPILE_WITH_X11_ + CIrrDeviceLinux* dl = dynamic_cast(irr_driver->getDevice()); + dl->setIMEEnable(false); +#endif } +#ifdef _IRR_COMPILE_WITH_X11_ + else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED) + { + CIrrDeviceLinux* dl = dynamic_cast(irr_driver->getDevice()); + dl->setIMEEnable(true); + dl->setIMELocation(calculateICPos()); + } +#endif break; #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) case EET_IMPUT_METHOD_EVENT: @@ -851,7 +870,9 @@ bool CGUIEditBox::processIMEEvent(const SEvent& event) return false; } +#endif +#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_) //! calculate the position of input composition window core::position2di CGUIEditBox::calculateICPos() { @@ -1588,6 +1609,13 @@ void CGUIEditBox::calculateScrollPos() VScrollPos = 0; // todo: adjust scrollbar +#if defined(_IRR_COMPILE_WITH_X11_) + CIrrDeviceLinux* dl = dynamic_cast(irr_driver->getDevice()); + if (dl) + { + dl->setIMELocation(calculateICPos()); + } +#endif } //! set text markers diff --git a/src/guiengine/widgets/CGUIEditBox.hpp b/src/guiengine/widgets/CGUIEditBox.hpp index fdc4d5e98..089102dda 100644 --- a/src/guiengine/widgets/CGUIEditBox.hpp +++ b/src/guiengine/widgets/CGUIEditBox.hpp @@ -139,6 +139,8 @@ using namespace gui; bool processMouse(const SEvent& event); #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) bool processIMEEvent(const SEvent& event); +#endif +#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_) //! calculates the input composition position core::position2di calculateICPos(); #endif From 19cd3656a9977c94981d2d5726e193bf943e3492 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 11 Nov 2016 15:29:17 +0800 Subject: [PATCH 02/10] Use all cores only in clang for travis --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a2716d235..2b52e85b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,9 +38,12 @@ addons: - zlib1g-dev before_script: - #- export THREADS=$((`nproc` + 1)) # Unfortunately using all threads crashes g++: "g++: internal compiler error: Killed (program cc1plus)" - - export THREADS=4 + - 'if [ ${CC} = "gcc" ]; then + export THREADS=4; + else + export THREADS=$((`nproc` + 1)); + fi' - echo "THREADS = $THREADS" - free -mt From 452c7c1e4037f1f92dad510bc45ca15bb219fcf0 Mon Sep 17 00:00:00 2001 From: Deve Date: Fri, 11 Nov 2016 13:44:51 +0100 Subject: [PATCH 03/10] Fixed compiler warning --- lib/irrlicht/source/Irrlicht/CGUIListBox.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/irrlicht/source/Irrlicht/CGUIListBox.cpp b/lib/irrlicht/source/Irrlicht/CGUIListBox.cpp index adbc28deb..d640f4c89 100644 --- a/lib/irrlicht/source/Irrlicht/CGUIListBox.cpp +++ b/lib/irrlicht/source/Irrlicht/CGUIListBox.cpp @@ -443,6 +443,8 @@ bool CGUIListBox::OnEvent(const SEvent& event) case EET_JOYSTICK_INPUT_EVENT: case EGUIET_FORCE_32_BIT: break; + default: + break; } } From 6b2bf1c088be80966a424546a62e44e379c368f0 Mon Sep 17 00:00:00 2001 From: Deve Date: Fri, 11 Nov 2016 14:07:18 +0100 Subject: [PATCH 04/10] Make sure that we are not out of array. Command line arguments are not available on android. --- src/utils/command_line.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/command_line.cpp b/src/utils/command_line.cpp index 0ac7193c6..0514d85ba 100644 --- a/src/utils/command_line.cpp +++ b/src/utils/command_line.cpp @@ -31,7 +31,9 @@ std::string CommandLine::m_exec_name=""; */ void CommandLine::init(unsigned int argc, char *argv[]) { - m_exec_name = argv[0]; + if (argc > 0) + m_exec_name = argv[0]; + for(unsigned int i=1; i Date: Fri, 11 Nov 2016 14:11:27 +0100 Subject: [PATCH 05/10] Remove pthread_setcancelstate functions. This function is not available on android and it is default on other platforms anyway. It makes easier to port changes from master to android branch. --- src/addons/news_manager.cpp | 3 --- src/audio/sfx_manager.cpp | 5 ----- src/network/network_console.cpp | 2 ++ src/online/request_manager.cpp | 6 ------ 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/addons/news_manager.cpp b/src/addons/news_manager.cpp index 53d793d19..ad2376912 100644 --- a/src/addons/news_manager.cpp +++ b/src/addons/news_manager.cpp @@ -75,9 +75,6 @@ void NewsManager::init(bool force_refresh) pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - // Should be the default, but just in case: - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_t thread_id; int error = pthread_create(&thread_id, &attr, &NewsManager::downloadNews, this); diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 13cb7c92a..e5c1013da 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -91,9 +91,6 @@ SFXManager::SFXManager() pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - // Should be the default, but just in case: - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - m_thread_id.setAtomic(new pthread_t()); // The thread is created even if there atm sfx are disabled // (since the user might enable it later). @@ -299,8 +296,6 @@ void* SFXManager::mainLoop(void *obj) VS::setThreadName("SFXManager"); SFXManager *me = (SFXManager*)obj; - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - me->m_sfx_commands.lock(); // Wait till we have an empty sfx in the queue diff --git a/src/network/network_console.cpp b/src/network/network_console.cpp index 45df23848..b83729ec3 100644 --- a/src/network/network_console.cpp +++ b/src/network/network_console.cpp @@ -43,8 +43,10 @@ NetworkConsole::NetworkConsole() // ---------------------------------------------------------------------------- NetworkConsole::~NetworkConsole() { +#ifndef ANDROID if (m_thread_keyboard) pthread_cancel(*m_thread_keyboard);//, SIGKILL); +#endif } // ---------------------------------------------------------------------------- diff --git a/src/online/request_manager.cpp b/src/online/request_manager.cpp index 71b0b9a71..b59221890 100644 --- a/src/online/request_manager.cpp +++ b/src/online/request_manager.cpp @@ -104,10 +104,6 @@ namespace Online pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - // Should be the default, but just in case: - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - m_thread_id.setAtomic(new pthread_t()); int error = pthread_create(m_thread_id.getData(), &attr, &RequestManager::mainLoop, this); @@ -189,8 +185,6 @@ namespace Online VS::setThreadName("RequestManager"); RequestManager *me = (RequestManager*) obj; - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - me->m_current_request = NULL; me->m_request_queue.lock(); while (me->m_request_queue.getData().empty() || From 7e4dfdb97e5df75585ba83945e806096c7d74cfd Mon Sep 17 00:00:00 2001 From: Deve Date: Fri, 11 Nov 2016 16:22:31 +0100 Subject: [PATCH 06/10] Remove version from graphics restrictions for sRGB-capable visual workaround. It doesn't look that they're going to fix it soon. --- data/graphical_restrictions.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/graphical_restrictions.xml b/data/graphical_restrictions.xml index 9d1374e55..67f70c876 100644 --- a/data/graphical_restrictions.xml +++ b/data/graphical_restrictions.xml @@ -7,7 +7,7 @@ - + From e6e302af1cd7e127855845dca48dc84f2d7747e8 Mon Sep 17 00:00:00 2001 From: Benau Date: Sun, 13 Nov 2016 15:43:00 +0800 Subject: [PATCH 07/10] Fix copy and paste of unicode characters --- .../source/Irrlicht/CIrrDeviceLinux.cpp | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index 49a3fb026..fb66b20ec 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -73,7 +73,6 @@ namespace Atom X_ATOM_CLIPBOARD; Atom X_ATOM_TARGETS; Atom X_ATOM_UTF8_STRING; - Atom X_ATOM_TEXT; }; namespace irr @@ -1721,7 +1720,7 @@ bool CIrrDeviceLinux::run() { XEvent respond; XSelectionRequestEvent *req = &(event.xselectionrequest); - if ( req->target == XA_STRING) + if ( req->target == X_ATOM_UTF8_STRING) { XChangeProperty (display, req->requestor, @@ -1734,14 +1733,13 @@ bool CIrrDeviceLinux::run() } else if ( req->target == X_ATOM_TARGETS ) { - long data[2]; + long data[1]; - data[0] = X_ATOM_TEXT; - data[1] = XA_STRING; + data[0] = X_ATOM_UTF8_STRING; XChangeProperty (display, req->requestor, - req->property, req->target, - 8, PropModeReplace, + req->property, XA_ATOM, + 32, PropModeReplace, (unsigned char *) &data, sizeof (data)); respond.xselection.property = req->property; @@ -2583,7 +2581,7 @@ const c8* CIrrDeviceLinux::getTextFromClipboard() const os::Printer::log("Couldn't access X clipboard", ELL_WARNING); return 0; } - + Window ownerWindow = XGetSelectionOwner(display, X_ATOM_CLIPBOARD); if (ownerWindow == window) { @@ -2596,8 +2594,8 @@ const c8* CIrrDeviceLinux::getTextFromClipboard() const return 0; Atom selection = XInternAtom(display, "IRR_SELECTION", False); - XConvertSelection(display, X_ATOM_CLIPBOARD, XA_STRING, selection, window, CurrentTime); - + XConvertSelection(display, X_ATOM_CLIPBOARD, X_ATOM_UTF8_STRING, selection, window, CurrentTime); + const int SELECTION_RETRIES = 500; int i = 0; for (i = 0; i < SELECTION_RETRIES; i++) @@ -2610,13 +2608,13 @@ const c8* CIrrDeviceLinux::getTextFromClipboard() const usleep(1000); } - + if (i == SELECTION_RETRIES) { os::Printer::log("Timed out waiting for SelectionNotify event", ELL_WARNING); return 0; } - + Atom type; int format; unsigned long numItems, dummy; @@ -2628,7 +2626,7 @@ const c8* CIrrDeviceLinux::getTextFromClipboard() const if (result == Success) Clipboard = (irr::c8*)data; - + XFree (data); return Clipboard.c_str(); #else @@ -2688,7 +2686,6 @@ void CIrrDeviceLinux::initXAtoms() X_ATOM_CLIPBOARD = XInternAtom(display, "CLIPBOARD", False); X_ATOM_TARGETS = XInternAtom(display, "TARGETS", False); X_ATOM_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); - X_ATOM_TEXT = XInternAtom (display, "TEXT", False); #endif } From feae91042af0839b18589c56ad6394bccd179637 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 14 Nov 2016 18:25:00 +1100 Subject: [PATCH 08/10] Explicitly disable X11 compilation for windows. No idea why it is defined in CGUIEditbox now, but it somehow is ;( --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae848ef7a..a00dcaed0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ if(WIN32) set(ENV{LIB} ${PROJECT_SOURCE_DIR}/dependencies/lib) set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/dependencies) add_definitions(-D_IRR_STATIC_LIB_) + add_definitions(-DNO_IRR_COMPILE_WITH_X11_) endif() if(USE_GLES2) From 621e61c644dad4631ae2d3f422d460d1432dc15a Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 14 Nov 2016 18:32:29 +1100 Subject: [PATCH 09/10] Fixed coding style. --- src/graphics/draw_tools.hpp | 2 +- src/graphics/irr_driver.cpp | 20 ++++++++++++++------ src/graphics/irr_driver.hpp | 2 +- src/graphics/stk_mesh_scene_node.cpp | 8 ++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/graphics/draw_tools.hpp b/src/graphics/draw_tools.hpp index 2bfde7bfb..0feb1917d 100644 --- a/src/graphics/draw_tools.hpp +++ b/src/graphics/draw_tools.hpp @@ -62,7 +62,7 @@ struct CustomUnrollArgs<> static void drawMesh(const STK::Tuple &t, Args... args) { - irr_driver->IncreaseObjectCount(); //TODO: move somewhere else + irr_driver->increaseObjectCount(); //TODO: move somewhere else GLMesh *mesh = STK::tuple_get<0>(t); //shadow_custom_unroll_args, rsm_custom_unroll_args and custom_unroll_args diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index b5bc0567e..094d52d79 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -158,38 +158,46 @@ void IrrDriver::reset() m_renderer->resetPostProcessing(); } // reset +// ---------------------------------------------------------------------------- void IrrDriver::setPhase(STKRenderingPass p) { m_phase = p; } +// ---------------------------------------------------------------------------- STKRenderingPass IrrDriver::getPhase() const { return m_phase; } -void IrrDriver::IncreaseObjectCount() +#// ---------------------------------------------------------------------------- +void IrrDriver::increaseObjectCount() { m_renderer->incObjectCount(m_phase); -} +} // increaseObjectCount +// ---------------------------------------------------------------------------- core::array &IrrDriver::getMainSetup() { return m_mrt; -} +} // getMainSetup + +// ---------------------------------------------------------------------------- +#ifndef SERVER_ONLY GPUTimer &IrrDriver::getGPUTimer(unsigned i) { return m_perf_query[i]; -} - +} // getGPUTimer +// ---------------------------------------------------------------------------- std::unique_ptr IrrDriver::createRenderTarget(const irr::core::dimension2du &dimension, const std::string &name) { return m_renderer->createRenderTarget(dimension, name); -} +} // createRenderTarget +#endif // ~SERVER_ONLY // ---------------------------------------------------------------------------- diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index d29bb8b17..1f7ffd4ea 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -203,7 +203,7 @@ public: void setPhase(STKRenderingPass); STKRenderingPass getPhase() const; - void IncreaseObjectCount(); + void increaseObjectCount(); core::array &getMainSetup(); void updateConfigIfRelevant(); void setAllMaterialFlags(scene::IMesh *mesh) const; diff --git a/src/graphics/stk_mesh_scene_node.cpp b/src/graphics/stk_mesh_scene_node.cpp index 3b5b3ac57..03f71e73c 100644 --- a/src/graphics/stk_mesh_scene_node.cpp +++ b/src/graphics/stk_mesh_scene_node.cpp @@ -345,7 +345,7 @@ void STKMeshSceneNode::render() // Only untextured for (unsigned i = 0; i < GLmeshes.size(); i++) { - irr_driver->IncreaseObjectCount(); + irr_driver->increaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; @@ -391,7 +391,7 @@ void STKMeshSceneNode::render() // Only untextured for (unsigned i = 0; i < GLmeshes.size(); i++) { - irr_driver->IncreaseObjectCount(); + irr_driver->increaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; @@ -494,7 +494,7 @@ void STKMeshSceneNode::render() for (unsigned i = 0; i < GLmeshes.size(); i++) { GLMesh &mesh = GLmeshes[i]; - irr_driver->IncreaseObjectCount(); + irr_driver->increaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -547,7 +547,7 @@ void STKMeshSceneNode::render() Shaders::TransparentShader::getInstance()->use(); for (unsigned i = 0; i < GLmeshes.size(); i++) { - irr_driver->IncreaseObjectCount(); + irr_driver->increaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; From 2f2940115e032c350d4692d53a475b3bb7acd851 Mon Sep 17 00:00:00 2001 From: Benau Date: Mon, 14 Nov 2016 15:47:55 +0800 Subject: [PATCH 10/10] Use a smooth dt on camera to determine its position --- src/graphics/camera_normal.cpp | 4 +++- src/graphics/camera_normal.hpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/graphics/camera_normal.cpp b/src/graphics/camera_normal.cpp index b02c11bb9..45ade8858 100644 --- a/src/graphics/camera_normal.cpp +++ b/src/graphics/camera_normal.cpp @@ -42,6 +42,7 @@ CameraNormal::CameraNormal(Camera::CameraType type, int camera_index, { m_distance = kart ? kart->getKartProperties()->getCameraDistance() : 1000.0f; m_ambient_light = World::getWorld()->getTrack()->getDefaultAmbientColor(); + m_smooth_dt = 0.0f; // TODO: Put these values into a config file // Global or per split screen zone? @@ -111,7 +112,8 @@ void CameraNormal::smoothMoveCamera(float dt) f = current_speed >0 ? current_speed/3 + 1.0f : -1.5f * current_speed + 2.0f; } - current_position += (wanted_position - current_position) * (dt *f); + m_smooth_dt = 0.3f * dt + 0.7f * m_smooth_dt; + current_position += (wanted_position - current_position) * (m_smooth_dt*f); // Avoid camera crash: if the speed is negative, the current_position // can oscillate between plus and minus, getting bigger and bigger. If diff --git a/src/graphics/camera_normal.hpp b/src/graphics/camera_normal.hpp index 742b3aeae..9185986cb 100644 --- a/src/graphics/camera_normal.hpp +++ b/src/graphics/camera_normal.hpp @@ -49,6 +49,8 @@ private: /** Factor of the effects of steering in camera aim. */ float m_rotation_range; + /** Used to smoothly move the camera. */ + float m_smooth_dt; void smoothMoveCamera(float dt); void handleEndCamera(float dt); void getCameraSettings(float *above_kart, float *cam_angle,