1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2000 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gtkimcontext.h"
23 #include "gtkmain.h" /* For _gtk_boolean_handled_accumulator */
24 #include "gtkmarshalers.h"
38 static guint im_context_signals[LAST_SIGNAL] = { 0 };
40 static void gtk_im_context_class_init (GtkIMContextClass *class);
41 static void gtk_im_context_init (GtkIMContext *im_context);
43 static void gtk_im_context_real_get_preedit_string (GtkIMContext *context,
45 PangoAttrList **attrs,
47 static gboolean gtk_im_context_real_filter_keypress (GtkIMContext *context,
49 static gboolean gtk_im_context_real_get_surrounding (GtkIMContext *context,
52 static void gtk_im_context_real_set_surrounding (GtkIMContext *context,
58 gtk_im_context_get_type (void)
60 static GType im_context_type = 0;
64 static const GTypeInfo im_context_info =
66 sizeof (GtkIMContextClass),
68 (GBaseFinalizeFunc) NULL,
69 (GClassInitFunc) gtk_im_context_class_init,
70 NULL, /* class_finalize */
71 NULL, /* class_data */
72 sizeof (GtkIMContext),
74 (GInstanceInitFunc) gtk_im_context_init,
75 NULL, /* value_table */
79 g_type_register_static (G_TYPE_OBJECT, I_("GtkIMContext"),
80 &im_context_info, G_TYPE_FLAG_ABSTRACT);
83 return im_context_type;
87 gtk_im_context_class_init (GtkIMContextClass *klass)
89 klass->get_preedit_string = gtk_im_context_real_get_preedit_string;
90 klass->filter_keypress = gtk_im_context_real_filter_keypress;
91 klass->get_surrounding = gtk_im_context_real_get_surrounding;
92 klass->set_surrounding = gtk_im_context_real_set_surrounding;
94 im_context_signals[PREEDIT_START] =
95 g_signal_new (I_("preedit_start"),
96 G_TYPE_FROM_CLASS (klass),
98 G_STRUCT_OFFSET (GtkIMContextClass, preedit_start),
100 _gtk_marshal_VOID__VOID,
103 im_context_signals[PREEDIT_END] =
104 g_signal_new (I_("preedit_end"),
105 G_TYPE_FROM_CLASS (klass),
107 G_STRUCT_OFFSET (GtkIMContextClass, preedit_end),
109 _gtk_marshal_VOID__VOID,
112 im_context_signals[PREEDIT_CHANGED] =
113 g_signal_new (I_("preedit_changed"),
114 G_TYPE_FROM_CLASS (klass),
116 G_STRUCT_OFFSET (GtkIMContextClass, preedit_changed),
118 _gtk_marshal_VOID__VOID,
121 im_context_signals[COMMIT] =
122 g_signal_new (I_("commit"),
123 G_TYPE_FROM_CLASS (klass),
125 G_STRUCT_OFFSET (GtkIMContextClass, commit),
127 _gtk_marshal_VOID__STRING,
131 im_context_signals[RETRIEVE_SURROUNDING] =
132 g_signal_new (I_("retrieve_surrounding"),
133 G_TYPE_FROM_CLASS (klass),
135 G_STRUCT_OFFSET (GtkIMContextClass, retrieve_surrounding),
136 _gtk_boolean_handled_accumulator, NULL,
137 _gtk_marshal_BOOLEAN__VOID,
139 im_context_signals[DELETE_SURROUNDING] =
140 g_signal_new (I_("delete_surrounding"),
141 G_TYPE_FROM_CLASS (klass),
143 G_STRUCT_OFFSET (GtkIMContextClass, delete_surrounding),
144 _gtk_boolean_handled_accumulator, NULL,
145 _gtk_marshal_BOOLEAN__INT_INT,
152 gtk_im_context_init (GtkIMContext *im_context)
157 gtk_im_context_real_get_preedit_string (GtkIMContext *context,
159 PangoAttrList **attrs,
163 *str = g_strdup ("");
165 *attrs = pango_attr_list_new ();
171 gtk_im_context_real_filter_keypress (GtkIMContext *context,
184 gtk_im_context_real_set_surrounding (GtkIMContext *context,
189 SurroundingInfo *info = g_object_get_data (G_OBJECT (context), "gtk-im-surrounding-info");
194 info->text = g_strndup (text, len);
195 info->cursor_index = cursor_index;
200 gtk_im_context_real_get_surrounding (GtkIMContext *context,
205 gboolean info_is_local = FALSE;
206 SurroundingInfo local_info = { NULL, 0 };
207 SurroundingInfo *info;
209 info = g_object_get_data (G_OBJECT (context), "gtk-im-surrounding-info");
213 g_object_set_data (G_OBJECT (context), I_("gtk-im-surrounding-info"), info);
214 info_is_local = TRUE;
217 g_signal_emit (context,
218 im_context_signals[RETRIEVE_SURROUNDING], 0,
223 *text = g_strdup (info->text ? info->text : "");
224 *cursor_index = info->cursor_index;
235 g_object_set_data (G_OBJECT (context), I_("gtk-im-surrounding-info"), NULL);
242 * gtk_im_context_set_client_window:
243 * @context: a #GtkIMContext
244 * @window: the client window. This may be %NULL to indicate
245 * that the previous client window no longer exists.
247 * Set the client window for the input context; this is the
248 * #GdkWindow in which the input appears. This window is
249 * used in order to correctly position status windows, and may
250 * also be used for purposes internal to the input method.
253 gtk_im_context_set_client_window (GtkIMContext *context,
256 GtkIMContextClass *klass;
258 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
260 klass = GTK_IM_CONTEXT_GET_CLASS (context);
261 if (klass->set_client_window)
262 klass->set_client_window (context, window);
266 * gtk_im_context_get_preedit_string:
267 * @context: a #GtkIMContext
268 * @str: location to store the retrieved string. The
269 * string retrieved must be freed with g_free ().
270 * @attrs: location to store the retrieved attribute list.
271 * When you are done with this list, you must
272 * unreference it with pango_attr_list_unref().
273 * @cursor_pos: location to store position of cursor (in characters)
274 * within the preedit string.
276 * Retrieve the current preedit string for the input context,
277 * and a list of attributes to apply to the string.
278 * This string should be displayed inserted at the insertion
282 gtk_im_context_get_preedit_string (GtkIMContext *context,
284 PangoAttrList **attrs,
287 GtkIMContextClass *klass;
289 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
291 klass = GTK_IM_CONTEXT_GET_CLASS (context);
292 klass->get_preedit_string (context, str, attrs, cursor_pos);
293 g_return_if_fail (str == NULL || g_utf8_validate (*str, -1, NULL));
297 * gtk_im_context_filter_keypress:
298 * @context: a #GtkIMContext
299 * @event: the key event
301 * Allow an input method to internally handle key press and release
302 * events. If this function returns %TRUE, then no further processing
303 * should be done for this key event.
305 * Return value: %TRUE if the input method handled the key event.
309 gtk_im_context_filter_keypress (GtkIMContext *context,
312 GtkIMContextClass *klass;
314 g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
315 g_return_val_if_fail (key != NULL, FALSE);
317 klass = GTK_IM_CONTEXT_GET_CLASS (context);
318 return klass->filter_keypress (context, key);
322 * gtk_im_context_focus_in:
323 * @context: a #GtkIMContext
325 * Notify the input method that the widget to which this
326 * input context corresponds has gained focus. The input method
327 * may, for example, change the displayed feedback to reflect
331 gtk_im_context_focus_in (GtkIMContext *context)
333 GtkIMContextClass *klass;
335 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
337 klass = GTK_IM_CONTEXT_GET_CLASS (context);
339 klass->focus_in (context);
343 * gtk_im_context_focus_out:
344 * @context: a #GtkIMContext
346 * Notify the input method that the widget to which this
347 * input context corresponds has lost focus. The input method
348 * may, for example, change the displayed feedback or reset the contexts
349 * state to reflect this change.
352 gtk_im_context_focus_out (GtkIMContext *context)
354 GtkIMContextClass *klass;
356 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
358 klass = GTK_IM_CONTEXT_GET_CLASS (context);
359 if (klass->focus_out)
360 klass->focus_out (context);
364 * gtk_im_context_reset:
365 * @context: a #GtkIMContext
367 * Notify the input method that a change such as a change in cursor
368 * position has been made. This will typically cause the input
369 * method to clear the preedit state.
372 gtk_im_context_reset (GtkIMContext *context)
374 GtkIMContextClass *klass;
376 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
378 klass = GTK_IM_CONTEXT_GET_CLASS (context);
380 klass->reset (context);
385 * gtk_im_context_set_cursor_location:
386 * @context: a #GtkIMContext
387 * @area: new location
389 * Notify the input method that a change in cursor
390 * position has been made. The location is relative to the client
394 gtk_im_context_set_cursor_location (GtkIMContext *context,
397 GtkIMContextClass *klass;
399 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
401 klass = GTK_IM_CONTEXT_GET_CLASS (context);
402 if (klass->set_cursor_location)
403 klass->set_cursor_location (context, area);
407 * gtk_im_context_set_use_preedit:
408 * @context: a #GtkIMContext
409 * @use_preedit: whether the IM context should use the preedit string.
411 * Sets whether the IM context should use the preedit string
412 * to display feedback. If @use_preedit is FALSE (default
413 * is TRUE), then the IM context may use some other method to display
414 * feedback, such as displaying it in a child of the root window.
417 gtk_im_context_set_use_preedit (GtkIMContext *context,
418 gboolean use_preedit)
420 GtkIMContextClass *klass;
422 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
424 klass = GTK_IM_CONTEXT_GET_CLASS (context);
425 if (klass->set_use_preedit)
426 klass->set_use_preedit (context, use_preedit);
430 * gtk_im_context_set_surrounding:
431 * @context: a #GtkIMContext
432 * @text: text surrounding the insertion point, as UTF-8.
433 * the preedit string should not be included within
435 * @len: the length of @text, or -1 if @text is nul-terminated
436 * @cursor_index: the byte index of the insertion cursor within @text.
438 * Sets surrounding context around the insertion point and preedit
439 * string. This function is expected to be called in response to the
440 * GtkIMContext::retrieve_surrounding signal, and will likely have no
441 * effect if called at other times.
444 gtk_im_context_set_surrounding (GtkIMContext *context,
449 GtkIMContextClass *klass;
451 g_return_if_fail (GTK_IS_IM_CONTEXT (context));
452 g_return_if_fail (text != NULL || len == 0);
454 if (text == NULL && len == 0)
459 g_return_if_fail (cursor_index >= 0 && cursor_index <= len);
461 klass = GTK_IM_CONTEXT_GET_CLASS (context);
462 if (klass->set_surrounding)
463 klass->set_surrounding (context, text, len, cursor_index);
467 * gtk_im_context_get_surrounding:
468 * @context: a #GtkIMContext
469 * @text: location to store a UTF-8 encoded string of text
470 * holding context around the insertion point.
471 * If the function returns %TRUE, then you must free
472 * the result stored in this location with g_free().
473 * @cursor_index: location to store byte index of the insertion cursor
476 * Retrieves context around the insertion point. Input methods
477 * typically want context in order to constrain input text based on
478 * existing text; this is important for languages such as Thai where
479 * only some sequences of characters are allowed.
481 * This function is implemented by emitting the
482 * GtkIMContext::retrieve_surrounding signal on the input method; in
483 * response to this signal, a widget should provide as much context as
484 * is available, up to an entire paragraph, by calling
485 * gtk_im_context_set_surrounding(). Note that there is no obligation
486 * for a widget to respond to the ::retrieve_surrounding signal, so input
487 * methods must be prepared to function without context.
489 * Return value: %TRUE if surrounding text was provided; in this case
490 * you must free the result stored in *text.
493 gtk_im_context_get_surrounding (GtkIMContext *context,
497 GtkIMContextClass *klass;
498 gchar *local_text = NULL;
500 gboolean result = FALSE;
502 g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
504 klass = GTK_IM_CONTEXT_GET_CLASS (context);
505 if (klass->get_surrounding)
506 result = klass->get_surrounding (context,
507 text ? text : &local_text,
508 cursor_index ? cursor_index : &local_index);
517 * gtk_im_context_delete_surrounding:
518 * @context: a #GtkIMContext
519 * @offset: offset from cursor position in chars;
520 * a negative value means start before the cursor.
521 * @n_chars: number of characters to delete.
523 * Asks the widget that the input context is attached to to delete
524 * characters around the cursor position by emitting the
525 * GtkIMContext::delete_surrounding signal. Note that @offset and @n_chars
526 * are in characters not in bytes which differs from the usage other
527 * places in #GtkIMContext.
529 * In order to use this function, you should first call
530 * gtk_im_context_get_surrounding() to get the current context, and
531 * call this function immediately afterwards to make sure that you
532 * know what you are deleting. You should also account for the fact
533 * that even if the signal was handled, the input context might not
534 * have deleted all the characters that were requested to be deleted.
536 * This function is used by an input method that wants to make
537 * subsitutions in the existing text in response to new input. It is
538 * not useful for applications.
540 * Return value: %TRUE if the signal was handled.
543 gtk_im_context_delete_surrounding (GtkIMContext *context,
549 g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
551 g_signal_emit (context,
552 im_context_signals[DELETE_SURROUNDING], 0,
553 offset, n_chars, &result);
558 #define __GTK_IM_CONTEXT_C__
559 #include "gtkaliasdef.c"