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" 47 #define IC_NAME_MAX 64 48 #define DBUS_TIMEOUT 500 50 typedef struct _FcitxClient
52 SDL_DBusContext *dbus;
54 char servicename[IC_NAME_MAX];
55 char icname[IC_NAME_MAX];
62 static FcitxClient fcitx_client;
84 buffer[p - display] =
'\0';
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';
121 static DBusHandlerResult
122 DBus_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;
170 FcitxClientICCallMethod(FcitxClient *client,
const char *method)
172 SDL_DBus_CallVoidMethod(client->servicename, client->icname, FCITX_IC_DBUS_INTERFACE, method, DBUS_TYPE_INVALID);
176 Fcitx_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);
192 FcitxClientCreateIC(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 334 Display *x_disp = info.
info.
x11.display;
335 Window x_win = info.
info.
x11.window;
336 int x_screen = displaydata->
screen;
338 X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &
y, &unused);
342 if (cursor->
x == -1 && cursor->
y == -1 && cursor->
w == 0 && cursor->
h == 0) {
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) {
void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect)
GLint GLint GLint GLint GLint x
GLuint GLuint GLuint GLuint arg1
GLfloat GLfloat GLfloat GLfloat h
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define SDL_GetKeyboardFocus
GLuint const GLchar * name
SDL_bool SDL_Fcitx_Init(void)
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
#define SDL_GetWindowSize
void SDL_Fcitx_Reset(void)
int SDL_SendKeyboardText(const char *text)
GLubyte GLubyte GLubyte GLubyte w
#define SDL_GetWindowPosition
GLint GLint GLint GLint GLint GLint y
void SDL_Fcitx_PumpEvents(void)
GLenum GLuint GLenum GLsizei const GLchar * buf
struct SDL_SysWMinfo::@18::@19 x11
#define SDL_HINT_IME_INTERNAL_EDITING
A variable to control whether certain IMEs should handle text editing internally instead of sending S...
SDL_Keymod
Enumeration of valid key mods (possibly OR'd together).
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)
#define SDL_GetWindowWMInfo
void SDL_Fcitx_Quit(void)
static char text[MAX_TEXT_LENGTH]
SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
The type used to identify a window.
GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg3
#define SDL_AddHintCallback
void SDL_Fcitx_SetFocus(SDL_bool focused)
GLuint GLuint GLsizei GLenum type
union SDL_SysWMinfo::@18 info
int SDL_SendEditingText(const char *text, int start, int length)
A rectangle, with the origin at the upper left.
#define SDL_TEXTEDITINGEVENT_TEXT_SIZE