|
Packit Service |
1d8f1c |
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
Packit Service |
1d8f1c |
/* vim:set et sts=4: */
|
|
Packit Service |
1d8f1c |
/* ibus
|
|
Packit Service |
1d8f1c |
* Copyright (C) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
|
|
Packit Service |
1d8f1c |
* Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
Packit Service |
1d8f1c |
* Copyright (C) 2007-2015 Red Hat, Inc.
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* main.c:
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
1d8f1c |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
1d8f1c |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
1d8f1c |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
1d8f1c |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
1d8f1c |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
1d8f1c |
* Lesser General Public License for more details.
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
1d8f1c |
* License along with this library; if not, write to the Free Software
|
|
Packit Service |
1d8f1c |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
Packit Service |
1d8f1c |
* USA
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
#define _GNU_SOURCE
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#include <X11/Xproto.h>
|
|
Packit Service |
1d8f1c |
#include <X11/Xlib.h>
|
|
Packit Service |
1d8f1c |
#include <X11/keysym.h>
|
|
Packit Service |
1d8f1c |
#include <X11/Xutil.h>
|
|
Packit Service |
1d8f1c |
#include <XimProto.h>
|
|
Packit Service |
1d8f1c |
#include <IMdkit.h>
|
|
Packit Service |
1d8f1c |
#include <Xi18n.h>
|
|
Packit Service |
1d8f1c |
#include <stdio.h>
|
|
Packit Service |
1d8f1c |
#include <gtk/gtk.h>
|
|
Packit Service |
1d8f1c |
#include <gdk/gdk.h>
|
|
Packit Service |
1d8f1c |
#include <gdk/gdkx.h>
|
|
Packit Service |
1d8f1c |
#include <langinfo.h>
|
|
Packit Service |
1d8f1c |
#include <locale.h>
|
|
Packit Service |
1d8f1c |
#include <iconv.h>
|
|
Packit Service |
1d8f1c |
#include <signal.h>
|
|
Packit Service |
1d8f1c |
#include <stdlib.h>
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#include <getopt.h>
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#define LOG(level, fmt_args...) \
|
|
Packit Service |
1d8f1c |
if (g_debug_level >= (level)) { \
|
|
Packit Service |
1d8f1c |
g_debug (fmt_args); \
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#include <ibus.h>
|
|
Packit Service |
1d8f1c |
#include "gdk-private.h"
|
|
Packit Service |
1d8f1c |
#include "locales.h"
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
struct _X11ICONN {
|
|
Packit Service |
1d8f1c |
GList *clients;
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
typedef struct _X11ICONN X11ICONN;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
typedef struct _X11IC X11IC;
|
|
Packit Service |
1d8f1c |
struct _X11IC {
|
|
Packit Service |
1d8f1c |
IBusInputContext *context;
|
|
Packit Service |
1d8f1c |
Window client_window;
|
|
Packit Service |
1d8f1c |
Window focus_window;
|
|
Packit Service |
1d8f1c |
gint32 input_style;
|
|
Packit Service |
1d8f1c |
X11ICONN *conn;
|
|
Packit Service |
1d8f1c |
gint icid;
|
|
Packit Service |
1d8f1c |
gint connect_id;
|
|
Packit Service |
1d8f1c |
gchar *lang;
|
|
Packit Service |
1d8f1c |
gboolean has_preedit_area;
|
|
Packit Service |
1d8f1c |
GdkRectangle preedit_area;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
gchar *preedit_string;
|
|
Packit Service |
1d8f1c |
IBusAttrList *preedit_attrs;
|
|
Packit Service |
1d8f1c |
gint preedit_cursor;
|
|
Packit Service |
1d8f1c |
gboolean preedit_visible;
|
|
Packit Service |
1d8f1c |
gboolean preedit_started;
|
|
Packit Service |
1d8f1c |
gint onspot_preedit_length;
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void _xim_set_cursor_location (X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
static void _context_commit_text_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
IBusText *text,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
static void _context_forward_key_event_cb
|
|
Packit Service |
1d8f1c |
(IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
guint keyval,
|
|
Packit Service |
1d8f1c |
guint keycode,
|
|
Packit Service |
1d8f1c |
guint state,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void _context_update_preedit_text_cb
|
|
Packit Service |
1d8f1c |
(IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
IBusText *text,
|
|
Packit Service |
1d8f1c |
gint cursor_pos,
|
|
Packit Service |
1d8f1c |
gboolean visible,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
static void _context_show_preedit_text_cb
|
|
Packit Service |
1d8f1c |
(IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
static void _context_hide_preedit_text_cb
|
|
Packit Service |
1d8f1c |
(IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
static void _context_enabled_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
static void _context_disabled_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static GHashTable *_x11_ic_table = NULL;
|
|
Packit Service |
1d8f1c |
static GHashTable *_connections = NULL;
|
|
Packit Service |
1d8f1c |
static XIMS _xims = NULL;
|
|
Packit Service |
1d8f1c |
static gchar *_server_name = NULL;
|
|
Packit Service |
1d8f1c |
static gchar *_locale = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean _kill_daemon = FALSE;
|
|
Packit Service |
1d8f1c |
static gint g_debug_level = 0;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static IBusBus *_bus = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean _use_sync_mode = TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_preedit_start (XIMS xims, const X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IMPreeditStateStruct ips;
|
|
Packit Service |
1d8f1c |
ips.major_code = 0;
|
|
Packit Service |
1d8f1c |
ips.minor_code = 0;
|
|
Packit Service |
1d8f1c |
ips.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
ips.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
IMPreeditStart (xims, (XPointer)&ips;;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_preedit_end (XIMS xims, const X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IMPreeditStateStruct ips;
|
|
Packit Service |
1d8f1c |
ips.major_code = 0;
|
|
Packit Service |
1d8f1c |
ips.minor_code = 0;
|
|
Packit Service |
1d8f1c |
ips.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
ips.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
IMPreeditEnd (xims, (XPointer)&ips;;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_preedit_callback_start (XIMS xims, const X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IMPreeditCBStruct pcb;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
pcb.major_code = XIM_PREEDIT_START;
|
|
Packit Service |
1d8f1c |
pcb.minor_code = 0;
|
|
Packit Service |
1d8f1c |
pcb.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
pcb.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
pcb.todo.return_value = 0;
|
|
Packit Service |
1d8f1c |
IMCallCallback (xims, (XPointer) & pcb);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_preedit_callback_done (XIMS xims, const X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IMPreeditCBStruct pcb;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
pcb.major_code = XIM_PREEDIT_DONE;
|
|
Packit Service |
1d8f1c |
pcb.minor_code = 0;
|
|
Packit Service |
1d8f1c |
pcb.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
pcb.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
pcb.todo.return_value = 0;
|
|
Packit Service |
1d8f1c |
IMCallCallback (xims, (XPointer) & pcb);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_preedit_callback_draw (XIMS xims, X11IC *x11ic, const gchar *preedit_string, IBusAttrList *attr_list)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IMPreeditCBStruct pcb;
|
|
Packit Service |
1d8f1c |
XIMText text;
|
|
Packit Service |
1d8f1c |
XTextProperty tp;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static XIMFeedback *feedback;
|
|
Packit Service |
1d8f1c |
static gint feedback_len = 0;
|
|
Packit Service |
1d8f1c |
guint j, i, len;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (preedit_string == NULL)
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
len = g_utf8_strlen (preedit_string, -1);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (len + 1 > feedback_len) {
|
|
Packit Service |
1d8f1c |
feedback_len = (len + 1 + 63) & ~63;
|
|
Packit Service |
1d8f1c |
if (feedback) {
|
|
Packit Service |
1d8f1c |
feedback = g_renew (XIMFeedback, feedback, feedback_len);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else {
|
|
Packit Service |
1d8f1c |
feedback = g_new (XIMFeedback, feedback_len);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
for (i = 0; feedback && i < len; i++) {
|
|
Packit Service |
1d8f1c |
feedback[i] = 0;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (attr_list != NULL) {
|
|
Packit Service |
1d8f1c |
for (i = 0;; i++) {
|
|
Packit Service |
1d8f1c |
XIMFeedback attr = 0;
|
|
Packit Service |
1d8f1c |
IBusAttribute *ibus_attr = ibus_attr_list_get (attr_list, i);
|
|
Packit Service |
1d8f1c |
if (ibus_attr == NULL) {
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
switch (ibus_attr->type) {
|
|
Packit Service |
1d8f1c |
case IBUS_ATTR_TYPE_UNDERLINE:
|
|
Packit Service |
1d8f1c |
if (ibus_attr->value == IBUS_ATTR_UNDERLINE_SINGLE) {
|
|
Packit Service |
1d8f1c |
attr = XIMUnderline;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case IBUS_ATTR_TYPE_BACKGROUND:
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
if (ibus_attr->value != 0xffffff) {
|
|
Packit Service |
1d8f1c |
attr = XIMReverse;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
default:
|
|
Packit Service |
1d8f1c |
continue;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
for (j = ibus_attr->start_index; j < ibus_attr->end_index; j++) {
|
|
Packit Service |
1d8f1c |
feedback[j] |= attr;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
for (i = 0; i < len; i++) {
|
|
Packit Service |
1d8f1c |
if (feedback[i] == 0) {
|
|
Packit Service |
1d8f1c |
feedback[i] = XIMUnderline;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
feedback[len] = 0;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
pcb.major_code = XIM_PREEDIT_DRAW;
|
|
Packit Service |
1d8f1c |
pcb.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
pcb.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
pcb.todo.draw.caret = len;
|
|
Packit Service |
1d8f1c |
pcb.todo.draw.chg_first = 0;
|
|
Packit Service |
1d8f1c |
pcb.todo.draw.chg_length = x11ic->onspot_preedit_length;
|
|
Packit Service |
1d8f1c |
pcb.todo.draw.text = &tex;;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
text.feedback = feedback;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (len > 0) {
|
|
Packit Service |
1d8f1c |
Xutf8TextListToTextProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
|
Packit Service |
1d8f1c |
(char **)&preedit_string,
|
|
Packit Service |
1d8f1c |
1, XCompoundTextStyle, &tp);
|
|
Packit Service |
1d8f1c |
text.encoding_is_wchar = 0;
|
|
Packit Service |
1d8f1c |
text.length = strlen ((char*)tp.value);
|
|
Packit Service |
1d8f1c |
text.string.multi_byte = (char*)tp.value;
|
|
Packit Service |
1d8f1c |
IMCallCallback (xims, (XPointer) & pcb);
|
|
Packit Service |
1d8f1c |
XFree (tp.value);
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
text.encoding_is_wchar = 0;
|
|
Packit Service |
1d8f1c |
text.length = 0;
|
|
Packit Service |
1d8f1c |
text.string.multi_byte = "";
|
|
Packit Service |
1d8f1c |
IMCallCallback (xims, (XPointer) & pcb);
|
|
Packit Service |
1d8f1c |
len = 0;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
x11ic->onspot_preedit_length = len;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
_xim_store_ic_values (X11IC *x11ic, IMChangeICStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
XICAttribute *ic_attr = call_data->ic_attr;
|
|
Packit Service |
1d8f1c |
XICAttribute *pre_attr = call_data->preedit_attr;
|
|
Packit Service |
1d8f1c |
XICAttribute *sts_attr = call_data->status_attr;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
gint i;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
for (i = 0; i < (int)call_data->ic_attr_num; ++i, ++ic_attr) {
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (XNInputStyle, ic_attr->name) == 0) {
|
|
Packit Service |
1d8f1c |
x11ic->input_style = *(gint32 *) ic_attr->value;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (XNClientWindow, ic_attr->name) == 0) {
|
|
Packit Service |
1d8f1c |
x11ic->client_window = (Window)(*(CARD32 *) call_data->ic_attr[i].value);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (XNFocusWindow, ic_attr->name) == 0) {
|
|
Packit Service |
1d8f1c |
x11ic->focus_window = (Window)(*(CARD32 *) call_data->ic_attr[i].value);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else {
|
|
Packit Service |
1d8f1c |
LOG (1, "Unknown ic attribute: %s", ic_attr->name);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
for (i = 0; i < (int)call_data->preedit_attr_num; ++i, ++pre_attr) {
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (XNSpotLocation, pre_attr->name) == 0) {
|
|
Packit Service |
1d8f1c |
x11ic->has_preedit_area = TRUE;
|
|
Packit Service |
1d8f1c |
x11ic->preedit_area.x = ((XPoint *)pre_attr->value)->x;
|
|
Packit Service |
1d8f1c |
x11ic->preedit_area.y = ((XPoint *)pre_attr->value)->y;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else {
|
|
Packit Service |
1d8f1c |
LOG (1, "Unknown preedit attribute: %s", pre_attr->name);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
for (i=0; i< (int) call_data->status_attr_num; ++i, ++sts_attr) {
|
|
Packit Service |
1d8f1c |
LOG (1, "Unknown status attribute: %s", sts_attr->name);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
static int base_icid = 1;
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
call_data->icid = base_icid ++;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_CREATE_IC ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = g_slice_new0 (X11IC);
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic->icid = call_data->icid;
|
|
Packit Service |
1d8f1c |
x11ic->connect_id = call_data->connect_id;
|
|
Packit Service |
1d8f1c |
x11ic->conn = (X11ICONN *)g_hash_table_lookup (_connections,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->connect_id));
|
|
Packit Service |
1d8f1c |
if (x11ic->conn == NULL) {
|
|
Packit Service |
1d8f1c |
g_slice_free (X11IC, x11ic);
|
|
Packit Service |
1d8f1c |
g_return_val_if_reached (0);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_xim_store_ic_values (x11ic, call_data);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic->context = ibus_bus_create_input_context (_bus, "xim");
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->context == NULL) {
|
|
Packit Service |
1d8f1c |
g_slice_free (X11IC, x11ic);
|
|
Packit Service |
1d8f1c |
g_return_val_if_reached (0);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_signal_connect (x11ic->context, "commit-text",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_context_commit_text_cb), x11ic);
|
|
Packit Service |
1d8f1c |
g_signal_connect (x11ic->context, "forward-key-event",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_context_forward_key_event_cb), x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_signal_connect (x11ic->context, "update-preedit-text",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_context_update_preedit_text_cb), x11ic);
|
|
Packit Service |
1d8f1c |
g_signal_connect (x11ic->context, "show-preedit-text",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_context_show_preedit_text_cb), x11ic);
|
|
Packit Service |
1d8f1c |
g_signal_connect (x11ic->context, "hide-preedit-text",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_context_hide_preedit_text_cb), x11ic);
|
|
Packit Service |
1d8f1c |
g_signal_connect (x11ic->context, "enabled",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_context_enabled_cb), x11ic);
|
|
Packit Service |
1d8f1c |
g_signal_connect (x11ic->context, "disabled",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_context_disabled_cb), x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->input_style & XIMPreeditCallbacks) {
|
|
Packit Service |
1d8f1c |
ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else {
|
|
Packit Service |
1d8f1c |
ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_hash_table_insert (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER (x11ic->icid), (gpointer)x11ic);
|
|
Packit Service |
1d8f1c |
x11ic->conn->clients = g_list_append (x11ic->conn->clients,
|
|
Packit Service |
1d8f1c |
(gpointer)x11ic);
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_destroy_ic (XIMS xims, IMChangeICStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_DESTROY_IC ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = (X11IC *)g_hash_table_lookup (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->context) {
|
|
Packit Service |
1d8f1c |
ibus_proxy_destroy ((IBusProxy *)x11ic->context);
|
|
Packit Service |
1d8f1c |
g_object_unref (x11ic->context);
|
|
Packit Service |
1d8f1c |
x11ic->context = NULL;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_hash_table_remove (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
x11ic->conn->clients = g_list_remove (x11ic->conn->clients, (gconstpointer)x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_free (x11ic->preedit_string);
|
|
Packit Service |
1d8f1c |
x11ic->preedit_string = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->preedit_attrs) {
|
|
Packit Service |
1d8f1c |
g_object_unref (x11ic->preedit_attrs);
|
|
Packit Service |
1d8f1c |
x11ic->preedit_attrs = NULL;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_slice_free (X11IC, x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_SET_IC_FOCUS ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
ibus_input_context_focus_in (x11ic->context);
|
|
Packit Service |
1d8f1c |
_xim_set_cursor_location (x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_UNSET_IC_FOCUS ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
ibus_input_context_focus_out (x11ic->context);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_process_key_event_done (GObject *object,
|
|
Packit Service |
1d8f1c |
GAsyncResult *res,
|
|
Packit Service |
1d8f1c |
gpointer user_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IBusInputContext *context = (IBusInputContext *)object;
|
|
Packit Service |
1d8f1c |
IMForwardEventStruct *pfe = (IMForwardEventStruct*) user_data;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
GError *error = NULL;
|
|
Packit Service |
1d8f1c |
gboolean retval = ibus_input_context_process_key_event_async_finish (
|
|
Packit Service |
1d8f1c |
context,
|
|
Packit Service |
1d8f1c |
res,
|
|
Packit Service |
1d8f1c |
&error);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (error != NULL) {
|
|
Packit Service |
1d8f1c |
g_warning ("Process Key Event failed: %s.", error->message);
|
|
Packit Service |
1d8f1c |
g_error_free (error);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (g_hash_table_lookup (_connections,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) pfe->connect_id))
|
|
Packit Service |
1d8f1c |
== NULL) {
|
|
Packit Service |
1d8f1c |
g_slice_free (IMForwardEventStruct, pfe);
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (retval == FALSE) {
|
|
Packit Service |
1d8f1c |
IMForwardEvent (_xims, (XPointer) pfe);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_slice_free (IMForwardEventStruct, pfe);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
XKeyEvent *xevent;
|
|
Packit Service |
1d8f1c |
GdkEventKey event;
|
|
Packit Service |
1d8f1c |
gboolean retval;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_FORWARD_EVENT ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
xevent = (XKeyEvent*) &(call_data->event);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
translate_key_event (gdk_display_get_default (),
|
|
Packit Service |
1d8f1c |
(GdkEvent *)&event, (XEvent *)xevent);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
event.send_event = xevent->send_event;
|
|
Packit Service |
1d8f1c |
event.window = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (event.type == GDK_KEY_RELEASE) {
|
|
Packit Service |
1d8f1c |
event.state |= IBUS_RELEASE_MASK;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (_use_sync_mode) {
|
|
Packit Service |
1d8f1c |
retval = ibus_input_context_process_key_event (
|
|
Packit Service |
1d8f1c |
x11ic->context,
|
|
Packit Service |
1d8f1c |
event.keyval,
|
|
Packit Service |
1d8f1c |
event.hardware_keycode - 8,
|
|
Packit Service |
1d8f1c |
event.state);
|
|
Packit Service |
1d8f1c |
if (retval) {
|
|
Packit Service |
1d8f1c |
if (! x11ic->has_preedit_area) {
|
|
Packit Service |
1d8f1c |
_xim_set_cursor_location (x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
IMForwardEventStruct fe;
|
|
Packit Service |
1d8f1c |
memset (&fe, 0, sizeof (fe));
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
fe.major_code = XIM_FORWARD_EVENT;
|
|
Packit Service |
1d8f1c |
fe.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
fe.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
fe.sync_bit = 0;
|
|
Packit Service |
1d8f1c |
fe.serial_number = 0L;
|
|
Packit Service |
1d8f1c |
fe.event = call_data->event;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
IMForwardEvent (_xims, (XPointer) &fe);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
retval = 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else {
|
|
Packit Service |
1d8f1c |
IMForwardEventStruct *pfe;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
pfe = g_slice_new0 (IMForwardEventStruct);
|
|
Packit Service |
1d8f1c |
pfe->major_code = XIM_FORWARD_EVENT;
|
|
Packit Service |
1d8f1c |
pfe->icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
pfe->connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
pfe->sync_bit = 0;
|
|
Packit Service |
1d8f1c |
pfe->serial_number = 0L;
|
|
Packit Service |
1d8f1c |
pfe->event = call_data->event;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
ibus_input_context_process_key_event_async (
|
|
Packit Service |
1d8f1c |
x11ic->context,
|
|
Packit Service |
1d8f1c |
event.keyval,
|
|
Packit Service |
1d8f1c |
event.hardware_keycode - 8,
|
|
Packit Service |
1d8f1c |
event.state,
|
|
Packit Service |
1d8f1c |
-1,
|
|
Packit Service |
1d8f1c |
NULL,
|
|
Packit Service |
1d8f1c |
_process_key_event_done,
|
|
Packit Service |
1d8f1c |
pfe);
|
|
Packit Service |
1d8f1c |
retval = 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
return retval;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_open (XIMS xims, IMOpenStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11ICONN *conn;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_OPEN connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
conn = (X11ICONN *) g_hash_table_lookup (_connections,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->connect_id));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (conn == NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
conn = g_slice_new0 (X11ICONN);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_hash_table_insert (_connections,
|
|
Packit Service |
1d8f1c |
(gpointer)(unsigned long)call_data->connect_id,
|
|
Packit Service |
1d8f1c |
(gpointer) conn);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_free_ic (gpointer data, gpointer user_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic = (X11IC *) data;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_if_fail (x11ic != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_free (x11ic->preedit_string);
|
|
Packit Service |
1d8f1c |
x11ic->preedit_string = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->preedit_attrs) {
|
|
Packit Service |
1d8f1c |
g_object_unref (x11ic->preedit_attrs);
|
|
Packit Service |
1d8f1c |
x11ic->preedit_attrs = NULL;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->context) {
|
|
Packit Service |
1d8f1c |
ibus_proxy_destroy ((IBusProxy *)x11ic->context);
|
|
Packit Service |
1d8f1c |
g_object_unref (x11ic->context);
|
|
Packit Service |
1d8f1c |
x11ic->context = NULL;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* Remove the IC from g_client dictionary */
|
|
Packit Service |
1d8f1c |
g_hash_table_remove (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER (x11ic->icid));
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_slice_free (X11IC, x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
_free_x11_iconn_from_id (CARD16 connect_id)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11ICONN *conn;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
conn = (X11ICONN *) g_hash_table_lookup (_connections,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) connect_id));
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (conn == NULL) {
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_list_free_full (conn->clients, (GDestroyNotify) _free_ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_hash_table_remove (_connections,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) connect_id));
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_slice_free (X11ICONN, conn);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_close (XIMS xims, IMCloseStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
CARD16 connect_id = call_data->connect_id;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_CLOSE connect_id=%d", connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return _free_x11_iconn_from_id (connect_id);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_disconnect_ic (XIMS xims, IMDisConnectStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
CARD16 connect_id = call_data->connect_id;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_DISCONNECT connect_id=%d", connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_free_x11_iconn_from_id (connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* I am not sure if this can return 1 because I have not experienced
|
|
Packit Service |
1d8f1c |
* that xim_disconnect_ic() is called. But I wish connect_id is
|
|
Packit Service |
1d8f1c |
* released from _connections to avoid SEGV. */
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_set_cursor_location (X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_if_fail (x11ic != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
GdkRectangle preedit_area = x11ic->preedit_area;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
Window w = x11ic->focus_window ?
|
|
Packit Service |
1d8f1c |
x11ic->focus_window :x11ic->client_window;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (w) {
|
|
Packit Service |
1d8f1c |
XWindowAttributes xwa;
|
|
Packit Service |
1d8f1c |
Window child;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), w, &xwa;;
|
|
Packit Service |
1d8f1c |
if (preedit_area.x <= 0 && preedit_area.y <= 0) {
|
|
Packit Service |
1d8f1c |
XTranslateCoordinates (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), w,
|
|
Packit Service |
1d8f1c |
xwa.root,
|
|
Packit Service |
1d8f1c |
0,
|
|
Packit Service |
1d8f1c |
xwa.height,
|
|
Packit Service |
1d8f1c |
&preedit_area.x,
|
|
Packit Service |
1d8f1c |
&preedit_area.y,
|
|
Packit Service |
1d8f1c |
&child);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else {
|
|
Packit Service |
1d8f1c |
XTranslateCoordinates (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), w,
|
|
Packit Service |
1d8f1c |
xwa.root,
|
|
Packit Service |
1d8f1c |
preedit_area.x,
|
|
Packit Service |
1d8f1c |
preedit_area.y,
|
|
Packit Service |
1d8f1c |
&preedit_area.x,
|
|
Packit Service |
1d8f1c |
&preedit_area.y,
|
|
Packit Service |
1d8f1c |
&child);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
ibus_input_context_set_cursor_location (x11ic->context,
|
|
Packit Service |
1d8f1c |
preedit_area.x,
|
|
Packit Service |
1d8f1c |
preedit_area.y,
|
|
Packit Service |
1d8f1c |
preedit_area.width,
|
|
Packit Service |
1d8f1c |
preedit_area.height);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_set_ic_values (XIMS xims, IMChangeICStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
gint i;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_SET_IC_VALUES ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
i = _xim_store_ic_values (x11ic, call_data);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (i) {
|
|
Packit Service |
1d8f1c |
_xim_set_cursor_location (x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_get_ic_values (XIMS xims, IMChangeICStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
gint i;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_GET_IC_VALUES ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
XICAttribute *ic_attr = call_data->ic_attr;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
for (i = 0; i < (int) call_data->ic_attr_num; ++i, ++ic_attr) {
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (XNFilterEvents, ic_attr->name) == 0) {
|
|
Packit Service |
1d8f1c |
ic_attr->value = (void *) malloc (sizeof (CARD32));
|
|
Packit Service |
1d8f1c |
*(CARD32 *) ic_attr->value = KeyPressMask | KeyReleaseMask;
|
|
Packit Service |
1d8f1c |
ic_attr->value_length = sizeof (CARD32);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
xim_reset_ic (XIMS xims, IMResetICStruct *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
X11IC *x11ic;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_RESET_IC ic=%d connect_id=%d",
|
|
Packit Service |
1d8f1c |
call_data->icid, call_data->connect_id);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
|
|
Packit Service |
1d8f1c |
GINT_TO_POINTER ((gint) call_data->icid));
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (x11ic != NULL, 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
ibus_input_context_reset (x11ic->context);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
int
|
|
Packit Service |
1d8f1c |
ims_protocol_handler (XIMS xims, IMProtocol *call_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (xims != NULL, 1);
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (call_data != NULL, 1);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
switch (call_data->major_code) {
|
|
Packit Service |
1d8f1c |
case XIM_OPEN:
|
|
Packit Service |
1d8f1c |
return xim_open (xims, (IMOpenStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_CLOSE:
|
|
Packit Service |
1d8f1c |
return xim_close (xims, (IMCloseStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_DISCONNECT:
|
|
Packit Service |
1d8f1c |
return xim_disconnect_ic (xims, (IMDisConnectStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_CREATE_IC:
|
|
Packit Service |
1d8f1c |
return xim_create_ic (xims, (IMChangeICStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_DESTROY_IC:
|
|
Packit Service |
1d8f1c |
return xim_destroy_ic (xims, (IMChangeICStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_SET_IC_VALUES:
|
|
Packit Service |
1d8f1c |
return xim_set_ic_values (xims, (IMChangeICStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_GET_IC_VALUES:
|
|
Packit Service |
1d8f1c |
return xim_get_ic_values (xims, (IMChangeICStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_FORWARD_EVENT:
|
|
Packit Service |
1d8f1c |
return xim_forward_event (xims, (IMForwardEventStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_SET_IC_FOCUS:
|
|
Packit Service |
1d8f1c |
return xim_set_ic_focus (xims, (IMChangeFocusStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_UNSET_IC_FOCUS:
|
|
Packit Service |
1d8f1c |
return xim_unset_ic_focus (xims, (IMChangeFocusStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_RESET_IC:
|
|
Packit Service |
1d8f1c |
return xim_reset_ic (xims, (IMResetICStruct *)call_data);
|
|
Packit Service |
1d8f1c |
case XIM_TRIGGER_NOTIFY:
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_TRIGGER_NOTIFY");
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
case XIM_PREEDIT_START_REPLY:
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_PREEDIT_START_REPLY");
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
case XIM_PREEDIT_CARET_REPLY:
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_PREEDIT_CARET_REPLY");
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
case XIM_SYNC_REPLY:
|
|
Packit Service |
1d8f1c |
LOG (1, "XIM_SYNC_REPLY");
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
default:
|
|
Packit Service |
1d8f1c |
LOG (1, "Unknown (%d)", call_data->major_code);
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_forward_key_event (X11IC *x11ic,
|
|
Packit Service |
1d8f1c |
guint keyval,
|
|
Packit Service |
1d8f1c |
guint keycode,
|
|
Packit Service |
1d8f1c |
guint state)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_if_fail (x11ic != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
IMForwardEventStruct fe = {0};
|
|
Packit Service |
1d8f1c |
XEvent xkp = {0};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
xkp.xkey.type = (state & IBUS_RELEASE_MASK) ? KeyRelease : KeyPress;
|
|
Packit Service |
1d8f1c |
xkp.xkey.serial = 0L;
|
|
Packit Service |
1d8f1c |
xkp.xkey.send_event = False;
|
|
Packit Service |
1d8f1c |
xkp.xkey.same_screen = True;
|
|
Packit Service |
1d8f1c |
xkp.xkey.display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
|
Packit Service |
1d8f1c |
xkp.xkey.window =
|
|
Packit Service |
1d8f1c |
x11ic->focus_window ? x11ic->focus_window : x11ic->client_window;
|
|
Packit Service |
1d8f1c |
xkp.xkey.subwindow = None;
|
|
Packit Service |
1d8f1c |
xkp.xkey.root = DefaultRootWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
xkp.xkey.time = 0;
|
|
Packit Service |
1d8f1c |
xkp.xkey.state = state;
|
|
Packit Service |
1d8f1c |
xkp.xkey.keycode = (keycode == 0) ? 0 : keycode + 8;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
fe.major_code = XIM_FORWARD_EVENT;
|
|
Packit Service |
1d8f1c |
fe.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
fe.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
fe.sync_bit = 0;
|
|
Packit Service |
1d8f1c |
fe.serial_number = 0L;
|
|
Packit Service |
1d8f1c |
fe.event = xkp;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
IMForwardEvent (_xims, (XPointer) & fe);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_bus_disconnected_cb (IBusBus *bus,
|
|
Packit Service |
1d8f1c |
gpointer user_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_warning ("Connection closed by ibus-daemon");
|
|
Packit Service |
1d8f1c |
g_object_unref (_bus);
|
|
Packit Service |
1d8f1c |
_bus = NULL;
|
|
Packit Service |
1d8f1c |
exit(EXIT_SUCCESS);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_context_commit_text_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
IBusText *text,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_INPUT_CONTEXT (context));
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_TEXT (text));
|
|
Packit Service |
1d8f1c |
g_assert (x11ic != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
XTextProperty tp;
|
|
Packit Service |
1d8f1c |
IMCommitStruct cms = {0};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
Xutf8TextListToTextProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
|
Packit Service |
1d8f1c |
(gchar **)&(text->text), 1, XCompoundTextStyle, &tp);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
cms.major_code = XIM_COMMIT;
|
|
Packit Service |
1d8f1c |
cms.icid = x11ic->icid;
|
|
Packit Service |
1d8f1c |
cms.connect_id = x11ic->connect_id;
|
|
Packit Service |
1d8f1c |
cms.flag = XimLookupChars;
|
|
Packit Service |
1d8f1c |
cms.commit_string = (gchar *)tp.value;
|
|
Packit Service |
1d8f1c |
IMCommitString (_xims, (XPointer) & cms);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
XFree (tp.value);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_context_forward_key_event_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
guint keyval,
|
|
Packit Service |
1d8f1c |
guint keycode,
|
|
Packit Service |
1d8f1c |
guint state,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_xim_forward_key_event (x11ic, keyval, keycode, state);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_update_preedit (X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
if (x11ic->preedit_visible == FALSE && x11ic->preedit_started == TRUE) {
|
|
Packit Service |
1d8f1c |
_xim_preedit_callback_draw (_xims, x11ic, "", NULL);
|
|
Packit Service |
1d8f1c |
_xim_preedit_callback_done (_xims, x11ic);
|
|
Packit Service |
1d8f1c |
x11ic->preedit_started = FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->preedit_visible == TRUE && x11ic->preedit_started == FALSE) {
|
|
Packit Service |
1d8f1c |
_xim_preedit_callback_start (_xims, x11ic);
|
|
Packit Service |
1d8f1c |
x11ic->preedit_started = TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (x11ic->preedit_visible == TRUE) {
|
|
Packit Service |
1d8f1c |
_xim_preedit_callback_draw (_xims, x11ic,
|
|
Packit Service |
1d8f1c |
x11ic->preedit_string, x11ic->preedit_attrs);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_context_update_preedit_text_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
IBusText *text,
|
|
Packit Service |
1d8f1c |
gint cursor_pos,
|
|
Packit Service |
1d8f1c |
gboolean visible,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_INPUT_CONTEXT (context));
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_TEXT (text));
|
|
Packit Service |
1d8f1c |
g_assert (x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->preedit_string) {
|
|
Packit Service |
1d8f1c |
g_free(x11ic->preedit_string);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
x11ic->preedit_string = g_strdup(text->text);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (x11ic->preedit_attrs) {
|
|
Packit Service |
1d8f1c |
g_object_unref (x11ic->preedit_attrs);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_object_ref(text->attrs);
|
|
Packit Service |
1d8f1c |
x11ic->preedit_attrs = text->attrs;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic->preedit_cursor = cursor_pos;
|
|
Packit Service |
1d8f1c |
x11ic->preedit_visible = visible;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_update_preedit (x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_context_show_preedit_text_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_INPUT_CONTEXT (context));
|
|
Packit Service |
1d8f1c |
g_assert (x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic->preedit_visible = TRUE;
|
|
Packit Service |
1d8f1c |
_update_preedit (x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_context_hide_preedit_text_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_INPUT_CONTEXT (context));
|
|
Packit Service |
1d8f1c |
g_assert (x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
x11ic->preedit_visible = FALSE;
|
|
Packit Service |
1d8f1c |
_update_preedit (x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_context_enabled_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_INPUT_CONTEXT (context));
|
|
Packit Service |
1d8f1c |
g_assert (x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_xim_preedit_start (_xims, x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_context_disabled_cb (IBusInputContext *context,
|
|
Packit Service |
1d8f1c |
X11IC *x11ic)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (IBUS_IS_INPUT_CONTEXT (context));
|
|
Packit Service |
1d8f1c |
g_assert (x11ic);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_xim_preedit_end (_xims, x11ic);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
_get_boolean_env(const gchar *name,
|
|
Packit Service |
1d8f1c |
gboolean defval)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
const gchar *value = g_getenv (name);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (value == NULL)
|
|
Packit Service |
1d8f1c |
return defval;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (value, "") == 0 ||
|
|
Packit Service |
1d8f1c |
g_strcmp0 (value, "0") == 0 ||
|
|
Packit Service |
1d8f1c |
g_strcmp0 (value, "false") == 0 ||
|
|
Packit Service |
1d8f1c |
g_strcmp0 (value, "False") == 0 ||
|
|
Packit Service |
1d8f1c |
g_strcmp0 (value, "FALSE") == 0)
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_init_ibus (void)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
if (_bus != NULL)
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
ibus_init ();
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_bus = ibus_bus_new ();
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_signal_connect (_bus, "disconnected",
|
|
Packit Service |
1d8f1c |
G_CALLBACK (_bus_disconnected_cb), NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* https://github.com/ibus/ibus/issues/1713 */
|
|
Packit Service |
1d8f1c |
_use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", TRUE);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_xim_init_IMdkit ()
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
#if 0
|
|
Packit Service |
1d8f1c |
XIMStyle ims_styles_overspot [] = {
|
|
Packit Service |
1d8f1c |
XIMPreeditPosition | XIMStatusNothing,
|
|
Packit Service |
1d8f1c |
XIMPreeditNothing | XIMStatusNothing,
|
|
Packit Service |
1d8f1c |
XIMPreeditPosition | XIMStatusCallbacks,
|
|
Packit Service |
1d8f1c |
XIMPreeditNothing | XIMStatusCallbacks,
|
|
Packit Service |
1d8f1c |
0
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
XIMStyle ims_styles_onspot [] = {
|
|
Packit Service |
1d8f1c |
XIMPreeditPosition | XIMStatusNothing,
|
|
Packit Service |
1d8f1c |
XIMPreeditCallbacks | XIMStatusNothing,
|
|
Packit Service |
1d8f1c |
XIMPreeditNothing | XIMStatusNothing,
|
|
Packit Service |
1d8f1c |
XIMPreeditPosition | XIMStatusCallbacks,
|
|
Packit Service |
1d8f1c |
XIMPreeditCallbacks | XIMStatusCallbacks,
|
|
Packit Service |
1d8f1c |
XIMPreeditNothing | XIMStatusCallbacks,
|
|
Packit Service |
1d8f1c |
0
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
XIMEncoding ims_encodings[] = {
|
|
Packit Service |
1d8f1c |
"COMPOUND_TEXT",
|
|
Packit Service |
1d8f1c |
0
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
GdkWindowAttr window_attr = {
|
|
Packit Service |
1d8f1c |
.title = "ibus-xim",
|
|
Packit Service |
1d8f1c |
.event_mask = GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
|
|
Packit Service |
1d8f1c |
.wclass = GDK_INPUT_OUTPUT,
|
|
Packit Service |
1d8f1c |
.window_type = GDK_WINDOW_TOPLEVEL,
|
|
Packit Service |
1d8f1c |
.override_redirect = 1,
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
XIMStyles styles;
|
|
Packit Service |
1d8f1c |
XIMEncodings encodings;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
GdkWindow *win;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
win = gdk_window_new (NULL, &window_attr, GDK_WA_TITLE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
styles.count_styles =
|
|
Packit Service |
1d8f1c |
sizeof (ims_styles_onspot)/sizeof (XIMStyle) - 1;
|
|
Packit Service |
1d8f1c |
styles.supported_styles = ims_styles_onspot;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
encodings.count_encodings =
|
|
Packit Service |
1d8f1c |
sizeof (ims_encodings)/sizeof (XIMEncoding) - 1;
|
|
Packit Service |
1d8f1c |
encodings.supported_encodings = ims_encodings;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_xims = IMOpenIM (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
|
Packit Service |
1d8f1c |
IMModifiers, "Xi18n",
|
|
Packit Service |
1d8f1c |
#if GTK_CHECK_VERSION (3, 0, 0)
|
|
Packit Service |
1d8f1c |
IMServerWindow, GDK_WINDOW_XID (win),
|
|
Packit Service |
1d8f1c |
#else
|
|
Packit Service |
1d8f1c |
IMServerWindow, GDK_WINDOW_XWINDOW (win),
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
IMServerName, _server_name != NULL ? _server_name : "ibus",
|
|
Packit Service |
1d8f1c |
IMLocale, _locale != NULL ? _locale : LOCALES_STRING,
|
|
Packit Service |
1d8f1c |
IMServerTransport, "X/",
|
|
Packit Service |
1d8f1c |
IMInputStyles, &styles,
|
|
Packit Service |
1d8f1c |
IMEncodingList, &encodings,
|
|
Packit Service |
1d8f1c |
IMProtocolHandler, ims_protocol_handler,
|
|
Packit Service |
1d8f1c |
IMFilterEventMask, KeyPressMask | KeyReleaseMask,
|
|
Packit Service |
1d8f1c |
NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_init_ibus ();
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (!ibus_bus_is_connected (_bus)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Can not connect to ibus daemon");
|
|
Packit Service |
1d8f1c |
exit (EXIT_FAILURE);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_atexit_cb ()
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
if (_bus && ibus_bus_is_connected (_bus)) {
|
|
Packit Service |
1d8f1c |
ibus_bus_exit(_bus, False);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_sighandler (int sig)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
exit(EXIT_FAILURE);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
_print_usage (FILE *fp, gchar *name)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
fprintf (fp,
|
|
Packit Service |
1d8f1c |
"Usage:\n"
|
|
Packit Service |
1d8f1c |
" %s --help Show this message\n"
|
|
Packit Service |
1d8f1c |
" --server-name= -n Setup xim sevrer name\n"
|
|
Packit Service |
1d8f1c |
" --locale= -l Setup support locales\n"
|
|
Packit Service |
1d8f1c |
" --locale-append= -a Append locales into the default support locales\n"
|
|
Packit Service |
1d8f1c |
" --kill-daemon -k Kill ibus daemon when exit\n"
|
|
Packit Service |
1d8f1c |
" --debug= -v Setup debug level\n",
|
|
Packit Service |
1d8f1c |
name);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
_xerror_handler (Display *dpy, XErrorEvent *e)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_debug (
|
|
Packit Service |
1d8f1c |
"XError: "
|
|
Packit Service |
1d8f1c |
"serial=%lu error_code=%d request_code=%d minor_code=%d resourceid=%lu",
|
|
Packit Service |
1d8f1c |
e->serial, e->error_code, e->request_code, e->minor_code, e->resourceid);
|
|
Packit Service |
1d8f1c |
return 1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* When log into GNOME3 desktop immediately after the system is booted,
|
|
Packit Service |
1d8f1c |
* ibus-daemon is sometimes alive but ibus-x11 is dead after log out
|
|
Packit Service |
1d8f1c |
* the session. Because gdk_x_io_error() is called as the callback of
|
|
Packit Service |
1d8f1c |
* XSetIOErrorHandler() in gtk/gdk/x11/gdkmain-x11.c in ibus-x11.
|
|
Packit Service |
1d8f1c |
* Now I assume the callback is called in logout.
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
static int
|
|
Packit Service |
1d8f1c |
_xerror_io_handler (Display *dpy)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
if (_kill_daemon)
|
|
Packit Service |
1d8f1c |
_atexit_cb ();
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
int
|
|
Packit Service |
1d8f1c |
main (int argc, char **argv)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gint option_index = 0;
|
|
Packit Service |
1d8f1c |
gint c;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* GDK_DISPLAY_XDISPLAY() and GDK_WINDOW_XID() does not work
|
|
Packit Service |
1d8f1c |
* with GdkWaylandDisplay.
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
#if GTK_CHECK_VERSION (3, 10, 0)
|
|
Packit Service |
1d8f1c |
gdk_set_allowed_backends ("x11");
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
gtk_init (&argc, &argv);
|
|
Packit Service |
1d8f1c |
XSetErrorHandler (_xerror_handler);
|
|
Packit Service |
1d8f1c |
XSetIOErrorHandler (_xerror_io_handler);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
while (1) {
|
|
Packit Service |
1d8f1c |
static struct option long_options [] = {
|
|
Packit Service |
1d8f1c |
{ "debug", 1, 0, 0},
|
|
Packit Service |
1d8f1c |
{ "server-name", 1, 0, 0},
|
|
Packit Service |
1d8f1c |
{ "locale", 1, 0, 0},
|
|
Packit Service |
1d8f1c |
{ "locale-append", 1, 0, 0},
|
|
Packit Service |
1d8f1c |
{ "help", 0, 0, 0},
|
|
Packit Service |
1d8f1c |
{ "kill-daemon", 0, 0, 0},
|
|
Packit Service |
1d8f1c |
{ 0, 0, 0, 0},
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
c = getopt_long (argc, argv, "v:n:l:k:a",
|
|
Packit Service |
1d8f1c |
long_options, &option_index);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (c == -1) break;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
switch (c) {
|
|
Packit Service |
1d8f1c |
case 0:
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (long_options[option_index].name, "debug") == 0) {
|
|
Packit Service |
1d8f1c |
g_debug_level = atoi (optarg);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (long_options[option_index].name, "server-name") == 0) {
|
|
Packit Service |
1d8f1c |
g_free (_server_name);
|
|
Packit Service |
1d8f1c |
_server_name = g_strdup (optarg);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (long_options[option_index].name, "locale") == 0) {
|
|
Packit Service |
1d8f1c |
g_free (_locale);
|
|
Packit Service |
1d8f1c |
_locale = g_strdup (optarg);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (long_options[option_index].name, "locale-append") == 0) {
|
|
Packit Service |
1d8f1c |
gchar *tmp = g_strdup_printf ("%s,%s",
|
|
Packit Service |
1d8f1c |
_locale != NULL ? _locale : LOCALES_STRING, optarg);
|
|
Packit Service |
1d8f1c |
g_free (_locale);
|
|
Packit Service |
1d8f1c |
_locale = tmp;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (long_options[option_index].name, "help") == 0) {
|
|
Packit Service |
1d8f1c |
_print_usage (stdout, argv[0]);
|
|
Packit Service |
1d8f1c |
exit (EXIT_SUCCESS);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (long_options[option_index].name, "kill-daemon") == 0) {
|
|
Packit Service |
1d8f1c |
_kill_daemon = TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case 'v':
|
|
Packit Service |
1d8f1c |
g_debug_level = atoi (optarg);
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case 'n':
|
|
Packit Service |
1d8f1c |
g_free (_server_name);
|
|
Packit Service |
1d8f1c |
_server_name = g_strdup (optarg);
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case 'l':
|
|
Packit Service |
1d8f1c |
g_free (_locale);
|
|
Packit Service |
1d8f1c |
_locale = g_strdup (optarg);
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case 'a': {
|
|
Packit Service |
1d8f1c |
gchar *tmp = g_strdup_printf ("%s,%s",
|
|
Packit Service |
1d8f1c |
_locale != NULL ? _locale : LOCALES_STRING, optarg);
|
|
Packit Service |
1d8f1c |
g_free (_locale);
|
|
Packit Service |
1d8f1c |
_locale = tmp;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case 'k':
|
|
Packit Service |
1d8f1c |
_kill_daemon = TRUE;
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case '?':
|
|
Packit Service |
1d8f1c |
default:
|
|
Packit Service |
1d8f1c |
_print_usage (stderr, argv[0]);
|
|
Packit Service |
1d8f1c |
exit (EXIT_FAILURE);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_x11_ic_table = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
Packit Service |
1d8f1c |
_connections = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
signal (SIGINT, _sighandler);
|
|
Packit Service |
1d8f1c |
signal (SIGTERM, _sighandler);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (_kill_daemon)
|
|
Packit Service |
1d8f1c |
atexit (_atexit_cb);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
_xim_init_IMdkit ();
|
|
Packit Service |
1d8f1c |
gtk_main();
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
exit (EXIT_SUCCESS);
|
|
Packit Service |
1d8f1c |
}
|