|
|
|
@ -23,8 +23,7 @@
|
|
|
|
|
#include "../core/math_func.hpp"
|
|
|
|
|
#include "../fileio_func.h"
|
|
|
|
|
#include "../framerate_type.h"
|
|
|
|
|
#include "../window_func.h"
|
|
|
|
|
#include "../window_gui.h"
|
|
|
|
|
#include "../scope.h"
|
|
|
|
|
#include "sdl2_v.h"
|
|
|
|
|
#include <SDL.h>
|
|
|
|
|
#include <mutex>
|
|
|
|
@ -35,6 +34,15 @@
|
|
|
|
|
#include "../3rdparty/mingw-std-threads/mingw.condition_variable.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
#include <fcitx/frontend.h>
|
|
|
|
|
#include <dbus/dbus.h>
|
|
|
|
|
#include <SDL_syswm.h>
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
|
#include <X11/keysym.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "../safeguards.h"
|
|
|
|
|
|
|
|
|
|
static FVideoDriver_SDL iFVideoDriver_SDL;
|
|
|
|
@ -64,6 +72,191 @@ static int _window_size_h;
|
|
|
|
|
|
|
|
|
|
static std::string _editing_text;
|
|
|
|
|
|
|
|
|
|
static void SetTextInputRect();
|
|
|
|
|
|
|
|
|
|
Point GetFocusedWindowCaret();
|
|
|
|
|
Point GetFocusedWindowTopLeft();
|
|
|
|
|
bool FocusedWindowIsConsole();
|
|
|
|
|
bool EditBoxInGlobalFocus();
|
|
|
|
|
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
static bool _fcitx_mode = false;
|
|
|
|
|
static char _fcitx_service_name[64];
|
|
|
|
|
static char _fcitx_ic_name[64];
|
|
|
|
|
static DBusConnection *_fcitx_dbus_session_conn = nullptr;
|
|
|
|
|
|
|
|
|
|
static void FcitxICMethod(const char *method)
|
|
|
|
|
{
|
|
|
|
|
DBusMessage *msg = dbus_message_new_method_call(_fcitx_service_name, _fcitx_ic_name, "org.fcitx.Fcitx.InputContext", method);
|
|
|
|
|
if (!msg) return;
|
|
|
|
|
dbus_connection_send(_fcitx_dbus_session_conn, msg, NULL);
|
|
|
|
|
dbus_connection_flush(_fcitx_dbus_session_conn);
|
|
|
|
|
dbus_message_unref(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int GetXDisplayNum()
|
|
|
|
|
{
|
|
|
|
|
const char *display = getenv("DISPLAY");
|
|
|
|
|
if (!display) return 0;
|
|
|
|
|
const char *colon = strchr(display, ':');
|
|
|
|
|
if (!colon) return 0;
|
|
|
|
|
return atoi(colon + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FcitxDeinit() {
|
|
|
|
|
if (_fcitx_mode) {
|
|
|
|
|
FcitxICMethod("DestroyIC");
|
|
|
|
|
_fcitx_mode = false;
|
|
|
|
|
}
|
|
|
|
|
if (_fcitx_dbus_session_conn) {
|
|
|
|
|
dbus_connection_close(_fcitx_dbus_session_conn);
|
|
|
|
|
_fcitx_dbus_session_conn = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static DBusHandlerResult FcitxDBusMessageFilter(DBusConnection *connection, DBusMessage *message, void *user_data)
|
|
|
|
|
{
|
|
|
|
|
if (dbus_message_is_signal(message, "org.fcitx.Fcitx.InputContext", "CommitString")) {
|
|
|
|
|
DBusMessageIter iter;
|
|
|
|
|
const char *text = nullptr;
|
|
|
|
|
dbus_message_iter_init(message, &iter);
|
|
|
|
|
dbus_message_iter_get_basic(&iter, &text);
|
|
|
|
|
|
|
|
|
|
if (text != nullptr && EditBoxInGlobalFocus()) {
|
|
|
|
|
HandleTextInput(nullptr, true);
|
|
|
|
|
HandleTextInput(text);
|
|
|
|
|
SetTextInputRect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dbus_message_is_signal(message, "org.fcitx.Fcitx.InputContext", "UpdatePreedit")) {
|
|
|
|
|
const char *text = nullptr;
|
|
|
|
|
int32 cursor;
|
|
|
|
|
if (!dbus_message_get_args(message, nullptr, DBUS_TYPE_STRING, &text, DBUS_TYPE_INT32, &cursor, DBUS_TYPE_INVALID)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
|
|
|
|
|
|
|
|
|
if (text != nullptr && EditBoxInGlobalFocus()) {
|
|
|
|
|
HandleTextInput(text, true, text + min<uint>(cursor, strlen(text)));
|
|
|
|
|
}
|
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FcitxInit()
|
|
|
|
|
{
|
|
|
|
|
DBusError err;
|
|
|
|
|
dbus_error_init(&err);
|
|
|
|
|
_fcitx_dbus_session_conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
|
|
|
|
|
if (dbus_error_is_set(&err)) {
|
|
|
|
|
dbus_error_free(&err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
dbus_connection_set_exit_on_disconnect(_fcitx_dbus_session_conn, false);
|
|
|
|
|
seprintf(_fcitx_service_name, lastof(_fcitx_service_name), "org.fcitx.Fcitx-%d", GetXDisplayNum());
|
|
|
|
|
|
|
|
|
|
auto guard = scope_guard([]() {
|
|
|
|
|
if (!_fcitx_mode) FcitxDeinit();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
int pid = getpid();
|
|
|
|
|
int id = -1;
|
|
|
|
|
uint32 enable, hk1sym, hk1state, hk2sym, hk2state;
|
|
|
|
|
DBusMessage *msg = dbus_message_new_method_call(_fcitx_service_name, "/inputmethod", "org.fcitx.Fcitx.InputMethod", "CreateICv3");
|
|
|
|
|
if (!msg) return;
|
|
|
|
|
auto guard1 = scope_guard([&]() {
|
|
|
|
|
dbus_message_unref(msg);
|
|
|
|
|
});
|
|
|
|
|
const char *name = "OpenTTD";
|
|
|
|
|
if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID)) return;
|
|
|
|
|
DBusMessage *reply = dbus_connection_send_with_reply_and_block(_fcitx_dbus_session_conn, msg, 100, nullptr);
|
|
|
|
|
if (!reply) return;
|
|
|
|
|
auto guard2 = scope_guard([&]() {
|
|
|
|
|
dbus_message_unref(reply);
|
|
|
|
|
});
|
|
|
|
|
if (!dbus_message_get_args(reply, nullptr, DBUS_TYPE_INT32, &id, DBUS_TYPE_BOOLEAN, &enable, DBUS_TYPE_UINT32, &hk1sym, DBUS_TYPE_UINT32, &hk1state, DBUS_TYPE_UINT32, &hk2sym, DBUS_TYPE_UINT32, &hk2state, DBUS_TYPE_INVALID)) return;
|
|
|
|
|
|
|
|
|
|
if (id < 0) return;
|
|
|
|
|
|
|
|
|
|
seprintf(_fcitx_ic_name, lastof(_fcitx_ic_name), "/inputcontext_%d", id);
|
|
|
|
|
dbus_bus_add_match(_fcitx_dbus_session_conn, "type='signal', interface='org.fcitx.Fcitx.InputContext'", nullptr);
|
|
|
|
|
dbus_connection_add_filter(_fcitx_dbus_session_conn, &FcitxDBusMessageFilter, nullptr, nullptr);
|
|
|
|
|
dbus_connection_flush(_fcitx_dbus_session_conn);
|
|
|
|
|
|
|
|
|
|
uint32 caps = CAPACITY_PREEDIT;
|
|
|
|
|
DBusMessage *msg2 = dbus_message_new_method_call(_fcitx_service_name, _fcitx_ic_name, "org.fcitx.Fcitx.InputContext", "SetCapacity");
|
|
|
|
|
if (!msg2) return;
|
|
|
|
|
auto guard3 = scope_guard([&]() {
|
|
|
|
|
dbus_message_unref(msg2);
|
|
|
|
|
});
|
|
|
|
|
if (!dbus_message_append_args(msg2, DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID)) return;
|
|
|
|
|
dbus_connection_send(_fcitx_dbus_session_conn, msg2, NULL);
|
|
|
|
|
dbus_connection_flush(_fcitx_dbus_session_conn);
|
|
|
|
|
|
|
|
|
|
SDL_EventState(SDL_SYSWMEVENT, 1);
|
|
|
|
|
|
|
|
|
|
_fcitx_mode = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32 _fcitx_last_keycode;
|
|
|
|
|
static uint32 _fcitx_last_keysym;
|
|
|
|
|
static bool FcitxProcessKey(const SDL_Keysym &key)
|
|
|
|
|
{
|
|
|
|
|
uint32 fcitx_mods = 0;
|
|
|
|
|
if (key.mod & KMOD_SHIFT) fcitx_mods |= FcitxKeyState_Shift;
|
|
|
|
|
if (key.mod & KMOD_CAPS) fcitx_mods |= FcitxKeyState_CapsLock;
|
|
|
|
|
if (key.mod & KMOD_CTRL) fcitx_mods |= FcitxKeyState_Ctrl;
|
|
|
|
|
if (key.mod & KMOD_ALT) fcitx_mods |= FcitxKeyState_Alt;
|
|
|
|
|
if (key.mod & KMOD_NUM) fcitx_mods |= FcitxKeyState_NumLock;
|
|
|
|
|
if (key.mod & KMOD_LGUI) fcitx_mods |= FcitxKeyState_Super;
|
|
|
|
|
if (key.mod & KMOD_RGUI) fcitx_mods |= FcitxKeyState_Meta;
|
|
|
|
|
|
|
|
|
|
int type = FCITX_PRESS_KEY;
|
|
|
|
|
uint32 event_time = 0;
|
|
|
|
|
|
|
|
|
|
DBusMessage *msg = dbus_message_new_method_call(_fcitx_service_name, _fcitx_ic_name, "org.fcitx.Fcitx.InputContext", "ProcessKeyEvent");
|
|
|
|
|
if (!msg) return false;
|
|
|
|
|
auto guard1 = scope_guard([&]() {
|
|
|
|
|
dbus_message_unref(msg);
|
|
|
|
|
});
|
|
|
|
|
if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &_fcitx_last_keysym, DBUS_TYPE_UINT32, &_fcitx_last_keycode, DBUS_TYPE_UINT32, &fcitx_mods,
|
|
|
|
|
DBUS_TYPE_INT32, &type, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID)) return false;
|
|
|
|
|
DBusMessage *reply = dbus_connection_send_with_reply_and_block(_fcitx_dbus_session_conn, msg, 300, nullptr);
|
|
|
|
|
if (!reply) return false;
|
|
|
|
|
auto guard2 = scope_guard([&]() {
|
|
|
|
|
dbus_message_unref(reply);
|
|
|
|
|
});
|
|
|
|
|
uint32 handled = 0;
|
|
|
|
|
if (!dbus_message_get_args(reply, nullptr, DBUS_TYPE_INT32, &handled, DBUS_TYPE_INVALID)) return false;
|
|
|
|
|
return handled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FcitxPoll()
|
|
|
|
|
{
|
|
|
|
|
dbus_connection_read_write(_fcitx_dbus_session_conn, 0);
|
|
|
|
|
while (dbus_connection_dispatch(_fcitx_dbus_session_conn) == DBUS_DISPATCH_DATA_REMAINS) {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FcitxFocusChange(bool focused)
|
|
|
|
|
{
|
|
|
|
|
FcitxICMethod(focused ? "FocusIn" : "FocusOut");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FcitxSYSWMEVENT(const SDL_SysWMEvent &event)
|
|
|
|
|
{
|
|
|
|
|
if (event.msg->subsystem != SDL_SYSWM_X11) return;
|
|
|
|
|
XEvent &xevent = event.msg->msg.x11.event;
|
|
|
|
|
if (xevent.type == KeyPress) {
|
|
|
|
|
KeySym keysym = XLookupKeysym(&xevent.xkey, 0);
|
|
|
|
|
_fcitx_last_keycode = xevent.xkey.keycode;
|
|
|
|
|
_fcitx_last_keysym = keysym;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
const static bool _fcitx_mode = false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height)
|
|
|
|
|
{
|
|
|
|
|
if (_num_dirty_rects < MAX_DIRTY_RECTS) {
|
|
|
|
@ -362,21 +555,79 @@ bool VideoDriver_SDL::ClaimMousePointer()
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void StartTextInput()
|
|
|
|
|
{
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
SDL_StartTextInput();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void StopTextInput()
|
|
|
|
|
{
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
SDL_StopTextInput();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void SetTextInputRect()
|
|
|
|
|
{
|
|
|
|
|
SDL_Rect winrect;
|
|
|
|
|
Point pt = _focused_window->GetCaretPosition();
|
|
|
|
|
winrect.x = _focused_window->left + pt.x;
|
|
|
|
|
winrect.y = _focused_window->top + pt.y;
|
|
|
|
|
Point caret = GetFocusedWindowCaret();
|
|
|
|
|
Point win = GetFocusedWindowTopLeft();
|
|
|
|
|
winrect.x = win.x + caret.x;
|
|
|
|
|
winrect.y = win.y + caret.y;
|
|
|
|
|
winrect.w = 1;
|
|
|
|
|
winrect.h = FONT_HEIGHT_NORMAL;
|
|
|
|
|
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode) {
|
|
|
|
|
SDL_SysWMinfo info;
|
|
|
|
|
SDL_VERSION(&info.version);
|
|
|
|
|
if (!SDL_GetWindowWMInfo(_sdl_window, &info)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int x = 0;
|
|
|
|
|
int y = 0;
|
|
|
|
|
if (info.subsystem == SDL_SYSWM_X11) {
|
|
|
|
|
Display *x_disp = info.info.x11.display;
|
|
|
|
|
Window x_win = info.info.x11.window;
|
|
|
|
|
XWindowAttributes attrib;
|
|
|
|
|
XGetWindowAttributes(x_disp, x_win, &attrib);
|
|
|
|
|
Window unused;
|
|
|
|
|
XTranslateCoordinates(x_disp, x_win, attrib.root, 0, 0, &x, &y, &unused);
|
|
|
|
|
} else {
|
|
|
|
|
SDL_GetWindowPosition(_sdl_window, &x, &y);
|
|
|
|
|
}
|
|
|
|
|
x += winrect.x;
|
|
|
|
|
y += winrect.y;
|
|
|
|
|
DBusMessage *msg = dbus_message_new_method_call(_fcitx_service_name, _fcitx_ic_name, "org.fcitx.Fcitx.InputContext", "SetCursorRect");
|
|
|
|
|
if (!msg) return;
|
|
|
|
|
auto guard = scope_guard([&]() {
|
|
|
|
|
dbus_message_unref(msg);
|
|
|
|
|
});
|
|
|
|
|
if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &winrect.w,
|
|
|
|
|
DBUS_TYPE_INT32, &winrect.h, DBUS_TYPE_INVALID)) return;
|
|
|
|
|
dbus_connection_send(_fcitx_dbus_session_conn, msg, NULL);
|
|
|
|
|
dbus_connection_flush(_fcitx_dbus_session_conn);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
SDL_SetTextInputRect(&winrect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VideoDriver_SDL::EditBoxGainedFocus()
|
|
|
|
|
{
|
|
|
|
|
if (!this->edit_box_focused) {
|
|
|
|
|
SDL_StartTextInput();
|
|
|
|
|
if (!_fcitx_mode) {
|
|
|
|
|
StartTextInput();
|
|
|
|
|
}
|
|
|
|
|
this->edit_box_focused = true;
|
|
|
|
|
}
|
|
|
|
|
SetTextInputRect();
|
|
|
|
@ -385,7 +636,14 @@ void VideoDriver_SDL::EditBoxGainedFocus()
|
|
|
|
|
void VideoDriver_SDL::EditBoxLostFocus()
|
|
|
|
|
{
|
|
|
|
|
if (this->edit_box_focused) {
|
|
|
|
|
SDL_StopTextInput();
|
|
|
|
|
if (_fcitx_mode) {
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
FcitxICMethod("Reset");
|
|
|
|
|
FcitxICMethod("CloseIC");
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
StopTextInput();
|
|
|
|
|
}
|
|
|
|
|
this->edit_box_focused = false;
|
|
|
|
|
}
|
|
|
|
|
/* Clear any marked string from the current edit box. */
|
|
|
|
@ -525,8 +783,11 @@ static uint ConvertSdlKeycodeIntoMy(SDL_Keycode kc)
|
|
|
|
|
|
|
|
|
|
int VideoDriver_SDL::PollEvent()
|
|
|
|
|
{
|
|
|
|
|
SDL_Event ev;
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode) FcitxPoll();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
SDL_Event ev;
|
|
|
|
|
if (!SDL_PollEvent(&ev)) return -2;
|
|
|
|
|
|
|
|
|
|
switch (ev.type) {
|
|
|
|
@ -584,6 +845,15 @@ int VideoDriver_SDL::PollEvent()
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDL_KEYDOWN: // Toggle full-screen on ALT + ENTER/F
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode && EditBoxInGlobalFocus() && !(FocusedWindowIsConsole() &&
|
|
|
|
|
ConvertSdlKeycodeIntoMy(SDL_GetKeyFromName(ev.text.text)) == WKC_BACKQUOTE)) {
|
|
|
|
|
if (FcitxProcessKey(ev.key.keysym)) {
|
|
|
|
|
/* key press handled by Fcitx */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_GUI)) &&
|
|
|
|
|
(ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) {
|
|
|
|
|
if (ev.key.repeat == 0) ToggleFullScreen(!_fullscreen);
|
|
|
|
@ -603,14 +873,15 @@ int VideoDriver_SDL::PollEvent()
|
|
|
|
|
keycode & WKC_ALT ||
|
|
|
|
|
(keycode >= WKC_F1 && keycode <= WKC_F12) ||
|
|
|
|
|
!IsValidChar(character, CS_ALPHANUMERAL) ||
|
|
|
|
|
!this->edit_box_focused) {
|
|
|
|
|
!this->edit_box_focused ||
|
|
|
|
|
_fcitx_mode) {
|
|
|
|
|
HandleKeypress(keycode, character);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDL_TEXTINPUT: {
|
|
|
|
|
if (EditBoxInGlobalFocus() && !(_focused_window->window_class == WC_CONSOLE &&
|
|
|
|
|
if (EditBoxInGlobalFocus() && !(FocusedWindowIsConsole() &&
|
|
|
|
|
ConvertSdlKeycodeIntoMy(SDL_GetKeyFromName(ev.text.text)) == WKC_BACKQUOTE)) {
|
|
|
|
|
HandleTextInput(nullptr, true);
|
|
|
|
|
HandleTextInput(ev.text.text);
|
|
|
|
@ -652,9 +923,25 @@ int VideoDriver_SDL::PollEvent()
|
|
|
|
|
// mouse left the window, undraw cursor
|
|
|
|
|
UndrawMouseCursor();
|
|
|
|
|
_cursor.in_window = false;
|
|
|
|
|
} else if (ev.window.event == SDL_WINDOWEVENT_MOVED) {
|
|
|
|
|
if (_fcitx_mode) SetTextInputRect();
|
|
|
|
|
} else if (ev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode) FcitxFocusChange(true);
|
|
|
|
|
#endif
|
|
|
|
|
} else if (ev.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode) FcitxFocusChange(false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case SDL_SYSWMEVENT: {
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
if (_fcitx_mode) FcitxSYSWMEVENT(ev.syswm);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
@ -690,11 +977,18 @@ const char *VideoDriver_SDL::Start(const char * const *parm)
|
|
|
|
|
SDL_StopTextInput();
|
|
|
|
|
this->edit_box_focused = false;
|
|
|
|
|
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
FcitxInit();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VideoDriver_SDL::Stop()
|
|
|
|
|
{
|
|
|
|
|
#if defined(WITH_FCITX)
|
|
|
|
|
FcitxDeinit();
|
|
|
|
|
#endif
|
|
|
|
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
|
|
|
if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) {
|
|
|
|
|
SDL_Quit(); // If there's nothing left, quit SDL
|
|
|
|
|