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

📄 gtkimcontextime.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * gtkimcontextime.c * Copyright (C) 2003 Takuro Ashie * Copyright (C) 2003-2004 Kazuki IWAMOTO * * 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. * *//* *  Please see the following site for the detail of Windows IME API. *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/appendix/hh/appendix/imeimes2_35ph.asp */#include "gtkimcontextime.h"#include "imm-extra.h"#include "gdk/win32/gdkwin32.h"#include "gdk/gdkkeysyms.h"#include "gtk/gtkwidget.h"#include <pango/pango-utils.h>/* avoid warning */#ifdef STRICT# undef STRICT# include <pango/pangowin32.h># ifndef STRICT#   define STRICT 1# endif#else /* STRICT */#   include <pango/pangowin32.h>#endif /* STRICT *//* #define BUFSIZE 4096 */#define FREE_PREEDIT_BUFFER(ctx) \{                                \  g_free((ctx)->priv->comp_str); \  g_free((ctx)->priv->read_str); \  (ctx)->priv->comp_str = NULL;  \  (ctx)->priv->read_str = NULL;  \  (ctx)->priv->comp_str_len = 0; \  (ctx)->priv->read_str_len = 0; \}struct _GtkIMContextIMEPrivate{  /* save IME context when the client window is focused out */  DWORD conversion_mode;  DWORD sentence_mode;  LPVOID comp_str;  DWORD comp_str_len;  LPVOID read_str;  DWORD read_str_len;};/* GObject class methods */static void gtk_im_context_ime_class_init (GtkIMContextIMEClass *class);static void gtk_im_context_ime_init       (GtkIMContextIME      *context_ime);static void gtk_im_context_ime_dispose    (GObject              *obj);static void gtk_im_context_ime_finalize   (GObject              *obj);static void gtk_im_context_ime_set_property (GObject      *object,                                             guint         prop_id,                                             const GValue *value,                                             GParamSpec   *pspec);static void gtk_im_context_ime_get_property (GObject      *object,                                             guint         prop_id,                                             GValue       *value,                                             GParamSpec   *pspec);/* GtkIMContext's virtual functions */static void gtk_im_context_ime_set_client_window   (GtkIMContext *context,                                                    GdkWindow    *client_window);static gboolean gtk_im_context_ime_filter_keypress (GtkIMContext   *context,                                                    GdkEventKey    *event);static void gtk_im_context_ime_reset               (GtkIMContext   *context);static void gtk_im_context_ime_get_preedit_string  (GtkIMContext   *context,                                                    gchar         **str,                                                    PangoAttrList **attrs,                                                    gint           *cursor_pos);static void gtk_im_context_ime_focus_in            (GtkIMContext   *context);static void gtk_im_context_ime_focus_out           (GtkIMContext   *context);static void gtk_im_context_ime_set_cursor_location (GtkIMContext   *context,                                                    GdkRectangle   *area);static void gtk_im_context_ime_set_use_preedit     (GtkIMContext   *context,                                                    gboolean        use_preedit);/* GtkIMContextIME's private functions */static void gtk_im_context_ime_set_preedit_font (GtkIMContext    *context);static GdkFilterReturngtk_im_context_ime_message_filter               (GdkXEvent       *xevent,                                                 GdkEvent        *event,                                                 gpointer         data);static void get_window_position                 (GdkWindow       *win,                                                 gint            *x,                                                 gint            *y);static void cb_client_widget_hierarchy_changed  (GtkWidget       *widget,                                                 GtkWidget       *widget2,                                                 GtkIMContextIME *context_ime);GType gtk_type_im_context_ime = 0;static GObjectClass *parent_class;voidgtk_im_context_ime_register_type (GTypeModule *type_module){  static const GTypeInfo im_context_ime_info = {    sizeof (GtkIMContextIMEClass),    (GBaseInitFunc) NULL,    (GBaseFinalizeFunc) NULL,    (GClassInitFunc) gtk_im_context_ime_class_init,    NULL,                       /* class_finalize */    NULL,                       /* class_data */    sizeof (GtkIMContextIME),    0,    (GInstanceInitFunc) gtk_im_context_ime_init,  };  gtk_type_im_context_ime =    g_type_module_register_type (type_module,                                 GTK_TYPE_IM_CONTEXT,                                 "GtkIMContextIME", &im_context_ime_info, 0);}static voidgtk_im_context_ime_class_init (GtkIMContextIMEClass *class){  GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);  GObjectClass *gobject_class = G_OBJECT_CLASS (class);  parent_class = g_type_class_peek_parent (class);  gobject_class->finalize     = gtk_im_context_ime_finalize;  gobject_class->dispose      = gtk_im_context_ime_dispose;  gobject_class->set_property = gtk_im_context_ime_set_property;  gobject_class->get_property = gtk_im_context_ime_get_property;  im_context_class->set_client_window   = gtk_im_context_ime_set_client_window;  im_context_class->filter_keypress     = gtk_im_context_ime_filter_keypress;  im_context_class->reset               = gtk_im_context_ime_reset;  im_context_class->get_preedit_string  = gtk_im_context_ime_get_preedit_string;  im_context_class->focus_in            = gtk_im_context_ime_focus_in;  im_context_class->focus_out           = gtk_im_context_ime_focus_out;  im_context_class->set_cursor_location = gtk_im_context_ime_set_cursor_location;  im_context_class->set_use_preedit     = gtk_im_context_ime_set_use_preedit;}static voidgtk_im_context_ime_init (GtkIMContextIME *context_ime){  context_ime->client_window          = NULL;  context_ime->toplevel               = NULL;  context_ime->use_preedit            = TRUE;  context_ime->preediting             = FALSE;  context_ime->opened                 = FALSE;  context_ime->focus                  = FALSE;  context_ime->cursor_location.x      = 0;  context_ime->cursor_location.y      = 0;  context_ime->cursor_location.width  = 0;  context_ime->cursor_location.height = 0;  context_ime->priv = g_malloc0 (sizeof (GtkIMContextIMEPrivate));  context_ime->priv->conversion_mode  = 0;  context_ime->priv->sentence_mode    = 0;  context_ime->priv->comp_str         = NULL;  context_ime->priv->comp_str_len     = 0;  context_ime->priv->read_str         = NULL;  context_ime->priv->read_str_len     = 0;}static voidgtk_im_context_ime_dispose (GObject *obj){  GtkIMContext *context = GTK_IM_CONTEXT (obj);  GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (obj);  if (context_ime->client_window)    gtk_im_context_ime_set_client_window (context, NULL);  FREE_PREEDIT_BUFFER (context_ime);  if (G_OBJECT_CLASS (parent_class)->dispose)    G_OBJECT_CLASS (parent_class)->dispose (obj);}static voidgtk_im_context_ime_finalize (GObject *obj){  /* GtkIMContext *context = GTK_IM_CONTEXT (obj); */  GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (obj);  g_free (context_ime->priv);  context_ime->priv = NULL;  if (G_OBJECT_CLASS (parent_class)->finalize)    G_OBJECT_CLASS (parent_class)->finalize (obj);}static voidgtk_im_context_ime_set_property (GObject      *object,                                 guint         prop_id,                                 const GValue *value,                                 GParamSpec   *pspec){  GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (object);  g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime));  switch (prop_id)    {    default:      break;    }}static voidgtk_im_context_ime_get_property (GObject    *object,                                 guint       prop_id,                                 GValue     *value,                                 GParamSpec *pspec){  GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (object);  g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime));  switch (prop_id)    {    default:      break;    }}GtkIMContext *gtk_im_context_ime_new (void){  return g_object_new (GTK_TYPE_IM_CONTEXT_IME, NULL);}static voidgtk_im_context_ime_set_client_window (GtkIMContext *context,                                      GdkWindow    *client_window){  GtkIMContextIME *context_ime;  g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));  context_ime = GTK_IM_CONTEXT_IME (context);  if (client_window)    {      HIMC himc;      HWND hwnd;      hwnd = GDK_WINDOW_HWND (client_window);      himc = ImmGetContext (hwnd);      if (himc)	{	  context_ime->opened = ImmGetOpenStatus (himc);	  ImmGetConversionStatus (himc,				  &context_ime->priv->conversion_mode,				  &context_ime->priv->sentence_mode);	  ImmReleaseContext (hwnd, himc);	}    }  else if (context_ime->focus)    {      gtk_im_context_ime_focus_out (context);    }  context_ime->client_window = client_window;}static gbooleangtk_im_context_ime_filter_keypress (GtkIMContext *context,                                    GdkEventKey  *event){  GtkIMContextIME *context_ime;  gboolean retval = FALSE;  guint32 c;  g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context), FALSE);  g_return_val_if_fail (event, FALSE);  if (event->type == GDK_KEY_RELEASE)    return FALSE;  if (event->state & GDK_CONTROL_MASK)    return FALSE;  context_ime = GTK_IM_CONTEXT_IME (context);  if (!context_ime->focus)    return FALSE;  if (!GDK_IS_WINDOW (context_ime->client_window))    return FALSE;  c = gdk_keyval_to_unicode (event->keyval);  if (c)    {      guchar utf8[10];      int len = g_unichar_to_utf8 (c, utf8);      utf8[len] = 0;      g_signal_emit_by_name (context_ime, "commit", utf8);      retval = TRUE;    }  return retval;}static voidgtk_im_context_ime_reset (GtkIMContext *context){  GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (context);  HWND hwnd;  HIMC himc;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return;  if (context_ime->preediting && ImmGetOpenStatus (himc))    ImmNotifyIME (himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);  context_ime->preediting = FALSE;  g_signal_emit_by_name (context, "preedit_changed");  ImmReleaseContext (hwnd, himc);}static gchar *get_utf8_preedit_string (GtkIMContextIME *context_ime, gint *pos_ret){  gchar *utf8str = NULL;  HWND hwnd;  HIMC himc;  gint pos = 0;  if (pos_ret)    *pos_ret = 0;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return g_strdup ("");  if (context_ime->preediting)    {      glong len;      len = ImmGetCompositionStringW (himc, GCS_COMPSTR, NULL, 0);      if (len > 0)	{	  GError *error = NULL;	  gpointer buf = g_alloca (len);	  ImmGetCompositionStringW (himc, GCS_COMPSTR, buf, len);	  len /= 2;	  utf8str = g_utf16_to_utf8 (buf, len, NULL, NULL, &error);	  if (error)	    {	      g_warning ("%s", error->message);	      g_error_free (error);	    }	  	  if (pos_ret)	    {	      pos = ImmGetCompositionStringW (himc, GCS_CURSORPOS, NULL, 0);	      if (pos < 0 || len < pos)		{		  g_warning ("ImmGetCompositionString: "			     "Invalid cursor position!");		  pos = 0;		}	    }	}    }  if (!utf8str)    {      utf8str = g_strdup ("");      pos = 0;    }  if (pos_ret)    *pos_ret = pos;  ImmReleaseContext (hwnd, himc);  return utf8str;}static PangoAttrList *get_pango_attr_list (GtkIMContextIME *context_ime, const gchar *utf8str){  PangoAttrList *attrs = pango_attr_list_new ();  HWND hwnd;  HIMC himc;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return attrs;  if (context_ime->preediting)    {      const gchar *schr = utf8str, *echr;      guint8 *buf;      guint16 f_red, f_green, f_blue, b_red, b_green, b_blue;      glong len, spos = 0, epos, sidx = 0, eidx;      PangoAttribute *attr;      /*       *  get attributes list of IME.       */      len = ImmGetCompositionStringW (himc, GCS_COMPATTR, NULL, 0);      buf = g_alloca (len);      ImmGetCompositionStringW (himc, GCS_COMPATTR, buf, len);      /*       *  schr and echr are pointer in utf8str.       */      for (echr = g_utf8_next_char (utf8str); *schr != '\0';           echr = g_utf8_next_char (echr))        {          /*           *  spos and epos are buf(attributes list of IME) position by           *  bytes.           *  Using the wide-char API, this value is same with UTF-8 offset.           */	  epos = g_utf8_pointer_to_offset (utf8str, echr);          /*           *  sidx and eidx are positions in utf8str by bytes.           */          eidx = echr - utf8str;          /*           *  convert attributes list to PangoAttriute.           */          if (*echr == '\0' || buf[spos] != buf[epos])            {              switch (buf[spos])                {                case ATTR_TARGET_CONVERTED:                  attr = pango_attr_underline_new (PANGO_UNDERLINE_DOUBLE);                  attr->start_index = sidx;                  attr->end_index = eidx;                  pango_attr_list_change (attrs, attr);                  f_red = f_green = f_blue = 0;                  b_red = b_green = b_blue = 0xffff;                  break;                case ATTR_TARGET_NOTCONVERTED:                  f_red = f_green = f_blue = 0xffff;                  b_red = b_green = b_blue = 0;                  break;                case ATTR_INPUT_ERROR:                  f_red = f_green = f_blue = 0;                  b_red = b_green = b_blue = 0x7fff;                  break;                default:        /* ATTR_INPUT,ATTR_CONVERTED,ATTR_FIXEDCONVERTED */                  attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);                  attr->start_index = sidx;                  attr->end_index = eidx;                  pango_attr_list_change (attrs, attr);                  f_red = f_green = f_blue = 0;                  b_red = b_green = b_blue = 0xffff;                }              attr = pango_attr_foreground_new (f_red, f_green, f_blue);              attr->start_index = sidx;              attr->end_index = eidx;              pango_attr_list_change (attrs, attr);              attr = pango_attr_background_new (b_red, b_green, b_blue);              attr->start_index = sidx;              attr->end_index = eidx;              pango_attr_list_change (attrs, attr);              schr = echr;              spos = epos;              sidx = eidx;            }        }    }  ImmReleaseContext (hwnd, himc);  return attrs;}static voidgtk_im_context_ime_get_preedit_string (GtkIMContext   *context,                                       gchar         **str,                                       PangoAttrList **attrs,                                       gint           *cursor_pos){  gchar *utf8str = NULL;  gint pos = 0;  GtkIMContextIME *context_ime;  context_ime = GTK_IM_CONTEXT_IME (context);  utf8str = get_utf8_preedit_string (context_ime, &pos);  if (attrs)    *attrs = get_pango_attr_list (context_ime, utf8str);  if (str)    {      *str = utf8str;    }  else    {

⌨️ 快捷键说明

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