implement pre-edit input method
* src/termhooks.h (enum event_kind): new pgtk value * src/pgtkterm.h (struct pgtk_display_info): * src/pgtkterm.c (x_free_frame_resources, pgtk_delete_terminal) (pgtk_enqueue_string, pgtk_enqueue_preedit, key_press_event) (focus_in_event, focus_out_event, pgtk_term_init): call pgtkim * src/pgtkim.c: new file (im_context_commit_cb, im_context_retrieve_surrounding_cb) (make_color_string, im_context_preedit_changed_cb) (im_context_preedit_end_cb, im_context_preedit_start_cb) (pgtk_im_focus_in, pgtk_im_focus_out, pgtk_im_filter_keypress) (pgtk_im_finish, Fpgtk_use_im_context, syms_of_pgtkim): * src/pgtkfns.c (check_pgtk_display_info): * src/keyboard.c (kbd_buffer_get_event, make_lispy_event) (keys_of_keyboard): * src/emacs.c (main): add syms_of_pgtkim * lisp/term/pgtk-win.el (pgtk-preedit-text): new defun * configure.ac (XWIDGETS_OBJ): add pgtkim.o input method 対応 preedit を overlay で表示するようにした。 preedit 表示後すぐに反映されなかったのを修正 この機能を ON/OFF できるようにした。 default off. 確定と同時に次の preedit が始まった場合に表示位置がおかしかったのを修正。 sample. preedit をテキストで渡すようにした
This commit is contained in:
parent
9e56fa9853
commit
232c129fe4
9 changed files with 367 additions and 2 deletions
|
@ -2830,7 +2830,7 @@ LIBS=$OLD_LIBS
|
|||
PGTK_OBJ=
|
||||
PGTK_LIBS=
|
||||
if test "$window_system" = "pgtk"; then
|
||||
PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o pgtkmenu.o xsettings.o"
|
||||
PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o pgtkmenu.o pgtkim.o xsettings.o"
|
||||
PGTK_LIBS="$GTK_LIBS -ldl"
|
||||
AC_DEFINE([HAVE_PGTK], 1, [Define to 1 if you have pure Gtk+-3.])
|
||||
fi
|
||||
|
|
|
@ -368,6 +368,39 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
|
|||
&context (window-system pgtk))
|
||||
(pgtk-get-selection-internal selection-symbol target-type))
|
||||
|
||||
|
||||
(defvar pgtk-preedit-overlay nil)
|
||||
|
||||
(defun pgtk-preedit-text (e)
|
||||
(interactive "e")
|
||||
(when pgtk-preedit-overlay
|
||||
(delete-overlay pgtk-preedit-overlay))
|
||||
(setq pgtk-preedit-overlay nil)
|
||||
|
||||
(let ((ovstr "")
|
||||
(idx 0)
|
||||
atts ov str color face-name)
|
||||
(dolist (part (nth 1 e))
|
||||
(setq str (car part))
|
||||
(setq face-name (intern (format "pgtk-im-%d" idx)))
|
||||
(eval
|
||||
`(defface ,face-name nil "face of input method preedit"))
|
||||
(setq atts nil)
|
||||
(when (setq color (cdr-safe (assq 'fg (cdr part))))
|
||||
(setq atts (append atts `(:foreground ,color))))
|
||||
(when (setq color (cdr-safe (assq 'bg (cdr part))))
|
||||
(setq atts (append atts `(:background ,color))))
|
||||
(when (setq color (cdr-safe (assq 'ul (cdr part))))
|
||||
(setq atts (append atts `(:underline ,color))))
|
||||
(face-spec-set face-name `((t . ,atts)))
|
||||
(add-text-properties 0 (length str) `(face ,face-name) str)
|
||||
(setq ovstr (concat ovstr str))
|
||||
(setq idx (1+ idx)))
|
||||
|
||||
(setq ov (make-overlay (point) (point)))
|
||||
(overlay-put ov 'before-string ovstr)
|
||||
(setq pgtk-preedit-overlay ov)))
|
||||
|
||||
(provide 'pgtk-win)
|
||||
(provide 'term/pgtk-win)
|
||||
|
||||
|
|
|
@ -1922,6 +1922,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
syms_of_pgtkfns();
|
||||
syms_of_pgtkselect ();
|
||||
syms_of_pgtkmenu ();
|
||||
syms_of_pgtkim ();
|
||||
syms_of_fontset ();
|
||||
syms_of_xsettings ();
|
||||
syms_of_xwidget ();
|
||||
|
|
|
@ -3939,6 +3939,9 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
*used_mouse_menu = true;
|
||||
FALLTHROUGH;
|
||||
#endif
|
||||
#ifdef HAVE_PGTK
|
||||
case PGTK_PREEDIT_TEXT_EVENT:
|
||||
#endif
|
||||
#ifdef HAVE_NTGUI
|
||||
case END_SESSION_EVENT:
|
||||
case LANGUAGE_CHANGE_EVENT:
|
||||
|
@ -6047,6 +6050,11 @@ make_lispy_event (struct input_event *event)
|
|||
return list3 (Qconfig_changed_event,
|
||||
event->arg, event->frame_or_window);
|
||||
|
||||
#ifdef HAVE_PGTK
|
||||
case PGTK_PREEDIT_TEXT_EVENT:
|
||||
return list2 (intern("pgtk-preedit-text"), event->arg);
|
||||
#endif
|
||||
|
||||
/* The 'kind' field of the event is something we don't recognize. */
|
||||
default:
|
||||
emacs_abort ();
|
||||
|
@ -12451,6 +12459,8 @@ keys_of_keyboard (void)
|
|||
"ns-put-working-text");
|
||||
initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text",
|
||||
"ns-unput-working-text");
|
||||
initial_define_lispy_key (Vspecial_event_map, "pgtk-preedit-text",
|
||||
"pgtk-preedit-text");
|
||||
/* Here we used to use `ignore-event' which would simple set prefix-arg to
|
||||
current-prefix-arg, as is done in `handle-switch-frame'.
|
||||
But `handle-switch-frame is not run from the special-map.
|
||||
|
|
|
@ -60,7 +60,7 @@ static const char *pgtk_app_name = "Emacs";
|
|||
|
||||
========================================================================== */
|
||||
|
||||
static struct pgtk_display_info *
|
||||
struct pgtk_display_info *
|
||||
check_pgtk_display_info (Lisp_Object object)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = NULL;
|
||||
|
|
243
src/pgtkim.c
Normal file
243
src/pgtkim.c
Normal file
|
@ -0,0 +1,243 @@
|
|||
/* Pure Gtk+-3 communication module. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2018 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This should be the first include, as it may set up #defines affecting
|
||||
interpretation of even the system includes. */
|
||||
#include <config.h>
|
||||
|
||||
#include "pgtkterm.h"
|
||||
|
||||
static void im_context_commit_cb(GtkIMContext *imc, gchar *str, gpointer user_data)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = user_data;
|
||||
struct frame *f = dpyinfo->im.focused_frame;
|
||||
|
||||
if (dpyinfo->im.context == NULL)
|
||||
return;
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
pgtk_enqueue_string(f, str);
|
||||
}
|
||||
|
||||
static gboolean im_context_retrieve_surrounding_cb(GtkIMContext *imc, gpointer user_data)
|
||||
{
|
||||
gtk_im_context_set_surrounding(imc, "", -1, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean im_context_delete_surrounding_cb(GtkIMContext *imc, int offset, int n_chars, gpointer user_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Lisp_Object make_color_string(PangoAttrColor *pac)
|
||||
{
|
||||
char buf[256];
|
||||
sprintf(buf, "#%02x%02x%02x",
|
||||
pac->color.red >> 8,
|
||||
pac->color.green >> 8,
|
||||
pac->color.blue >> 8);
|
||||
return build_string(buf);
|
||||
}
|
||||
|
||||
static void im_context_preedit_changed_cb(GtkIMContext *imc, gpointer user_data)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = user_data;
|
||||
struct frame *f = dpyinfo->im.focused_frame;
|
||||
char *str;
|
||||
PangoAttrList *attrs;
|
||||
int pos;
|
||||
|
||||
if (dpyinfo->im.context == NULL)
|
||||
return;
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
gtk_im_context_get_preedit_string(imc, &str, &attrs, &pos);
|
||||
|
||||
|
||||
/*
|
||||
* (
|
||||
* (TEXT (ul . COLOR) (bg . COLOR) (fg . COLOR))
|
||||
* ...
|
||||
* )
|
||||
*/
|
||||
Lisp_Object list = Qnil;
|
||||
|
||||
PangoAttrIterator* iter;
|
||||
iter = pango_attr_list_get_iterator(attrs);
|
||||
do {
|
||||
int st, ed;
|
||||
int has_underline = 0;
|
||||
Lisp_Object part = Qnil;
|
||||
|
||||
pango_attr_iterator_range(iter, &st, &ed);
|
||||
|
||||
if (ed > strlen(str))
|
||||
ed = strlen(str);
|
||||
if (st >= ed)
|
||||
continue;
|
||||
|
||||
Lisp_Object text = make_string(str + st, ed - st);
|
||||
part = Fcons(text, part);
|
||||
|
||||
PangoAttrInt *ul = (PangoAttrInt *) pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
|
||||
if (ul != NULL) {
|
||||
if (ul->value != PANGO_UNDERLINE_NONE)
|
||||
has_underline = 1;
|
||||
}
|
||||
|
||||
PangoAttrColor *pac;
|
||||
if (has_underline) {
|
||||
pac = (PangoAttrColor *) pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE_COLOR);
|
||||
if (pac != NULL)
|
||||
part = Fcons(Fcons(Qul, make_color_string(pac)), part);
|
||||
else
|
||||
part = Fcons(Fcons(Qul, Qt), part);
|
||||
}
|
||||
|
||||
pac = (PangoAttrColor *) pango_attr_iterator_get(iter, PANGO_ATTR_FOREGROUND);
|
||||
if (pac != NULL)
|
||||
part = Fcons(Fcons(Qfg, make_color_string(pac)), part);
|
||||
|
||||
pac = (PangoAttrColor *) pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND);
|
||||
if (pac != NULL)
|
||||
part = Fcons(Fcons(Qbg, make_color_string(pac)), part);
|
||||
|
||||
part = Fnreverse(part);
|
||||
list = Fcons(part, list);
|
||||
} while (pango_attr_iterator_next(iter));
|
||||
|
||||
list = Fnreverse(list);
|
||||
pgtk_enqueue_preedit(f, list);
|
||||
|
||||
g_free(str);
|
||||
pango_attr_list_unref(attrs);
|
||||
}
|
||||
|
||||
static void im_context_preedit_end_cb(GtkIMContext *imc, gpointer user_data)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = user_data;
|
||||
struct frame *f = dpyinfo->im.focused_frame;
|
||||
|
||||
if (dpyinfo->im.context == NULL)
|
||||
return;
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
pgtk_enqueue_preedit(f, Qnil);
|
||||
}
|
||||
|
||||
static void im_context_preedit_start_cb(GtkIMContext *imc, gpointer user_data)
|
||||
{
|
||||
}
|
||||
|
||||
void pgtk_im_focus_in(struct frame *f)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
if (dpyinfo->im.context != NULL) {
|
||||
gtk_im_context_reset (dpyinfo->im.context);
|
||||
gtk_im_context_set_client_window (dpyinfo->im.context, gtk_widget_get_window (FRAME_GTK_WIDGET (f)));
|
||||
gtk_im_context_focus_in (dpyinfo->im.context);
|
||||
}
|
||||
dpyinfo->im.focused_frame = f;
|
||||
}
|
||||
|
||||
void pgtk_im_focus_out(struct frame *f)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
if (dpyinfo->im.focused_frame == f) {
|
||||
if (dpyinfo->im.context != NULL) {
|
||||
gtk_im_context_reset (dpyinfo->im.context);
|
||||
gtk_im_context_focus_out (dpyinfo->im.context);
|
||||
gtk_im_context_set_client_window (dpyinfo->im.context, NULL);
|
||||
}
|
||||
dpyinfo->im.focused_frame = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool pgtk_im_filter_keypress(struct frame *f, GdkEventKey *ev)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
if (dpyinfo->im.context != NULL) {
|
||||
if (gtk_im_context_filter_keypress (dpyinfo->im.context, ev))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void pgtk_im_init(struct pgtk_display_info *dpyinfo)
|
||||
{
|
||||
dpyinfo->im.context = NULL;
|
||||
}
|
||||
|
||||
void pgtk_im_finish(struct pgtk_display_info *dpyinfo)
|
||||
{
|
||||
if (dpyinfo->im.context != NULL)
|
||||
g_object_unref(dpyinfo->im.context);
|
||||
dpyinfo->im.context = NULL;
|
||||
}
|
||||
|
||||
DEFUN ("pgtk-use-im-context", Fpgtk_use_im_context, Spgtk_use_im_context,
|
||||
1, 2, 0,
|
||||
doc: /* Set whether use Gtk's im context. */)
|
||||
(Lisp_Object use_p, Lisp_Object terminal)
|
||||
{
|
||||
struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
|
||||
|
||||
if (NILP(use_p)) {
|
||||
if (dpyinfo->im.context != NULL) {
|
||||
gtk_im_context_reset (dpyinfo->im.context);
|
||||
gtk_im_context_focus_out (dpyinfo->im.context);
|
||||
gtk_im_context_set_client_window (dpyinfo->im.context, NULL);
|
||||
|
||||
g_object_unref(dpyinfo->im.context);
|
||||
dpyinfo->im.context = NULL;
|
||||
}
|
||||
} else {
|
||||
if (dpyinfo->im.context == NULL) {
|
||||
dpyinfo->im.context = gtk_im_multicontext_new();
|
||||
g_signal_connect(dpyinfo->im.context, "commit", G_CALLBACK(im_context_commit_cb), dpyinfo);
|
||||
g_signal_connect(dpyinfo->im.context, "retrieve-surrounding", G_CALLBACK(im_context_retrieve_surrounding_cb), dpyinfo);
|
||||
g_signal_connect(dpyinfo->im.context, "delete-surrounding", G_CALLBACK(im_context_delete_surrounding_cb), dpyinfo);
|
||||
g_signal_connect(dpyinfo->im.context, "preedit-changed", G_CALLBACK(im_context_preedit_changed_cb), dpyinfo);
|
||||
g_signal_connect(dpyinfo->im.context, "preedit-end", G_CALLBACK(im_context_preedit_end_cb), dpyinfo);
|
||||
g_signal_connect(dpyinfo->im.context, "preedit-start", G_CALLBACK(im_context_preedit_start_cb), dpyinfo);
|
||||
gtk_im_context_set_use_preedit (dpyinfo->im.context, TRUE);
|
||||
|
||||
if (dpyinfo->im.focused_frame)
|
||||
pgtk_im_focus_in(dpyinfo->im.focused_frame);
|
||||
}
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_pgtkim (void)
|
||||
{
|
||||
defsubr (&Spgtk_use_im_context);
|
||||
|
||||
DEFSYM (Qpgtk_refresh_preedit, "pgtk-refresh-preedit");
|
||||
DEFSYM (Qul, "ul");
|
||||
DEFSYM (Qfg, "fg");
|
||||
DEFSYM (Qbg, "bg");
|
||||
}
|
|
@ -188,6 +188,7 @@ x_free_frame_resources (struct frame *f)
|
|||
CLEAR_IF_EQ(last_mouse_frame);
|
||||
CLEAR_IF_EQ(last_mouse_motion_frame);
|
||||
CLEAR_IF_EQ(last_mouse_glyph_frame);
|
||||
CLEAR_IF_EQ(im.focused_frame);
|
||||
|
||||
#undef CLEAR_IF_EQ
|
||||
|
||||
|
@ -4282,6 +4283,8 @@ pgtk_delete_terminal (struct terminal *terminal)
|
|||
|
||||
block_input ();
|
||||
|
||||
pgtk_im_finish (dpyinfo);
|
||||
|
||||
/* Normally, the display is available... */
|
||||
if (dpyinfo->gdpy)
|
||||
{
|
||||
|
@ -4952,6 +4955,45 @@ pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info *dpyinfo, int state)
|
|||
#define IsKeypadKey(keysym) (0xff80 <= (keysym) && (keysym) < 0xffbe)
|
||||
#define IsFunctionKey(keysym) (0xffbe <= (keysym) && (keysym) < 0xffe1)
|
||||
|
||||
void
|
||||
pgtk_enqueue_string(struct frame *f, gchar *str)
|
||||
{
|
||||
gunichar *ustr;
|
||||
|
||||
ustr = g_utf8_to_ucs4 (str, -1, NULL, NULL, NULL);
|
||||
if (ustr == NULL)
|
||||
return;
|
||||
for ( ; *ustr != 0; ustr++) {
|
||||
union buffered_input_event inev;
|
||||
Lisp_Object c = make_fixnum (*ustr);
|
||||
EVENT_INIT (inev.ie);
|
||||
inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
|
||||
? ASCII_KEYSTROKE_EVENT
|
||||
: MULTIBYTE_CHAR_KEYSTROKE_EVENT);
|
||||
inev.ie.arg = Qnil;
|
||||
inev.ie.code = XFIXNAT (c);
|
||||
XSETFRAME (inev.ie.frame_or_window, f);
|
||||
inev.ie.modifiers = 0;
|
||||
inev.ie.timestamp = 0;
|
||||
evq_enqueue (&inev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
pgtk_enqueue_preedit(struct frame *f, Lisp_Object preedit)
|
||||
{
|
||||
union buffered_input_event inev;
|
||||
EVENT_INIT (inev.ie);
|
||||
inev.ie.kind = PGTK_PREEDIT_TEXT_EVENT;
|
||||
inev.ie.arg = preedit;
|
||||
inev.ie.code = 0;
|
||||
XSETFRAME (inev.ie.frame_or_window, f);
|
||||
inev.ie.modifiers = 0;
|
||||
inev.ie.timestamp = 0;
|
||||
evq_enqueue (&inev);
|
||||
}
|
||||
|
||||
static gboolean key_press_event(GtkWidget *widget, GdkEvent *event, gpointer *user_data)
|
||||
{
|
||||
struct coding_system coding;
|
||||
|
@ -4978,6 +5020,11 @@ static gboolean key_press_event(GtkWidget *widget, GdkEvent *event, gpointer *us
|
|||
hlinfo->mouse_face_hidden = true;
|
||||
}
|
||||
|
||||
if (f != 0) {
|
||||
if (pgtk_im_filter_keypress (f, &event->key))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (f != 0)
|
||||
{
|
||||
guint keysym, orig_keysym;
|
||||
|
@ -5462,6 +5509,9 @@ focus_in_event(GtkWidget *widget, GdkEvent *event, gpointer *user_data)
|
|||
FRAME_DISPLAY_INFO(frame), frame, &inev);
|
||||
if (inev.ie.kind != NO_EVENT)
|
||||
evq_enqueue (&inev);
|
||||
|
||||
pgtk_im_focus_in (frame);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -5483,6 +5533,9 @@ focus_out_event(GtkWidget *widget, GdkEvent *event, gpointer *user_data)
|
|||
FRAME_DISPLAY_INFO(frame), frame, &inev);
|
||||
if (inev.ie.kind != NO_EVENT)
|
||||
evq_enqueue(&inev);
|
||||
|
||||
pgtk_im_focus_out (frame);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -6219,6 +6272,8 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name)
|
|||
|
||||
pgtk_selection_init();
|
||||
|
||||
pgtk_im_init (dpyinfo);
|
||||
|
||||
unblock_input ();
|
||||
|
||||
return dpyinfo;
|
||||
|
|
|
@ -226,6 +226,14 @@ struct pgtk_display_info
|
|||
|
||||
/* Modifier masks in gdk */
|
||||
int meta_mod_mask, alt_mod_mask;
|
||||
|
||||
/* whether to use Gtk's IM context. */
|
||||
|
||||
/* input method */
|
||||
struct {
|
||||
GtkIMContext *context;
|
||||
struct frame *focused_frame;
|
||||
} im;
|
||||
};
|
||||
|
||||
/* This is a chain of structures for all the PGTK displays currently in use. */
|
||||
|
@ -579,6 +587,7 @@ extern void syms_of_pgtkterm (void);
|
|||
extern void syms_of_pgtkfns (void);
|
||||
extern void syms_of_pgtkmenu (void);
|
||||
extern void syms_of_pgtkselect (void);
|
||||
extern void syms_of_pgtkim (void);
|
||||
|
||||
/* Implemented in pgtkselect. */
|
||||
extern void nxatoms_of_pgtkselect (void);
|
||||
|
@ -602,4 +611,14 @@ extern void pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo);
|
|||
|
||||
extern void x_change_tab_bar_height (struct frame *, int);
|
||||
|
||||
extern struct pgtk_display_info *check_pgtk_display_info (Lisp_Object object);
|
||||
|
||||
extern void pgtk_enqueue_string(struct frame *f, gchar *str);
|
||||
extern void pgtk_enqueue_preedit(struct frame *f, Lisp_Object image_data);
|
||||
extern void pgtk_im_focus_in(struct frame *f);
|
||||
extern void pgtk_im_focus_out(struct frame *f);
|
||||
extern bool pgtk_im_filter_keypress(struct frame *f, GdkEventKey *ev);
|
||||
extern void pgtk_im_init(struct pgtk_display_info *dpyinfo);
|
||||
extern void pgtk_im_finish(struct pgtk_display_info *dpyinfo);
|
||||
|
||||
#endif /* HAVE_PGTK */
|
||||
|
|
|
@ -264,6 +264,10 @@ enum event_kind
|
|||
, FILE_NOTIFY_EVENT
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PGTK
|
||||
/* Pre-edit text was changed. */
|
||||
, PGTK_PREEDIT_TEXT_EVENT
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Bit width of an enum event_kind tag at the start of structs and unions. */
|
||||
|
|
Loading…
Add table
Reference in a new issue