21#include "../../SDL_internal.h"
23#ifdef HAVE_FCITX_FRONTEND_H
25#include <fcitx/frontend.h>
31#include "../../events/SDL_keyboard_c.h"
34#if SDL_VIDEO_DRIVER_X11
35# include "../../video/x11/SDL_x11video.h"
39#define FCITX_DBUS_SERVICE "org.fcitx.Fcitx"
41#define FCITX_IM_DBUS_PATH "/inputmethod"
42#define FCITX_IC_DBUS_PATH "/inputcontext_%d"
44#define FCITX_IM_DBUS_INTERFACE "org.fcitx.Fcitx.InputMethod"
45#define FCITX_IC_DBUS_INTERFACE "org.fcitx.Fcitx.InputContext"
48#define DBUS_TIMEOUT 500
50typedef struct _FcitxClient
52 SDL_DBusContext *dbus;
54 char servicename[IC_NAME_MAX];
55 char icname[IC_NAME_MAX];
62static FcitxClient fcitx_client;
95#if defined(__LINUX__) || defined(__FREEBSD__)
101#if defined(__LINUX__)
102 SDL_snprintf(procfile,
sizeof(procfile),
"/proc/%d/exe", getpid());
103#elif defined(__FREEBSD__)
104 SDL_snprintf(procfile,
sizeof(procfile),
"/proc/%d/file", getpid());
106 linksize = readlink(procfile, linkfile,
sizeof(linkfile) - 1);
108 linkfile[linksize] =
'\0';
121static DBusHandlerResult
122DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg,
void *
data)
124 SDL_DBusContext *dbus = (SDL_DBusContext *)
data;
126 if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE,
"CommitString")) {
127 DBusMessageIter iter;
130 dbus->message_iter_init(msg, &iter);
131 dbus->message_iter_get_basic(&iter, &
text);
136 return DBUS_HANDLER_RESULT_HANDLED;
139 if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE,
"UpdatePreedit")) {
140 DBusMessageIter iter;
143 dbus->message_iter_init(msg, &iter);
144 dbus->message_iter_get_basic(&iter, &
text);
151 while (
i < text_bytes) {
163 return DBUS_HANDLER_RESULT_HANDLED;
166 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
170FcitxClientICCallMethod(FcitxClient *client,
const char *method)
172 SDL_DBus_CallVoidMethod(client->servicename, client->icname, FCITX_IC_DBUS_INTERFACE, method, DBUS_TYPE_INVALID);
176Fcitx_SetCapabilities(
void *
data,
179 const char *internal_editing)
181 FcitxClient *client = (FcitxClient *)
data;
182 Uint32 caps = CAPACITY_NONE;
184 if (!(internal_editing && *internal_editing ==
'1')) {
185 caps |= CAPACITY_PREEDIT;
188 SDL_DBus_CallVoidMethod(client->servicename, client->icname, FCITX_IC_DBUS_INTERFACE,
"SetCapacity", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID);
192FcitxClientCreateIC(FcitxClient *client)
194 char *appname = GetAppName();
195 pid_t pid = getpid();
199 if (!SDL_DBus_CallMethod(client->servicename, FCITX_IM_DBUS_PATH, FCITX_IM_DBUS_INTERFACE,
"CreateICv3",
200 DBUS_TYPE_STRING, &appname, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID,
201 DBUS_TYPE_INT32, &
id, DBUS_TYPE_BOOLEAN, &
enable, DBUS_TYPE_UINT32, &
arg1, DBUS_TYPE_UINT32, &
arg2, DBUS_TYPE_UINT32, &
arg3, DBUS_TYPE_UINT32, &arg4, DBUS_TYPE_INVALID)) {
208 SDL_DBusContext *dbus = client->dbus;
212 SDL_snprintf(client->icname, IC_NAME_MAX, FCITX_IC_DBUS_PATH, client->id);
214 dbus->bus_add_match(dbus->session_conn,
215 "type='signal', interface='org.fcitx.Fcitx.InputContext'",
217 dbus->connection_add_filter(dbus->session_conn,
218 &DBus_MessageFilter, dbus,
220 dbus->connection_flush(dbus->session_conn);
235 if (sdl_mods &
KMOD_SHIFT) fcitx_mods |= FcitxKeyState_Shift;
236 if (sdl_mods &
KMOD_CAPS) fcitx_mods |= FcitxKeyState_CapsLock;
237 if (sdl_mods &
KMOD_CTRL) fcitx_mods |= FcitxKeyState_Ctrl;
238 if (sdl_mods &
KMOD_ALT) fcitx_mods |= FcitxKeyState_Alt;
239 if (sdl_mods &
KMOD_NUM) fcitx_mods |= FcitxKeyState_NumLock;
240 if (sdl_mods &
KMOD_LGUI) fcitx_mods |= FcitxKeyState_Super;
241 if (sdl_mods &
KMOD_RGUI) fcitx_mods |= FcitxKeyState_Meta;
249 fcitx_client.dbus = SDL_DBus_GetContext();
251 fcitx_client.cursor_rect.x = -1;
252 fcitx_client.cursor_rect.y = -1;
253 fcitx_client.cursor_rect.w = 0;
254 fcitx_client.cursor_rect.h = 0;
258 FCITX_DBUS_SERVICE, GetDisplayNumber());
260 return FcitxClientCreateIC(&fcitx_client);
266 FcitxClientICCallMethod(&fcitx_client,
"DestroyIC");
273 FcitxClientICCallMethod(&fcitx_client,
"FocusIn");
275 FcitxClientICCallMethod(&fcitx_client,
"FocusOut");
282 FcitxClientICCallMethod(&fcitx_client,
"Reset");
283 FcitxClientICCallMethod(&fcitx_client,
"CloseIC");
291 int type = FCITX_PRESS_KEY;
294 if (SDL_DBus_CallMethod(fcitx_client.servicename, fcitx_client.icname, FCITX_IC_DBUS_INTERFACE,
"ProcessKeyEvent",
295 DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &
state, DBUS_TYPE_INT32, &
type, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
296 DBUS_TYPE_INT32, &handled, DBUS_TYPE_INVALID)) {
330#if SDL_VIDEO_DRIVER_X11
336 int x_screen = displaydata->
screen;
338 X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &
x, &
y, &unused);
353 SDL_DBus_CallVoidMethod(fcitx_client.servicename, fcitx_client.icname, FCITX_IC_DBUS_INTERFACE,
"SetCursorRect",
354 DBUS_TYPE_INT32, &
x, DBUS_TYPE_INT32, &
y, DBUS_TYPE_INT32, &
cursor->w, DBUS_TYPE_INT32, &
cursor->h, DBUS_TYPE_INVALID);
360 SDL_DBusContext *dbus = fcitx_client.dbus;
361 DBusConnection *conn = dbus->session_conn;
363 dbus->connection_read_write(conn, 0);
365 while (dbus->connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS) {
#define SDL_GetWindowSize
#define SDL_GetKeyboardFocus
#define SDL_GetWindowPosition
#define SDL_AddHintCallback
#define SDL_GetWindowWMInfo
#define SDL_TEXTEDITINGEVENT_TEXT_SIZE
void SDL_Fcitx_SetFocus(SDL_bool focused)
void SDL_Fcitx_PumpEvents(void)
void SDL_Fcitx_Quit(void)
SDL_bool SDL_Fcitx_Init(void)
void SDL_Fcitx_Reset(void)
void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect)
SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
#define SDL_HINT_IME_INTERNAL_EDITING
A variable to control whether certain IMEs should handle text editing internally instead of sending S...
int SDL_SendEditingText(const char *text, int start, int length)
int SDL_SendKeyboardText(const char *text)
SDL_Keymod
Enumeration of valid key mods (possibly OR'd together).
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei GLenum type
GLuint GLuint GLuint GLuint arg1
GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg3
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
GLuint const GLchar * name
GLenum GLuint GLenum GLsizei const GLchar * buf
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
A rectangle, with the origin at the upper left (integer).
struct SDL_SysWMinfo::@17::@18 x11
union SDL_SysWMinfo::@17 info
The type used to identify a window.
static char text[MAX_TEXT_LENGTH]