diff options
author | Owen Taylor <otaylor@redhat.com> | 1998-12-09 06:36:57 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 1998-12-09 06:36:57 +0000 |
commit | 207757e70d8b2d9aa8335d968fd7ac79796264ab (patch) | |
tree | ae572a9674c8dc7b8a0ae7200e6d4e7c5c7632e8 /gdk | |
parent | af84227184f9cbe2c87f0aa09d5c93564150bb70 (diff) | |
download | gtk+-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.am | 3 | ||||
-rw-r--r-- | gdk/gdk.c | 774 | ||||
-rw-r--r-- | gdk/gdk.h | 63 | ||||
-rw-r--r-- | gdk/gdkdraw.c | 60 | ||||
-rw-r--r-- | gdk/gdkfont.c | 106 | ||||
-rw-r--r-- | gdk/gdkglobals.c | 4 | ||||
-rw-r--r-- | gdk/gdki18n.h | 123 | ||||
-rw-r--r-- | gdk/gdkprivate.h | 17 | ||||
-rw-r--r-- | gdk/gdktypes.h | 70 | ||||
-rw-r--r-- | gdk/gdkwindow.c | 7 | ||||
-rw-r--r-- | gdk/x11/gdkfont-x11.c | 106 | ||||
-rw-r--r-- | gdk/x11/gdkglobals-x11.c | 4 | ||||
-rw-r--r-- | gdk/x11/gdkmain-x11.c | 774 | ||||
-rw-r--r-- | gdk/x11/gdkwindow-x11.c | 7 |
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 \ @@ -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) @@ -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); |