summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>1998-12-09 06:36:57 +0000
committerOwen Taylor <otaylor@src.gnome.org>1998-12-09 06:36:57 +0000
commit207757e70d8b2d9aa8335d968fd7ac79796264ab (patch)
treeae572a9674c8dc7b8a0ae7200e6d4e7c5c7632e8 /gdk
parentaf84227184f9cbe2c87f0aa09d5c93564150bb70 (diff)
downloadgtk+-207757e70d8b2d9aa8335d968fd7ac79796264ab.tar.gz
Destroy widgets _after_ propagating unrealize signals through the widget
Mon Dec 7 10:27:09 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize signals through the widget heirarchy. This is unpleasant, as it causes more X traffic, but is necessary, because we have to clean up our Input Contexts before destroying the X windows. (from matsu-981109-0.patch) Mon Dec 7 10:18:18 1998 Owen Taylor <otaylor@redhat.com> Applied gtk-a-higuti-981202-0 : [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ] * gdk/gdk.h gdk/gdk.c (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but implemented by a combination of Xlib functions, so it works even with X_LOCALE. (gdk_wcstombs): New function. (g_mbtowc): Removed. No longer needed. * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: Added _wc() variants to gdk_text_width(), gdk_char_width(), gdk_draw_text(), * gdk/gdki18n.h (mblen, mbtowc, wctomb, mbstowcs, wcstombs, wcslen, wcscpy, wcsncpy): Removed. No longer needed. (iswalnum): Removed. (gdk_iswalnum): New macro. (gdk_iswspace): New macro. * gdk/gdktype.h (GdkWChar): New typedef. * gtk/gtkentry.h, gtk/gtkentry.c There are many changes according to the change of the internal representation of text, from multibyte string to wide characters. * gtk/gtkprivate.h, gtk/gtkmain.c Removed the variable gtk_use_mb and related codes. * gtk/gtkspinbutton.c Some changes according to the change of type of entry->text. * gtk/gtktext.h, gtk/gtktext.c Changed the internal representation of text. We use GdkWchar if a fontset is supplied. If not, we use guchar to save memory.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/Makefile.am3
-rw-r--r--gdk/gdk.c774
-rw-r--r--gdk/gdk.h63
-rw-r--r--gdk/gdkdraw.c60
-rw-r--r--gdk/gdkfont.c106
-rw-r--r--gdk/gdkglobals.c4
-rw-r--r--gdk/gdki18n.h123
-rw-r--r--gdk/gdkprivate.h17
-rw-r--r--gdk/gdktypes.h70
-rw-r--r--gdk/gdkwindow.c7
-rw-r--r--gdk/x11/gdkfont-x11.c106
-rw-r--r--gdk/x11/gdkglobals-x11.c4
-rw-r--r--gdk/x11/gdkmain-x11.c774
-rw-r--r--gdk/x11/gdkwindow-x11.c7
14 files changed, 542 insertions, 1576 deletions
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index ec4f78af9a..2766b3781a 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -24,6 +24,7 @@ libgdk_la_SOURCES = \
gdkfont.c \
gdkgc.c \
gdkglobals.c \
+ gdkim.c \
gdkimage.c \
gdkinput.c \
gdkinput.h \
@@ -53,7 +54,7 @@ gdkinclude_HEADERS = \
gdk.h \
gdkcursors.h \
gdkrgb.h \
- gdki18n.h \
+ gdki18n.h \
gdkkeysyms.h \
gdkprivate.h \
gdktypes.h \
diff --git a/gdk/gdk.c b/gdk/gdk.c
index f504ea313a..15dcaa3035 100644
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -28,9 +28,6 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-#ifdef USE_XIM
-#include <stdarg.h>
-#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
@@ -42,16 +39,13 @@
#include <X11/Xos.h>
#include <X11/Xutil.h>
#include <X11/Xmu/WinUtil.h>
-#ifdef USE_XIM
-#include <X11/Xresource.h>
-#endif
#include <X11/cursorfont.h>
#include "gdk.h"
#include "gdkprivate.h"
#include "gdkinput.h"
+#include "gdki18n.h"
#include "gdkx.h"
#include "gdkkeysyms.h"
-#include "gdki18n.h"
#ifndef X_GETTIMEOFDAY
#define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL)
@@ -139,21 +133,6 @@ static int gdk_x_error (Display *display,
static int gdk_x_io_error (Display *display);
static RETSIGTYPE gdk_signal (int signum);
-
-#ifdef USE_XIM
-static guint gdk_im_va_count (va_list list);
-static XVaNestedList gdk_im_va_to_nested (va_list list,
- guint count);
-
-static GdkIM gdk_im_get (void);
-static gint gdk_im_open (XrmDatabase db,
- gchar* res_name,
- gchar* rec_class);
-static void gdk_im_close (void);
-static void gdk_ic_cleanup (void);
-
-#endif /* USE_XIM */
-
GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data);
@@ -212,17 +191,6 @@ static GdkWindowPrivate *xgrab_window = NULL; /* Window that currently holds
static GList *client_filters; /* Filters for client messages */
-#ifdef USE_XIM
-static gint xim_using; /* using XIM Protocol if TRUE */
-static GdkIM xim_im; /* global IM */
-static XIMStyles* xim_styles; /* im supports these styles */
-static XIMStyle xim_best_allowed_style;
-static GdkICPrivate *xim_ic; /* currently using IC */
-static GdkWindow* xim_window; /* currently using Widow */
-static GList* xim_ic_list;
-
-#endif
-
static GList *putback_events = NULL;
static gulong base_id;
@@ -570,18 +538,7 @@ gdk_init (int *argc,
gdk_wm_protocols_filter, NULL);
#ifdef USE_XIM
- /* initialize XIM Protocol variables */
- xim_using = FALSE;
- xim_im = NULL;
- xim_styles = NULL;
- if (!(xim_best_allowed_style & GDK_IM_PREEDIT_MASK))
- gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS);
- if (!(xim_best_allowed_style & GDK_IM_STATUS_MASK))
- gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS);
- xim_ic = NULL;
- xim_window = (GdkWindow*)NULL;
-
- gdk_im_open (NULL, NULL, NULL);
+ gdk_im_open ();
#endif
gdk_initialized = 1;
@@ -1005,16 +962,22 @@ gdk_event_get (void)
* has occurred. Read it.
*/
#ifdef USE_XIM
- gint filter_status;
- if (xim_using && xim_window)
- do
- { /* don't dispatch events used by IM */
- XNextEvent (gdk_display, &xevent);
- filter_status = XFilterEvent (&xevent,
- GDK_WINDOW_XWINDOW (xim_window));
- } while (filter_status == True);
- else
- XNextEvent (gdk_display, &xevent);
+ Window w = None;
+
+ XNextEvent (gdk_display, &xevent);
+ if (gdk_xim_window)
+ switch (xevent.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ w = GDK_WINDOW_XWINDOW (gdk_xim_window);
+ break;
+ }
+
+ if (XFilterEvent (&xevent, w))
+ return NULL;
#else
XNextEvent (gdk_display, &xevent);
#endif
@@ -2067,13 +2030,6 @@ gdk_event_translate (GdkEvent *event,
if (window != NULL)
gdk_window_ref (window);
-#ifdef USE_XIM
- else if (XFilterEvent(xevent, None)) /* for xlib XIM handling */
- return FALSE;
-#endif
- else
- GDK_NOTE (EVENTS,
- g_message ("Got event for unknown window: %#lx\n", xevent->xany.window));
event->any.window = window;
event->any.send_event = xevent->xany.send_event;
@@ -2088,17 +2044,46 @@ gdk_event_translate (GdkEvent *event,
/* Check for filters for this window */
GdkFilterReturn result;
+
+#ifdef USE_XIM
+ if (window == NULL &&
+ xevent->type == KeyPress &&
+ gdk_xim_window &&
+ !((GdkWindowPrivate *) gdk_xim_window)->destroyed)
+ {
+ /*
+ * If user presses a key in Preedit or Status window, keypress event
+ * is sometimes sent to these windows. These windows are not managed
+ * by GDK, so we redirect KeyPress event to gdk_xim_window.
+ *
+ * If someone want to use the window whitch is not managed by GDK
+ * and want to get KeyPress event, he/she must register the filter
+ * function to gdk_default_filters to intercept the event.
+ */
+
+ window = gdk_xim_window;
+ window_private = (GdkWindowPrivate *) window;
+ gdk_window_ref (window);
+ event->any.window = window;
+
+ GDK_NOTE (XIM,
+ g_message ("KeyPress event is redirected to gdk_xim_window: %#lx",
+ xevent->xany.window));
+ }
+#endif /* USE_XIM */
+
result = gdk_event_apply_filters (xevent, event,
window_private
?window_private->filters
:gdk_default_filters);
if (result != GDK_FILTER_CONTINUE)
- {
- return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
- }
+ return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
}
+ if (window == NULL)
+ g_message ("Got event for unknown window: %#lx\n", xevent->xany.window);
+
/* We do a "manual" conversion of the XEvent to a
* GdkEvent. The structures are mostly the same so
* the conversion is fairly straightforward. We also
@@ -2121,12 +2106,12 @@ gdk_event_translate (GdkEvent *event,
}
keysym = GDK_VoidSymbol;
- if (xim_using == TRUE && xim_ic)
+ if (gdk_xim_ic && gdk_xim_ic->xic)
{
Status status;
/* Clear keyval. Depending on status, may not be set */
- charcount = XmbLookupString(xim_ic->xic,
+ charcount = XmbLookupString(gdk_xim_ic->xic,
&xevent->xkey, buf, buf_len-1,
&keysym, &status);
if (status == XBufferOverflow)
@@ -2139,7 +2124,7 @@ gdk_event_translate (GdkEvent *event,
buf_len *= 2;
buf = (gchar *) g_realloc (buf, buf_len);
- charcount = XmbLookupString (xim_ic->xic,
+ charcount = XmbLookupString (gdk_xim_ic->xic,
&xevent->xkey, buf, buf_len-1,
&keysym, &status);
}
@@ -2520,6 +2505,13 @@ gdk_event_translate (GdkEvent *event,
(xevent->xany.type == FocusIn) ? "in" : "out",
xevent->xfocus.window - base_id));
+ /* gdk_keyboard_grab() causes following events. These events confuse
+ * the XIM focus, so ignore them.
+ */
+ if (xevent->xfocus.mode == NotifyGrab ||
+ xevent->xfocus.mode == NotifyUngrab)
+ break;
+
event->focus_change.type = GDK_FOCUS_CHANGE;
event->focus_change.window = window;
event->focus_change.in = (xevent->xany.type == FocusIn);
@@ -3186,652 +3178,6 @@ gdk_signal (int sig_num)
#endif /* !G_ENABLE_DEBUG */
}
-#ifdef USE_XIM
-
-/* The following routines duplicate functionality in Xlib to
- * translate from varargs to X's internal opaque XVaNestedList.
- *
- * If all vendors have stuck close to the reference implementation,
- * then we should hopefully be OK.
- */
-
-/* This needs to match XIMArg as defined in Xlcint.h exactly */
-
-typedef struct {
- gchar *name;
- gpointer value;
-} GdkImArg;
-
-/*************************************************************
- * gdk_im_va_count:
- * Counts the number of name/value pairs in the vararg list
- *
- * arguments:
- *
- * results:
- *************************************************************/
-
-static guint
-gdk_im_va_count (va_list list)
-{
- gint count = 0;
- gchar *name;
-
- name = va_arg (list, gchar *);
- while (name)
- {
- count++;
- (void)va_arg (list, gpointer);
- name = va_arg (list, gchar *);
- }
-
- return count;
-}
-
-/*************************************************************
- * gdk_im_va_to_nested:
- * Given a varargs list and the result of gdk_im_va_count,
- * create a XVaNestedList.
- *
- * arguments:
- *
- * results:
- *************************************************************/
-
-static XVaNestedList
-gdk_im_va_to_nested (va_list list, guint count)
-{
- GdkImArg *result;
- GdkImArg *arg;
-
- gchar *name;
-
- if (count == 0)
- return NULL;
-
- result = g_new (GdkImArg, count+1);
- arg = result;
-
- name = va_arg (list, gchar *);
- while (name)
- {
- arg->name = name;
- arg->value = va_arg (list, gpointer);
- arg++;
- name = va_arg (list, gchar *);
- }
-
- arg->name = NULL;
-
- return (XVaNestedList)result;
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_begin
- *
- * Begin using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- * "ic" is the "Input Context" which is created by gtk_ic_new.
- * The input area is specified with "window".
- *
- * Results:
- * The gdk's event handling routine is switched to XIM based routine.
- * XIM based routine uses XFilterEvent to get rid of events used by IM,
- * and uses XmbLookupString instead of XLookupString.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
- GdkICPrivate *private;
- Window xwin;
-
- g_return_if_fail (ic != NULL);
- g_return_if_fail (window);
-
- private = (GdkICPrivate *) ic;
-
- xim_using = TRUE;
- xim_ic = private;
- xim_window = window;
- if (gdk_im_ready())
- {
- XGetICValues (private->xic, XNFocusWindow, &xwin, NULL);
- if (xwin != GDK_WINDOW_XWINDOW(window))
- XSetICValues (private->xic, XNFocusWindow,
- GDK_WINDOW_XWINDOW(window), NULL);
- if (private != xim_ic)
- XSetICFocus (private->xic);
- }
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_end
- *
- * End using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- *
- * Results:
- * The gdk's event handling routine is switched to normal routine.
- * User should call this function before ic and window will be destroyed.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void
-gdk_im_end (void)
-{
- xim_using = FALSE;
- xim_ic = NULL;
- xim_window = NULL;
-}
-
-static GdkIM
-gdk_im_get (void)
-{
- return xim_im;
-}
-
-static GdkIMStyle
-gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2)
-{
- GdkIMStyle s1, s2, u;
-
- if (style1 == 0) return style2;
- if (style2 == 0) return style1;
- if ((style1 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK))
- == (style2 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK)))
- return style1;
-
- s1 = style1 & GDK_IM_PREEDIT_MASK;
- s2 = style2 & GDK_IM_PREEDIT_MASK;
- u = s1 | s2;
- if (s1 != s2) {
- if (u & GDK_IM_PREEDIT_CALLBACKS)
- return (s1 == GDK_IM_PREEDIT_CALLBACKS)? style1:style2;
- else if (u & GDK_IM_PREEDIT_POSITION)
- return (s1 == GDK_IM_PREEDIT_POSITION)? style1:style2;
- else if (u & GDK_IM_PREEDIT_AREA)
- return (s1 == GDK_IM_PREEDIT_AREA)? style1:style2;
- else if (u & GDK_IM_PREEDIT_NOTHING)
- return (s1 == GDK_IM_PREEDIT_NOTHING)? style1:style2;
- } else {
- s1 = style1 & GDK_IM_STATUS_MASK;
- s2 = style2 & GDK_IM_STATUS_MASK;
- u = s1 | s2;
- if ( u & GDK_IM_STATUS_CALLBACKS)
- return (s1 == GDK_IM_STATUS_CALLBACKS)? style1:style2;
- else if ( u & GDK_IM_STATUS_AREA)
- return (s1 == GDK_IM_STATUS_AREA)? style1:style2;
- else if ( u & GDK_IM_STATUS_NOTHING)
- return (s1 == GDK_IM_STATUS_NOTHING)? style1:style2;
- else if ( u & GDK_IM_STATUS_NONE)
- return (s1 == GDK_IM_STATUS_NONE)? style1:style2;
- }
- return 0; /* Get rid of stupid warning */
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
- gint i;
- GdkIMStyle style, tmp;
-
- g_return_val_if_fail (xim_styles != NULL, 0);
-
- style = 0;
- for (i=0; i<xim_styles->count_styles; i++)
- {
- tmp = xim_styles->supported_styles[i];
- if (tmp == (tmp & supported_style & xim_best_allowed_style))
- style = gdk_im_choose_better_style (style, tmp);
- }
- return style;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
- if (style & GDK_IM_PREEDIT_MASK)
- {
- xim_best_allowed_style &= ~GDK_IM_PREEDIT_MASK;
-
- xim_best_allowed_style |= GDK_IM_PREEDIT_NONE;
- if (!(style & GDK_IM_PREEDIT_NONE))
- {
- xim_best_allowed_style |= GDK_IM_PREEDIT_NOTHING;
- if (!(style & GDK_IM_PREEDIT_NOTHING))
- {
- xim_best_allowed_style |= GDK_IM_PREEDIT_AREA;
- if (!(style & GDK_IM_PREEDIT_AREA))
- {
- xim_best_allowed_style |= GDK_IM_PREEDIT_POSITION;
- if (!(style & GDK_IM_PREEDIT_POSITION))
- xim_best_allowed_style |= GDK_IM_PREEDIT_CALLBACKS;
- }
- }
- }
- }
- if (style & GDK_IM_STATUS_MASK)
- {
- xim_best_allowed_style &= ~GDK_IM_STATUS_MASK;
-
- xim_best_allowed_style |= GDK_IM_STATUS_NONE;
- if (!(style & GDK_IM_STATUS_NONE))
- {
- xim_best_allowed_style |= GDK_IM_STATUS_NOTHING;
- if (!(style & GDK_IM_STATUS_NOTHING))
- {
- xim_best_allowed_style |= GDK_IM_STATUS_AREA;
- if (!(style & GDK_IM_STATUS_AREA))
- xim_best_allowed_style |= GDK_IM_STATUS_CALLBACKS;
- }
- }
- }
-
- return xim_best_allowed_style;
-}
-
-static gint
-gdk_im_open (XrmDatabase db, gchar* res_name, gchar* res_class)
-{
- xim_im = XOpenIM (GDK_DISPLAY(), db, res_name, res_class);
- if (xim_im == NULL)
- {
- GDK_NOTE (XIM, g_warning ("Unable to open open IM."));
- return FALSE;
- }
- XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL);
-
- return TRUE;
-}
-
-static void
-gdk_im_close (void)
-{
- if (xim_im)
- {
- XCloseIM (xim_im);
- xim_im = NULL;
- }
- if (xim_styles)
- {
- XFree (xim_styles);
- xim_styles = NULL;
- }
-}
-
-gint
-gdk_im_ready (void)
-{
- return (xim_im != NULL);
-}
-
-GdkIC
-gdk_ic_new (GdkWindow* client_window,
- GdkWindow* focus_window,
- GdkIMStyle style, ...)
-{
- va_list list;
- GdkICPrivate *private;
- XVaNestedList preedit_attr = NULL;
- guint count;
-
- g_return_val_if_fail (client_window != NULL, NULL);
- g_return_val_if_fail (focus_window != NULL, NULL);
- g_return_val_if_fail (gdk_im_ready(), NULL);
-
- private = g_new (GdkICPrivate, 1);
-
- va_start (list, style);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, style);
- preedit_attr = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- private->style = gdk_im_decide_style (style);
- if (private->style != style)
- {
- g_warning ("can not create input context with specified input style.");
- g_free (private);
- return NULL;
- }
-
- private->xic = XCreateIC(gdk_im_get (),
- XNInputStyle, style,
- XNClientWindow, GDK_WINDOW_XWINDOW (client_window),
- XNFocusWindow, GDK_WINDOW_XWINDOW (focus_window),
- preedit_attr? XNPreeditAttributes : NULL, preedit_attr,
- NULL);
-
- g_free (preedit_attr);
-
- if (!private->xic)
- {
- g_free (private);
- return NULL;
- }
-
- xim_ic_list = g_list_append (xim_ic_list, private);
- return private;
-}
-
-void
-gdk_ic_destroy (GdkIC ic)
-{
- GdkICPrivate *private;
-
- g_return_if_fail (ic != NULL);
-
- private = (GdkICPrivate *) ic;
-
- if (xim_ic == private)
- gdk_im_end ();
-
- XDestroyIC (private->xic);
- xim_ic_list = g_list_remove (xim_ic_list, private);
- g_free (private);
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
- GdkICPrivate *private;
-
- g_return_val_if_fail (ic != NULL, 0);
-
- private = (GdkICPrivate *) ic;
-
- return private->style;
-}
-
-void
-gdk_ic_set_values (GdkIC ic, ...)
-{
- va_list list;
- XVaNestedList args;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, ic);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, ic);
- args = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XSetICValues (private->xic, XNVaNestedList, args, NULL);
-
- g_free (args);
-}
-
-void
-gdk_ic_get_values (GdkIC ic, ...)
-{
- va_list list;
- XVaNestedList args;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, ic);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, ic);
- args = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XGetICValues (private->xic, XNVaNestedList, args, NULL);
-
- g_free (args);
-}
-
-void
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
- va_list list;
- XVaNestedList attr;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
- g_return_if_fail (target != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, target);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, target);
- attr = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XSetICValues (private->xic, target, attr, NULL);
-
- g_free (attr);
-}
-
-void
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
- va_list list;
- XVaNestedList attr;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
- g_return_if_fail (target != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, target);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, target);
- attr = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XGetICValues (private->xic, target, attr, NULL);
-
- g_free (attr);
-}
-
-GdkEventMask
-gdk_ic_get_events (GdkIC ic)
-{
- GdkEventMask mask;
- glong xmask;
- glong bit;
- GdkICPrivate *private;
- gint i;
-
- /* From gdkwindow.c */
- extern int nevent_masks;
- extern int event_mask_table[];
-
- g_return_val_if_fail (ic != NULL, 0);
-
- private = (GdkICPrivate *) ic;
-
- if (XGetICValues (private->xic, XNFilterEvents, &xmask, NULL) != NULL)
- {
- GDK_NOTE (XIM, g_warning ("Call to XGetICValues: %s failed", XNFilterEvents));
- return 0;
- }
-
- mask = 0;
- for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1)
- if (xmask & event_mask_table [i])
- {
- mask |= bit;
- xmask &= ~ event_mask_table [i];
- }
-
- if (xmask)
- g_warning ("ic requires events not supported by the application (%#04lx)", xmask);
-
- return mask;
-}
-
-static void
-gdk_ic_cleanup (void)
-{
- GList* node;
- gint destroyed;
- GdkICPrivate *private;
-
- destroyed = 0;
- for (node = xim_ic_list; node != NULL; node = node->next)
- {
- if (node->data)
- {
- private = (GdkICPrivate *) (node->data);
- XDestroyIC (private->xic);
- g_free (private);
- destroyed++;
- }
- }
-#ifdef G_ENABLE_DEBUG
- if ((gdk_debug_flags & GDK_DEBUG_XIM) && destroyed > 0)
- {
- g_warning ("Cleaned up %i IC(s)\n", destroyed);
- }
-#endif /* G_ENABLE_DEBUG */
- g_list_free(xim_ic_list);
- xim_ic_list = NULL;
-}
-
-#else /* !USE_XIM */
-
-void
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
-}
-
-void
-gdk_im_end (void)
-{
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
- return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
- return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-gint
-gdk_im_ready (void)
-{
- return FALSE;
-}
-
-GdkIC
-gdk_ic_new (GdkWindow* client_window,
- GdkWindow* focus_window,
- GdkIMStyle style, ...)
-{
- return NULL;
-}
-
-void
-gdk_ic_destroy (GdkIC ic)
-{
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
- return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-void
-gdk_ic_set_values (GdkIC ic, ...)
-{
-}
-
-void
-gdk_ic_get_values (GdkIC ic, ...)
-{
-}
-
-void
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-void
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-GdkEventMask
-gdk_ic_get_events (GdkIC ic)
-{
- return 0;
-}
-
-#endif /* USE_XIM */
-
-#ifdef X_LOCALE
-
-gint
-_g_mbtowc (wchar_t *wstr, const char *str, size_t len)
-{
- static wchar_t wcs[MB_CUR_MAX + 1];
- static gchar mbs[MB_CUR_MAX + 1];
-
- wcs[0] = (wchar_t) NULL;
- mbs[0] = '\0';
-
- /* The last argument isn't a mistake. The X locale code trims
- * the input string to the length of the output string!
- */
- len = _Xmbstowcs (wcs, str, (len<MB_CUR_MAX)? len:MB_CUR_MAX);
- if (len < 1)
- return len;
- else if (wcs[0] == (wchar_t) NULL)
- return -1;
-
- len = _Xwctomb (mbs, wcs[0]);
- if (mbs[0] == '\0')
- return -1;
- if (wstr)
- *wstr = wcs[0];
-
- return len;
-}
-
-#endif /* X_LOCALE */
-
/* Sends a ClientMessage to all toplevel client windows */
gboolean
gdk_event_send_client_message (GdkEvent *event, guint32 xid)
diff --git a/gdk/gdk.h b/gdk/gdk.h
index 4cd435a841..0127077fc2 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -22,7 +22,6 @@
#include <gdk/gdktypes.h>
-
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -571,8 +570,13 @@ gint gdk_string_width (GdkFont *font,
gint gdk_text_width (GdkFont *font,
const gchar *text,
gint text_length);
+gint gdk_text_width_wc (GdkFont *font,
+ const GdkWChar *text,
+ gint text_length);
gint gdk_char_width (GdkFont *font,
gchar character);
+gint gdk_char_width_wc (GdkFont *font,
+ GdkWChar character);
gint gdk_string_measure (GdkFont *font,
const gchar *string);
gint gdk_text_measure (GdkFont *font,
@@ -642,14 +646,21 @@ void gdk_draw_string (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
- const gchar *string);
+ const gchar *string);
void gdk_draw_text (GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
- const gchar *text,
+ const gchar *text,
gint text_length);
+void gdk_draw_text_wc (GdkDrawable *drawable,
+ GdkFont *font,
+ GdkGC *gc,
+ gint x,
+ gint y,
+ const GdkWChar *text,
+ gint text_length);
void gdk_draw_pixmap (GdkDrawable *drawable,
GdkGC *gc,
GdkDrawable *src,
@@ -798,25 +809,35 @@ GdkTimeCoord *gdk_input_motion_events (GdkWindow *window,
gint gdk_im_ready (void);
-void gdk_im_begin (GdkIC ic,
- GdkWindow* window);
+void gdk_im_begin (GdkIC *ic,
+ GdkWindow *window);
void gdk_im_end (void);
-GdkIMStyle gdk_im_decide_style (GdkIMStyle supported_style);
-GdkIMStyle gdk_im_set_best_style (GdkIMStyle best_allowed_style);
-GdkIC gdk_ic_new (GdkWindow* client_window,
- GdkWindow* focus_window,
- GdkIMStyle style, ...);
-void gdk_ic_destroy (GdkIC ic);
-GdkIMStyle gdk_ic_get_style (GdkIC ic);
-void gdk_ic_set_values (GdkIC ic,
- ...);
-void gdk_ic_get_values (GdkIC ic,
- ...);
-void gdk_ic_set_attr (GdkIC ic,
- const char *target, ...);
-void gdk_ic_get_attr (GdkIC ic,
- const char *target, ...);
-GdkEventMask gdk_ic_get_events (GdkIC ic);
+GdkIMStyle gdk_im_decide_style (GdkIMStyle supported_style);
+GdkIMStyle gdk_im_set_best_style (GdkIMStyle best_allowed_style);
+
+GdkIC* gdk_ic_new (GdkICAttr *attr,
+ GdkICAttributesType mask);
+void gdk_ic_destroy (GdkIC *ic);
+GdkIMStyle gdk_ic_get_style (GdkIC *ic);
+GdkEventMask gdk_ic_get_events (GdkIC *ic);
+
+GdkICAttr* gdk_ic_attr_new (void);
+void gdk_ic_attr_destroy (GdkICAttr *attr);
+
+GdkICAttributesType gdk_ic_set_attr (GdkIC *ic,
+ GdkICAttr *attr,
+ GdkICAttributesType mask);
+GdkICAttributesType gdk_ic_get_attr (GdkIC *ic,
+ GdkICAttr *attr,
+ GdkICAttributesType mask);
+
+/* Conversion functions between wide char and multibyte strings.
+ */
+gchar *gdk_wcstombs (const GdkWChar *src);
+gint gdk_mbstowcs (GdkWChar *dest,
+ const gchar *src,
+ gint dest_max);
+
/* Color Context */
diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c
index 2725367c16..2d61d5dc4a 100644
--- a/gdk/gdkdraw.c
+++ b/gdk/gdkdraw.c
@@ -294,6 +294,66 @@ gdk_draw_text (GdkDrawable *drawable,
}
void
+gdk_draw_text_wc (GdkDrawable *drawable,
+ GdkFont *font,
+ GdkGC *gc,
+ gint x,
+ gint y,
+ const GdkWChar *text,
+ gint text_length)
+{
+ GdkWindowPrivate *drawable_private;
+ GdkFontPrivate *font_private;
+ GdkGCPrivate *gc_private;
+
+ g_return_if_fail (drawable != NULL);
+ g_return_if_fail (font != NULL);
+ g_return_if_fail (gc != NULL);
+ g_return_if_fail (text != NULL);
+
+ drawable_private = (GdkWindowPrivate*) drawable;
+ if (drawable_private->destroyed)
+ return;
+ gc_private = (GdkGCPrivate*) gc;
+ font_private = (GdkFontPrivate*) font;
+
+ if (font->type == GDK_FONT_FONT)
+ {
+ XFontStruct *xfont = (XFontStruct *) font_private->xfont;
+ gchar *text_8bit;
+ gint i;
+ XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
+ text_8bit = g_new (gchar, text_length);
+ for (i=0; i<text_length; i++) text_8bit[i] = text[i];
+ XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+ gc_private->xgc, x, y, text_8bit, text_length);
+ g_free (text_8bit);
+ }
+ else if (font->type == GDK_FONT_FONTSET)
+ {
+ if (sizeof(GdkWChar) == sizeof(wchar_t))
+ {
+ XwcDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+ (XFontSet) font_private->xfont,
+ gc_private->xgc, x, y, (wchar_t *)text, text_length);
+ }
+ else
+ {
+ wchar_t *text_wchar;
+ gint i;
+ text_wchar = g_new (wchar_t, text_length);
+ for (i=0; i<text_length; i++) text_wchar[i] = text[i];
+ XwcDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+ (XFontSet) font_private->xfont,
+ gc_private->xgc, x, y, text_wchar, text_length);
+ g_free (text_wchar);
+ }
+ }
+ else
+ g_error("undefined font type\n");
+}
+
+void
gdk_draw_pixmap (GdkDrawable *drawable,
GdkGC *gc,
GdkPixmap *src,
diff --git a/gdk/gdkfont.c b/gdk/gdkfont.c
index cc1274a0d6..0308fa8e0d 100644
--- a/gdk/gdkfont.c
+++ b/gdk/gdkfont.c
@@ -271,6 +271,62 @@ gdk_text_width (GdkFont *font,
return width;
}
+gint
+gdk_text_width_wc (GdkFont *font,
+ const GdkWChar *text,
+ gint text_length)
+{
+ GdkFontPrivate *private;
+ gint width;
+ XFontStruct *xfont;
+ XFontSet fontset;
+
+ g_return_val_if_fail (font != NULL, -1);
+ g_return_val_if_fail (text != NULL, -1);
+
+ private = (GdkFontPrivate*) font;
+
+ switch (font->type)
+ {
+ case GDK_FONT_FONT:
+ xfont = (XFontStruct *) private->xfont;
+ if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+ {
+ gchar *text_8bit;
+ gint i;
+ text_8bit = g_new (gchar, text_length);
+ for (i=0; i<text_length; i++) text_8bit[i] = text[i];
+ width = XTextWidth (xfont, text_8bit, text_length);
+ g_free (text_8bit);
+ }
+ else
+ {
+ width = 0;
+ }
+ break;
+ case GDK_FONT_FONTSET:
+ if (sizeof(GdkWChar) == sizeof(wchar_t))
+ {
+ fontset = (XFontSet) private->xfont;
+ width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
+ }
+ else
+ {
+ wchar_t *text_wchar;
+ gint i;
+ fontset = (XFontSet) private->xfont;
+ text_wchar = g_new(wchar_t, text_length);
+ for (i=0; i<text_length; i++) text_wchar[i] = text[i];
+ width = XwcTextEscapement (fontset, text_wchar, text_length);
+ g_free (text_wchar);
+ }
+ break;
+ default:
+ width = 0;
+ }
+ return width;
+}
+
/* Problem: What if a character is a 16 bits character ?? */
gint
gdk_char_width (GdkFont *font,
@@ -319,6 +375,56 @@ gdk_char_width (GdkFont *font,
}
gint
+gdk_char_width_wc (GdkFont *font,
+ GdkWChar character)
+{
+ GdkFontPrivate *private;
+ XCharStruct *chars;
+ gint width;
+ guint ch = character & 0xff; /* get rid of sign-extension */
+ XFontStruct *xfont;
+ XFontSet fontset;
+
+ g_return_val_if_fail (font != NULL, -1);
+
+ private = (GdkFontPrivate*) font;
+
+ switch (font->type)
+ {
+ case GDK_FONT_FONT:
+ /* only 8 bits characters are considered here */
+ xfont = (XFontStruct *) private->xfont;
+ if ((xfont->min_byte1 == 0) &&
+ (xfont->max_byte1 == 0) &&
+ (ch >= xfont->min_char_or_byte2) &&
+ (ch <= xfont->max_char_or_byte2))
+ {
+ chars = xfont->per_char;
+ if (chars)
+ width = chars[ch - xfont->min_char_or_byte2].width;
+ else
+ width = xfont->min_bounds.width;
+ }
+ else
+ {
+ char ch2 = character;
+ width = XTextWidth (xfont, &ch2, 1);
+ }
+ break;
+ case GDK_FONT_FONTSET:
+ fontset = (XFontSet) private->xfont;
+ {
+ wchar_t char_wc = character;
+ width = XwcTextEscapement (fontset, &char_wc, 1) ;
+ }
+ break;
+ default:
+ width = 0;
+ }
+ return width;
+}
+
+gint
gdk_string_measure (GdkFont *font,
const gchar *string)
{
diff --git a/gdk/gdkglobals.c b/gdk/gdkglobals.c
index 5736a1a80d..eeebb51491 100644
--- a/gdk/gdkglobals.c
+++ b/gdk/gdkglobals.c
@@ -62,4 +62,8 @@ gint gdk_threads_pipe[2];
gboolean gdk_select_waiting = FALSE;
#endif
+#ifdef USE_XIM
+GdkICPrivate *gdk_xim_ic; /* currently using IC */
+GdkWindow *gdk_xim_window; /* currently using Window */
+#endif
diff --git a/gdk/gdki18n.h b/gdk/gdki18n.h
index f2bf8553df..c7dba9e702 100644
--- a/gdk/gdki18n.h
+++ b/gdk/gdki18n.h
@@ -28,124 +28,6 @@
#include <stdlib.h>
-#ifdef X_LOCALE
-
-#include <X11/Xfuncproto.h>
-#include <X11/Xosdefs.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-_XFUNCPROTOBEGIN
-extern int _Xmblen (
-#if NeedFunctionPrototypes
- const char *s, size_t n
-#endif
-
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xmbtowc (
-#if NeedFunctionPrototypes
- wchar_t *wstr, const char *str, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xwctomb (
-#if NeedFunctionPrototypes
- char *str, wchar_t wc
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern size_t _Xmbstowcs (
-#if NeedFunctionPrototypes
- wchar_t *wstr, const char *str, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern size_t _Xwcstombs (
-#if NeedFunctionPrototypes
- char *str, const wchar_t *wstr, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern size_t _Xwcslen (
-#if NeedFunctionPrototypes
- const wchar_t *wstr
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern wchar_t* _Xwcscpy (
-#if NeedFunctionPrototypes
- wchar_t *wstr1, const wchar_t *wstr2
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern wchar_t* _Xwcsncpy (
-#if NeedFunctionPrototypes
- wchar_t *wstr1, const wchar_t *wstr2, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xwcscmp (
-#if NeedFunctionPrototypes
- const wchar_t *wstr1, const wchar_t *wstr2
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xwcsncmp (
-#if NeedFunctionPrototypes
- const wchar_t *wstr1, const wchar_t *wstr2, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-/*
- * mblen, mbtowc, and mbstowcs of the locale "ja_JP.eucJP" are buggy.
- */
-
-#ifdef MB_CUR_MAX
-# undef MB_CUR_MAX
-#endif
-#define MB_CUR_MAX 4
-extern int _g_mbtowc (wchar_t *wstr, const char *str, size_t len);
-
-/* #define mblen _Xmblen */
-/* #define mbtowc _Xmbtowc */
-#define mblen(a,b) _g_mbtowc ((wchar_t *)(NULL), (a), (b))
-#define mbtowc(a,b,c) _g_mbtowc ((a),(b),(c))
-
-#define wctomb(a,b) _Xwctomb ((a),(b))
-#define mbstowcs(a,b,c) _Xmbstowcs ((a),(b),(c))
-#define wcstombs(a,b,c) _Xwcstombs ((a),(b),(c))
-#define wcslen(a) _Xwcslen ((a))
-#define wcscpy(a,b) _Xwcscpy ((a),(b))
-#define wcsncpy(a,b,c) _Xwcsncpy ((a),(b),(c))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* X_LOCALE */
-
#if !defined(G_HAVE_BROKEN_WCTYPE) && (defined(G_HAVE_WCTYPE_H) || defined(G_HAVE_WCHAR_H)) && !defined(X_LOCALE)
# ifdef G_HAVE_WCTYPE_H
# include <wctype.h>
@@ -154,8 +36,11 @@ extern int _g_mbtowc (wchar_t *wstr, const char *str, size_t len);
# include <wchar.h>
# endif
# endif
+# define gdk_iswalnum(c) iswalnum(c)
+# define gdk_iswspace(c) iswspace(c)
#else
-# define iswalnum(c) ((wchar_t)(c) <= 0xFF && isalnum(c))
+# define gdk_iswalnum(c) ((wchar_t)(c) <= 0xFF && isalnum(c))
+# define gdk_iswspace(c) ((wchar_t)(c) <= 0xFF && isspace(c))
#endif
#endif /* __GDK_I18N_H__ */
diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h
index d7f71cd224..e095853d3f 100644
--- a/gdk/gdkprivate.h
+++ b/gdk/gdkprivate.h
@@ -186,14 +186,15 @@ struct _GdkClientFilter {
#ifdef USE_XIM
+typedef struct _GdkICPrivate GdkICPrivate;
+
struct _GdkICPrivate
{
XIC xic;
- GdkIMStyle style;
+ GdkICAttr *attr;
+ GdkICAttributesType mask;
};
-typedef struct _GdkICPrivate GdkICPrivate;
-
#endif /* USE_XIM */
struct _GdkColorContextPrivate
@@ -282,6 +283,16 @@ extern gint gdk_threads_pipe[2];
extern gboolean gdk_select_waiting;
#endif
+#ifdef USE_XIM
+/* XIM support */
+gint gdk_im_open (void);
+void gdk_im_close (void);
+void gdk_ic_cleanup (void);
+
+extern GdkICPrivate *gdk_xim_ic; /* currently using IC */
+extern GdkWindow *gdk_xim_window; /* currently using Window */
+#endif USE_XIM
+
/* Debugging support */
#ifdef G_ENABLE_DEBUG
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
index bb38385b84..99befe3cb9 100644
--- a/gdk/gdktypes.h
+++ b/gdk/gdktypes.h
@@ -89,9 +89,11 @@ typedef struct _GdkRegion GdkRegion;
typedef gint (*GdkEventFunc) (GdkEvent *event,
gpointer data);
-typedef void* GdkIC;
-typedef void* GdkIM;
+typedef struct _GdkIC GdkIC;
+typedef struct _GdkICAttr GdkICAttr;
+typedef guint32 GdkWChar;
+
/* Types of windows.
* Root: There is only 1 root window and it is initialized
@@ -617,6 +619,45 @@ typedef enum /*< flags >*/
GDK_IM_STATUS_MASK = 0x0f00
} GdkIMStyle;
+typedef enum
+{
+ GDK_IC_STYLE = 1 << 0,
+ GDK_IC_CLIENT_WINDOW = 1 << 1,
+ GDK_IC_FOCUS_WINDOW = 1 << 2,
+ GDK_IC_FILTER_EVENTS = 1 << 3,
+ GDK_IC_SPOT_LOCATION = 1 << 4,
+ GDK_IC_LINE_SPACING = 1 << 5,
+ GDK_IC_CURSOR = 1 << 6,
+
+ GDK_IC_PREEDIT_FONTSET = 1 << 10,
+ GDK_IC_PREEDIT_AREA = 1 << 11,
+ GDK_IC_PREEDIT_AREA_NEEDED = 1 << 12,
+ GDK_IC_PREEDIT_FOREGROUND = 1 << 13,
+ GDK_IC_PREEDIT_BACKGROUND = 1 << 14,
+ GDK_IC_PREEDIT_PIXMAP = 1 << 15,
+ GDK_IC_PREEDIT_COLORMAP = 1 << 16,
+
+ GDK_IC_STATUS_FONTSET = 1 << 21,
+ GDK_IC_STATUS_AREA = 1 << 22,
+ GDK_IC_STATUS_AREA_NEEDED = 1 << 23,
+ GDK_IC_STATUS_FOREGROUND = 1 << 24,
+ GDK_IC_STATUS_BACKGROUND = 1 << 25,
+ GDK_IC_STATUS_PIXMAP = 1 << 26,
+ GDK_IC_STATUS_COLORMAP = 1 << 27,
+
+ GDK_IC_ALL_REQ = GDK_IC_STYLE |
+ GDK_IC_CLIENT_WINDOW,
+
+ GDK_IC_PREEDIT_AREA_REQ = GDK_IC_PREEDIT_AREA |
+ GDK_IC_PREEDIT_FONTSET,
+ GDK_IC_PREEDIT_POSITION_REQ = GDK_IC_PREEDIT_AREA |
+ GDK_IC_SPOT_LOCATION |
+ GDK_IC_PREEDIT_FONTSET,
+
+ GDK_IC_STATUS_AREA_REQ = GDK_IC_STATUS_AREA |
+ GDK_IC_STATUS_FONTSET,
+} GdkICAttributesType;
+
/* The next two enumeration values current match the
* Motif constants. If this is changed, the implementation
* of gdk_window_set_decorations/gdk_window_set_functions
@@ -1182,7 +1223,32 @@ struct _GdkRegion
gpointer user_data;
};
+struct _GdkICAttr
+{
+ GdkIMStyle style;
+ GdkWindow *client_window;
+ GdkWindow *focus_window;
+ GdkEventMask filter_events;
+ GdkPoint spot_location;
+ gint line_spacing;
+ GdkCursor *cursor;
+ GdkFont *preedit_fontset;
+ GdkRectangle preedit_area;
+ GdkRectangle preedit_area_needed;
+ GdkColor preedit_foreground;
+ GdkColor preedit_background;
+ GdkPixmap *preedit_pixmap;
+ GdkColormap *preedit_colormap;
+
+ GdkFont *status_fontset;
+ GdkRectangle status_area;
+ GdkRectangle status_area_needed;
+ GdkColor status_foreground;
+ GdkColor status_background;
+ GdkPixmap *status_pixmap;
+ GdkColormap *status_colormap;
+};
#ifdef __cplusplus
}
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index efbd713144..72a56d8584 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -323,7 +323,12 @@ gdk_window_new (GdkWindow *parent,
if (attributes_mask & GDK_WA_COLORMAP)
private->colormap = attributes->colormap;
else
- private->colormap = gdk_colormap_get_system ();
+ {
+ if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
+ private->colormap = gdk_colormap_get_system ();
+ else
+ private->colormap = gdk_colormap_new (visual, False);
+ }
xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
diff --git a/gdk/x11/gdkfont-x11.c b/gdk/x11/gdkfont-x11.c
index cc1274a0d6..0308fa8e0d 100644
--- a/gdk/x11/gdkfont-x11.c
+++ b/gdk/x11/gdkfont-x11.c
@@ -271,6 +271,62 @@ gdk_text_width (GdkFont *font,
return width;
}
+gint
+gdk_text_width_wc (GdkFont *font,
+ const GdkWChar *text,
+ gint text_length)
+{
+ GdkFontPrivate *private;
+ gint width;
+ XFontStruct *xfont;
+ XFontSet fontset;
+
+ g_return_val_if_fail (font != NULL, -1);
+ g_return_val_if_fail (text != NULL, -1);
+
+ private = (GdkFontPrivate*) font;
+
+ switch (font->type)
+ {
+ case GDK_FONT_FONT:
+ xfont = (XFontStruct *) private->xfont;
+ if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+ {
+ gchar *text_8bit;
+ gint i;
+ text_8bit = g_new (gchar, text_length);
+ for (i=0; i<text_length; i++) text_8bit[i] = text[i];
+ width = XTextWidth (xfont, text_8bit, text_length);
+ g_free (text_8bit);
+ }
+ else
+ {
+ width = 0;
+ }
+ break;
+ case GDK_FONT_FONTSET:
+ if (sizeof(GdkWChar) == sizeof(wchar_t))
+ {
+ fontset = (XFontSet) private->xfont;
+ width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
+ }
+ else
+ {
+ wchar_t *text_wchar;
+ gint i;
+ fontset = (XFontSet) private->xfont;
+ text_wchar = g_new(wchar_t, text_length);
+ for (i=0; i<text_length; i++) text_wchar[i] = text[i];
+ width = XwcTextEscapement (fontset, text_wchar, text_length);
+ g_free (text_wchar);
+ }
+ break;
+ default:
+ width = 0;
+ }
+ return width;
+}
+
/* Problem: What if a character is a 16 bits character ?? */
gint
gdk_char_width (GdkFont *font,
@@ -319,6 +375,56 @@ gdk_char_width (GdkFont *font,
}
gint
+gdk_char_width_wc (GdkFont *font,
+ GdkWChar character)
+{
+ GdkFontPrivate *private;
+ XCharStruct *chars;
+ gint width;
+ guint ch = character & 0xff; /* get rid of sign-extension */
+ XFontStruct *xfont;
+ XFontSet fontset;
+
+ g_return_val_if_fail (font != NULL, -1);
+
+ private = (GdkFontPrivate*) font;
+
+ switch (font->type)
+ {
+ case GDK_FONT_FONT:
+ /* only 8 bits characters are considered here */
+ xfont = (XFontStruct *) private->xfont;
+ if ((xfont->min_byte1 == 0) &&
+ (xfont->max_byte1 == 0) &&
+ (ch >= xfont->min_char_or_byte2) &&
+ (ch <= xfont->max_char_or_byte2))
+ {
+ chars = xfont->per_char;
+ if (chars)
+ width = chars[ch - xfont->min_char_or_byte2].width;
+ else
+ width = xfont->min_bounds.width;
+ }
+ else
+ {
+ char ch2 = character;
+ width = XTextWidth (xfont, &ch2, 1);
+ }
+ break;
+ case GDK_FONT_FONTSET:
+ fontset = (XFontSet) private->xfont;
+ {
+ wchar_t char_wc = character;
+ width = XwcTextEscapement (fontset, &char_wc, 1) ;
+ }
+ break;
+ default:
+ width = 0;
+ }
+ return width;
+}
+
+gint
gdk_string_measure (GdkFont *font,
const gchar *string)
{
diff --git a/gdk/x11/gdkglobals-x11.c b/gdk/x11/gdkglobals-x11.c
index 5736a1a80d..eeebb51491 100644
--- a/gdk/x11/gdkglobals-x11.c
+++ b/gdk/x11/gdkglobals-x11.c
@@ -62,4 +62,8 @@ gint gdk_threads_pipe[2];
gboolean gdk_select_waiting = FALSE;
#endif
+#ifdef USE_XIM
+GdkICPrivate *gdk_xim_ic; /* currently using IC */
+GdkWindow *gdk_xim_window; /* currently using Window */
+#endif
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index f504ea313a..15dcaa3035 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -28,9 +28,6 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-#ifdef USE_XIM
-#include <stdarg.h>
-#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
@@ -42,16 +39,13 @@
#include <X11/Xos.h>
#include <X11/Xutil.h>
#include <X11/Xmu/WinUtil.h>
-#ifdef USE_XIM
-#include <X11/Xresource.h>
-#endif
#include <X11/cursorfont.h>
#include "gdk.h"
#include "gdkprivate.h"
#include "gdkinput.h"
+#include "gdki18n.h"
#include "gdkx.h"
#include "gdkkeysyms.h"
-#include "gdki18n.h"
#ifndef X_GETTIMEOFDAY
#define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL)
@@ -139,21 +133,6 @@ static int gdk_x_error (Display *display,
static int gdk_x_io_error (Display *display);
static RETSIGTYPE gdk_signal (int signum);
-
-#ifdef USE_XIM
-static guint gdk_im_va_count (va_list list);
-static XVaNestedList gdk_im_va_to_nested (va_list list,
- guint count);
-
-static GdkIM gdk_im_get (void);
-static gint gdk_im_open (XrmDatabase db,
- gchar* res_name,
- gchar* rec_class);
-static void gdk_im_close (void);
-static void gdk_ic_cleanup (void);
-
-#endif /* USE_XIM */
-
GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data);
@@ -212,17 +191,6 @@ static GdkWindowPrivate *xgrab_window = NULL; /* Window that currently holds
static GList *client_filters; /* Filters for client messages */
-#ifdef USE_XIM
-static gint xim_using; /* using XIM Protocol if TRUE */
-static GdkIM xim_im; /* global IM */
-static XIMStyles* xim_styles; /* im supports these styles */
-static XIMStyle xim_best_allowed_style;
-static GdkICPrivate *xim_ic; /* currently using IC */
-static GdkWindow* xim_window; /* currently using Widow */
-static GList* xim_ic_list;
-
-#endif
-
static GList *putback_events = NULL;
static gulong base_id;
@@ -570,18 +538,7 @@ gdk_init (int *argc,
gdk_wm_protocols_filter, NULL);
#ifdef USE_XIM
- /* initialize XIM Protocol variables */
- xim_using = FALSE;
- xim_im = NULL;
- xim_styles = NULL;
- if (!(xim_best_allowed_style & GDK_IM_PREEDIT_MASK))
- gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS);
- if (!(xim_best_allowed_style & GDK_IM_STATUS_MASK))
- gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS);
- xim_ic = NULL;
- xim_window = (GdkWindow*)NULL;
-
- gdk_im_open (NULL, NULL, NULL);
+ gdk_im_open ();
#endif
gdk_initialized = 1;
@@ -1005,16 +962,22 @@ gdk_event_get (void)
* has occurred. Read it.
*/
#ifdef USE_XIM
- gint filter_status;
- if (xim_using && xim_window)
- do
- { /* don't dispatch events used by IM */
- XNextEvent (gdk_display, &xevent);
- filter_status = XFilterEvent (&xevent,
- GDK_WINDOW_XWINDOW (xim_window));
- } while (filter_status == True);
- else
- XNextEvent (gdk_display, &xevent);
+ Window w = None;
+
+ XNextEvent (gdk_display, &xevent);
+ if (gdk_xim_window)
+ switch (xevent.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ w = GDK_WINDOW_XWINDOW (gdk_xim_window);
+ break;
+ }
+
+ if (XFilterEvent (&xevent, w))
+ return NULL;
#else
XNextEvent (gdk_display, &xevent);
#endif
@@ -2067,13 +2030,6 @@ gdk_event_translate (GdkEvent *event,
if (window != NULL)
gdk_window_ref (window);
-#ifdef USE_XIM
- else if (XFilterEvent(xevent, None)) /* for xlib XIM handling */
- return FALSE;
-#endif
- else
- GDK_NOTE (EVENTS,
- g_message ("Got event for unknown window: %#lx\n", xevent->xany.window));
event->any.window = window;
event->any.send_event = xevent->xany.send_event;
@@ -2088,17 +2044,46 @@ gdk_event_translate (GdkEvent *event,
/* Check for filters for this window */
GdkFilterReturn result;
+
+#ifdef USE_XIM
+ if (window == NULL &&
+ xevent->type == KeyPress &&
+ gdk_xim_window &&
+ !((GdkWindowPrivate *) gdk_xim_window)->destroyed)
+ {
+ /*
+ * If user presses a key in Preedit or Status window, keypress event
+ * is sometimes sent to these windows. These windows are not managed
+ * by GDK, so we redirect KeyPress event to gdk_xim_window.
+ *
+ * If someone want to use the window whitch is not managed by GDK
+ * and want to get KeyPress event, he/she must register the filter
+ * function to gdk_default_filters to intercept the event.
+ */
+
+ window = gdk_xim_window;
+ window_private = (GdkWindowPrivate *) window;
+ gdk_window_ref (window);
+ event->any.window = window;
+
+ GDK_NOTE (XIM,
+ g_message ("KeyPress event is redirected to gdk_xim_window: %#lx",
+ xevent->xany.window));
+ }
+#endif /* USE_XIM */
+
result = gdk_event_apply_filters (xevent, event,
window_private
?window_private->filters
:gdk_default_filters);
if (result != GDK_FILTER_CONTINUE)
- {
- return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
- }
+ return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
}
+ if (window == NULL)
+ g_message ("Got event for unknown window: %#lx\n", xevent->xany.window);
+
/* We do a "manual" conversion of the XEvent to a
* GdkEvent. The structures are mostly the same so
* the conversion is fairly straightforward. We also
@@ -2121,12 +2106,12 @@ gdk_event_translate (GdkEvent *event,
}
keysym = GDK_VoidSymbol;
- if (xim_using == TRUE && xim_ic)
+ if (gdk_xim_ic && gdk_xim_ic->xic)
{
Status status;
/* Clear keyval. Depending on status, may not be set */
- charcount = XmbLookupString(xim_ic->xic,
+ charcount = XmbLookupString(gdk_xim_ic->xic,
&xevent->xkey, buf, buf_len-1,
&keysym, &status);
if (status == XBufferOverflow)
@@ -2139,7 +2124,7 @@ gdk_event_translate (GdkEvent *event,
buf_len *= 2;
buf = (gchar *) g_realloc (buf, buf_len);
- charcount = XmbLookupString (xim_ic->xic,
+ charcount = XmbLookupString (gdk_xim_ic->xic,
&xevent->xkey, buf, buf_len-1,
&keysym, &status);
}
@@ -2520,6 +2505,13 @@ gdk_event_translate (GdkEvent *event,
(xevent->xany.type == FocusIn) ? "in" : "out",
xevent->xfocus.window - base_id));
+ /* gdk_keyboard_grab() causes following events. These events confuse
+ * the XIM focus, so ignore them.
+ */
+ if (xevent->xfocus.mode == NotifyGrab ||
+ xevent->xfocus.mode == NotifyUngrab)
+ break;
+
event->focus_change.type = GDK_FOCUS_CHANGE;
event->focus_change.window = window;
event->focus_change.in = (xevent->xany.type == FocusIn);
@@ -3186,652 +3178,6 @@ gdk_signal (int sig_num)
#endif /* !G_ENABLE_DEBUG */
}
-#ifdef USE_XIM
-
-/* The following routines duplicate functionality in Xlib to
- * translate from varargs to X's internal opaque XVaNestedList.
- *
- * If all vendors have stuck close to the reference implementation,
- * then we should hopefully be OK.
- */
-
-/* This needs to match XIMArg as defined in Xlcint.h exactly */
-
-typedef struct {
- gchar *name;
- gpointer value;
-} GdkImArg;
-
-/*************************************************************
- * gdk_im_va_count:
- * Counts the number of name/value pairs in the vararg list
- *
- * arguments:
- *
- * results:
- *************************************************************/
-
-static guint
-gdk_im_va_count (va_list list)
-{
- gint count = 0;
- gchar *name;
-
- name = va_arg (list, gchar *);
- while (name)
- {
- count++;
- (void)va_arg (list, gpointer);
- name = va_arg (list, gchar *);
- }
-
- return count;
-}
-
-/*************************************************************
- * gdk_im_va_to_nested:
- * Given a varargs list and the result of gdk_im_va_count,
- * create a XVaNestedList.
- *
- * arguments:
- *
- * results:
- *************************************************************/
-
-static XVaNestedList
-gdk_im_va_to_nested (va_list list, guint count)
-{
- GdkImArg *result;
- GdkImArg *arg;
-
- gchar *name;
-
- if (count == 0)
- return NULL;
-
- result = g_new (GdkImArg, count+1);
- arg = result;
-
- name = va_arg (list, gchar *);
- while (name)
- {
- arg->name = name;
- arg->value = va_arg (list, gpointer);
- arg++;
- name = va_arg (list, gchar *);
- }
-
- arg->name = NULL;
-
- return (XVaNestedList)result;
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_begin
- *
- * Begin using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- * "ic" is the "Input Context" which is created by gtk_ic_new.
- * The input area is specified with "window".
- *
- * Results:
- * The gdk's event handling routine is switched to XIM based routine.
- * XIM based routine uses XFilterEvent to get rid of events used by IM,
- * and uses XmbLookupString instead of XLookupString.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
- GdkICPrivate *private;
- Window xwin;
-
- g_return_if_fail (ic != NULL);
- g_return_if_fail (window);
-
- private = (GdkICPrivate *) ic;
-
- xim_using = TRUE;
- xim_ic = private;
- xim_window = window;
- if (gdk_im_ready())
- {
- XGetICValues (private->xic, XNFocusWindow, &xwin, NULL);
- if (xwin != GDK_WINDOW_XWINDOW(window))
- XSetICValues (private->xic, XNFocusWindow,
- GDK_WINDOW_XWINDOW(window), NULL);
- if (private != xim_ic)
- XSetICFocus (private->xic);
- }
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_end
- *
- * End using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- *
- * Results:
- * The gdk's event handling routine is switched to normal routine.
- * User should call this function before ic and window will be destroyed.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void
-gdk_im_end (void)
-{
- xim_using = FALSE;
- xim_ic = NULL;
- xim_window = NULL;
-}
-
-static GdkIM
-gdk_im_get (void)
-{
- return xim_im;
-}
-
-static GdkIMStyle
-gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2)
-{
- GdkIMStyle s1, s2, u;
-
- if (style1 == 0) return style2;
- if (style2 == 0) return style1;
- if ((style1 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK))
- == (style2 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK)))
- return style1;
-
- s1 = style1 & GDK_IM_PREEDIT_MASK;
- s2 = style2 & GDK_IM_PREEDIT_MASK;
- u = s1 | s2;
- if (s1 != s2) {
- if (u & GDK_IM_PREEDIT_CALLBACKS)
- return (s1 == GDK_IM_PREEDIT_CALLBACKS)? style1:style2;
- else if (u & GDK_IM_PREEDIT_POSITION)
- return (s1 == GDK_IM_PREEDIT_POSITION)? style1:style2;
- else if (u & GDK_IM_PREEDIT_AREA)
- return (s1 == GDK_IM_PREEDIT_AREA)? style1:style2;
- else if (u & GDK_IM_PREEDIT_NOTHING)
- return (s1 == GDK_IM_PREEDIT_NOTHING)? style1:style2;
- } else {
- s1 = style1 & GDK_IM_STATUS_MASK;
- s2 = style2 & GDK_IM_STATUS_MASK;
- u = s1 | s2;
- if ( u & GDK_IM_STATUS_CALLBACKS)
- return (s1 == GDK_IM_STATUS_CALLBACKS)? style1:style2;
- else if ( u & GDK_IM_STATUS_AREA)
- return (s1 == GDK_IM_STATUS_AREA)? style1:style2;
- else if ( u & GDK_IM_STATUS_NOTHING)
- return (s1 == GDK_IM_STATUS_NOTHING)? style1:style2;
- else if ( u & GDK_IM_STATUS_NONE)
- return (s1 == GDK_IM_STATUS_NONE)? style1:style2;
- }
- return 0; /* Get rid of stupid warning */
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
- gint i;
- GdkIMStyle style, tmp;
-
- g_return_val_if_fail (xim_styles != NULL, 0);
-
- style = 0;
- for (i=0; i<xim_styles->count_styles; i++)
- {
- tmp = xim_styles->supported_styles[i];
- if (tmp == (tmp & supported_style & xim_best_allowed_style))
- style = gdk_im_choose_better_style (style, tmp);
- }
- return style;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
- if (style & GDK_IM_PREEDIT_MASK)
- {
- xim_best_allowed_style &= ~GDK_IM_PREEDIT_MASK;
-
- xim_best_allowed_style |= GDK_IM_PREEDIT_NONE;
- if (!(style & GDK_IM_PREEDIT_NONE))
- {
- xim_best_allowed_style |= GDK_IM_PREEDIT_NOTHING;
- if (!(style & GDK_IM_PREEDIT_NOTHING))
- {
- xim_best_allowed_style |= GDK_IM_PREEDIT_AREA;
- if (!(style & GDK_IM_PREEDIT_AREA))
- {
- xim_best_allowed_style |= GDK_IM_PREEDIT_POSITION;
- if (!(style & GDK_IM_PREEDIT_POSITION))
- xim_best_allowed_style |= GDK_IM_PREEDIT_CALLBACKS;
- }
- }
- }
- }
- if (style & GDK_IM_STATUS_MASK)
- {
- xim_best_allowed_style &= ~GDK_IM_STATUS_MASK;
-
- xim_best_allowed_style |= GDK_IM_STATUS_NONE;
- if (!(style & GDK_IM_STATUS_NONE))
- {
- xim_best_allowed_style |= GDK_IM_STATUS_NOTHING;
- if (!(style & GDK_IM_STATUS_NOTHING))
- {
- xim_best_allowed_style |= GDK_IM_STATUS_AREA;
- if (!(style & GDK_IM_STATUS_AREA))
- xim_best_allowed_style |= GDK_IM_STATUS_CALLBACKS;
- }
- }
- }
-
- return xim_best_allowed_style;
-}
-
-static gint
-gdk_im_open (XrmDatabase db, gchar* res_name, gchar* res_class)
-{
- xim_im = XOpenIM (GDK_DISPLAY(), db, res_name, res_class);
- if (xim_im == NULL)
- {
- GDK_NOTE (XIM, g_warning ("Unable to open open IM."));
- return FALSE;
- }
- XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL);
-
- return TRUE;
-}
-
-static void
-gdk_im_close (void)
-{
- if (xim_im)
- {
- XCloseIM (xim_im);
- xim_im = NULL;
- }
- if (xim_styles)
- {
- XFree (xim_styles);
- xim_styles = NULL;
- }
-}
-
-gint
-gdk_im_ready (void)
-{
- return (xim_im != NULL);
-}
-
-GdkIC
-gdk_ic_new (GdkWindow* client_window,
- GdkWindow* focus_window,
- GdkIMStyle style, ...)
-{
- va_list list;
- GdkICPrivate *private;
- XVaNestedList preedit_attr = NULL;
- guint count;
-
- g_return_val_if_fail (client_window != NULL, NULL);
- g_return_val_if_fail (focus_window != NULL, NULL);
- g_return_val_if_fail (gdk_im_ready(), NULL);
-
- private = g_new (GdkICPrivate, 1);
-
- va_start (list, style);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, style);
- preedit_attr = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- private->style = gdk_im_decide_style (style);
- if (private->style != style)
- {
- g_warning ("can not create input context with specified input style.");
- g_free (private);
- return NULL;
- }
-
- private->xic = XCreateIC(gdk_im_get (),
- XNInputStyle, style,
- XNClientWindow, GDK_WINDOW_XWINDOW (client_window),
- XNFocusWindow, GDK_WINDOW_XWINDOW (focus_window),
- preedit_attr? XNPreeditAttributes : NULL, preedit_attr,
- NULL);
-
- g_free (preedit_attr);
-
- if (!private->xic)
- {
- g_free (private);
- return NULL;
- }
-
- xim_ic_list = g_list_append (xim_ic_list, private);
- return private;
-}
-
-void
-gdk_ic_destroy (GdkIC ic)
-{
- GdkICPrivate *private;
-
- g_return_if_fail (ic != NULL);
-
- private = (GdkICPrivate *) ic;
-
- if (xim_ic == private)
- gdk_im_end ();
-
- XDestroyIC (private->xic);
- xim_ic_list = g_list_remove (xim_ic_list, private);
- g_free (private);
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
- GdkICPrivate *private;
-
- g_return_val_if_fail (ic != NULL, 0);
-
- private = (GdkICPrivate *) ic;
-
- return private->style;
-}
-
-void
-gdk_ic_set_values (GdkIC ic, ...)
-{
- va_list list;
- XVaNestedList args;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, ic);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, ic);
- args = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XSetICValues (private->xic, XNVaNestedList, args, NULL);
-
- g_free (args);
-}
-
-void
-gdk_ic_get_values (GdkIC ic, ...)
-{
- va_list list;
- XVaNestedList args;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, ic);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, ic);
- args = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XGetICValues (private->xic, XNVaNestedList, args, NULL);
-
- g_free (args);
-}
-
-void
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
- va_list list;
- XVaNestedList attr;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
- g_return_if_fail (target != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, target);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, target);
- attr = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XSetICValues (private->xic, target, attr, NULL);
-
- g_free (attr);
-}
-
-void
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
- va_list list;
- XVaNestedList attr;
- GdkICPrivate *private;
- guint count;
-
- g_return_if_fail (ic != NULL);
- g_return_if_fail (target != NULL);
-
- private = (GdkICPrivate *) ic;
-
- va_start (list, target);
- count = gdk_im_va_count (list);
- va_end (list);
-
- va_start (list, target);
- attr = gdk_im_va_to_nested (list, count);
- va_end (list);
-
- XGetICValues (private->xic, target, attr, NULL);
-
- g_free (attr);
-}
-
-GdkEventMask
-gdk_ic_get_events (GdkIC ic)
-{
- GdkEventMask mask;
- glong xmask;
- glong bit;
- GdkICPrivate *private;
- gint i;
-
- /* From gdkwindow.c */
- extern int nevent_masks;
- extern int event_mask_table[];
-
- g_return_val_if_fail (ic != NULL, 0);
-
- private = (GdkICPrivate *) ic;
-
- if (XGetICValues (private->xic, XNFilterEvents, &xmask, NULL) != NULL)
- {
- GDK_NOTE (XIM, g_warning ("Call to XGetICValues: %s failed", XNFilterEvents));
- return 0;
- }
-
- mask = 0;
- for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1)
- if (xmask & event_mask_table [i])
- {
- mask |= bit;
- xmask &= ~ event_mask_table [i];
- }
-
- if (xmask)
- g_warning ("ic requires events not supported by the application (%#04lx)", xmask);
-
- return mask;
-}
-
-static void
-gdk_ic_cleanup (void)
-{
- GList* node;
- gint destroyed;
- GdkICPrivate *private;
-
- destroyed = 0;
- for (node = xim_ic_list; node != NULL; node = node->next)
- {
- if (node->data)
- {
- private = (GdkICPrivate *) (node->data);
- XDestroyIC (private->xic);
- g_free (private);
- destroyed++;
- }
- }
-#ifdef G_ENABLE_DEBUG
- if ((gdk_debug_flags & GDK_DEBUG_XIM) && destroyed > 0)
- {
- g_warning ("Cleaned up %i IC(s)\n", destroyed);
- }
-#endif /* G_ENABLE_DEBUG */
- g_list_free(xim_ic_list);
- xim_ic_list = NULL;
-}
-
-#else /* !USE_XIM */
-
-void
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
-}
-
-void
-gdk_im_end (void)
-{
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
- return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
- return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-gint
-gdk_im_ready (void)
-{
- return FALSE;
-}
-
-GdkIC
-gdk_ic_new (GdkWindow* client_window,
- GdkWindow* focus_window,
- GdkIMStyle style, ...)
-{
- return NULL;
-}
-
-void
-gdk_ic_destroy (GdkIC ic)
-{
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
- return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-void
-gdk_ic_set_values (GdkIC ic, ...)
-{
-}
-
-void
-gdk_ic_get_values (GdkIC ic, ...)
-{
-}
-
-void
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-void
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-GdkEventMask
-gdk_ic_get_events (GdkIC ic)
-{
- return 0;
-}
-
-#endif /* USE_XIM */
-
-#ifdef X_LOCALE
-
-gint
-_g_mbtowc (wchar_t *wstr, const char *str, size_t len)
-{
- static wchar_t wcs[MB_CUR_MAX + 1];
- static gchar mbs[MB_CUR_MAX + 1];
-
- wcs[0] = (wchar_t) NULL;
- mbs[0] = '\0';
-
- /* The last argument isn't a mistake. The X locale code trims
- * the input string to the length of the output string!
- */
- len = _Xmbstowcs (wcs, str, (len<MB_CUR_MAX)? len:MB_CUR_MAX);
- if (len < 1)
- return len;
- else if (wcs[0] == (wchar_t) NULL)
- return -1;
-
- len = _Xwctomb (mbs, wcs[0]);
- if (mbs[0] == '\0')
- return -1;
- if (wstr)
- *wstr = wcs[0];
-
- return len;
-}
-
-#endif /* X_LOCALE */
-
/* Sends a ClientMessage to all toplevel client windows */
gboolean
gdk_event_send_client_message (GdkEvent *event, guint32 xid)
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index efbd713144..72a56d8584 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -323,7 +323,12 @@ gdk_window_new (GdkWindow *parent,
if (attributes_mask & GDK_WA_COLORMAP)
private->colormap = attributes->colormap;
else
- private->colormap = gdk_colormap_get_system ();
+ {
+ if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
+ private->colormap = gdk_colormap_get_system ();
+ else
+ private->colormap = gdk_colormap_new (visual, False);
+ }
xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);