⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkimcontextxim.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 2000 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include "locale.h"#include <string.h>#include <stdlib.h>#include "gtk/gtkintl.h"#include "gtk/gtklabel.h"#include "gtk/gtksignal.h"#include "gtk/gtkwindow.h"#include "gtkimcontextxim.h"typedef struct _StatusWindow StatusWindow;typedef struct _GtkXIMInfo GtkXIMInfo;struct _GtkIMContextXIM{  GtkIMContext object;  GtkXIMInfo *im_info;  gchar *locale;  gchar *mb_charset;  GdkWindow *client_window;  GtkWidget *client_widget;  /* The status window for this input context; we claim the   * status window when we are focused and have created an XIC   */  StatusWindow *status_window;  gint preedit_size;  gint preedit_length;  gunichar *preedit_chars;  XIMFeedback *feedbacks;  gint preedit_cursor;    XIMCallback preedit_start_callback;  XIMCallback preedit_done_callback;  XIMCallback preedit_draw_callback;  XIMCallback preedit_caret_callback;  XIMCallback status_start_callback;  XIMCallback status_done_callback;  XIMCallback status_draw_callback;  XIMCallback string_conversion_callback;  XIC ic;  guint filter_key_release : 1;  guint use_preedit : 1;  guint finalizing : 1;  guint in_toplevel : 1;  guint has_focus : 1;};struct _GtkXIMInfo{  GdkScreen *screen;  XIM im;  char *locale;  XIMStyle preedit_style_setting;  XIMStyle status_style_setting;  XIMStyle style;  GtkSettings *settings;  gulong status_set;  gulong preedit_set;  XIMStyles *xim_styles;  GSList *ics;  guint reconnecting :1;  guint supports_string_conversion;};/* A context status window; these are kept in the status_windows list. */struct _StatusWindow{  GtkWidget *window;    /* Toplevel window to which the status window corresponds */  GtkWidget *toplevel;  /* Currently focused GtkIMContextXIM for the toplevel, if any */  GtkIMContextXIM *context;};static void     gtk_im_context_xim_class_init         (GtkIMContextXIMClass  *class);static void     gtk_im_context_xim_init               (GtkIMContextXIM       *im_context_xim);static void     gtk_im_context_xim_finalize           (GObject               *obj);static void     gtk_im_context_xim_set_client_window  (GtkIMContext          *context,						       GdkWindow             *client_window);static gboolean gtk_im_context_xim_filter_keypress    (GtkIMContext          *context,						       GdkEventKey           *key);static void     gtk_im_context_xim_reset              (GtkIMContext          *context);static void     gtk_im_context_xim_focus_in           (GtkIMContext          *context);static void     gtk_im_context_xim_focus_out          (GtkIMContext          *context);static void     gtk_im_context_xim_set_cursor_location (GtkIMContext          *context,						       GdkRectangle		*area);static void     gtk_im_context_xim_set_use_preedit    (GtkIMContext          *context,						       gboolean		      use_preedit);static void     gtk_im_context_xim_get_preedit_string (GtkIMContext          *context,						       gchar                **str,						       PangoAttrList        **attrs,						       gint                  *cursor_pos);static void reinitialize_ic      (GtkIMContextXIM *context_xim);static void set_ic_client_window (GtkIMContextXIM *context_xim,				  GdkWindow       *client_window);static void setup_styles (GtkXIMInfo *info);static void update_client_widget   (GtkIMContextXIM *context_xim);static void update_status_window   (GtkIMContextXIM *context_xim);static StatusWindow *status_window_get      (GtkWidget    *toplevel);static void          status_window_free     (StatusWindow *status_window);static void          status_window_set_text (StatusWindow *status_window,					     const gchar  *text);static void xim_destroy_callback   (XIM      xim,				    XPointer client_data,				    XPointer call_data);static XIC       gtk_im_context_xim_get_ic            (GtkIMContextXIM *context_xim);static GObjectClass *parent_class;GType gtk_type_im_context_xim = 0;GSList *open_ims = NULL;/* List of status windows for different toplevels */static GSList *status_windows = NULL;voidgtk_im_context_xim_register_type (GTypeModule *type_module){  static const GTypeInfo im_context_xim_info =  {    sizeof (GtkIMContextXIMClass),    (GBaseInitFunc) NULL,    (GBaseFinalizeFunc) NULL,    (GClassInitFunc) gtk_im_context_xim_class_init,    NULL,           /* class_finalize */        NULL,           /* class_data */    sizeof (GtkIMContextXIM),    0,    (GInstanceInitFunc) gtk_im_context_xim_init,  };  gtk_type_im_context_xim =     g_type_module_register_type (type_module,				 GTK_TYPE_IM_CONTEXT,				 "GtkIMContextXIM",				 &im_context_xim_info, 0);}#define PREEDIT_MASK (XIMPreeditCallbacks | XIMPreeditPosition | \		      XIMPreeditArea | XIMPreeditNothing | XIMPreeditNone)#define STATUS_MASK (XIMStatusCallbacks | XIMStatusArea | \		      XIMStatusNothing | XIMStatusNone)#define ALLOWED_MASK (XIMPreeditCallbacks | XIMPreeditNothing | XIMPreeditNone | \		      XIMStatusCallbacks | XIMStatusNothing | XIMStatusNone)static XIMStyle choose_better_style (XIMStyle style1, XIMStyle style2) {  XIMStyle s1, s2, u;     if (style1 == 0) return style2;  if (style2 == 0) return style1;  if ((style1 & (PREEDIT_MASK | STATUS_MASK))    	== (style2 & (PREEDIT_MASK | STATUS_MASK)))    return style1;  s1 = style1 & PREEDIT_MASK;  s2 = style2 & PREEDIT_MASK;  u = s1 | s2;  if (s1 != s2) {    if (u & XIMPreeditCallbacks)      return (s1 == XIMPreeditCallbacks) ? style1 : style2;    else if (u & XIMPreeditPosition)      return (s1 == XIMPreeditPosition) ? style1 :style2;    else if (u & XIMPreeditArea)      return (s1 == XIMPreeditArea) ? style1 : style2;    else if (u & XIMPreeditNothing)      return (s1 == XIMPreeditNothing) ? style1 : style2;    else if (u & XIMPreeditNone)      return (s1 == XIMPreeditNone) ? style1 : style2;  } else {    s1 = style1 & STATUS_MASK;    s2 = style2 & STATUS_MASK;    u = s1 | s2;    if (u & XIMStatusCallbacks)      return (s1 == XIMStatusCallbacks) ? style1 : style2;    else if (u & XIMStatusArea)      return (s1 == XIMStatusArea) ? style1 : style2;    else if (u & XIMStatusNothing)      return (s1 == XIMStatusNothing) ? style1 : style2;    else if (u & XIMStatusNone)      return (s1 == XIMStatusNone) ? style1 : style2;  }  return 0; /* Get rid of stupid warning */}static voidreinitialize_all_ics (GtkXIMInfo *info){  GSList *tmp_list;  for (tmp_list = info->ics; tmp_list; tmp_list = tmp_list->next)    reinitialize_ic (tmp_list->data);}static voidstatus_style_change (GtkXIMInfo *info){  GtkIMStatusStyle status_style;    g_object_get (info->settings,		"gtk-im-status-style", &status_style,		NULL);  if (status_style == GTK_IM_STATUS_CALLBACK)    info->status_style_setting = XIMStatusCallbacks;  else if (status_style == GTK_IM_STATUS_NOTHING)    info->status_style_setting = XIMStatusNothing;  else if (status_style == GTK_IM_STATUS_NONE)    info->status_style_setting = XIMStatusNone;  else    return;  setup_styles (info);    reinitialize_all_ics (info);}static voidpreedit_style_change (GtkXIMInfo *info){  GtkIMPreeditStyle preedit_style;  g_object_get (info->settings,		"gtk-im-preedit-style", &preedit_style,		NULL);  if (preedit_style == GTK_IM_PREEDIT_CALLBACK)    info->preedit_style_setting = XIMPreeditCallbacks;  else if (preedit_style == GTK_IM_PREEDIT_NOTHING)    info->preedit_style_setting = XIMPreeditNothing;  else if (preedit_style == GTK_IM_PREEDIT_NONE)    info->preedit_style_setting = XIMPreeditNone;  else    return;  setup_styles (info);    reinitialize_all_ics (info);}static voidsetup_styles (GtkXIMInfo *info){  int i;  unsigned long settings_preference;  XIMStyles *xim_styles = info->xim_styles;  settings_preference = info->status_style_setting|info->preedit_style_setting;  info->style = 0;  if (xim_styles)    {      for (i = 0; i < xim_styles->count_styles; i++)	if ((xim_styles->supported_styles[i] & ALLOWED_MASK) == xim_styles->supported_styles[i])	  {	    if (settings_preference == xim_styles->supported_styles[i])	      {		info->style = settings_preference;		break;	      }	    info->style = choose_better_style (info->style,					       xim_styles->supported_styles[i]);	  }    }  if (info->style == 0)    info->style = XIMPreeditNothing | XIMStatusNothing;}static voidsetup_im (GtkXIMInfo *info){  XIMValuesList *ic_values = NULL;  XIMCallback im_destroy_callback;  if (info->im == NULL)    return;  im_destroy_callback.client_data = (XPointer)info;  im_destroy_callback.callback = (XIMProc)xim_destroy_callback;  XSetIMValues (info->im,		XNDestroyCallback, &im_destroy_callback,		NULL);  XGetIMValues (info->im,		XNQueryInputStyle, &info->xim_styles,		XNQueryICValuesList, &ic_values,		NULL);  info->settings = gtk_settings_get_for_screen (info->screen);  if (!g_object_class_find_property (G_OBJECT_GET_CLASS (info->settings),				     "gtk-im-preedit-style"))    gtk_settings_install_property (g_param_spec_enum ("gtk-im-preedit-style",						      P_("IM Preedit style"),						      P_("How to draw the input method preedit string"),						      GTK_TYPE_IM_PREEDIT_STYLE,						      GTK_IM_PREEDIT_CALLBACK,						      G_PARAM_READWRITE));  if (!g_object_class_find_property (G_OBJECT_GET_CLASS (info->settings),				     "gtk-im-status-style"))    gtk_settings_install_property (g_param_spec_enum ("gtk-im-status-style",						      P_("IM Status style"),						      P_("How to draw the input method statusbar"),						      GTK_TYPE_IM_STATUS_STYLE,						      GTK_IM_STATUS_CALLBACK,						      G_PARAM_READWRITE));  info->status_set = g_signal_connect_swapped (info->settings,					       "notify::gtk-im-status-style",					       G_CALLBACK (status_style_change),					       info);  info->preedit_set = g_signal_connect_swapped (info->settings,						"notify::gtk-im-preedit-style",						G_CALLBACK (preedit_style_change),						info);  info->supports_string_conversion = FALSE;  if (ic_values)    {      int i;            for (i = 0; i < ic_values->count_values; i++)	if (strcmp (ic_values->supported_values[i],		    XNStringConversionCallback) == 0)	  {	    info->supports_string_conversion = TRUE;	    break;	  }#if 0      for (i = 0; i < ic_values->count_values; i++)	g_print ("%s\n", ic_values->supported_values[i]);      for (i = 0; i < xim_styles->count_styles; i++)	g_print ("%#x\n", xim_styles->supported_styles[i]);#endif            XFree (ic_values);    }  status_style_change (info);  preedit_style_change (info);}static voidxim_info_display_closed (GdkDisplay *display,			 gboolean    is_error,			 GtkXIMInfo *info){  GSList *ics, *tmp_list;  open_ims = g_slist_remove (open_ims, info);  ics = info->ics;  info->ics = NULL;  for (tmp_list = ics; tmp_list; tmp_list = tmp_list->next)    set_ic_client_window (tmp_list->data, NULL);  g_slist_free (ics);    g_signal_handler_disconnect (info->settings, info->status_set);  g_signal_handler_disconnect (info->settings, info->preedit_set);    XFree (info->xim_styles->supported_styles);  XFree (info->xim_styles);  g_free (info->locale);  if (info->im)    XCloseIM (info->im);  g_free (info);}static voidxim_instantiate_callback (Display *display, XPointer client_data,			  XPointer call_data){  GtkXIMInfo *info = (GtkXIMInfo*)client_data;  XIM im = NULL;  im = XOpenIM (display, NULL, NULL, NULL);  if (!im)    return;  info->im = im;  setup_im (info);  XUnregisterIMInstantiateCallback (display, NULL, NULL, NULL,				    xim_instantiate_callback,				    (XPointer)info);  info->reconnecting = FALSE;}/* initialize info->im */static voidxim_info_try_im (GtkXIMInfo *info){  GdkScreen *screen = info->screen;  GdkDisplay *display = gdk_screen_get_display (screen);  g_assert (info->im == NULL);  if (info->reconnecting)    return;  if (XSupportsLocale ())    {      if (!XSetLocaleModifiers (""))	g_warning ("Unable to set locale modifiers with XSetLocaleModifiers()");      info->im = XOpenIM (GDK_DISPLAY_XDISPLAY (display), NULL, NULL, NULL);      if (!info->im)	{	  XRegisterIMInstantiateCallback (GDK_DISPLAY_XDISPLAY(display),					  NULL, NULL, NULL,					  xim_instantiate_callback,					  (XPointer)info);	  info->reconnecting = TRUE;	  return;	}      setup_im (info);      g_signal_connect (display, "closed",			G_CALLBACK (xim_info_display_closed), info);    }}static voidxim_destroy_callback (XIM      xim,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -