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

📄 gtkimcontextime.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 2 页
字号:
      g_free (utf8str);      utf8str = NULL;    }  if (cursor_pos)    *cursor_pos = pos;}static voidgtk_im_context_ime_focus_in (GtkIMContext *context){  GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (context);  GdkWindow *toplevel;  GtkWidget *widget = NULL;  HWND hwnd, top_hwnd;  HIMC himc;  if (!GDK_IS_WINDOW (context_ime->client_window))    return;  /* swtich current context */  context_ime->focus = TRUE;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return;  toplevel = gdk_window_get_toplevel (context_ime->client_window);  if (GDK_IS_WINDOW (toplevel))    {      gdk_window_add_filter (toplevel,                             gtk_im_context_ime_message_filter, context_ime);      top_hwnd = GDK_WINDOW_HWND (toplevel);      context_ime->toplevel = toplevel;    }  else    {      g_warning ("gtk_im_context_ime_focus_in(): "                 "cannot find toplevel window.");      return;    }  /* trace reparenting (probably no need) */  gdk_window_get_user_data (context_ime->client_window, (gpointer) & widget);  if (GTK_IS_WIDGET (widget))    {      g_signal_connect (widget, "hierarchy-changed",                        G_CALLBACK (cb_client_widget_hierarchy_changed),                        context_ime);    }  else    {      /* warning? */    }  /* restore preedit context */  ImmSetConversionStatus (himc,                          context_ime->priv->conversion_mode,                          context_ime->priv->sentence_mode);  if (context_ime->opened)    {      if (!ImmGetOpenStatus (himc))        ImmSetOpenStatus (himc, TRUE);      if (context_ime->preediting)        {          ImmSetCompositionStringW (himc,				    SCS_SETSTR,				    context_ime->priv->comp_str,				    context_ime->priv->comp_str_len, NULL, 0);          FREE_PREEDIT_BUFFER (context_ime);        }    }  /* clean */  ImmReleaseContext (hwnd, himc);}static voidgtk_im_context_ime_focus_out (GtkIMContext *context){  GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (context);  GdkWindow *toplevel;  GtkWidget *widget = NULL;  HWND hwnd, top_hwnd;  HIMC himc;  if (!GDK_IS_WINDOW (context_ime->client_window))    return;  /* swtich current context */  context_ime->focus = FALSE;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return;  /* save preedit context */  ImmGetConversionStatus (himc,                          &context_ime->priv->conversion_mode,                          &context_ime->priv->sentence_mode);  if (ImmGetOpenStatus (himc))    {      gboolean preediting = context_ime->preediting;      if (preediting)        {          FREE_PREEDIT_BUFFER (context_ime);          context_ime->priv->comp_str_len            = ImmGetCompositionStringW (himc, GCS_COMPSTR, NULL, 0);          context_ime->priv->comp_str            = g_malloc (context_ime->priv->comp_str_len);          ImmGetCompositionStringW (himc, GCS_COMPSTR,				    context_ime->priv->comp_str,				    context_ime->priv->comp_str_len);          context_ime->priv->read_str_len            = ImmGetCompositionStringW (himc, GCS_COMPREADSTR, NULL, 0);          context_ime->priv->read_str            = g_malloc (context_ime->priv->read_str_len);          ImmGetCompositionStringW (himc, GCS_COMPREADSTR,				    context_ime->priv->read_str,				    context_ime->priv->read_str_len);        }      ImmSetOpenStatus (himc, FALSE);      context_ime->opened = TRUE;      context_ime->preediting = preediting;    }  else    {      context_ime->opened = FALSE;      context_ime->preediting = FALSE;    }  /* remove signal handler */  gdk_window_get_user_data (context_ime->client_window, (gpointer) & widget);  if (GTK_IS_WIDGET (widget))    {      g_signal_handlers_disconnect_by_func        (G_OBJECT (widget),         G_CALLBACK (cb_client_widget_hierarchy_changed), context_ime);    }  /* remove event fileter */  toplevel = gdk_window_get_toplevel (context_ime->client_window);  if (GDK_IS_WINDOW (toplevel))    {      gdk_window_remove_filter (toplevel,                                gtk_im_context_ime_message_filter,                                context_ime);      top_hwnd = GDK_WINDOW_HWND (toplevel);      context_ime->toplevel = NULL;    }  else    {      g_warning ("gtk_im_context_ime_focus_out(): "                 "cannot find toplevel window.");    }  /* clean */  ImmReleaseContext (hwnd, himc);}static voidgtk_im_context_ime_set_cursor_location (GtkIMContext *context,                                        GdkRectangle *area){  gint wx = 0, wy = 0;  GtkIMContextIME *context_ime;  COMPOSITIONFORM cf;  HWND hwnd;  HIMC himc;  g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));  context_ime = GTK_IM_CONTEXT_IME (context);  if (area)    context_ime->cursor_location = *area;  if (!context_ime->client_window)    return;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return;  get_window_position (context_ime->client_window, &wx, &wy);  cf.dwStyle = CFS_POINT;  cf.ptCurrentPos.x = wx + context_ime->cursor_location.x;  cf.ptCurrentPos.y = wy + context_ime->cursor_location.y;  ImmSetCompositionWindow (himc, &cf);  ImmReleaseContext (hwnd, himc);}static voidgtk_im_context_ime_set_use_preedit (GtkIMContext *context,                                    gboolean      use_preedit){  GtkIMContextIME *context_ime;  g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));  context_ime = GTK_IM_CONTEXT_IME (context);  context_ime->use_preedit = use_preedit;  if (context_ime->preediting)    {      HWND hwnd;      HIMC himc;      hwnd = GDK_WINDOW_HWND (context_ime->client_window);      himc = ImmGetContext (hwnd);      if (!himc)        return;      /* FIXME: What to do? */      ImmReleaseContext (hwnd, himc);    }}static voidgtk_im_context_ime_set_preedit_font (GtkIMContext *context){  GtkIMContextIME *context_ime;  GtkWidget *widget = NULL;  HWND hwnd;  HIMC himc;  HKL ime = GetKeyboardLayout (0);  const gchar *lang;  gunichar wc;  PangoContext *pango_context;  PangoFont *font;  LOGFONT *logfont;  g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));  context_ime = GTK_IM_CONTEXT_IME (context);  if (!context_ime->client_window)    return;  gdk_window_get_user_data (context_ime->client_window, (gpointer) &widget);  if (!GTK_IS_WIDGET (widget))    return;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return;  /* set font */  pango_context = gtk_widget_get_pango_context (widget);  if (!pango_context)    goto ERROR_OUT;  /* Try to make sure we use a font that actually can show the   * language in question.   */   switch (PRIMARYLANGID (LOWORD (ime)))    {    case LANG_JAPANESE:      lang = "ja"; break;    case LANG_KOREAN:      lang = "ko"; break;    case LANG_CHINESE:      switch (SUBLANGID (LOWORD (ime)))	{	case SUBLANG_CHINESE_TRADITIONAL:	  lang = "zh_TW"; break;	case SUBLANG_CHINESE_SIMPLIFIED:	  lang = "zh_CN"; break;	case SUBLANG_CHINESE_HONGKONG:	  lang = "zh_HK"; break;	case SUBLANG_CHINESE_SINGAPORE:	  lang = "zh_SG"; break;	case SUBLANG_CHINESE_MACAU:	  lang = "zh_MO"; break;	default:	  lang = "zh"; break;	}      break;    default:      lang = ""; break;    }    if (lang[0])    {      /* We know what language it is. Look for a character, any       * character, that language needs.       */      PangoLanguage *pango_lang = pango_language_from_string (lang);      PangoFontset *fontset =	pango_context_load_fontset (pango_context,				    widget->style->font_desc,				    pango_lang);      gunichar *sample =	g_utf8_to_ucs4 (pango_language_get_sample_string (pango_lang),			-1, NULL, NULL, NULL);      wc = 0x4E00;		/* In all CJK languages? */      if (sample != NULL)	{	  int i;	  for (i = 0; sample[i]; i++)	    if (g_unichar_iswide (sample[i]))	      {		wc = sample[i];		break;	      }	  g_free (sample);	}      font = pango_fontset_get_font (fontset, wc);      g_object_unref (fontset);    }  else    font = pango_context_load_font (pango_context, widget->style->font_desc);  if (!font)    goto ERROR_OUT;  logfont = pango_win32_font_logfont (font);  if (logfont)    ImmSetCompositionFont (himc, logfont);  g_object_unref (font);ERROR_OUT:  /* clean */  ImmReleaseContext (hwnd, himc);}static GdkFilterReturngtk_im_context_ime_message_filter (GdkXEvent *xevent,                                   GdkEvent  *event,                                   gpointer   data){  GtkIMContext *context;  GtkIMContextIME *context_ime;  HWND hwnd;  HIMC himc;  MSG *msg = (MSG *) xevent;  GdkFilterReturn retval = GDK_FILTER_CONTINUE;  g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (data), retval);  context = GTK_IM_CONTEXT (data);  context_ime = GTK_IM_CONTEXT_IME (data);  if (!context_ime->focus)    return retval;  hwnd = GDK_WINDOW_HWND (context_ime->client_window);  himc = ImmGetContext (hwnd);  if (!himc)    return retval;  switch (msg->message)    {    case WM_IME_COMPOSITION:      {        gint wx = 0, wy = 0;        CANDIDATEFORM cf;        get_window_position (context_ime->client_window, &wx, &wy);        /* FIXME! */        {          HWND hwnd_top;          POINT pt;          RECT rc;          hwnd_top =            GDK_WINDOW_HWND (gdk_window_get_toplevel                             (context_ime->client_window));          GetWindowRect (hwnd_top, &rc);          pt.x = wx;          pt.y = wy;          ClientToScreen (hwnd_top, &pt);          wx = pt.x - rc.left;          wy = pt.y - rc.top;        }        cf.dwIndex = 0;        cf.dwStyle = CFS_CANDIDATEPOS;        cf.ptCurrentPos.x = wx + context_ime->cursor_location.x;        cf.ptCurrentPos.y = wy + context_ime->cursor_location.y          + context_ime->cursor_location.height;        ImmSetCandidateWindow (himc, &cf);        if ((msg->lParam & GCS_COMPSTR))          g_signal_emit_by_name (context, "preedit_changed");        if (msg->lParam & GCS_RESULTSTR)          {            gsize len;            gchar *utf8str = NULL;            GError *error = NULL;	    len = ImmGetCompositionStringW (himc, GCS_RESULTSTR, NULL, 0);            if (len > 0)              {		gpointer buf = g_alloca (len);		ImmGetCompositionStringW (himc, GCS_RESULTSTR, 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 (utf8str)              {                g_signal_emit_by_name (context, "commit", utf8str);                g_free (utf8str);		retval = TRUE;              }          }        if (context_ime->use_preedit)          retval = TRUE;        break;      }    case WM_IME_STARTCOMPOSITION:      context_ime->preediting = TRUE;      gtk_im_context_ime_set_cursor_location (context, NULL);      g_signal_emit_by_name (context, "preedit_start");      if (context_ime->use_preedit)        retval = TRUE;      break;    case WM_IME_ENDCOMPOSITION:      context_ime->preediting = FALSE;      g_signal_emit_by_name (context, "preedit_changed");      g_signal_emit_by_name (context, "preedit_end");      if (context_ime->use_preedit)        retval = TRUE;      break;    case WM_IME_NOTIFY:      switch (msg->wParam)        {        case IMN_SETOPENSTATUS:          context_ime->opened = ImmGetOpenStatus (himc);          gtk_im_context_ime_set_preedit_font (context);          break;        default:          break;        }    default:      break;    }  ImmReleaseContext (hwnd, himc);  return retval;}/* * x and y must be initialized to 0. */static voidget_window_position (GdkWindow *win, gint *x, gint *y){  GdkWindow *parent, *toplevel;  gint wx, wy;  g_return_if_fail (GDK_IS_WINDOW (win));  g_return_if_fail (x && y);  gdk_window_get_position (win, &wx, &wy);  *x += wx;  *y += wy;  parent = gdk_window_get_parent (win);  toplevel = gdk_window_get_toplevel (win);  if (parent && parent != toplevel)    get_window_position (parent, x, y);}/* *  probably, this handler isn't needed. */static voidcb_client_widget_hierarchy_changed (GtkWidget       *widget,                                    GtkWidget       *widget2,                                    GtkIMContextIME *context_ime){  GdkWindow *new_toplevel;  g_return_if_fail (GTK_IS_WIDGET (widget));  g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime));  if (!context_ime->client_window)    return;  if (!context_ime->focus)    return;  new_toplevel = gdk_window_get_toplevel (context_ime->client_window);  if (context_ime->toplevel == new_toplevel)    return;  /* remove filter from old toplevel */  if (GDK_IS_WINDOW (context_ime->toplevel))    {      gdk_window_remove_filter (context_ime->toplevel,                                gtk_im_context_ime_message_filter,                                context_ime);    }  else    {    }  /* add filter to new toplevel */  if (GDK_IS_WINDOW (new_toplevel))    {      gdk_window_add_filter (new_toplevel,                             gtk_im_context_ime_message_filter, context_ime);    }  else    {    }  context_ime->toplevel = new_toplevel;}

⌨️ 快捷键说明

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