Fixed bug 5103 - Port fcitx support to both fcitx 4 & 5
wengxt Due to the new major fcitx version is coming close, the existing code need to be ported to use new Fcitx dbus interface. The new dbus interface is supported by both fcitx 4 and 5, and has a good side effect, which is that it will work with flatpak for free. Also the patch remove the dependency on fcitx header. Instead, it just hardcodes a few enum value in the code so need to handle the different header for fcitx4 or 5.
parent
33642b47b2
commit
eadc8693dd
|
@ -1213,6 +1213,8 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
||||||
set(HAVE_DBUS_DBUS_H TRUE)
|
set(HAVE_DBUS_DBUS_H TRUE)
|
||||||
include_directories(${DBUS_INCLUDE_DIRS})
|
include_directories(${DBUS_INCLUDE_DIRS})
|
||||||
list(APPEND EXTRA_LIBS ${DBUS_LIBRARIES})
|
list(APPEND EXTRA_LIBS ${DBUS_LIBRARIES})
|
||||||
|
# Fcitx need only dbus.
|
||||||
|
set(HAVE_FCITX TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
pkg_search_module(IBUS ibus-1.0 ibus)
|
pkg_search_module(IBUS ibus-1.0 ibus)
|
||||||
|
@ -1220,6 +1222,9 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
||||||
set(HAVE_IBUS_IBUS_H TRUE)
|
set(HAVE_IBUS_IBUS_H TRUE)
|
||||||
include_directories(${IBUS_INCLUDE_DIRS})
|
include_directories(${IBUS_INCLUDE_DIRS})
|
||||||
list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES})
|
list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (HAVE_IBUS_IBUS_H OR HAVE_FCITX)
|
||||||
add_definitions(-DSDL_USE_IME)
|
add_definitions(-DSDL_USE_IME)
|
||||||
endif()
|
endif()
|
||||||
if(HAVE_LIBUNWIND_H)
|
if(HAVE_LIBUNWIND_H)
|
||||||
|
@ -1229,8 +1234,6 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
||||||
list(APPEND EXTRA_LIBS ${UNWIND_LIBRARIES} ${UNWIND_GENERIC_LIBRARIES})
|
list(APPEND EXTRA_LIBS ${UNWIND_LIBRARIES} ${UNWIND_GENERIC_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(INPUT_TSLIB)
|
if(INPUT_TSLIB)
|
||||||
|
|
15
configure.ac
15
configure.ac
|
@ -2731,26 +2731,15 @@ CheckFcitx()
|
||||||
AS_HELP_STRING([--enable-fcitx], [enable fcitx support [[default=yes]]]),
|
AS_HELP_STRING([--enable-fcitx], [enable fcitx support [[default=yes]]]),
|
||||||
, enable_fcitx=yes)
|
, enable_fcitx=yes)
|
||||||
if test x$enable_fcitx = xyes; then
|
if test x$enable_fcitx = xyes; then
|
||||||
PKG_CHECK_MODULES([FCITX], [fcitx], have_fcitx=yes, have_fcitx=no)
|
|
||||||
CFLAGS="$CFLAGS $FCITX_CFLAGS"
|
|
||||||
AC_CHECK_HEADER(fcitx/frontend.h,
|
|
||||||
have_fcitx_frontend_h_hdr=yes,
|
|
||||||
have_fcitx_frontend_h_hdr=no)
|
|
||||||
CFLAGS="$save_CFLAGS"
|
|
||||||
if test x$have_fcitx_frontend_h_hdr = xyes; then
|
|
||||||
if test x$enable_ime != xyes; then
|
if test x$enable_ime != xyes; then
|
||||||
AC_MSG_WARN([IME support is required for fcitx.])
|
AC_MSG_WARN([IME support is required for fcitx.])
|
||||||
have_fcitx_frontend_h_hdr=no
|
|
||||||
elif test x$enable_dbus != xyes; then
|
elif test x$enable_dbus != xyes; then
|
||||||
AC_MSG_WARN([DBus support is required for fcitx.])
|
AC_MSG_WARN([DBus support is required for fcitx.])
|
||||||
have_fcitx_frontend_h_hdr=no
|
|
||||||
else
|
else
|
||||||
AC_DEFINE(HAVE_FCITX_FRONTEND_H, 1, [ ])
|
AC_DEFINE(HAVE_FCITX, 1, [ ])
|
||||||
EXTRA_CFLAGS="$EXTRA_CFLAGS $FCITX_CFLAGS"
|
|
||||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c"
|
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dnl See if we can use the Touchscreen input library
|
dnl See if we can use the Touchscreen input library
|
||||||
|
@ -4408,7 +4397,7 @@ if test x$have_ibus_ibus_h_hdr = xyes; then
|
||||||
else
|
else
|
||||||
SUMMARY="${SUMMARY}Using ibus : NO\n"
|
SUMMARY="${SUMMARY}Using ibus : NO\n"
|
||||||
fi
|
fi
|
||||||
if test x$have_fcitx_frontend_h_hdr = xyes; then
|
if test x$enable_fcitx = xyes; then
|
||||||
SUMMARY="${SUMMARY}Using fcitx : YES\n"
|
SUMMARY="${SUMMARY}Using fcitx : YES\n"
|
||||||
else
|
else
|
||||||
SUMMARY="${SUMMARY}Using fcitx : NO\n"
|
SUMMARY="${SUMMARY}Using fcitx : NO\n"
|
||||||
|
|
|
@ -203,7 +203,7 @@
|
||||||
|
|
||||||
#cmakedefine HAVE_ALTIVEC_H 1
|
#cmakedefine HAVE_ALTIVEC_H 1
|
||||||
#cmakedefine HAVE_DBUS_DBUS_H 1
|
#cmakedefine HAVE_DBUS_DBUS_H 1
|
||||||
#cmakedefine HAVE_FCITX_FRONTEND_H 1
|
#cmakedefine HAVE_FCITX 1
|
||||||
#cmakedefine HAVE_IBUS_IBUS_H 1
|
#cmakedefine HAVE_IBUS_IBUS_H 1
|
||||||
#cmakedefine HAVE_IMMINTRIN_H 1
|
#cmakedefine HAVE_IMMINTRIN_H 1
|
||||||
#cmakedefine HAVE_LIBSAMPLERATE_H 1
|
#cmakedefine HAVE_LIBSAMPLERATE_H 1
|
||||||
|
|
|
@ -204,7 +204,7 @@
|
||||||
|
|
||||||
#undef HAVE_ALTIVEC_H
|
#undef HAVE_ALTIVEC_H
|
||||||
#undef HAVE_DBUS_DBUS_H
|
#undef HAVE_DBUS_DBUS_H
|
||||||
#undef HAVE_FCITX_FRONTEND_H
|
#undef HAVE_FCITX
|
||||||
#undef HAVE_IBUS_IBUS_H
|
#undef HAVE_IBUS_IBUS_H
|
||||||
#undef HAVE_IMMINTRIN_H
|
#undef HAVE_IMMINTRIN_H
|
||||||
#undef HAVE_LIBSAMPLERATE_H
|
#undef HAVE_LIBSAMPLERATE_H
|
||||||
|
|
|
@ -57,6 +57,10 @@ LoadDBUSSyms(void)
|
||||||
SDL_DBUS_SYM(message_new_method_call);
|
SDL_DBUS_SYM(message_new_method_call);
|
||||||
SDL_DBUS_SYM(message_append_args);
|
SDL_DBUS_SYM(message_append_args);
|
||||||
SDL_DBUS_SYM(message_append_args_valist);
|
SDL_DBUS_SYM(message_append_args_valist);
|
||||||
|
SDL_DBUS_SYM(message_iter_init_append);
|
||||||
|
SDL_DBUS_SYM(message_iter_open_container);
|
||||||
|
SDL_DBUS_SYM(message_iter_append_basic);
|
||||||
|
SDL_DBUS_SYM(message_iter_close_container);
|
||||||
SDL_DBUS_SYM(message_get_args);
|
SDL_DBUS_SYM(message_get_args);
|
||||||
SDL_DBUS_SYM(message_get_args_valist);
|
SDL_DBUS_SYM(message_get_args_valist);
|
||||||
SDL_DBUS_SYM(message_iter_init);
|
SDL_DBUS_SYM(message_iter_init);
|
||||||
|
|
|
@ -54,6 +54,10 @@ typedef struct SDL_DBusContext {
|
||||||
DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *);
|
DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *);
|
||||||
dbus_bool_t (*message_append_args)(DBusMessage *, int, ...);
|
dbus_bool_t (*message_append_args)(DBusMessage *, int, ...);
|
||||||
dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list);
|
dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list);
|
||||||
|
void (*message_iter_init_append)(DBusMessage *, DBusMessageIter *);
|
||||||
|
dbus_bool_t (*message_iter_open_container)(DBusMessageIter *, int, const char *, DBusMessageIter *);
|
||||||
|
dbus_bool_t (*message_iter_append_basic)(DBusMessageIter *, int, const void *);
|
||||||
|
dbus_bool_t (*message_iter_close_container)(DBusMessageIter *, DBusMessageIter *);
|
||||||
dbus_bool_t (*message_get_args)(DBusMessage *, DBusError *, int, ...);
|
dbus_bool_t (*message_get_args)(DBusMessage *, DBusError *, int, ...);
|
||||||
dbus_bool_t (*message_get_args_valist)(DBusMessage *, DBusError *, int, va_list);
|
dbus_bool_t (*message_get_args_valist)(DBusMessage *, DBusError *, int, va_list);
|
||||||
dbus_bool_t (*message_iter_init)(DBusMessage *, DBusMessageIter *);
|
dbus_bool_t (*message_iter_init)(DBusMessage *, DBusMessageIter *);
|
||||||
|
|
|
@ -20,9 +20,6 @@
|
||||||
*/
|
*/
|
||||||
#include "../../SDL_internal.h"
|
#include "../../SDL_internal.h"
|
||||||
|
|
||||||
#ifdef HAVE_FCITX_FRONTEND_H
|
|
||||||
|
|
||||||
#include <fcitx/frontend.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "SDL_fcitx.h"
|
#include "SDL_fcitx.h"
|
||||||
|
@ -36,23 +33,20 @@
|
||||||
#endif
|
#endif
|
||||||
#include "SDL_hints.h"
|
#include "SDL_hints.h"
|
||||||
|
|
||||||
#define FCITX_DBUS_SERVICE "org.fcitx.Fcitx"
|
#define FCITX_DBUS_SERVICE "org.freedesktop.portal.Fcitx"
|
||||||
|
|
||||||
#define FCITX_IM_DBUS_PATH "/inputmethod"
|
#define FCITX_IM_DBUS_PATH "/org/freedesktop/portal/inputmethod"
|
||||||
#define FCITX_IC_DBUS_PATH "/inputcontext_%d"
|
|
||||||
|
|
||||||
#define FCITX_IM_DBUS_INTERFACE "org.fcitx.Fcitx.InputMethod"
|
#define FCITX_IM_DBUS_INTERFACE "org.fcitx.Fcitx.InputMethod1"
|
||||||
#define FCITX_IC_DBUS_INTERFACE "org.fcitx.Fcitx.InputContext"
|
#define FCITX_IC_DBUS_INTERFACE "org.fcitx.Fcitx.InputContext1"
|
||||||
|
|
||||||
#define IC_NAME_MAX 64
|
|
||||||
#define DBUS_TIMEOUT 500
|
#define DBUS_TIMEOUT 500
|
||||||
|
|
||||||
typedef struct _FcitxClient
|
typedef struct _FcitxClient
|
||||||
{
|
{
|
||||||
SDL_DBusContext *dbus;
|
SDL_DBusContext *dbus;
|
||||||
|
|
||||||
char servicename[IC_NAME_MAX];
|
char *ic_path;
|
||||||
char icname[IC_NAME_MAX];
|
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
@ -61,34 +55,6 @@ typedef struct _FcitxClient
|
||||||
|
|
||||||
static FcitxClient fcitx_client;
|
static FcitxClient fcitx_client;
|
||||||
|
|
||||||
static int
|
|
||||||
GetDisplayNumber()
|
|
||||||
{
|
|
||||||
const char *display = SDL_getenv("DISPLAY");
|
|
||||||
const char *p = NULL;
|
|
||||||
int number = 0;
|
|
||||||
|
|
||||||
if (display == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
display = SDL_strchr(display, ':');
|
|
||||||
if (display == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
display++;
|
|
||||||
p = SDL_strchr(display, '.');
|
|
||||||
if (p == NULL && display != NULL) {
|
|
||||||
number = SDL_strtod(display, NULL);
|
|
||||||
} else {
|
|
||||||
char *buffer = SDL_strdup(display);
|
|
||||||
buffer[p - display] = '\0';
|
|
||||||
number = SDL_strtod(buffer, NULL);
|
|
||||||
SDL_free(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
GetAppName()
|
GetAppName()
|
||||||
{
|
{
|
||||||
|
@ -118,6 +84,54 @@ GetAppName()
|
||||||
return SDL_strdup("SDL_App");
|
return SDL_strdup("SDL_App");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Fcitx_GetPreeditString(SDL_DBusContext *dbus, DBusMessage *msg, char **ret) {
|
||||||
|
char *text = NULL, *subtext;
|
||||||
|
size_t text_bytes = 0;
|
||||||
|
DBusMessageIter iter, array, sub;
|
||||||
|
|
||||||
|
dbus->message_iter_init(msg, &iter);
|
||||||
|
/* Message type is a(si)i, we only need string part */
|
||||||
|
if (dbus->message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
|
||||||
|
/* First pass: calculate string length */
|
||||||
|
dbus->message_iter_recurse(&iter, &array);
|
||||||
|
while (dbus->message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
|
||||||
|
dbus->message_iter_recurse(&array, &sub);
|
||||||
|
if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
|
||||||
|
dbus->message_iter_get_basic(&sub, &subtext);
|
||||||
|
if (subtext && *subtext) {
|
||||||
|
text_bytes += SDL_strlen(subtext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbus->message_iter_next(&array);
|
||||||
|
}
|
||||||
|
if (text_bytes) {
|
||||||
|
text = SDL_malloc(text_bytes + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text) {
|
||||||
|
char* pivot = text;
|
||||||
|
/* Second pass: join all the sub string */
|
||||||
|
dbus->message_iter_recurse(&iter, &array);
|
||||||
|
while (dbus->message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
|
||||||
|
dbus->message_iter_recurse(&array, &sub);
|
||||||
|
if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
|
||||||
|
dbus->message_iter_get_basic(&sub, &subtext);
|
||||||
|
if (subtext && *subtext) {
|
||||||
|
size_t length = SDL_strlen(subtext);
|
||||||
|
SDL_strlcpy(pivot, subtext, length + 1);
|
||||||
|
pivot += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbus->message_iter_next(&array);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
text_bytes = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ret= text;
|
||||||
|
return text_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
static DBusHandlerResult
|
static DBusHandlerResult
|
||||||
DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||||
{
|
{
|
||||||
|
@ -136,16 +150,12 @@ DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "UpdatePreedit")) {
|
if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "UpdateFormattedPreedit")) {
|
||||||
DBusMessageIter iter;
|
char *text = NULL;
|
||||||
const char *text;
|
size_t text_bytes = Fcitx_GetPreeditString(dbus, msg, &text);
|
||||||
|
if (text_bytes) {
|
||||||
dbus->message_iter_init(msg, &iter);
|
|
||||||
dbus->message_iter_get_basic(&iter, &text);
|
|
||||||
|
|
||||||
if (text && *text) {
|
|
||||||
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
|
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
|
||||||
size_t text_bytes = SDL_strlen(text), i = 0;
|
size_t i = 0;
|
||||||
size_t cursor = 0;
|
size_t cursor = 0;
|
||||||
|
|
||||||
while (i < text_bytes) {
|
while (i < text_bytes) {
|
||||||
|
@ -157,6 +167,9 @@ DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||||
i += sz;
|
i += sz;
|
||||||
cursor += chars;
|
cursor += chars;
|
||||||
}
|
}
|
||||||
|
SDL_free(text);
|
||||||
|
} else {
|
||||||
|
SDL_SendEditingText("", 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Fcitx_UpdateTextRect(NULL);
|
SDL_Fcitx_UpdateTextRect(NULL);
|
||||||
|
@ -169,7 +182,10 @@ DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||||
static void
|
static void
|
||||||
FcitxClientICCallMethod(FcitxClient *client, const char *method)
|
FcitxClientICCallMethod(FcitxClient *client, const char *method)
|
||||||
{
|
{
|
||||||
SDL_DBus_CallVoidMethod(client->servicename, client->icname, FCITX_IC_DBUS_INTERFACE, method, DBUS_TYPE_INVALID);
|
if (!client->ic_path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SDL_DBus_CallVoidMethod(FCITX_DBUS_SERVICE, client->ic_path, FCITX_IC_DBUS_INTERFACE, method, DBUS_TYPE_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDLCALL
|
static void SDLCALL
|
||||||
|
@ -179,40 +195,68 @@ Fcitx_SetCapabilities(void *data,
|
||||||
const char *internal_editing)
|
const char *internal_editing)
|
||||||
{
|
{
|
||||||
FcitxClient *client = (FcitxClient *)data;
|
FcitxClient *client = (FcitxClient *)data;
|
||||||
Uint32 caps = CAPACITY_NONE;
|
Uint32 caps = 0;
|
||||||
|
if (!client->ic_path) {
|
||||||
if (!(internal_editing && *internal_editing == '1')) {
|
return;
|
||||||
caps |= CAPACITY_PREEDIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DBus_CallVoidMethod(client->servicename, client->icname, FCITX_IC_DBUS_INTERFACE, "SetCapacity", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID);
|
if (!(internal_editing && *internal_editing == '1')) {
|
||||||
|
caps |= (1 << 1); /* Preedit Flag */
|
||||||
|
caps |= (1 << 4); /* Formatted Preedit Flag */
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DBus_CallVoidMethod(FCITX_DBUS_SERVICE, client->ic_path, FCITX_IC_DBUS_INTERFACE, "SetCapability", DBUS_TYPE_UINT64, &caps, DBUS_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_bool
|
||||||
|
FcitxCreateInputContext(SDL_DBusContext* dbus, const char *appname, char **ic_path) {
|
||||||
|
const char *program = "program";
|
||||||
|
SDL_bool retval = SDL_FALSE;
|
||||||
|
if (dbus->session_conn) {
|
||||||
|
DBusMessage *msg = dbus->message_new_method_call(FCITX_DBUS_SERVICE, FCITX_IM_DBUS_PATH, FCITX_IM_DBUS_INTERFACE, "CreateInputContext");
|
||||||
|
if (msg) {
|
||||||
|
DBusMessage *reply = NULL;
|
||||||
|
DBusMessageIter args, array, sub;
|
||||||
|
dbus->message_iter_init_append(msg, &args);
|
||||||
|
dbus->message_iter_open_container(&args, DBUS_TYPE_ARRAY, "(ss)", &array);
|
||||||
|
dbus->message_iter_open_container(&array, DBUS_TYPE_STRUCT, 0, &sub);
|
||||||
|
dbus->message_iter_append_basic(&sub, DBUS_TYPE_STRING, &program);
|
||||||
|
dbus->message_iter_append_basic(&sub, DBUS_TYPE_STRING, &appname);
|
||||||
|
dbus->message_iter_close_container(&array, &sub);
|
||||||
|
dbus->message_iter_close_container(&args, &array);
|
||||||
|
reply = dbus->connection_send_with_reply_and_block(dbus->session_conn, msg, 300, NULL);
|
||||||
|
if (reply) {
|
||||||
|
if (dbus->message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, ic_path, DBUS_TYPE_INVALID)) {
|
||||||
|
retval = SDL_TRUE;
|
||||||
|
}
|
||||||
|
dbus->message_unref(reply);
|
||||||
|
}
|
||||||
|
dbus->message_unref(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
FcitxClientCreateIC(FcitxClient *client)
|
FcitxClientCreateIC(FcitxClient *client)
|
||||||
{
|
{
|
||||||
char *appname = GetAppName();
|
char *appname = GetAppName();
|
||||||
pid_t pid = getpid();
|
char *ic_path = NULL;
|
||||||
int id = -1;
|
SDL_DBusContext *dbus = client->dbus;
|
||||||
Uint32 enable, arg1, arg2, arg3, arg4;
|
|
||||||
|
|
||||||
if (!SDL_DBus_CallMethod(client->servicename, FCITX_IM_DBUS_PATH, FCITX_IM_DBUS_INTERFACE, "CreateICv3",
|
/* SDL_DBus_CallMethod cannot handle a(ss) type, call dbus function directly */
|
||||||
DBUS_TYPE_STRING, &appname, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID,
|
if (!FcitxCreateInputContext(dbus, appname, &ic_path)) {
|
||||||
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)) {
|
ic_path = NULL; /* just in case. */
|
||||||
id = -1; /* just in case. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(appname);
|
SDL_free(appname);
|
||||||
|
|
||||||
if (id >= 0) {
|
if (ic_path) {
|
||||||
SDL_DBusContext *dbus = client->dbus;
|
SDL_free(client->ic_path);
|
||||||
|
client->ic_path = SDL_strdup(ic_path);
|
||||||
client->id = id;
|
|
||||||
|
|
||||||
SDL_snprintf(client->icname, IC_NAME_MAX, FCITX_IC_DBUS_PATH, client->id);
|
|
||||||
|
|
||||||
dbus->bus_add_match(dbus->session_conn,
|
dbus->bus_add_match(dbus->session_conn,
|
||||||
"type='signal', interface='org.fcitx.Fcitx.InputContext'",
|
"type='signal', interface='org.fcitx.Fcitx.InputContext1'",
|
||||||
NULL);
|
NULL);
|
||||||
dbus->connection_add_filter(dbus->session_conn,
|
dbus->connection_add_filter(dbus->session_conn,
|
||||||
&DBus_MessageFilter, dbus,
|
&DBus_MessageFilter, dbus,
|
||||||
|
@ -232,13 +276,14 @@ Fcitx_ModState(void)
|
||||||
Uint32 fcitx_mods = 0;
|
Uint32 fcitx_mods = 0;
|
||||||
SDL_Keymod sdl_mods = SDL_GetModState();
|
SDL_Keymod sdl_mods = SDL_GetModState();
|
||||||
|
|
||||||
if (sdl_mods & KMOD_SHIFT) fcitx_mods |= FcitxKeyState_Shift;
|
if (sdl_mods & KMOD_SHIFT) fcitx_mods |= (1 << 0);
|
||||||
if (sdl_mods & KMOD_CAPS) fcitx_mods |= FcitxKeyState_CapsLock;
|
if (sdl_mods & KMOD_CAPS) fcitx_mods |= (1 << 1);
|
||||||
if (sdl_mods & KMOD_CTRL) fcitx_mods |= FcitxKeyState_Ctrl;
|
if (sdl_mods & KMOD_CTRL) fcitx_mods |= (1 << 2);
|
||||||
if (sdl_mods & KMOD_ALT) fcitx_mods |= FcitxKeyState_Alt;
|
if (sdl_mods & KMOD_ALT) fcitx_mods |= (1 << 3);
|
||||||
if (sdl_mods & KMOD_NUM) fcitx_mods |= FcitxKeyState_NumLock;
|
if (sdl_mods & KMOD_NUM) fcitx_mods |= (1 << 4);
|
||||||
if (sdl_mods & KMOD_LGUI) fcitx_mods |= FcitxKeyState_Super;
|
if (sdl_mods & KMOD_MODE) fcitx_mods |= (1 << 7);
|
||||||
if (sdl_mods & KMOD_RGUI) fcitx_mods |= FcitxKeyState_Meta;
|
if (sdl_mods & KMOD_LGUI) fcitx_mods |= (1 << 6);
|
||||||
|
if (sdl_mods & KMOD_RGUI) fcitx_mods |= (1 << 28);
|
||||||
|
|
||||||
return fcitx_mods;
|
return fcitx_mods;
|
||||||
}
|
}
|
||||||
|
@ -253,10 +298,6 @@ SDL_Fcitx_Init()
|
||||||
fcitx_client.cursor_rect.w = 0;
|
fcitx_client.cursor_rect.w = 0;
|
||||||
fcitx_client.cursor_rect.h = 0;
|
fcitx_client.cursor_rect.h = 0;
|
||||||
|
|
||||||
SDL_snprintf(fcitx_client.servicename, IC_NAME_MAX,
|
|
||||||
"%s-%d",
|
|
||||||
FCITX_DBUS_SERVICE, GetDisplayNumber());
|
|
||||||
|
|
||||||
return FcitxClientCreateIC(&fcitx_client);
|
return FcitxClientCreateIC(&fcitx_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +305,10 @@ void
|
||||||
SDL_Fcitx_Quit()
|
SDL_Fcitx_Quit()
|
||||||
{
|
{
|
||||||
FcitxClientICCallMethod(&fcitx_client, "DestroyIC");
|
FcitxClientICCallMethod(&fcitx_client, "DestroyIC");
|
||||||
|
if (fcitx_client.ic_path) {
|
||||||
|
SDL_free(fcitx_client.ic_path);
|
||||||
|
fcitx_client.ic_path = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -288,12 +333,16 @@ SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
||||||
{
|
{
|
||||||
Uint32 state = Fcitx_ModState();
|
Uint32 state = Fcitx_ModState();
|
||||||
Uint32 handled = SDL_FALSE;
|
Uint32 handled = SDL_FALSE;
|
||||||
int type = FCITX_PRESS_KEY;
|
Uint32 is_release = SDL_FALSE;
|
||||||
Uint32 event_time = 0;
|
Uint32 event_time = 0;
|
||||||
|
|
||||||
if (SDL_DBus_CallMethod(fcitx_client.servicename, fcitx_client.icname, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
|
if (!fcitx_client.ic_path) {
|
||||||
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INT32, &type, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
|
return SDL_FALSE;
|
||||||
DBUS_TYPE_INT32, &handled, DBUS_TYPE_INVALID)) {
|
}
|
||||||
|
|
||||||
|
if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
|
||||||
|
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
|
||||||
|
DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) {
|
||||||
if (handled) {
|
if (handled) {
|
||||||
SDL_Fcitx_UpdateTextRect(NULL);
|
SDL_Fcitx_UpdateTextRect(NULL);
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
|
@ -350,7 +399,7 @@ SDL_Fcitx_UpdateTextRect(SDL_Rect *rect)
|
||||||
x += cursor->x;
|
x += cursor->x;
|
||||||
y += cursor->y;
|
y += cursor->y;
|
||||||
|
|
||||||
SDL_DBus_CallVoidMethod(fcitx_client.servicename, fcitx_client.icname, FCITX_IC_DBUS_INTERFACE, "SetCursorRect",
|
SDL_DBus_CallVoidMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "SetCursorRect",
|
||||||
DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &cursor->w, DBUS_TYPE_INT32, &cursor->h, DBUS_TYPE_INVALID);
|
DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &cursor->w, DBUS_TYPE_INT32, &cursor->h, DBUS_TYPE_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +417,4 @@ SDL_Fcitx_PumpEvents(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_FCITX_FRONTEND_H */
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -43,7 +43,7 @@ static void
|
||||||
InitIME()
|
InitIME()
|
||||||
{
|
{
|
||||||
static SDL_bool inited = SDL_FALSE;
|
static SDL_bool inited = SDL_FALSE;
|
||||||
#ifdef HAVE_FCITX_FRONTEND_H
|
#ifdef HAVE_FCITX
|
||||||
const char *im_module = SDL_getenv("SDL_IM_MODULE");
|
const char *im_module = SDL_getenv("SDL_IM_MODULE");
|
||||||
const char *xmodifiers = SDL_getenv("XMODIFIERS");
|
const char *xmodifiers = SDL_getenv("XMODIFIERS");
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,7 +54,7 @@ InitIME()
|
||||||
inited = SDL_TRUE;
|
inited = SDL_TRUE;
|
||||||
|
|
||||||
/* See if fcitx IME support is being requested */
|
/* See if fcitx IME support is being requested */
|
||||||
#ifdef HAVE_FCITX_FRONTEND_H
|
#ifdef HAVE_FCITX
|
||||||
if (!SDL_IME_Init_Real &&
|
if (!SDL_IME_Init_Real &&
|
||||||
((im_module && SDL_strcmp(im_module, "fcitx") == 0) ||
|
((im_module && SDL_strcmp(im_module, "fcitx") == 0) ||
|
||||||
(!im_module && xmodifiers && SDL_strstr(xmodifiers, "@im=fcitx") != NULL))) {
|
(!im_module && xmodifiers && SDL_strstr(xmodifiers, "@im=fcitx") != NULL))) {
|
||||||
|
@ -66,7 +66,7 @@ InitIME()
|
||||||
SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect;
|
SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect;
|
||||||
SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents;
|
SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_FCITX_FRONTEND_H */
|
#endif /* HAVE_FCITX */
|
||||||
|
|
||||||
/* default to IBus */
|
/* default to IBus */
|
||||||
#ifdef HAVE_IBUS_IBUS_H
|
#ifdef HAVE_IBUS_IBUS_H
|
||||||
|
|
|
@ -683,7 +683,7 @@ X11_DispatchEvent(_THIS)
|
||||||
/* But only if we're using one of the DBus IMEs, otherwise
|
/* But only if we're using one of the DBus IMEs, otherwise
|
||||||
some XIM IMEs will generate duplicate events */
|
some XIM IMEs will generate duplicate events */
|
||||||
if (orig_keycode) {
|
if (orig_keycode) {
|
||||||
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
|
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX)
|
||||||
SDL_Scancode scancode = videodata->key_layout[orig_keycode];
|
SDL_Scancode scancode = videodata->key_layout[orig_keycode];
|
||||||
videodata->filter_code = orig_keycode;
|
videodata->filter_code = orig_keycode;
|
||||||
videodata->filter_time = xevent.xkey.time;
|
videodata->filter_time = xevent.xkey.time;
|
||||||
|
|
Loading…
Reference in New Issue