summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>1998-08-25 00:06:38 +0000
committerOwen Taylor <otaylor@src.gnome.org>1998-08-25 00:06:38 +0000
commitcaf8ebc6f141697ae7a8a89ddce6afc295c69588 (patch)
tree7a5490219e90c7d42bda5f5f8c965e85fb5b98d3
parentb93d68929025fd54f10c9dcdfaa95b023406d057 (diff)
downloadgdk-pixbuf-caf8ebc6f141697ae7a8a89ddce6afc295c69588.tar.gz
Reference count the fonts used in the text widget.
Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtktext.c: Reference count the fonts used in the text widget. * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation freeing functions to be more consistent, and more convenient; leave the old names in for backwards compatibility. * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the allocations in pseudo-color colormaps to greatly reduce calls to XAllocColor. Keep a per-colormap hashtable to speed up finding if there is an already-allocated matching color. * gdk/gdkcolor.c: Don't just match read the system colormap when the colormap is created, but synchronize our copy with the system colormap periodically. * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c: Change XIM constants names to match GDK conventions * gtk/testinput.c: Allow the drawing area to get the focus. * gtk/testgtk.c: Change around the Text test to demonstrates multiple fonts, use more colors. * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual() so they work after a widget is unrealized. * gtk/gtktext.[ch]: Remove the requirement that the text widget be realized before adding text (!) Allocate colors ourself, instead of requiring the caller allocate them. Allow changing styles to work properly by keeping track of the values for a certain property are default or set explicitely. * gtk/gtkmenu.h: Added some comments. * gtk/gtkentry.c: Changes to match XIM constants. * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(), for adding keyed data to drawables. (Uses g_dataset internally) * gdk/gdkpixmap.c: Keep track of the colors we allocate, when creating an XPM - store them as user data for the GdkPixmap, so we don't leak colors when we create pixmaps from XPM's. Allocate memory for color information in large blocks instead of as many little pieces.
-rw-r--r--ChangeLog52
-rw-r--r--ChangeLog.pre-2-052
-rw-r--r--ChangeLog.pre-2-1052
-rw-r--r--ChangeLog.pre-2-252
-rw-r--r--ChangeLog.pre-2-452
-rw-r--r--ChangeLog.pre-2-652
-rw-r--r--ChangeLog.pre-2-852
-rw-r--r--TODO2
-rw-r--r--gdk/gdk.c122
-rw-r--r--gdk/gdk.h65
-rw-r--r--gdk/gdkcolor.c678
-rw-r--r--gdk/gdkpixmap.c88
-rw-r--r--gdk/gdkprivate.h17
-rw-r--r--gdk/gdktypes.h30
-rw-r--r--gdk/gdkwindow.c10
-rw-r--r--gdk/gdkx.h2
-rw-r--r--gdk/x11/gdkcolor-x11.c678
-rw-r--r--gdk/x11/gdkmain-x11.c122
-rw-r--r--gdk/x11/gdkpixmap-x11.c88
-rw-r--r--gdk/x11/gdkwindow-x11.c10
-rw-r--r--gdk/x11/gdkx.h2
-rw-r--r--gtk/gtk.defs23
-rw-r--r--gtk/gtkentry.c16
-rw-r--r--gtk/gtkmenu.h26
-rw-r--r--gtk/gtktext.c482
-rw-r--r--gtk/gtktext.h5
-rw-r--r--gtk/gtktypebuiltins.h1
-rw-r--r--gtk/gtktypebuiltins_evals.c24
-rw-r--r--gtk/gtktypebuiltins_ids.c2
-rw-r--r--gtk/gtktypebuiltins_vars.c1
-rw-r--r--gtk/gtkwidget.c24
-rw-r--r--gtk/testgtk.c69
-rw-r--r--gtk/testgtkrc2
-rw-r--r--gtk/testinput.c1
-rw-r--r--tests/testgtk.c69
-rw-r--r--tests/testgtkrc2
-rw-r--r--tests/testinput.c1
37 files changed, 2421 insertions, 605 deletions
diff --git a/ChangeLog b/ChangeLog
index 6cefa1fc3..65f98ce78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtktext.c: Reference count the fonts used in
+ the text widget.
+
+ * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation
+ freeing functions to be more consistent, and more
+ convenient; leave the old names in for backwards compatibility.
+
+ * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the
+ allocations in pseudo-color colormaps to greatly reduce
+ calls to XAllocColor. Keep a per-colormap hashtable to
+ speed up finding if there is an already-allocated matching
+ color.
+
+ * gdk/gdkcolor.c: Don't just match read the system colormap
+ when the colormap is created, but synchronize our copy
+ with the system colormap periodically.
+
+ * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c:
+ Change XIM constants names to match GDK conventions
+
+ * gtk/testinput.c: Allow the drawing area to get the focus.
+
+ * gtk/testgtk.c: Change around the Text test to demonstrates
+ multiple fonts, use more colors.
+
+ * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual()
+ so they work after a widget is unrealized.
+
+ * gtk/gtktext.[ch]: Remove the requirement that the text
+ widget be realized before adding text (!) Allocate colors
+ ourself, instead of requiring the caller allocate them.
+ Allow changing styles to work properly by keeping track
+ of the values for a certain property are default or
+ set explicitely.
+
+ * gtk/gtkmenu.h: Added some comments.
+
+ * gtk/gtkentry.c: Changes to match XIM constants.
+
+ * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(),
+ for adding keyed data to drawables. (Uses g_dataset
+ internally)
+
+ * gdk/gdkpixmap.c: Keep track of the colors we allocate,
+ when creating an XPM - store them as user data for the GdkPixmap,
+ so we don't leak colors when we create pixmaps from XPM's.
+
+ Allocate memory for color information in large blocks instead of
+ as many little pieces.
+
Mon Aug 24 11:09:32 PDT 1998 Manish Singh <yosh@gimp.org>
* gdk/gdkrgb.c: removed some unused variables
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 6cefa1fc3..65f98ce78 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,55 @@
+Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtktext.c: Reference count the fonts used in
+ the text widget.
+
+ * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation
+ freeing functions to be more consistent, and more
+ convenient; leave the old names in for backwards compatibility.
+
+ * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the
+ allocations in pseudo-color colormaps to greatly reduce
+ calls to XAllocColor. Keep a per-colormap hashtable to
+ speed up finding if there is an already-allocated matching
+ color.
+
+ * gdk/gdkcolor.c: Don't just match read the system colormap
+ when the colormap is created, but synchronize our copy
+ with the system colormap periodically.
+
+ * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c:
+ Change XIM constants names to match GDK conventions
+
+ * gtk/testinput.c: Allow the drawing area to get the focus.
+
+ * gtk/testgtk.c: Change around the Text test to demonstrates
+ multiple fonts, use more colors.
+
+ * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual()
+ so they work after a widget is unrealized.
+
+ * gtk/gtktext.[ch]: Remove the requirement that the text
+ widget be realized before adding text (!) Allocate colors
+ ourself, instead of requiring the caller allocate them.
+ Allow changing styles to work properly by keeping track
+ of the values for a certain property are default or
+ set explicitely.
+
+ * gtk/gtkmenu.h: Added some comments.
+
+ * gtk/gtkentry.c: Changes to match XIM constants.
+
+ * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(),
+ for adding keyed data to drawables. (Uses g_dataset
+ internally)
+
+ * gdk/gdkpixmap.c: Keep track of the colors we allocate,
+ when creating an XPM - store them as user data for the GdkPixmap,
+ so we don't leak colors when we create pixmaps from XPM's.
+
+ Allocate memory for color information in large blocks instead of
+ as many little pieces.
+
Mon Aug 24 11:09:32 PDT 1998 Manish Singh <yosh@gimp.org>
* gdk/gdkrgb.c: removed some unused variables
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 6cefa1fc3..65f98ce78 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,55 @@
+Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtktext.c: Reference count the fonts used in
+ the text widget.
+
+ * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation
+ freeing functions to be more consistent, and more
+ convenient; leave the old names in for backwards compatibility.
+
+ * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the
+ allocations in pseudo-color colormaps to greatly reduce
+ calls to XAllocColor. Keep a per-colormap hashtable to
+ speed up finding if there is an already-allocated matching
+ color.
+
+ * gdk/gdkcolor.c: Don't just match read the system colormap
+ when the colormap is created, but synchronize our copy
+ with the system colormap periodically.
+
+ * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c:
+ Change XIM constants names to match GDK conventions
+
+ * gtk/testinput.c: Allow the drawing area to get the focus.
+
+ * gtk/testgtk.c: Change around the Text test to demonstrates
+ multiple fonts, use more colors.
+
+ * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual()
+ so they work after a widget is unrealized.
+
+ * gtk/gtktext.[ch]: Remove the requirement that the text
+ widget be realized before adding text (!) Allocate colors
+ ourself, instead of requiring the caller allocate them.
+ Allow changing styles to work properly by keeping track
+ of the values for a certain property are default or
+ set explicitely.
+
+ * gtk/gtkmenu.h: Added some comments.
+
+ * gtk/gtkentry.c: Changes to match XIM constants.
+
+ * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(),
+ for adding keyed data to drawables. (Uses g_dataset
+ internally)
+
+ * gdk/gdkpixmap.c: Keep track of the colors we allocate,
+ when creating an XPM - store them as user data for the GdkPixmap,
+ so we don't leak colors when we create pixmaps from XPM's.
+
+ Allocate memory for color information in large blocks instead of
+ as many little pieces.
+
Mon Aug 24 11:09:32 PDT 1998 Manish Singh <yosh@gimp.org>
* gdk/gdkrgb.c: removed some unused variables
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 6cefa1fc3..65f98ce78 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,55 @@
+Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtktext.c: Reference count the fonts used in
+ the text widget.
+
+ * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation
+ freeing functions to be more consistent, and more
+ convenient; leave the old names in for backwards compatibility.
+
+ * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the
+ allocations in pseudo-color colormaps to greatly reduce
+ calls to XAllocColor. Keep a per-colormap hashtable to
+ speed up finding if there is an already-allocated matching
+ color.
+
+ * gdk/gdkcolor.c: Don't just match read the system colormap
+ when the colormap is created, but synchronize our copy
+ with the system colormap periodically.
+
+ * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c:
+ Change XIM constants names to match GDK conventions
+
+ * gtk/testinput.c: Allow the drawing area to get the focus.
+
+ * gtk/testgtk.c: Change around the Text test to demonstrates
+ multiple fonts, use more colors.
+
+ * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual()
+ so they work after a widget is unrealized.
+
+ * gtk/gtktext.[ch]: Remove the requirement that the text
+ widget be realized before adding text (!) Allocate colors
+ ourself, instead of requiring the caller allocate them.
+ Allow changing styles to work properly by keeping track
+ of the values for a certain property are default or
+ set explicitely.
+
+ * gtk/gtkmenu.h: Added some comments.
+
+ * gtk/gtkentry.c: Changes to match XIM constants.
+
+ * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(),
+ for adding keyed data to drawables. (Uses g_dataset
+ internally)
+
+ * gdk/gdkpixmap.c: Keep track of the colors we allocate,
+ when creating an XPM - store them as user data for the GdkPixmap,
+ so we don't leak colors when we create pixmaps from XPM's.
+
+ Allocate memory for color information in large blocks instead of
+ as many little pieces.
+
Mon Aug 24 11:09:32 PDT 1998 Manish Singh <yosh@gimp.org>
* gdk/gdkrgb.c: removed some unused variables
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 6cefa1fc3..65f98ce78 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,55 @@
+Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtktext.c: Reference count the fonts used in
+ the text widget.
+
+ * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation
+ freeing functions to be more consistent, and more
+ convenient; leave the old names in for backwards compatibility.
+
+ * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the
+ allocations in pseudo-color colormaps to greatly reduce
+ calls to XAllocColor. Keep a per-colormap hashtable to
+ speed up finding if there is an already-allocated matching
+ color.
+
+ * gdk/gdkcolor.c: Don't just match read the system colormap
+ when the colormap is created, but synchronize our copy
+ with the system colormap periodically.
+
+ * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c:
+ Change XIM constants names to match GDK conventions
+
+ * gtk/testinput.c: Allow the drawing area to get the focus.
+
+ * gtk/testgtk.c: Change around the Text test to demonstrates
+ multiple fonts, use more colors.
+
+ * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual()
+ so they work after a widget is unrealized.
+
+ * gtk/gtktext.[ch]: Remove the requirement that the text
+ widget be realized before adding text (!) Allocate colors
+ ourself, instead of requiring the caller allocate them.
+ Allow changing styles to work properly by keeping track
+ of the values for a certain property are default or
+ set explicitely.
+
+ * gtk/gtkmenu.h: Added some comments.
+
+ * gtk/gtkentry.c: Changes to match XIM constants.
+
+ * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(),
+ for adding keyed data to drawables. (Uses g_dataset
+ internally)
+
+ * gdk/gdkpixmap.c: Keep track of the colors we allocate,
+ when creating an XPM - store them as user data for the GdkPixmap,
+ so we don't leak colors when we create pixmaps from XPM's.
+
+ Allocate memory for color information in large blocks instead of
+ as many little pieces.
+
Mon Aug 24 11:09:32 PDT 1998 Manish Singh <yosh@gimp.org>
* gdk/gdkrgb.c: removed some unused variables
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 6cefa1fc3..65f98ce78 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,55 @@
+Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtktext.c: Reference count the fonts used in
+ the text widget.
+
+ * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation
+ freeing functions to be more consistent, and more
+ convenient; leave the old names in for backwards compatibility.
+
+ * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the
+ allocations in pseudo-color colormaps to greatly reduce
+ calls to XAllocColor. Keep a per-colormap hashtable to
+ speed up finding if there is an already-allocated matching
+ color.
+
+ * gdk/gdkcolor.c: Don't just match read the system colormap
+ when the colormap is created, but synchronize our copy
+ with the system colormap periodically.
+
+ * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c:
+ Change XIM constants names to match GDK conventions
+
+ * gtk/testinput.c: Allow the drawing area to get the focus.
+
+ * gtk/testgtk.c: Change around the Text test to demonstrates
+ multiple fonts, use more colors.
+
+ * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual()
+ so they work after a widget is unrealized.
+
+ * gtk/gtktext.[ch]: Remove the requirement that the text
+ widget be realized before adding text (!) Allocate colors
+ ourself, instead of requiring the caller allocate them.
+ Allow changing styles to work properly by keeping track
+ of the values for a certain property are default or
+ set explicitely.
+
+ * gtk/gtkmenu.h: Added some comments.
+
+ * gtk/gtkentry.c: Changes to match XIM constants.
+
+ * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(),
+ for adding keyed data to drawables. (Uses g_dataset
+ internally)
+
+ * gdk/gdkpixmap.c: Keep track of the colors we allocate,
+ when creating an XPM - store them as user data for the GdkPixmap,
+ so we don't leak colors when we create pixmaps from XPM's.
+
+ Allocate memory for color information in large blocks instead of
+ as many little pieces.
+
Mon Aug 24 11:09:32 PDT 1998 Manish Singh <yosh@gimp.org>
* gdk/gdkrgb.c: removed some unused variables
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 6cefa1fc3..65f98ce78 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,55 @@
+Mon Aug 24 18:37:15 1998 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtktext.c: Reference count the fonts used in
+ the text widget.
+
+ * gdk/gdk.h gdk/gdkcolor.c: Rename the color allocation
+ freeing functions to be more consistent, and more
+ convenient; leave the old names in for backwards compatibility.
+
+ * gdk/gdkcolor.c gdk/gdkprivate.h: Reference count the
+ allocations in pseudo-color colormaps to greatly reduce
+ calls to XAllocColor. Keep a per-colormap hashtable to
+ speed up finding if there is an already-allocated matching
+ color.
+
+ * gdk/gdkcolor.c: Don't just match read the system colormap
+ when the colormap is created, but synchronize our copy
+ with the system colormap periodically.
+
+ * gdk/gdk.c gdk/gdktypes.h gtk/gtkentry.c gtk/gtktext.c:
+ Change XIM constants names to match GDK conventions
+
+ * gtk/testinput.c: Allow the drawing area to get the focus.
+
+ * gtk/testgtk.c: Change around the Text test to demonstrates
+ multiple fonts, use more colors.
+
+ * gtk/gtkwidget.c: Improve gtk_widget_get_colormap()/visual()
+ so they work after a widget is unrealized.
+
+ * gtk/gtktext.[ch]: Remove the requirement that the text
+ widget be realized before adding text (!) Allocate colors
+ ourself, instead of requiring the caller allocate them.
+ Allow changing styles to work properly by keeping track
+ of the values for a certain property are default or
+ set explicitely.
+
+ * gtk/gtkmenu.h: Added some comments.
+
+ * gtk/gtkentry.c: Changes to match XIM constants.
+
+ * gtk/gdk.h gdk/gdkwindow.c: Add gdk_drawable_set_data(),
+ for adding keyed data to drawables. (Uses g_dataset
+ internally)
+
+ * gdk/gdkpixmap.c: Keep track of the colors we allocate,
+ when creating an XPM - store them as user data for the GdkPixmap,
+ so we don't leak colors when we create pixmaps from XPM's.
+
+ Allocate memory for color information in large blocks instead of
+ as many little pieces.
+
Mon Aug 24 11:09:32 PDT 1998 Manish Singh <yosh@gimp.org>
* gdk/gdkrgb.c: removed some unused variables
diff --git a/TODO b/TODO
index 0be764de5..6f22b89b7 100644
--- a/TODO
+++ b/TODO
@@ -271,3 +271,5 @@ Text/Edit widget:
[ From: Stefan Jeske <jeske@braunschweig.netsurf.de> ]
- "changed" emitted when doing deletes on empty Text widget.
+
+ - Delete IC in editable->unrealize, not editable->finalize? \ No newline at end of file
diff --git a/gdk/gdk.c b/gdk/gdk.c
index 5573d1001..1932d7d3b 100644
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -446,15 +446,15 @@ gdk_init (int *argc,
{
(*argv)[i++] = NULL;
if (strcmp ("none", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditNone);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_NONE);
else if (strcmp ("nothing", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditNothing);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_NOTHING);
else if (strcmp ("area", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditArea);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_AREA);
else if (strcmp ("position", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditPosition);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_POSITION);
else if (strcmp ("callbacks", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditCallbacks);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS);
}
}
else if (strcmp ("--xim-status", (*argv)[i]) == 0)
@@ -463,13 +463,13 @@ gdk_init (int *argc,
{
(*argv)[i++] = NULL;
if (strcmp ("none", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusNone);
+ gdk_im_set_best_style (GDK_IM_STATUS_NONE);
else if (strcmp ("nothing", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusNothing);
+ gdk_im_set_best_style (GDK_IM_STATUS_NOTHING);
else if (strcmp ("area", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusArea);
+ gdk_im_set_best_style (GDK_IM_STATUS_AREA);
else if (strcmp ("callbacks", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusCallbacks);
+ gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS);
}
}
#endif
@@ -584,10 +584,10 @@ gdk_init (int *argc,
xim_using = FALSE;
xim_im = NULL;
xim_styles = NULL;
- if (!(xim_best_allowed_style & GdkIMPreeditMask))
- gdk_im_set_best_style (GdkIMPreeditCallbacks);
- if (!(xim_best_allowed_style & GdkIMStatusMask))
- gdk_im_set_best_style (GdkIMStatusCallbacks);
+ 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;
@@ -3570,34 +3570,34 @@ gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2)
if (style1 == 0) return style2;
if (style2 == 0) return style1;
- if ((style1 & (GdkIMPreeditMask | GdkIMStatusMask))
- == (style2 & (GdkIMPreeditMask | GdkIMStatusMask)))
+ if ((style1 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK))
+ == (style2 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK)))
return style1;
-
- s1 = style1 & GdkIMPreeditMask;
- s2 = style2 & GdkIMPreeditMask;
+
+ s1 = style1 & GDK_IM_PREEDIT_MASK;
+ s2 = style2 & GDK_IM_PREEDIT_MASK;
u = s1 | s2;
if (s1 != s2) {
- if (u & GdkIMPreeditCallbacks)
- return (s1 == GdkIMPreeditCallbacks)? style1:style2;
- else if (u & GdkIMPreeditPosition)
- return (s1 == GdkIMPreeditPosition)? style1:style2;
- else if (u & GdkIMPreeditArea)
- return (s1 == GdkIMPreeditArea)? style1:style2;
- else if (u & GdkIMPreeditNothing)
- return (s1 == GdkIMPreeditNothing)? style1:style2;
+ 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 & GdkIMStatusMask;
- s2 = style2 & GdkIMStatusMask;
+ s1 = style1 & GDK_IM_STATUS_MASK;
+ s2 = style2 & GDK_IM_STATUS_MASK;
u = s1 | s2;
- if ( u & GdkIMStatusCallbacks)
- return (s1 == GdkIMStatusCallbacks)? style1:style2;
- else if ( u & GdkIMStatusArea)
- return (s1 == GdkIMStatusArea)? style1:style2;
- else if ( u & GdkIMStatusNothing)
- return (s1 == GdkIMStatusNothing)? style1:style2;
- else if ( u & GdkIMStatusNone)
- return (s1 == GdkIMStatusNone)? style1:style2;
+ 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 */
}
@@ -3623,39 +3623,39 @@ gdk_im_decide_style (GdkIMStyle supported_style)
GdkIMStyle
gdk_im_set_best_style (GdkIMStyle style)
{
- if (style & GdkIMPreeditMask)
+ if (style & GDK_IM_PREEDIT_MASK)
{
- xim_best_allowed_style &= ~GdkIMPreeditMask;
-
- xim_best_allowed_style |= GdkIMPreeditNone;
- if (!(style & GdkIMPreeditNone))
+ 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 |= GdkIMPreeditNothing;
- if (!(style & GdkIMPreeditNothing))
+ xim_best_allowed_style |= GDK_IM_PREEDIT_NOTHING;
+ if (!(style & GDK_IM_PREEDIT_NOTHING))
{
- xim_best_allowed_style |= GdkIMPreeditArea;
- if (!(style & GdkIMPreeditArea))
+ xim_best_allowed_style |= GDK_IM_PREEDIT_AREA;
+ if (!(style & GDK_IM_PREEDIT_AREA))
{
- xim_best_allowed_style |= GdkIMPreeditPosition;
- if (!(style & GdkIMPreeditPosition))
- xim_best_allowed_style |= GdkIMPreeditCallbacks;
+ xim_best_allowed_style |= GDK_IM_PREEDIT_POSITION;
+ if (!(style & GDK_IM_PREEDIT_POSITION))
+ xim_best_allowed_style |= GDK_IM_PREEDIT_CALLBACKS;
}
}
}
}
- if (style & GdkIMStatusMask)
+ if (style & GDK_IM_STATUS_MASK)
{
- xim_best_allowed_style &= ~GdkIMStatusMask;
-
- xim_best_allowed_style |= GdkIMStatusNone;
- if (!(style & GdkIMStatusNone))
+ 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 |= GdkIMStatusNothing;
- if (!(style & GdkIMStatusNothing))
+ xim_best_allowed_style |= GDK_IM_STATUS_NOTHING;
+ if (!(style & GDK_IM_STATUS_NOTHING))
{
- xim_best_allowed_style |= GdkIMStatusArea;
- if (!(style & GdkIMStatusArea))
- xim_best_allowed_style |= GdkIMStatusCallbacks;
+ xim_best_allowed_style |= GDK_IM_STATUS_AREA;
+ if (!(style & GDK_IM_STATUS_AREA))
+ xim_best_allowed_style |= GDK_IM_STATUS_CALLBACKS;
}
}
}
@@ -3960,13 +3960,13 @@ gdk_im_end (void)
GdkIMStyle
gdk_im_decide_style (GdkIMStyle supported_style)
{
- return GdkIMPreeditNone | GdkIMStatusNone;
+ return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
GdkIMStyle
gdk_im_set_best_style (GdkIMStyle style)
{
- return GdkIMPreeditNone | GdkIMStatusNone;
+ return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
gint
@@ -3991,7 +3991,7 @@ gdk_ic_destroy (GdkIC ic)
GdkIMStyle
gdk_ic_get_style (GdkIC ic)
{
- return GdkIMPreeditNone | GdkIMStatusNone;
+ return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
void
diff --git a/gdk/gdk.h b/gdk/gdk.h
index 313270024..cf4babbcb 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -307,6 +307,11 @@ void gdk_window_set_functions (GdkWindow *window,
GdkWMFunction functions);
GList * gdk_window_get_toplevels (void);
+void gdk_drawable_set_data (GdkDrawable *drawable,
+ const gchar *key,
+ gpointer data,
+ GDestroyNotify destroy_func);
+
/* Cursors
*/
@@ -455,6 +460,22 @@ gint gdk_colormap_get_system_size (void);
void gdk_colormap_change (GdkColormap *colormap,
gint ncolors);
+
+
+gint gdk_colormap_alloc_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success);
+gboolean gdk_colormap_alloc_color (GdkColormap *colormap,
+ GdkColor *color,
+ gboolean writeable,
+ gboolean best_match);
+void gdk_colormap_free_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors);
+
void gdk_colors_store (GdkColormap *colormap,
GdkColor *colors,
gint ncolors);
@@ -482,8 +503,10 @@ gint gdk_color_alloc (GdkColormap *colormap,
GdkColor *color);
gint gdk_color_change (GdkColormap *colormap,
GdkColor *color);
-gint gdk_color_equal (GdkColor *colora,
- GdkColor *colorb);
+guint gdk_color_hash (const GdkColor *colora,
+ const GdkColor *colorb);
+gint gdk_color_equal (const GdkColor *colora,
+ const GdkColor *colorb);
/* Fonts
@@ -722,22 +745,27 @@ GdkTimeCoord *gdk_input_motion_events (GdkWindow *window,
/* International Input Method Support Functions
*/
-gint gdk_im_ready (void);
-
-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);
+gint gdk_im_ready (void);
+
+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);
/* Color Context */
@@ -857,6 +885,7 @@ guint gdk_keyval_to_lower (guint keyval);
gboolean gdk_keyval_is_upper (guint keyval);
gboolean gdk_keyval_is_lower (guint keyval);
+
#include <gdk/gdkrgb.h>
#ifdef __cplusplus
diff --git a/gdk/gdkcolor.c b/gdk/gdkcolor.c
index b17e26a1c..fa810473e 100644
--- a/gdk/gdkcolor.c
+++ b/gdk/gdkcolor.c
@@ -16,6 +16,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+#include <time.h>
#include <X11/Xlib.h>
#include "gdk.h"
#include "gdkprivate.h"
@@ -52,8 +53,12 @@ gdk_colormap_new (GdkVisual *visual,
private->xdisplay = gdk_display;
private->visual = visual;
- private->next_color = 0;
private->ref_count = 1;
+
+ private->hash = NULL;
+ private->last_sync_time = 0;
+ private->info = NULL;
+
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
colormap->size = visual->colormap_size;
@@ -63,6 +68,12 @@ gdk_colormap_new (GdkVisual *visual,
{
case GDK_VISUAL_GRAYSCALE:
case GDK_VISUAL_PSEUDO_COLOR:
+ private->info = g_new0 (GdkColorInfo, colormap->size);
+ colormap->colors = g_new (GdkColor, colormap->size);
+
+ private->hash = g_hash_table_new (gdk_color_hash,
+ gdk_color_equal);
+
private->private_val = private_cmap;
private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
@@ -134,12 +145,15 @@ gdk_colormap_real_destroy (GdkColormap *colormap)
GdkColormapPrivate *private = (GdkColormapPrivate*) colormap;
g_return_if_fail (colormap != NULL);
-
- if (private->ref_count > 0)
- return;
+ g_return_if_fail (private->ref_count > 0);
gdk_colormap_remove (colormap);
XFreeColormap (private->xdisplay, private->xcolormap);
+
+ if (private->hash)
+ g_hash_table_destroy (private->hash);
+
+ g_free (private->info);
g_free (colormap->colors);
g_free (colormap);
}
@@ -165,13 +179,61 @@ gdk_colormap_unref (GdkColormap *cmap)
gdk_colormap_real_destroy (cmap);
}
+#define MIN_SYNC_TIME 2
+
+void
+gdk_colormap_sync (GdkColormap *colormap,
+ gboolean force)
+{
+ time_t current_time;
+ GdkColormapPrivate *private = (GdkColormapPrivate *)colormap;
+ XColor *xpalette;
+ gint nlookup;
+ gint i;
+
+ g_return_if_fail (colormap != NULL);
+
+ current_time = time (NULL);
+ if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
+ return;
+
+ private->last_sync_time = current_time;
+
+ nlookup = 0;
+ xpalette = g_new (XColor, colormap->size);
+
+ for (i = 0; i < colormap->size; i++)
+ {
+ if (private->info[i].ref_count == 0)
+ {
+ xpalette[nlookup].pixel = i;
+ xpalette[nlookup].red = 0;
+ xpalette[nlookup].green = 0;
+ xpalette[nlookup].blue = 0;
+ nlookup++;
+ }
+ }
+
+ XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
+
+ for (i = 0; i < nlookup; i++)
+ {
+ gulong pixel = xpalette[i].pixel;
+ colormap->colors[pixel].pixel = pixel;
+ colormap->colors[pixel].red = xpalette[i].red;
+ colormap->colors[pixel].green = xpalette[i].green;
+ colormap->colors[pixel].blue = xpalette[i].blue;
+ }
+
+ g_free (xpalette);
+}
+
+
GdkColormap*
gdk_colormap_get_system (void)
{
static GdkColormap *colormap = NULL;
GdkColormapPrivate *private;
- XColor *xpalette;
- gint i;
if (!colormap)
{
@@ -182,37 +244,25 @@ gdk_colormap_get_system (void)
private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
private->visual = gdk_visual_get_system ();
private->private_val = FALSE;
- private->next_color = 0;
private->ref_count = 1;
+ private->hash = NULL;
+ private->last_sync_time = 0;
+ private->info = NULL;
+
+ colormap->colors = NULL;
colormap->size = private->visual->colormap_size;
- colormap->colors = g_new (GdkColor, colormap->size);
if ((private->visual->type == GDK_VISUAL_GRAYSCALE) ||
(private->visual->type == GDK_VISUAL_PSEUDO_COLOR))
{
- xpalette = g_new (XColor, colormap->size);
+ private->info = g_new0 (GdkColorInfo, colormap->size);
+ colormap->colors = g_new (GdkColor, colormap->size);
- for (i = 0; i < colormap->size; i++)
- {
- xpalette[i].pixel = i;
- xpalette[i].red = 0;
- xpalette[i].green = 0;
- xpalette[i].blue = 0;
- }
-
- XQueryColors (gdk_display, private->xcolormap, xpalette,
- colormap->size);
-
- for (i = 0; i < colormap->size; i++)
- {
- colormap->colors[i].pixel = xpalette[i].pixel;
- colormap->colors[i].red = xpalette[i].red;
- colormap->colors[i].green = xpalette[i].green;
- colormap->colors[i].blue = xpalette[i].blue;
- }
+ private->hash = g_hash_table_new (gdk_color_hash,
+ gdk_color_equal);
- g_free (xpalette);
+ gdk_colormap_sync (colormap, TRUE);
}
gdk_colormap_add (colormap);
@@ -258,7 +308,6 @@ gdk_colormap_change (GdkColormap *colormap,
}
XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
- private->next_color = MAX (private->next_color, ncolors);
break;
case GDK_VISUAL_DIRECT_COLOR:
@@ -339,6 +388,7 @@ gdk_colors_alloc (GdkColormap *colormap,
{
GdkColormapPrivate *private;
gint return_val;
+ gint i;
g_return_val_if_fail (colormap != NULL, 0);
@@ -347,23 +397,65 @@ gdk_colors_alloc (GdkColormap *colormap,
return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
contiguous, planes, nplanes, pixels, npixels);
+ if (return_val)
+ {
+ for (i=0; i<npixels; i++)
+ {
+ private->info[pixels[i]].ref_count++;
+ private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
+ }
+ }
+
return return_val;
}
+/* This is almost identical to gdk_colormap_free_colors.
+ * Keep them in sync!
+ */
void
gdk_colors_free (GdkColormap *colormap,
- gulong *pixels,
- gint npixels,
+ gulong *in_pixels,
+ gint in_npixels,
gulong planes)
{
GdkColormapPrivate *private;
+ gulong *pixels;
+ gint npixels = 0;
+ gint i;
g_return_if_fail (colormap != NULL);
+ g_return_if_fail (in_pixels != NULL);
private = (GdkColormapPrivate*) colormap;
- XFreeColors (private->xdisplay, private->xcolormap,
- pixels, npixels, planes);
+ if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
+ (private->visual->type != GDK_VISUAL_GRAYSCALE))
+ return;
+
+ pixels = g_new (gulong, in_npixels);
+
+ for (i=0; i<in_npixels; i++)
+ {
+ gulong pixel = in_pixels[i];
+
+ if (private->info[pixel].ref_count)
+ {
+ private->info[pixel].ref_count--;
+
+ if (private->info[pixel].ref_count == 0)
+ {
+ pixels[npixels++] = pixel;
+ if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
+ g_hash_table_remove (private->hash, &colormap->colors[in_pixels[i]]);
+ private->info[pixel].flags = 0;
+ }
+ }
+ }
+
+ if (npixels)
+ XFreeColors (private->xdisplay, private->xcolormap,
+ pixels, npixels, planes);
+ g_free (pixels);
}
/*
@@ -494,19 +586,22 @@ gdk_color_parse (const gchar *spec,
return return_val;
}
-gboolean
-gdk_color_alloc (GdkColormap *colormap,
- GdkColor *color)
+/********************
+ * Color allocation *
+ ********************/
+
+/* Try to allocate a single color using XAllocColor. If it succeeds,
+ * cache the result in our colormap, and store in ret.
+ */
+static gboolean
+gdk_colormap_alloc1 (GdkColormap *colormap,
+ GdkColor *color,
+ GdkColor *ret)
{
GdkColormapPrivate *private;
- GdkVisual *visual;
XColor xcolor;
- gchar *available = NULL;
- gboolean return_val;
- gint i, index;
- g_return_val_if_fail (colormap != NULL, FALSE);
- g_return_val_if_fail (color != NULL, FALSE);
+ private = (GdkColormapPrivate*) colormap;
xcolor.red = color->red;
xcolor.green = color->green;
@@ -514,113 +609,458 @@ gdk_color_alloc (GdkColormap *colormap,
xcolor.pixel = color->pixel;
xcolor.flags = DoRed | DoGreen | DoBlue;
- return_val = FALSE;
+ if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ {
+ ret->pixel = xcolor.pixel;
+ ret->red = xcolor.red;
+ ret->green = xcolor.green;
+ ret->blue = xcolor.blue;
+
+ if (ret->pixel < colormap->size)
+ {
+ if (private->info[ret->pixel].ref_count) /* got a duplicate */
+ {
+ XFreeColors (private->xdisplay, private->xcolormap,
+ &ret->pixel, 1, 0);
+ }
+ else
+ {
+ colormap->colors[ret->pixel] = *color;
+ private->info[ret->pixel].ref_count = 1;
+
+ g_hash_table_insert (private->hash,
+ &colormap->colors[ret->pixel],
+ &colormap->colors[ret->pixel]);
+ }
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static gint
+gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ gulong *pixels;
+ Status status;
+ gint i, index;
+
private = (GdkColormapPrivate*) colormap;
- switch (private->visual->type)
+ if (private->private_val)
{
- case GDK_VISUAL_GRAYSCALE:
- case GDK_VISUAL_PSEUDO_COLOR:
- if (private->private_val)
+ index = 0;
+ for (i=0; i<ncolors; i++)
{
- if (private->next_color >= colormap->size)
+ while ((index < colormap->size) && (private->info[index].ref_count != 0))
+ index++;
+
+ if (index < colormap->size)
{
- available = g_new (gchar, colormap->size);
- for (i = 0; i < colormap->size; i++)
- available[i] = TRUE;
-
- index = gdk_colormap_match_color (colormap, color, available);
- if (index != -1)
- {
- available[index] = FALSE;
- *color = colormap->colors[index];
- return_val = TRUE;
- }
- else
- {
- return_val = FALSE;
- }
+ colors[i].pixel = index;
+ success[i] = TRUE;
+ private->info[index].ref_count++;
+ private->info[i].flags |= GDK_COLOR_WRITEABLE;
}
else
+ break;
+ }
+ return i;
+ }
+ else
+ {
+ pixels = g_new (gulong, ncolors);
+ /* Allocation of a writeable color cells */
+
+ status = XAllocColorCells (private->xdisplay, private->xcolormap,
+ FALSE, NULL, 0, pixels, ncolors);
+ if (status)
+ {
+ for (i=0; i<ncolors; i++)
{
- xcolor.pixel = colormap->size - 1 -private->next_color;
- color->pixel = xcolor.pixel;
- private->next_color += 1;
+ colors[i].pixel = pixels[i];
+ private->info[pixels[i]].ref_count++;
+ private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
+ }
+ }
+
+ g_free (pixels);
- XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
- return_val = TRUE;
+ return status ? ncolors : 0;
+ }
+}
+
+static gint
+gdk_colormap_alloc_colors_private (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ gint i, index;
+ XColor *store = g_new (XColor, ncolors);
+ gint nstore = 0;
+ gint nremaining = 0;
+
+ private = (GdkColormapPrivate*) colormap;
+ index = -1;
+
+ /* First, store the colors we have room for */
+
+ index = 0;
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ while ((index < colormap->size) && (private->info[index].ref_count != 0))
+ index++;
+
+ if (index < colormap->size)
+ {
+ store[nstore].red = colors[i].red;
+ store[nstore].blue = colors[i].blue;
+ store[nstore].green = colors[i].green;
+ store[nstore].pixel = index;
+ nstore++;
+
+ success[i] = TRUE;
+
+ colors[i].pixel = index;
+ private->info[index].ref_count++;
}
+ else
+ nremaining++;
}
- else
+ }
+
+ XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
+ g_free (store);
+
+ if (nremaining > 0 && best_match)
+ {
+ /* Get best matches for remaining colors */
+
+ gchar *available = g_new (gchar, colormap->size);
+ for (i = 0; i < colormap->size; i++)
+ available[i] = TRUE;
+
+ for (i=0; i<ncolors; i++)
{
- while (1)
+ if (!success[i])
{
- if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ index = gdk_colormap_match_color (colormap,
+ &colors[i],
+ available);
+ if (index != -1)
{
- color->pixel = xcolor.pixel;
- color->red = xcolor.red;
- color->green = xcolor.green;
- color->blue = xcolor.blue;
-
- if (color->pixel < colormap->size)
- colormap->colors[color->pixel] = *color;
+ colors[i] = colormap->colors[index];
+ private->info[index].ref_count++;
- return_val = TRUE;
- break;
+ success[i] = TRUE;
+ nremaining--;
}
- else
- {
- if (available == NULL)
- {
- available = g_new (gchar, colormap->size);
- for (i = 0; i < colormap->size; i++)
- available[i] = TRUE;
- }
+ }
+ }
+ g_free (available);
+ }
+
+ return (ncolors - nremaining);
+}
+
+static gint
+gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ gint i, index;
+ gint nremaining = 0;
+ gint nfailed = 0;
+
+ private = (GdkColormapPrivate*) colormap;
+ index = -1;
+
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
+ success[i] = TRUE;
+ else
+ nremaining++;
+ }
+ }
+
- index = gdk_colormap_match_color (colormap, color, available);
+ if (nremaining > 0 && best_match)
+ {
+ gchar *available = g_new (gchar, colormap->size);
+ for (i = 0; i < colormap->size; i++)
+ available[i] = ((private->info[i].ref_count == 0) ||
+ !(private->info[i].flags && GDK_COLOR_WRITEABLE));
+ gdk_colormap_sync (colormap, FALSE);
+
+ while (nremaining > 0)
+ {
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ index = gdk_colormap_match_color (colormap, &colors[i], available);
if (index != -1)
{
- available[index] = FALSE;
- xcolor.red = colormap->colors[index].red;
- xcolor.green = colormap->colors[index].green;
- xcolor.blue = colormap->colors[index].blue;
+ if (private->info[index].ref_count)
+ {
+ private->info[index].ref_count++;
+ colors[i] = colormap->colors[index];
+ success[i] = TRUE;
+ nremaining--;
+ }
+ else
+ {
+ if (gdk_colormap_alloc1 (colormap,
+ &colormap->colors[index],
+ &colors[i]))
+ {
+ success[i] = TRUE;
+ nremaining--;
+ break;
+ }
+ else
+ {
+ available[index] = FALSE;
+ }
+ }
}
else
{
- return_val = FALSE;
- break;
+ nfailed++;
+ nremaining--;
+ success[i] = 2; /* flag as permanent failure */
}
}
}
}
+ g_free (available);
+ }
+
+ /* Change back the values we flagged as permanent failures */
+ if (nfailed > 0)
+ {
+ for (i=0; i<ncolors; i++)
+ if (success[i] == 2)
+ success[i] = FALSE;
+ nremaining = nfailed;
+ }
+
+ return (ncolors - nremaining);
+}
+
+static gint
+gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ GdkColor *lookup_color;
+ gint i;
+ gint nremaining = 0;
+
+ private = (GdkColormapPrivate*) colormap;
+
+ /* Check for an exact match among previously allocated colors */
+
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
+ if (lookup_color)
+ {
+ private->info[lookup_color->pixel].ref_count++;
+ colors[i].pixel = lookup_color->pixel;
+ success[i] = TRUE;
+ }
+ else
+ nremaining++;
+ }
+ }
+
+ /* If that failed, we try to allocate a new color, or approxmiate
+ * with what we can get if best_match is TRUE.
+ */
+ if (nremaining > 0)
+ {
+ if (private->private_val)
+ return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
+ else
+ return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
+ }
+ else
+ return 0;
+}
+
+gint
+gdk_colormap_alloc_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ GdkVisual *visual;
+ gint i;
+ gint nremaining = 0;
+ XColor xcolor;
+
+ g_return_val_if_fail (colormap != NULL, FALSE);
+ g_return_val_if_fail (colors != NULL, FALSE);
+
+ private = (GdkColormapPrivate*) colormap;
+
+ for (i=0; i<ncolors; i++)
+ {
+ success[i] = FALSE;
+ }
+
+ switch (private->visual->type)
+ {
+ case GDK_VISUAL_PSEUDO_COLOR:
+ case GDK_VISUAL_GRAYSCALE:
+ if (writeable)
+ return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
+ writeable, best_match, success);
+ else
+ return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
+ writeable, best_match, success);
break;
case GDK_VISUAL_DIRECT_COLOR:
+ case GDK_VISUAL_TRUE_COLOR:
visual = private->visual;
- xcolor.pixel = (((xcolor.red >> (16 - visual->red_prec)) << visual->red_shift) +
- ((xcolor.green >> (16 - visual->green_prec)) << visual->green_shift) +
- ((xcolor.blue >> (16 - visual->blue_prec)) << visual->blue_shift));
- color->pixel = xcolor.pixel;
- return_val = TRUE;
+
+ for (i=0; i<ncolors; i++)
+ {
+ colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
+ ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
+ ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
+ success[i] = TRUE;
+ }
break;
case GDK_VISUAL_STATIC_GRAY:
case GDK_VISUAL_STATIC_COLOR:
- case GDK_VISUAL_TRUE_COLOR:
- if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ for (i=0; i<ncolors; i++)
{
- color->pixel = xcolor.pixel;
- return_val = TRUE;
+ xcolor.red = colors[i].red;
+ xcolor.green = colors[i].green;
+ xcolor.blue = colors[i].blue;
+ xcolor.pixel = colors[i].pixel;
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+
+ if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ {
+ colors[i].pixel = xcolor.pixel;
+ success[i] = TRUE;
+ }
+ else
+ nremaining++;
}
- else
- return_val = FALSE;
break;
}
+ return nremaining;
+}
- if (available)
- g_free (available);
-
- return return_val;
+gboolean
+gdk_colormap_alloc_color (GdkColormap *colormap,
+ GdkColor *color,
+ gboolean writeable,
+ gboolean best_match)
+{
+ gboolean success;
+
+ gdk_colormap_alloc_colors (colormap, color, 1, writeable, best_match,
+ &success);
+
+ return success;
+}
+
+/* This is almost identical to gdk_colors_free.
+ * Keep them in sync!
+ */
+void
+gdk_colormap_free_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors)
+{
+ GdkColormapPrivate *private;
+ gulong *pixels;
+ gint npixels = 0;
+ gint i;
+
+ g_return_if_fail (colormap != NULL);
+ g_return_if_fail (colors != NULL);
+
+ private = (GdkColormapPrivate*) colormap;
+
+ if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
+ (private->visual->type != GDK_VISUAL_GRAYSCALE))
+ return;
+
+ pixels = g_new (gulong, ncolors);
+
+ for (i=0; i<ncolors; i++)
+ {
+ gulong pixel = colors[i].pixel;
+
+ if (private->info[pixel].ref_count)
+ {
+ private->info[pixel].ref_count--;
+
+ if (private->info[pixel].ref_count == 0)
+ {
+ pixels[npixels++] = pixel;
+ if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
+ g_hash_table_remove (private->hash, &colors[i]);
+ private->info[pixel].flags = 0;
+ }
+ }
+ }
+
+ if (npixels)
+ XFreeColors (private->xdisplay, private->xcolormap,
+ pixels, npixels, 0);
+
+ g_free (pixels);
+}
+
+gboolean
+gdk_color_alloc (GdkColormap *colormap,
+ GdkColor *color)
+{
+ gboolean success;
+
+ gdk_colormap_alloc_colors (colormap, color, 1, FALSE, TRUE, &success);
+
+ return success;
}
gboolean
@@ -645,9 +1085,19 @@ gdk_color_change (GdkColormap *colormap,
return TRUE;
}
+guint
+gdk_color_hash (const GdkColor *colora,
+ const GdkColor *colorb)
+{
+ return ((colora->red) +
+ (colora->green << 11) +
+ (colora->blue << 22) +
+ (colora->blue >> 6));
+}
+
gint
-gdk_color_equal (GdkColor *colora,
- GdkColor *colorb)
+gdk_color_equal (const GdkColor *colora,
+ const GdkColor *colorb)
{
g_return_val_if_fail (colora != NULL, FALSE);
g_return_val_if_fail (colorb != NULL, FALSE);
@@ -657,6 +1107,9 @@ gdk_color_equal (GdkColor *colora,
(colora->blue == colorb->blue));
}
+/* XXX: Do not use this function until it is fixed. An X Colormap
+ * is useless unless we also have the visual.
+ */
GdkColormap*
gdkx_colormap_get (Colormap xcolormap)
{
@@ -677,7 +1130,6 @@ gdkx_colormap_get (Colormap xcolormap)
private->xcolormap = xcolormap;
private->visual = NULL;
private->private_val = TRUE;
- private->next_color = 0;
/* To do the following safely, we would have to have some way of finding
* out what the size or visual of the given colormap is. It seems
diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c
index 9fdef0ffc..dfaf4822c 100644
--- a/gdk/gdkpixmap.c
+++ b/gdk/gdkpixmap.c
@@ -34,6 +34,13 @@ typedef struct
gint transparent;
} _GdkPixmapColor;
+typedef struct
+{
+ guint ncolors;
+ GdkColormap *colormap;
+ gulong pixels[1];
+} _GdkPixmapInfo;
+
GdkPixmap*
gdk_pixmap_new (GdkWindow *window,
gint width,
@@ -388,13 +395,6 @@ gdk_pixmap_extract_color (gchar *buffer)
return retcol;
}
-static void
-free_color (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- g_free (value);
-}
-
enum buffer_op
{
@@ -403,6 +403,23 @@ enum buffer_op
op_body
};
+
+static void
+gdk_xpm_destroy_notify (gpointer data)
+{
+ _GdkPixmapInfo *info = (_GdkPixmapInfo *)data;
+ GdkColor color;
+ int i;
+
+ for (i=0; i<info->ncolors; i++)
+ {
+ color.pixel = info->pixels[i];
+ gdk_colormap_free_colors (info->colormap, &color, 1);
+ }
+
+ gdk_colormap_unref (info->colormap);
+ g_free (info);
+}
static GdkPixmap *
_gdk_pixmap_create_from_xpm (GdkWindow *window,
@@ -420,9 +437,12 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
GdkColor tmp_color;
gint width, height, num_cols, cpp, n, ns, cnt, xcnt, ycnt, wbytes;
gchar *buffer, pixel_str[32];
+ gchar *name_buf;
_GdkPixmapColor *color = NULL, *fallbackcolor = NULL;
+ _GdkPixmapColor *colors = NULL;
gulong index;
- GHashTable *colors = NULL;
+ GHashTable *color_hash = NULL;
+ _GdkPixmapInfo *color_info = NULL;
if ((window == NULL) && (colormap == NULL))
g_warning ("Creating pixmap from xpm with NULL window and colormap");
@@ -449,14 +469,30 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
return NULL;
}
- colors = g_hash_table_new (g_str_hash, g_str_equal);
+ color_hash = g_hash_table_new (g_str_hash, g_str_equal);
if (transparent_color == NULL)
{
gdk_color_white (colormap, &tmp_color);
transparent_color = &tmp_color;
}
-
+
+ /* For pseudo-color and grayscale visuals, we have to remember
+ * the colors we allocated, so we can free them later.
+ */
+ if ((visual->type == GDK_VISUAL_PSEUDO_COLOR) ||
+ (visual->type == GDK_VISUAL_GRAYSCALE))
+ {
+ color_info = g_malloc (sizeof (_GdkPixmapInfo) +
+ sizeof(gulong) * (num_cols - 1));
+ color_info->ncolors = num_cols;
+ color_info->colormap = colormap;
+ gdk_colormap_ref (colormap);
+ }
+
+ name_buf = g_new (gchar, num_cols * (cpp+1));
+ colors = g_new (_GdkPixmapColor, num_cols);
+
for (cnt = 0; cnt < num_cols; cnt++)
{
gchar *color_name;
@@ -465,8 +501,8 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
if (buffer == NULL)
goto error;
- color = g_new (_GdkPixmapColor, 1);
- color->color_string = g_new (gchar, cpp + 1);
+ color = &colors[cnt];
+ color->color_string = &name_buf [cnt * (cpp + 1)];
strncpy (color->color_string, buffer, cpp);
color->color_string[cpp] = 0;
buffer += strlen (color->color_string);
@@ -486,7 +522,11 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
/* FIXME: The remaining slowness appears to happen in this
function. */
gdk_color_alloc (colormap, &color->color);
- g_hash_table_insert (colors, color->color_string, color);
+
+ if (color_info)
+ color_info->pixels[cnt] = color->color.pixel;
+
+ g_hash_table_insert (color_hash, color->color_string, color);
if (cnt == 0)
fallbackcolor = color;
}
@@ -531,7 +571,7 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
pixel_str[cpp] = 0;
ns = 0;
- color = g_hash_table_lookup (colors, pixel_str);
+ color = g_hash_table_lookup (color_hash, pixel_str);
if (!color) /* screwed up XPM file */
color = fallbackcolor;
@@ -558,6 +598,10 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
if (image != NULL)
{
pixmap = gdk_pixmap_new (window, width, height, visual->depth);
+
+ if (color_info)
+ gdk_drawable_set_data (pixmap, "gdk-xpm", color_info,
+ gdk_xpm_destroy_notify);
gc = gdk_gc_new (pixmap);
gdk_gc_set_foreground (gc, transparent_color);
@@ -565,13 +609,18 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
gdk_gc_destroy (gc);
gdk_image_destroy (image);
}
+ else if (color_info)
+ gdk_xpm_destroy_notify (color_info);
+ if (color_hash != NULL)
+ g_hash_table_destroy (color_hash);
+
if (colors != NULL)
- {
- g_hash_table_foreach (colors, free_color, 0);
- g_hash_table_destroy (colors);
- }
-
+ g_free (colors);
+
+ if (name_buf != NULL)
+ g_free (name_buf);
+
return pixmap;
}
@@ -720,6 +769,7 @@ gdk_pixmap_unref (GdkPixmap *pixmap)
{
XFreePixmap (private->xdisplay, private->xwindow);
gdk_xid_table_remove (private->xwindow);
+ g_dataset_destroy (private);
g_free (private);
}
}
diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h
index 6e9889c3e..9ed85a466 100644
--- a/gdk/gdkprivate.h
+++ b/gdk/gdkprivate.h
@@ -41,6 +41,7 @@ typedef struct _GdkWindowPrivate GdkPixmapPrivate;
typedef struct _GdkImagePrivate GdkImagePrivate;
typedef struct _GdkGCPrivate GdkGCPrivate;
typedef struct _GdkColormapPrivate GdkColormapPrivate;
+typedef struct _GdkColorInfo GdkColorInfo;
typedef struct _GdkVisualPrivate GdkVisualPrivate;
typedef struct _GdkFontPrivate GdkFontPrivate;
typedef struct _GdkCursorPrivate GdkCursorPrivate;
@@ -111,6 +112,16 @@ struct _GdkGCPrivate
guint ref_count;
};
+typedef enum {
+ GDK_COLOR_WRITEABLE = 1 << 0
+} GdkColorInfoFlags;
+
+struct _GdkColorInfo
+{
+ GdkColorInfoFlags flags;
+ guint ref_count;
+};
+
struct _GdkColormapPrivate
{
GdkColormap colormap;
@@ -118,7 +129,11 @@ struct _GdkColormapPrivate
Display *xdisplay;
GdkVisual *visual;
gint private_val;
- gint next_color;
+
+ GHashTable *hash;
+ GdkColorInfo *info;
+ time_t last_sync_time;
+
guint ref_count;
};
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
index 5ec44c2d4..67f9fb353 100644
--- a/gdk/gdktypes.h
+++ b/gdk/gdktypes.h
@@ -618,15 +618,18 @@ typedef enum
typedef enum /*< flags >*/
{
- GdkIMPreeditArea = 0x0001L, /*< nick=preedit-area >*/
- GdkIMPreeditCallbacks = 0x0002L, /*< nick=preedit-callbacks >*/
- GdkIMPreeditPosition = 0x0004L, /*< nick=preedit-position >*/
- GdkIMPreeditNothing = 0x0008L, /*< nick=preedit-nothing >*/
- GdkIMPreeditNone = 0x0010L, /*< nick=preedit-none >*/
- GdkIMStatusArea = 0x0100L, /*< nick=status-area >*/
- GdkIMStatusCallbacks = 0x0200L, /*< nick=status-callbacks >*/
- GdkIMStatusNothing = 0x0400L, /*< nick=status-nothing >*/
- GdkIMStatusNone = 0x0800L /*< nick=status-none >*/
+ GDK_IM_PREEDIT_AREA = 0x0001,
+ GDK_IM_PREEDIT_CALLBACKS = 0x0002,
+ GDK_IM_PREEDIT_POSITION = 0x0004,
+ GDK_IM_PREEDIT_NOTHING = 0x0008,
+ GDK_IM_PREEDIT_NONE = 0x0010,
+ GDK_IM_PREEDIT_MASK = 0x001f,
+
+ GDK_IM_STATUS_AREA = 0x0100,
+ GDK_IM_STATUS_CALLBACKS = 0x0200,
+ GDK_IM_STATUS_NOTHING = 0x0400,
+ GDK_IM_STATUS_NONE = 0x0800,
+ GDK_IM_STATUS_MASK = 0x0f00
} GdkIMStyle;
/* The next two enumeration values current match the
@@ -655,15 +658,6 @@ typedef enum
GDK_FUNC_CLOSE = 1 << 5
} GdkWMFunction;
-#define GdkIMPreeditMask \
- ( GdkIMPreeditArea | GdkIMPreeditCallbacks | \
- GdkIMPreeditPosition | GdkIMPreeditNothing | \
- GdkIMPreeditNone )
-
-#define GdkIMStatusMask \
- ( GdkIMStatusArea | GdkIMStatusCallbacks | \
- GdkIMStatusNothing | GdkIMStatusNone )
-
typedef void (*GdkInputFunction) (gpointer data,
gint source,
GdkInputCondition condition);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index bd4adfaee..afbcdc4cc 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -704,8 +704,10 @@ gdk_window_unref (GdkWindow *window)
{
if (!private->destroyed)
g_warning ("losing last reference to undestroyed window\n");
+ g_dataset_destroy (window);
g_free (window);
}
+
}
void
@@ -2076,3 +2078,11 @@ gdk_window_get_toplevels (void)
return new_list;
}
+void
+gdk_drawable_set_data (GdkDrawable *drawable,
+ const gchar *key,
+ gpointer data,
+ GDestroyNotify destroy_func)
+{
+ g_dataset_set_data_full (drawable, key, data, destroy_func);
+}
diff --git a/gdk/gdkx.h b/gdk/gdkx.h
index 2f43fd85f..fbe655d2e 100644
--- a/gdk/gdkx.h
+++ b/gdk/gdkx.h
@@ -39,6 +39,8 @@
GdkVisual* gdkx_visual_get (VisualID xvisualid);
+/* XXX: Do not use this function until it is fixed. An X Colormap
+ * is useless unless we also have the visual. */
GdkColormap* gdkx_colormap_get (Colormap xcolormap);
/* Utility function in gdk.c - not sure where it belongs, but it's
needed in more than one place, so make it public */
diff --git a/gdk/x11/gdkcolor-x11.c b/gdk/x11/gdkcolor-x11.c
index b17e26a1c..fa810473e 100644
--- a/gdk/x11/gdkcolor-x11.c
+++ b/gdk/x11/gdkcolor-x11.c
@@ -16,6 +16,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+#include <time.h>
#include <X11/Xlib.h>
#include "gdk.h"
#include "gdkprivate.h"
@@ -52,8 +53,12 @@ gdk_colormap_new (GdkVisual *visual,
private->xdisplay = gdk_display;
private->visual = visual;
- private->next_color = 0;
private->ref_count = 1;
+
+ private->hash = NULL;
+ private->last_sync_time = 0;
+ private->info = NULL;
+
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
colormap->size = visual->colormap_size;
@@ -63,6 +68,12 @@ gdk_colormap_new (GdkVisual *visual,
{
case GDK_VISUAL_GRAYSCALE:
case GDK_VISUAL_PSEUDO_COLOR:
+ private->info = g_new0 (GdkColorInfo, colormap->size);
+ colormap->colors = g_new (GdkColor, colormap->size);
+
+ private->hash = g_hash_table_new (gdk_color_hash,
+ gdk_color_equal);
+
private->private_val = private_cmap;
private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
@@ -134,12 +145,15 @@ gdk_colormap_real_destroy (GdkColormap *colormap)
GdkColormapPrivate *private = (GdkColormapPrivate*) colormap;
g_return_if_fail (colormap != NULL);
-
- if (private->ref_count > 0)
- return;
+ g_return_if_fail (private->ref_count > 0);
gdk_colormap_remove (colormap);
XFreeColormap (private->xdisplay, private->xcolormap);
+
+ if (private->hash)
+ g_hash_table_destroy (private->hash);
+
+ g_free (private->info);
g_free (colormap->colors);
g_free (colormap);
}
@@ -165,13 +179,61 @@ gdk_colormap_unref (GdkColormap *cmap)
gdk_colormap_real_destroy (cmap);
}
+#define MIN_SYNC_TIME 2
+
+void
+gdk_colormap_sync (GdkColormap *colormap,
+ gboolean force)
+{
+ time_t current_time;
+ GdkColormapPrivate *private = (GdkColormapPrivate *)colormap;
+ XColor *xpalette;
+ gint nlookup;
+ gint i;
+
+ g_return_if_fail (colormap != NULL);
+
+ current_time = time (NULL);
+ if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
+ return;
+
+ private->last_sync_time = current_time;
+
+ nlookup = 0;
+ xpalette = g_new (XColor, colormap->size);
+
+ for (i = 0; i < colormap->size; i++)
+ {
+ if (private->info[i].ref_count == 0)
+ {
+ xpalette[nlookup].pixel = i;
+ xpalette[nlookup].red = 0;
+ xpalette[nlookup].green = 0;
+ xpalette[nlookup].blue = 0;
+ nlookup++;
+ }
+ }
+
+ XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
+
+ for (i = 0; i < nlookup; i++)
+ {
+ gulong pixel = xpalette[i].pixel;
+ colormap->colors[pixel].pixel = pixel;
+ colormap->colors[pixel].red = xpalette[i].red;
+ colormap->colors[pixel].green = xpalette[i].green;
+ colormap->colors[pixel].blue = xpalette[i].blue;
+ }
+
+ g_free (xpalette);
+}
+
+
GdkColormap*
gdk_colormap_get_system (void)
{
static GdkColormap *colormap = NULL;
GdkColormapPrivate *private;
- XColor *xpalette;
- gint i;
if (!colormap)
{
@@ -182,37 +244,25 @@ gdk_colormap_get_system (void)
private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
private->visual = gdk_visual_get_system ();
private->private_val = FALSE;
- private->next_color = 0;
private->ref_count = 1;
+ private->hash = NULL;
+ private->last_sync_time = 0;
+ private->info = NULL;
+
+ colormap->colors = NULL;
colormap->size = private->visual->colormap_size;
- colormap->colors = g_new (GdkColor, colormap->size);
if ((private->visual->type == GDK_VISUAL_GRAYSCALE) ||
(private->visual->type == GDK_VISUAL_PSEUDO_COLOR))
{
- xpalette = g_new (XColor, colormap->size);
+ private->info = g_new0 (GdkColorInfo, colormap->size);
+ colormap->colors = g_new (GdkColor, colormap->size);
- for (i = 0; i < colormap->size; i++)
- {
- xpalette[i].pixel = i;
- xpalette[i].red = 0;
- xpalette[i].green = 0;
- xpalette[i].blue = 0;
- }
-
- XQueryColors (gdk_display, private->xcolormap, xpalette,
- colormap->size);
-
- for (i = 0; i < colormap->size; i++)
- {
- colormap->colors[i].pixel = xpalette[i].pixel;
- colormap->colors[i].red = xpalette[i].red;
- colormap->colors[i].green = xpalette[i].green;
- colormap->colors[i].blue = xpalette[i].blue;
- }
+ private->hash = g_hash_table_new (gdk_color_hash,
+ gdk_color_equal);
- g_free (xpalette);
+ gdk_colormap_sync (colormap, TRUE);
}
gdk_colormap_add (colormap);
@@ -258,7 +308,6 @@ gdk_colormap_change (GdkColormap *colormap,
}
XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
- private->next_color = MAX (private->next_color, ncolors);
break;
case GDK_VISUAL_DIRECT_COLOR:
@@ -339,6 +388,7 @@ gdk_colors_alloc (GdkColormap *colormap,
{
GdkColormapPrivate *private;
gint return_val;
+ gint i;
g_return_val_if_fail (colormap != NULL, 0);
@@ -347,23 +397,65 @@ gdk_colors_alloc (GdkColormap *colormap,
return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
contiguous, planes, nplanes, pixels, npixels);
+ if (return_val)
+ {
+ for (i=0; i<npixels; i++)
+ {
+ private->info[pixels[i]].ref_count++;
+ private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
+ }
+ }
+
return return_val;
}
+/* This is almost identical to gdk_colormap_free_colors.
+ * Keep them in sync!
+ */
void
gdk_colors_free (GdkColormap *colormap,
- gulong *pixels,
- gint npixels,
+ gulong *in_pixels,
+ gint in_npixels,
gulong planes)
{
GdkColormapPrivate *private;
+ gulong *pixels;
+ gint npixels = 0;
+ gint i;
g_return_if_fail (colormap != NULL);
+ g_return_if_fail (in_pixels != NULL);
private = (GdkColormapPrivate*) colormap;
- XFreeColors (private->xdisplay, private->xcolormap,
- pixels, npixels, planes);
+ if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
+ (private->visual->type != GDK_VISUAL_GRAYSCALE))
+ return;
+
+ pixels = g_new (gulong, in_npixels);
+
+ for (i=0; i<in_npixels; i++)
+ {
+ gulong pixel = in_pixels[i];
+
+ if (private->info[pixel].ref_count)
+ {
+ private->info[pixel].ref_count--;
+
+ if (private->info[pixel].ref_count == 0)
+ {
+ pixels[npixels++] = pixel;
+ if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
+ g_hash_table_remove (private->hash, &colormap->colors[in_pixels[i]]);
+ private->info[pixel].flags = 0;
+ }
+ }
+ }
+
+ if (npixels)
+ XFreeColors (private->xdisplay, private->xcolormap,
+ pixels, npixels, planes);
+ g_free (pixels);
}
/*
@@ -494,19 +586,22 @@ gdk_color_parse (const gchar *spec,
return return_val;
}
-gboolean
-gdk_color_alloc (GdkColormap *colormap,
- GdkColor *color)
+/********************
+ * Color allocation *
+ ********************/
+
+/* Try to allocate a single color using XAllocColor. If it succeeds,
+ * cache the result in our colormap, and store in ret.
+ */
+static gboolean
+gdk_colormap_alloc1 (GdkColormap *colormap,
+ GdkColor *color,
+ GdkColor *ret)
{
GdkColormapPrivate *private;
- GdkVisual *visual;
XColor xcolor;
- gchar *available = NULL;
- gboolean return_val;
- gint i, index;
- g_return_val_if_fail (colormap != NULL, FALSE);
- g_return_val_if_fail (color != NULL, FALSE);
+ private = (GdkColormapPrivate*) colormap;
xcolor.red = color->red;
xcolor.green = color->green;
@@ -514,113 +609,458 @@ gdk_color_alloc (GdkColormap *colormap,
xcolor.pixel = color->pixel;
xcolor.flags = DoRed | DoGreen | DoBlue;
- return_val = FALSE;
+ if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ {
+ ret->pixel = xcolor.pixel;
+ ret->red = xcolor.red;
+ ret->green = xcolor.green;
+ ret->blue = xcolor.blue;
+
+ if (ret->pixel < colormap->size)
+ {
+ if (private->info[ret->pixel].ref_count) /* got a duplicate */
+ {
+ XFreeColors (private->xdisplay, private->xcolormap,
+ &ret->pixel, 1, 0);
+ }
+ else
+ {
+ colormap->colors[ret->pixel] = *color;
+ private->info[ret->pixel].ref_count = 1;
+
+ g_hash_table_insert (private->hash,
+ &colormap->colors[ret->pixel],
+ &colormap->colors[ret->pixel]);
+ }
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static gint
+gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ gulong *pixels;
+ Status status;
+ gint i, index;
+
private = (GdkColormapPrivate*) colormap;
- switch (private->visual->type)
+ if (private->private_val)
{
- case GDK_VISUAL_GRAYSCALE:
- case GDK_VISUAL_PSEUDO_COLOR:
- if (private->private_val)
+ index = 0;
+ for (i=0; i<ncolors; i++)
{
- if (private->next_color >= colormap->size)
+ while ((index < colormap->size) && (private->info[index].ref_count != 0))
+ index++;
+
+ if (index < colormap->size)
{
- available = g_new (gchar, colormap->size);
- for (i = 0; i < colormap->size; i++)
- available[i] = TRUE;
-
- index = gdk_colormap_match_color (colormap, color, available);
- if (index != -1)
- {
- available[index] = FALSE;
- *color = colormap->colors[index];
- return_val = TRUE;
- }
- else
- {
- return_val = FALSE;
- }
+ colors[i].pixel = index;
+ success[i] = TRUE;
+ private->info[index].ref_count++;
+ private->info[i].flags |= GDK_COLOR_WRITEABLE;
}
else
+ break;
+ }
+ return i;
+ }
+ else
+ {
+ pixels = g_new (gulong, ncolors);
+ /* Allocation of a writeable color cells */
+
+ status = XAllocColorCells (private->xdisplay, private->xcolormap,
+ FALSE, NULL, 0, pixels, ncolors);
+ if (status)
+ {
+ for (i=0; i<ncolors; i++)
{
- xcolor.pixel = colormap->size - 1 -private->next_color;
- color->pixel = xcolor.pixel;
- private->next_color += 1;
+ colors[i].pixel = pixels[i];
+ private->info[pixels[i]].ref_count++;
+ private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
+ }
+ }
+
+ g_free (pixels);
- XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
- return_val = TRUE;
+ return status ? ncolors : 0;
+ }
+}
+
+static gint
+gdk_colormap_alloc_colors_private (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ gint i, index;
+ XColor *store = g_new (XColor, ncolors);
+ gint nstore = 0;
+ gint nremaining = 0;
+
+ private = (GdkColormapPrivate*) colormap;
+ index = -1;
+
+ /* First, store the colors we have room for */
+
+ index = 0;
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ while ((index < colormap->size) && (private->info[index].ref_count != 0))
+ index++;
+
+ if (index < colormap->size)
+ {
+ store[nstore].red = colors[i].red;
+ store[nstore].blue = colors[i].blue;
+ store[nstore].green = colors[i].green;
+ store[nstore].pixel = index;
+ nstore++;
+
+ success[i] = TRUE;
+
+ colors[i].pixel = index;
+ private->info[index].ref_count++;
}
+ else
+ nremaining++;
}
- else
+ }
+
+ XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
+ g_free (store);
+
+ if (nremaining > 0 && best_match)
+ {
+ /* Get best matches for remaining colors */
+
+ gchar *available = g_new (gchar, colormap->size);
+ for (i = 0; i < colormap->size; i++)
+ available[i] = TRUE;
+
+ for (i=0; i<ncolors; i++)
{
- while (1)
+ if (!success[i])
{
- if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ index = gdk_colormap_match_color (colormap,
+ &colors[i],
+ available);
+ if (index != -1)
{
- color->pixel = xcolor.pixel;
- color->red = xcolor.red;
- color->green = xcolor.green;
- color->blue = xcolor.blue;
-
- if (color->pixel < colormap->size)
- colormap->colors[color->pixel] = *color;
+ colors[i] = colormap->colors[index];
+ private->info[index].ref_count++;
- return_val = TRUE;
- break;
+ success[i] = TRUE;
+ nremaining--;
}
- else
- {
- if (available == NULL)
- {
- available = g_new (gchar, colormap->size);
- for (i = 0; i < colormap->size; i++)
- available[i] = TRUE;
- }
+ }
+ }
+ g_free (available);
+ }
+
+ return (ncolors - nremaining);
+}
+
+static gint
+gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ gint i, index;
+ gint nremaining = 0;
+ gint nfailed = 0;
+
+ private = (GdkColormapPrivate*) colormap;
+ index = -1;
+
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
+ success[i] = TRUE;
+ else
+ nremaining++;
+ }
+ }
+
- index = gdk_colormap_match_color (colormap, color, available);
+ if (nremaining > 0 && best_match)
+ {
+ gchar *available = g_new (gchar, colormap->size);
+ for (i = 0; i < colormap->size; i++)
+ available[i] = ((private->info[i].ref_count == 0) ||
+ !(private->info[i].flags && GDK_COLOR_WRITEABLE));
+ gdk_colormap_sync (colormap, FALSE);
+
+ while (nremaining > 0)
+ {
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ index = gdk_colormap_match_color (colormap, &colors[i], available);
if (index != -1)
{
- available[index] = FALSE;
- xcolor.red = colormap->colors[index].red;
- xcolor.green = colormap->colors[index].green;
- xcolor.blue = colormap->colors[index].blue;
+ if (private->info[index].ref_count)
+ {
+ private->info[index].ref_count++;
+ colors[i] = colormap->colors[index];
+ success[i] = TRUE;
+ nremaining--;
+ }
+ else
+ {
+ if (gdk_colormap_alloc1 (colormap,
+ &colormap->colors[index],
+ &colors[i]))
+ {
+ success[i] = TRUE;
+ nremaining--;
+ break;
+ }
+ else
+ {
+ available[index] = FALSE;
+ }
+ }
}
else
{
- return_val = FALSE;
- break;
+ nfailed++;
+ nremaining--;
+ success[i] = 2; /* flag as permanent failure */
}
}
}
}
+ g_free (available);
+ }
+
+ /* Change back the values we flagged as permanent failures */
+ if (nfailed > 0)
+ {
+ for (i=0; i<ncolors; i++)
+ if (success[i] == 2)
+ success[i] = FALSE;
+ nremaining = nfailed;
+ }
+
+ return (ncolors - nremaining);
+}
+
+static gint
+gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ GdkColor *lookup_color;
+ gint i;
+ gint nremaining = 0;
+
+ private = (GdkColormapPrivate*) colormap;
+
+ /* Check for an exact match among previously allocated colors */
+
+ for (i=0; i<ncolors; i++)
+ {
+ if (!success[i])
+ {
+ lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
+ if (lookup_color)
+ {
+ private->info[lookup_color->pixel].ref_count++;
+ colors[i].pixel = lookup_color->pixel;
+ success[i] = TRUE;
+ }
+ else
+ nremaining++;
+ }
+ }
+
+ /* If that failed, we try to allocate a new color, or approxmiate
+ * with what we can get if best_match is TRUE.
+ */
+ if (nremaining > 0)
+ {
+ if (private->private_val)
+ return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
+ else
+ return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
+ }
+ else
+ return 0;
+}
+
+gint
+gdk_colormap_alloc_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ GdkColormapPrivate *private;
+ GdkVisual *visual;
+ gint i;
+ gint nremaining = 0;
+ XColor xcolor;
+
+ g_return_val_if_fail (colormap != NULL, FALSE);
+ g_return_val_if_fail (colors != NULL, FALSE);
+
+ private = (GdkColormapPrivate*) colormap;
+
+ for (i=0; i<ncolors; i++)
+ {
+ success[i] = FALSE;
+ }
+
+ switch (private->visual->type)
+ {
+ case GDK_VISUAL_PSEUDO_COLOR:
+ case GDK_VISUAL_GRAYSCALE:
+ if (writeable)
+ return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
+ writeable, best_match, success);
+ else
+ return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
+ writeable, best_match, success);
break;
case GDK_VISUAL_DIRECT_COLOR:
+ case GDK_VISUAL_TRUE_COLOR:
visual = private->visual;
- xcolor.pixel = (((xcolor.red >> (16 - visual->red_prec)) << visual->red_shift) +
- ((xcolor.green >> (16 - visual->green_prec)) << visual->green_shift) +
- ((xcolor.blue >> (16 - visual->blue_prec)) << visual->blue_shift));
- color->pixel = xcolor.pixel;
- return_val = TRUE;
+
+ for (i=0; i<ncolors; i++)
+ {
+ colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
+ ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
+ ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
+ success[i] = TRUE;
+ }
break;
case GDK_VISUAL_STATIC_GRAY:
case GDK_VISUAL_STATIC_COLOR:
- case GDK_VISUAL_TRUE_COLOR:
- if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ for (i=0; i<ncolors; i++)
{
- color->pixel = xcolor.pixel;
- return_val = TRUE;
+ xcolor.red = colors[i].red;
+ xcolor.green = colors[i].green;
+ xcolor.blue = colors[i].blue;
+ xcolor.pixel = colors[i].pixel;
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+
+ if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+ {
+ colors[i].pixel = xcolor.pixel;
+ success[i] = TRUE;
+ }
+ else
+ nremaining++;
}
- else
- return_val = FALSE;
break;
}
+ return nremaining;
+}
- if (available)
- g_free (available);
-
- return return_val;
+gboolean
+gdk_colormap_alloc_color (GdkColormap *colormap,
+ GdkColor *color,
+ gboolean writeable,
+ gboolean best_match)
+{
+ gboolean success;
+
+ gdk_colormap_alloc_colors (colormap, color, 1, writeable, best_match,
+ &success);
+
+ return success;
+}
+
+/* This is almost identical to gdk_colors_free.
+ * Keep them in sync!
+ */
+void
+gdk_colormap_free_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors)
+{
+ GdkColormapPrivate *private;
+ gulong *pixels;
+ gint npixels = 0;
+ gint i;
+
+ g_return_if_fail (colormap != NULL);
+ g_return_if_fail (colors != NULL);
+
+ private = (GdkColormapPrivate*) colormap;
+
+ if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
+ (private->visual->type != GDK_VISUAL_GRAYSCALE))
+ return;
+
+ pixels = g_new (gulong, ncolors);
+
+ for (i=0; i<ncolors; i++)
+ {
+ gulong pixel = colors[i].pixel;
+
+ if (private->info[pixel].ref_count)
+ {
+ private->info[pixel].ref_count--;
+
+ if (private->info[pixel].ref_count == 0)
+ {
+ pixels[npixels++] = pixel;
+ if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
+ g_hash_table_remove (private->hash, &colors[i]);
+ private->info[pixel].flags = 0;
+ }
+ }
+ }
+
+ if (npixels)
+ XFreeColors (private->xdisplay, private->xcolormap,
+ pixels, npixels, 0);
+
+ g_free (pixels);
+}
+
+gboolean
+gdk_color_alloc (GdkColormap *colormap,
+ GdkColor *color)
+{
+ gboolean success;
+
+ gdk_colormap_alloc_colors (colormap, color, 1, FALSE, TRUE, &success);
+
+ return success;
}
gboolean
@@ -645,9 +1085,19 @@ gdk_color_change (GdkColormap *colormap,
return TRUE;
}
+guint
+gdk_color_hash (const GdkColor *colora,
+ const GdkColor *colorb)
+{
+ return ((colora->red) +
+ (colora->green << 11) +
+ (colora->blue << 22) +
+ (colora->blue >> 6));
+}
+
gint
-gdk_color_equal (GdkColor *colora,
- GdkColor *colorb)
+gdk_color_equal (const GdkColor *colora,
+ const GdkColor *colorb)
{
g_return_val_if_fail (colora != NULL, FALSE);
g_return_val_if_fail (colorb != NULL, FALSE);
@@ -657,6 +1107,9 @@ gdk_color_equal (GdkColor *colora,
(colora->blue == colorb->blue));
}
+/* XXX: Do not use this function until it is fixed. An X Colormap
+ * is useless unless we also have the visual.
+ */
GdkColormap*
gdkx_colormap_get (Colormap xcolormap)
{
@@ -677,7 +1130,6 @@ gdkx_colormap_get (Colormap xcolormap)
private->xcolormap = xcolormap;
private->visual = NULL;
private->private_val = TRUE;
- private->next_color = 0;
/* To do the following safely, we would have to have some way of finding
* out what the size or visual of the given colormap is. It seems
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index 5573d1001..1932d7d3b 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -446,15 +446,15 @@ gdk_init (int *argc,
{
(*argv)[i++] = NULL;
if (strcmp ("none", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditNone);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_NONE);
else if (strcmp ("nothing", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditNothing);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_NOTHING);
else if (strcmp ("area", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditArea);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_AREA);
else if (strcmp ("position", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditPosition);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_POSITION);
else if (strcmp ("callbacks", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMPreeditCallbacks);
+ gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS);
}
}
else if (strcmp ("--xim-status", (*argv)[i]) == 0)
@@ -463,13 +463,13 @@ gdk_init (int *argc,
{
(*argv)[i++] = NULL;
if (strcmp ("none", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusNone);
+ gdk_im_set_best_style (GDK_IM_STATUS_NONE);
else if (strcmp ("nothing", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusNothing);
+ gdk_im_set_best_style (GDK_IM_STATUS_NOTHING);
else if (strcmp ("area", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusArea);
+ gdk_im_set_best_style (GDK_IM_STATUS_AREA);
else if (strcmp ("callbacks", (*argv)[i]) == 0)
- gdk_im_set_best_style (GdkIMStatusCallbacks);
+ gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS);
}
}
#endif
@@ -584,10 +584,10 @@ gdk_init (int *argc,
xim_using = FALSE;
xim_im = NULL;
xim_styles = NULL;
- if (!(xim_best_allowed_style & GdkIMPreeditMask))
- gdk_im_set_best_style (GdkIMPreeditCallbacks);
- if (!(xim_best_allowed_style & GdkIMStatusMask))
- gdk_im_set_best_style (GdkIMStatusCallbacks);
+ 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;
@@ -3570,34 +3570,34 @@ gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2)
if (style1 == 0) return style2;
if (style2 == 0) return style1;
- if ((style1 & (GdkIMPreeditMask | GdkIMStatusMask))
- == (style2 & (GdkIMPreeditMask | GdkIMStatusMask)))
+ if ((style1 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK))
+ == (style2 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK)))
return style1;
-
- s1 = style1 & GdkIMPreeditMask;
- s2 = style2 & GdkIMPreeditMask;
+
+ s1 = style1 & GDK_IM_PREEDIT_MASK;
+ s2 = style2 & GDK_IM_PREEDIT_MASK;
u = s1 | s2;
if (s1 != s2) {
- if (u & GdkIMPreeditCallbacks)
- return (s1 == GdkIMPreeditCallbacks)? style1:style2;
- else if (u & GdkIMPreeditPosition)
- return (s1 == GdkIMPreeditPosition)? style1:style2;
- else if (u & GdkIMPreeditArea)
- return (s1 == GdkIMPreeditArea)? style1:style2;
- else if (u & GdkIMPreeditNothing)
- return (s1 == GdkIMPreeditNothing)? style1:style2;
+ 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 & GdkIMStatusMask;
- s2 = style2 & GdkIMStatusMask;
+ s1 = style1 & GDK_IM_STATUS_MASK;
+ s2 = style2 & GDK_IM_STATUS_MASK;
u = s1 | s2;
- if ( u & GdkIMStatusCallbacks)
- return (s1 == GdkIMStatusCallbacks)? style1:style2;
- else if ( u & GdkIMStatusArea)
- return (s1 == GdkIMStatusArea)? style1:style2;
- else if ( u & GdkIMStatusNothing)
- return (s1 == GdkIMStatusNothing)? style1:style2;
- else if ( u & GdkIMStatusNone)
- return (s1 == GdkIMStatusNone)? style1:style2;
+ 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 */
}
@@ -3623,39 +3623,39 @@ gdk_im_decide_style (GdkIMStyle supported_style)
GdkIMStyle
gdk_im_set_best_style (GdkIMStyle style)
{
- if (style & GdkIMPreeditMask)
+ if (style & GDK_IM_PREEDIT_MASK)
{
- xim_best_allowed_style &= ~GdkIMPreeditMask;
-
- xim_best_allowed_style |= GdkIMPreeditNone;
- if (!(style & GdkIMPreeditNone))
+ 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 |= GdkIMPreeditNothing;
- if (!(style & GdkIMPreeditNothing))
+ xim_best_allowed_style |= GDK_IM_PREEDIT_NOTHING;
+ if (!(style & GDK_IM_PREEDIT_NOTHING))
{
- xim_best_allowed_style |= GdkIMPreeditArea;
- if (!(style & GdkIMPreeditArea))
+ xim_best_allowed_style |= GDK_IM_PREEDIT_AREA;
+ if (!(style & GDK_IM_PREEDIT_AREA))
{
- xim_best_allowed_style |= GdkIMPreeditPosition;
- if (!(style & GdkIMPreeditPosition))
- xim_best_allowed_style |= GdkIMPreeditCallbacks;
+ xim_best_allowed_style |= GDK_IM_PREEDIT_POSITION;
+ if (!(style & GDK_IM_PREEDIT_POSITION))
+ xim_best_allowed_style |= GDK_IM_PREEDIT_CALLBACKS;
}
}
}
}
- if (style & GdkIMStatusMask)
+ if (style & GDK_IM_STATUS_MASK)
{
- xim_best_allowed_style &= ~GdkIMStatusMask;
-
- xim_best_allowed_style |= GdkIMStatusNone;
- if (!(style & GdkIMStatusNone))
+ 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 |= GdkIMStatusNothing;
- if (!(style & GdkIMStatusNothing))
+ xim_best_allowed_style |= GDK_IM_STATUS_NOTHING;
+ if (!(style & GDK_IM_STATUS_NOTHING))
{
- xim_best_allowed_style |= GdkIMStatusArea;
- if (!(style & GdkIMStatusArea))
- xim_best_allowed_style |= GdkIMStatusCallbacks;
+ xim_best_allowed_style |= GDK_IM_STATUS_AREA;
+ if (!(style & GDK_IM_STATUS_AREA))
+ xim_best_allowed_style |= GDK_IM_STATUS_CALLBACKS;
}
}
}
@@ -3960,13 +3960,13 @@ gdk_im_end (void)
GdkIMStyle
gdk_im_decide_style (GdkIMStyle supported_style)
{
- return GdkIMPreeditNone | GdkIMStatusNone;
+ return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
GdkIMStyle
gdk_im_set_best_style (GdkIMStyle style)
{
- return GdkIMPreeditNone | GdkIMStatusNone;
+ return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
gint
@@ -3991,7 +3991,7 @@ gdk_ic_destroy (GdkIC ic)
GdkIMStyle
gdk_ic_get_style (GdkIC ic)
{
- return GdkIMPreeditNone | GdkIMStatusNone;
+ return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
void
diff --git a/gdk/x11/gdkpixmap-x11.c b/gdk/x11/gdkpixmap-x11.c
index 9fdef0ffc..dfaf4822c 100644
--- a/gdk/x11/gdkpixmap-x11.c
+++ b/gdk/x11/gdkpixmap-x11.c
@@ -34,6 +34,13 @@ typedef struct
gint transparent;
} _GdkPixmapColor;
+typedef struct
+{
+ guint ncolors;
+ GdkColormap *colormap;
+ gulong pixels[1];
+} _GdkPixmapInfo;
+
GdkPixmap*
gdk_pixmap_new (GdkWindow *window,
gint width,
@@ -388,13 +395,6 @@ gdk_pixmap_extract_color (gchar *buffer)
return retcol;
}
-static void
-free_color (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- g_free (value);
-}
-
enum buffer_op
{
@@ -403,6 +403,23 @@ enum buffer_op
op_body
};
+
+static void
+gdk_xpm_destroy_notify (gpointer data)
+{
+ _GdkPixmapInfo *info = (_GdkPixmapInfo *)data;
+ GdkColor color;
+ int i;
+
+ for (i=0; i<info->ncolors; i++)
+ {
+ color.pixel = info->pixels[i];
+ gdk_colormap_free_colors (info->colormap, &color, 1);
+ }
+
+ gdk_colormap_unref (info->colormap);
+ g_free (info);
+}
static GdkPixmap *
_gdk_pixmap_create_from_xpm (GdkWindow *window,
@@ -420,9 +437,12 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
GdkColor tmp_color;
gint width, height, num_cols, cpp, n, ns, cnt, xcnt, ycnt, wbytes;
gchar *buffer, pixel_str[32];
+ gchar *name_buf;
_GdkPixmapColor *color = NULL, *fallbackcolor = NULL;
+ _GdkPixmapColor *colors = NULL;
gulong index;
- GHashTable *colors = NULL;
+ GHashTable *color_hash = NULL;
+ _GdkPixmapInfo *color_info = NULL;
if ((window == NULL) && (colormap == NULL))
g_warning ("Creating pixmap from xpm with NULL window and colormap");
@@ -449,14 +469,30 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
return NULL;
}
- colors = g_hash_table_new (g_str_hash, g_str_equal);
+ color_hash = g_hash_table_new (g_str_hash, g_str_equal);
if (transparent_color == NULL)
{
gdk_color_white (colormap, &tmp_color);
transparent_color = &tmp_color;
}
-
+
+ /* For pseudo-color and grayscale visuals, we have to remember
+ * the colors we allocated, so we can free them later.
+ */
+ if ((visual->type == GDK_VISUAL_PSEUDO_COLOR) ||
+ (visual->type == GDK_VISUAL_GRAYSCALE))
+ {
+ color_info = g_malloc (sizeof (_GdkPixmapInfo) +
+ sizeof(gulong) * (num_cols - 1));
+ color_info->ncolors = num_cols;
+ color_info->colormap = colormap;
+ gdk_colormap_ref (colormap);
+ }
+
+ name_buf = g_new (gchar, num_cols * (cpp+1));
+ colors = g_new (_GdkPixmapColor, num_cols);
+
for (cnt = 0; cnt < num_cols; cnt++)
{
gchar *color_name;
@@ -465,8 +501,8 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
if (buffer == NULL)
goto error;
- color = g_new (_GdkPixmapColor, 1);
- color->color_string = g_new (gchar, cpp + 1);
+ color = &colors[cnt];
+ color->color_string = &name_buf [cnt * (cpp + 1)];
strncpy (color->color_string, buffer, cpp);
color->color_string[cpp] = 0;
buffer += strlen (color->color_string);
@@ -486,7 +522,11 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
/* FIXME: The remaining slowness appears to happen in this
function. */
gdk_color_alloc (colormap, &color->color);
- g_hash_table_insert (colors, color->color_string, color);
+
+ if (color_info)
+ color_info->pixels[cnt] = color->color.pixel;
+
+ g_hash_table_insert (color_hash, color->color_string, color);
if (cnt == 0)
fallbackcolor = color;
}
@@ -531,7 +571,7 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
pixel_str[cpp] = 0;
ns = 0;
- color = g_hash_table_lookup (colors, pixel_str);
+ color = g_hash_table_lookup (color_hash, pixel_str);
if (!color) /* screwed up XPM file */
color = fallbackcolor;
@@ -558,6 +598,10 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
if (image != NULL)
{
pixmap = gdk_pixmap_new (window, width, height, visual->depth);
+
+ if (color_info)
+ gdk_drawable_set_data (pixmap, "gdk-xpm", color_info,
+ gdk_xpm_destroy_notify);
gc = gdk_gc_new (pixmap);
gdk_gc_set_foreground (gc, transparent_color);
@@ -565,13 +609,18 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
gdk_gc_destroy (gc);
gdk_image_destroy (image);
}
+ else if (color_info)
+ gdk_xpm_destroy_notify (color_info);
+ if (color_hash != NULL)
+ g_hash_table_destroy (color_hash);
+
if (colors != NULL)
- {
- g_hash_table_foreach (colors, free_color, 0);
- g_hash_table_destroy (colors);
- }
-
+ g_free (colors);
+
+ if (name_buf != NULL)
+ g_free (name_buf);
+
return pixmap;
}
@@ -720,6 +769,7 @@ gdk_pixmap_unref (GdkPixmap *pixmap)
{
XFreePixmap (private->xdisplay, private->xwindow);
gdk_xid_table_remove (private->xwindow);
+ g_dataset_destroy (private);
g_free (private);
}
}
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index bd4adfaee..afbcdc4cc 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -704,8 +704,10 @@ gdk_window_unref (GdkWindow *window)
{
if (!private->destroyed)
g_warning ("losing last reference to undestroyed window\n");
+ g_dataset_destroy (window);
g_free (window);
}
+
}
void
@@ -2076,3 +2078,11 @@ gdk_window_get_toplevels (void)
return new_list;
}
+void
+gdk_drawable_set_data (GdkDrawable *drawable,
+ const gchar *key,
+ gpointer data,
+ GDestroyNotify destroy_func)
+{
+ g_dataset_set_data_full (drawable, key, data, destroy_func);
+}
diff --git a/gdk/x11/gdkx.h b/gdk/x11/gdkx.h
index 2f43fd85f..fbe655d2e 100644
--- a/gdk/x11/gdkx.h
+++ b/gdk/x11/gdkx.h
@@ -39,6 +39,8 @@
GdkVisual* gdkx_visual_get (VisualID xvisualid);
+/* XXX: Do not use this function until it is fixed. An X Colormap
+ * is useless unless we also have the visual. */
GdkColormap* gdkx_colormap_get (Colormap xcolormap);
/* Utility function in gdk.c - not sure where it belongs, but it's
needed in more than one place, so make it public */
diff --git a/gtk/gtk.defs b/gtk/gtk.defs
index 024fcf5d0..318334539 100644
--- a/gtk/gtk.defs
+++ b/gtk/gtk.defs
@@ -416,6 +416,9 @@
; enumerations from "../gdk/gdkprivate.h"
+(define-flags GdkColorInfoFlags
+ (writeable GDK_COLOR_WRITEABLE))
+
(define-flags GdkDebugFlag
(misc GDK_DEBUG_MISC)
(events GDK_DEBUG_EVENTS)
@@ -809,15 +812,17 @@
(cursor GDK_EXTENSION_EVENTS_CURSOR))
(define-flags GdkIMStyle
- (preedit-area GdkIMPreeditArea)
- (preedit-callbacks GdkIMPreeditCallbacks)
- (preedit-position GdkIMPreeditPosition)
- (preedit-nothing GdkIMPreeditNothing)
- (preedit-none GdkIMPreeditNone)
- (status-area GdkIMStatusArea)
- (status-callbacks GdkIMStatusCallbacks)
- (status-nothing GdkIMStatusNothing)
- (status-none GdkIMStatusNone))
+ (preedit-area GDK_IM_PREEDIT_AREA)
+ (preedit-callbacks GDK_IM_PREEDIT_CALLBACKS)
+ (preedit-position GDK_IM_PREEDIT_POSITION)
+ (preedit-nothing GDK_IM_PREEDIT_NOTHING)
+ (preedit-none GDK_IM_PREEDIT_NONE)
+ (preedit-mask GDK_IM_PREEDIT_MASK)
+ (status-area GDK_IM_STATUS_AREA)
+ (status-callbacks GDK_IM_STATUS_CALLBACKS)
+ (status-nothing GDK_IM_STATUS_NOTHING)
+ (status-none GDK_IM_STATUS_NONE)
+ (status-mask GDK_IM_STATUS_MASK))
(define-flags GdkWMDecoration
(all GDK_DECOR_ALL)
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 613d64239..5aaaf25a0 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -587,17 +587,17 @@ gtk_entry_realize (GtkWidget *widget)
gint width, height;
GdkEventMask mask;
GdkIMStyle style;
- GdkIMStyle supported_style = GdkIMPreeditNone | GdkIMPreeditNothing |
- GdkIMPreeditPosition |
- GdkIMStatusNone | GdkIMStatusNothing;
+ GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE | GDK_IM_PREEDIT_NOTHING |
+ GDK_IM_PREEDIT_POSITION |
+ GDK_IM_STATUS_NONE | GDK_IM_STATUS_NOTHING;
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
- supported_style &= ~GdkIMPreeditPosition;
+ supported_style &= ~GDK_IM_PREEDIT_POSITION;
style = gdk_im_decide_style (supported_style);
- switch (style & GdkIMPreeditMask)
+ switch (style & GDK_IM_PREEDIT_MASK)
{
- case GdkIMPreeditPosition:
+ case GDK_IM_PREEDIT_POSITION:
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
{
g_warning ("over-the-spot style requires fontset");
@@ -768,7 +768,7 @@ gtk_entry_size_allocate (GtkWidget *widget,
gtk_entry_adjust_scroll (entry);
#ifdef USE_XIM
- if (editable->ic && (gdk_ic_get_style (editable->ic) & GdkIMPreeditPosition))
+ if (editable->ic && (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
{
gint width, height;
GdkRectangle rect;
@@ -1442,7 +1442,7 @@ gtk_entry_draw_cursor_on_drawable (GtkEntry *entry, GdkDrawable *drawable)
gdk_draw_line (drawable, gc, xoffset, 0, xoffset, text_area_height);
#ifdef USE_XIM
if (gdk_im_ready() && editable->ic &&
- gdk_ic_get_style (editable->ic) & GdkIMPreeditPosition)
+ gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION)
{
GdkPoint spot;
diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h
index 8600627dd..856eb2788 100644
--- a/gtk/gtkmenu.h
+++ b/gtk/gtkmenu.h
@@ -73,6 +73,8 @@ struct _GtkMenuClass
GtkType gtk_menu_get_type (void);
GtkWidget* gtk_menu_new (void);
+
+/* Wrappers for the Menu Shell operations */
void gtk_menu_append (GtkMenu *menu,
GtkWidget *child);
void gtk_menu_prepend (GtkMenu *menu,
@@ -80,6 +82,8 @@ void gtk_menu_prepend (GtkMenu *menu,
void gtk_menu_insert (GtkMenu *menu,
GtkWidget *child,
gint position);
+
+/* Display the menu onscreen */
void gtk_menu_popup (GtkMenu *menu,
GtkWidget *parent_menu_shell,
GtkWidget *parent_menu_item,
@@ -87,17 +91,39 @@ void gtk_menu_popup (GtkMenu *menu,
gpointer data,
guint button,
guint32 activate_time);
+
+/* Position the menu according to it's position function. Called
+ * from gtkmenuitem.c when a menu-item changes its allocation
+ */
void gtk_menu_reposition (GtkMenu *menu);
+
void gtk_menu_popdown (GtkMenu *menu);
+
+/* Keep track of the last menu item selected. (For the purposes
+ * of the option menu
+ */
GtkWidget* gtk_menu_get_active (GtkMenu *menu);
void gtk_menu_set_active (GtkMenu *menu,
guint index);
+
void gtk_menu_set_accel_group (GtkMenu *menu,
GtkAccelGroup *accel_group);
+
+/* A reference count is kept for a widget when it is attached to
+ * a particular widget. This is typically a menu item; it may also
+ * be a widget with a popup menu - for instance, the Notebook widget.
+ */
void gtk_menu_attach_to_widget (GtkMenu *menu,
GtkWidget *attach_widget,
GtkMenuDetachFunc detacher);
+void gtk_menu_detach (GtkMenu *menu);
+
+/* This should be dumped in favor of data set when the menu is popped
+ * up - that is currently in the ItemFactory code, but should be
+ * in the Menu code.
+ */
GtkWidget* gtk_menu_get_attach_widget (GtkMenu *menu);
+
void gtk_menu_detach (GtkMenu *menu);
void gtk_menu_set_tearoff_state (GtkMenu *menu,
gboolean torn_off);
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index 2cfed81c5..ba0c1e697 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -59,11 +59,25 @@
#define MARK_NEXT_LIST_PTR(mark) ((mark)->property->next)
#define MARK_OFFSET(mark) ((mark)->offset)
#define MARK_PROPERTY_LENGTH(mark) (MARK_CURRENT_PROPERTY(mark)->length)
-#define MARK_CURRENT_FONT(mark) (((TextProperty*)(mark)->property->data)->font->gdk_font)
-#define MARK_CURRENT_FORE(mark) (&((TextProperty*)(mark)->property->data)->fore_color)
-#define MARK_CURRENT_BACK(mark) (&((TextProperty*)(mark)->property->data)->back_color)
-#define MARK_CURRENT_TEXT_FONT(m) (((TextProperty*)(m)->property->data)->font)
+
+#define MARK_CURRENT_FONT(text, mark) \
+ ((MARK_CURRENT_PROPERTY(mark)->flags & PROPERTY_FONT) ? \
+ MARK_CURRENT_PROPERTY(mark)->font->gdk_font : \
+ GTK_WIDGET (text)->style->font)
+#define MARK_CURRENT_FORE(text, mark) \
+ ((MARK_CURRENT_PROPERTY(mark)->flags & PROPERTY_FOREGROUND) ? \
+ &MARK_CURRENT_PROPERTY(mark)->fore_color : \
+ &((GtkWidget *)text)->style->text[((GtkWidget *)text)->state])
+#define MARK_CURRENT_BACK(text, mark) \
+ ((MARK_CURRENT_PROPERTY(mark)->flags & PROPERTY_BACKGROUND) ? \
+ &MARK_CURRENT_PROPERTY(mark)->back_color : \
+ &((GtkWidget *)text)->style->base[((GtkWidget *)text)->state])
+#define MARK_CURRENT_TEXT_FONT(text, mark) \
+ ((MARK_CURRENT_PROPERTY(mark)->flags & PROPERTY_FONT) ? \
+ MARK_CURRENT_PROPERTY(mark)->font : \
+ text->current_font)
+
#define TEXT_LENGTH(t) ((t)->text_end - (t)->gap_size)
#define FONT_HEIGHT(f) ((f)->ascent + (f)->descent)
#define LINE_HEIGHT(l) ((l).font_ascent + (l).font_descent)
@@ -73,7 +87,6 @@
#define LAST_INDEX(t, m) ((m).index == TEXT_LENGTH(t))
#define CACHE_DATA(c) (*(LineParams*)(c)->data)
-typedef struct _TextFont TextFont;
typedef struct _TextProperty TextProperty;
typedef struct _TabStopMark TabStopMark;
typedef struct _PrevTabCont PrevTabCont;
@@ -96,25 +109,35 @@ struct _SetVerticalScrollData {
GtkPropertyMark mark;
};
-struct _TextFont
+struct _GtkTextFont
{
/* The actual font. */
GdkFont *gdk_font;
-
+ guint ref_count;
+
gint16 char_widths[256];
};
+typedef enum {
+ PROPERTY_FONT = 1 << 0,
+ PROPERTY_FOREGROUND = 1 << 1,
+ PROPERTY_BACKGROUND = 1 << 2
+} TextPropertyFlags;
+
struct _TextProperty
{
/* Font. */
- TextFont* font;
-
+ GtkTextFont* font;
+
/* Background Color. */
GdkColor back_color;
/* Foreground Color. */
GdkColor fore_color;
-
+
+ /* Show which properties are set */
+ TextPropertyFlags flags;
+
/* Length of this property. */
guint length;
};
@@ -213,10 +236,24 @@ static gint gtk_text_focus_out (GtkWidget *widget,
static void move_gap_to_point (GtkText* text);
static void make_forward_space (GtkText* text, guint len);
+
+/* Property management */
+static GtkTextFont* get_text_font (GdkFont* gfont);
+static void text_font_unref (GtkTextFont *text_font);
+
static void insert_text_property (GtkText* text, GdkFont* font,
GdkColor *fore, GdkColor* back, guint len);
+static TextProperty* new_text_property (GtkText *text, GdkFont* font,
+ GdkColor* fore, GdkColor* back, guint length);
+static void destroy_text_property (TextProperty *prop);
+static void init_properties (GtkText *text);
+static void realize_property (GtkText *text, TextProperty *prop);
+static void realize_properties (GtkText *text);
+static void unrealize_property (GtkText *text, TextProperty *prop);
+static void unrealize_properties (GtkText *text);
+
static void delete_text_property (GtkText* text, guint len);
-static void init_properties (GtkText *text);
+
static guint pixel_height_of (GtkText* text, GList* cache_line);
/* Property Movement and Size Computations */
@@ -229,7 +266,6 @@ static GtkPropertyMark find_mark (GtkText* text, guint mark_position);
static GtkPropertyMark find_mark_near (GtkText* text, guint mark_position, const GtkPropertyMark* near);
static void find_line_containing_point (GtkText* text, guint point,
gboolean scroll);
-static TextProperty* new_text_property (GdkFont* font, GdkColor* fore, GdkColor* back, guint length);
/* Display */
static void compute_lines_pixels (GtkText* text, guint char_count,
@@ -551,6 +587,10 @@ gtk_text_init (GtkText *text)
text->timer = 0;
text->button = 0;
+ text->current_font = NULL;
+
+ init_properties (text);
+
GTK_EDITABLE(text)->editable = FALSE;
}
@@ -745,10 +785,7 @@ gtk_text_insert (GtkText *text,
g_return_if_fail (text != NULL);
g_return_if_fail (GTK_IS_TEXT (text));
-
- /* This must be because we need to have the style set up. */
- g_assert (GTK_WIDGET_REALIZED(text));
-
+
if (nchars < 0)
length = strlen (chars);
else
@@ -763,11 +800,6 @@ gtk_text_insert (GtkText *text,
frozen = TRUE;
}
- if (fore == NULL)
- fore = &GTK_WIDGET (text)->style->text[GTK_STATE_NORMAL];
- if (back == NULL)
- back = &GTK_WIDGET (text)->style->base[GTK_STATE_NORMAL];
-
if (!text->freeze && (text->line_start_cache != NULL))
{
find_line_containing_point (text, text->point.index, TRUE);
@@ -789,12 +821,8 @@ gtk_text_insert (GtkText *text,
text->cursor_mark.index += length;
move_gap_to_point (text);
-
- if (font == NULL)
- font = GTK_WIDGET (text)->style->font;
-
+
make_forward_space (text, length);
-
memcpy (text->text + text->gap_position, chars, length);
insert_text_property (text, font, fore, back, length);
@@ -1010,9 +1038,11 @@ gtk_text_finalize (GtkObject *object)
tmp_list = text->text_properties;
while (tmp_list)
{
- g_mem_chunk_free (text_property_chunk, tmp_list->data);
+ destroy_text_property (tmp_list->data);
tmp_list = tmp_list->next;
}
+
+ text_font_unref (text->current_font);
g_list_free (text->text_properties);
@@ -1096,17 +1126,19 @@ gtk_text_realize (GtkWidget *widget)
gint width, height;
GdkEventMask mask;
GdkIMStyle style;
- GdkIMStyle supported_style = GdkIMPreeditNone | GdkIMPreeditNothing |
- GdkIMPreeditPosition |
- GdkIMStatusNone | GdkIMStatusNothing;
+ GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE |
+ GDK_IM_PREEDIT_NOTHING |
+ GDK_IM_PREEDIT_POSITION |
+ GDK_IM_STATUS_NONE |
+ GDK_IM_STATUS_NOTHING;
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
- supported_style &= ~GdkIMPreeditPosition;
+ supported_style &= ~GDK_IM_PREEDIT_POSITION;
style = gdk_im_decide_style (supported_style);
- switch (style & GdkIMPreeditMask)
+ switch (style & GDK_IM_PREEDIT_MASK)
{
- case GdkIMPreeditPosition:
+ case GDK_IM_PREEDIT_POSITION:
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
{
g_warning ("over-the-spot style requires fontset");
@@ -1152,11 +1184,11 @@ gtk_text_realize (GtkWidget *widget)
}
}
#endif
-
- init_properties (text);
+ realize_properties (text);
gdk_window_show (text->text_area);
-
+ init_properties (text);
+
if (editable->selection_start_pos != editable->selection_end_pos)
gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
@@ -1182,7 +1214,11 @@ gtk_text_style_set (GtkWidget *widget,
if ((widget->allocation.width > 1) || (widget->allocation.height > 1))
recompute_geometry (text);
}
-
+
+ if (text->current_font)
+ text_font_unref (text->current_font);
+ text->current_font = get_text_font (widget->style->font);
+
if (GTK_WIDGET_DRAWABLE (widget))
gdk_window_clear (widget->window);
}
@@ -1206,7 +1242,9 @@ gtk_text_unrealize (GtkWidget *widget)
gdk_pixmap_unref (text->line_wrap_bitmap);
gdk_pixmap_unref (text->line_arrow_bitmap);
-
+
+ unrealize_properties (text);
+
if (GTK_WIDGET_CLASS (parent_class)->unrealize)
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
}
@@ -1399,7 +1437,7 @@ gtk_text_size_allocate (GtkWidget *widget,
TEXT_BORDER_ROOM) * 2);
#ifdef USE_XIM
- if (editable->ic && (gdk_ic_get_style (editable->ic) & GdkIMPreeditPosition))
+ if (editable->ic && (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
{
gint width, height;
GdkRectangle rect;
@@ -1703,14 +1741,20 @@ gtk_text_insert_text (GtkEditable *editable,
gint *position)
{
GtkText *text = GTK_TEXT (editable);
-
+ GdkFont *font;
+ GdkColor *fore, *back;
+
+ TextProperty *property;
+
gtk_text_set_point (text, *position);
- gtk_text_insert (text,
- MARK_CURRENT_FONT (&text->point),
- MARK_CURRENT_FORE (&text->point),
- MARK_CURRENT_BACK (&text->point),
- new_text, new_text_length);
+
+ property = MARK_CURRENT_PROPERTY (&text->point);
+ font = property->flags & PROPERTY_FONT ? property->font->gdk_font : NULL;
+ fore = property->flags & PROPERTY_FOREGROUND ? &property->fore_color : NULL;
+ back = property->flags & PROPERTY_BACKGROUND ? &property->back_color : NULL;
+ gtk_text_insert (text, font, fore, back, new_text, new_text_length);
+
*position = text->point.index;
}
@@ -2649,31 +2693,38 @@ insert_expose (GtkText* text, guint old_pixels, gint nchars,
TEXT_SHOW(text);
}
+/* Text property functions */
+
static guint
font_hash (gconstpointer font)
{
return gdk_font_id ((const GdkFont*) font);
}
-static TextFont*
+static GHashTable *font_cache_table = NULL;
+
+static GtkTextFont*
get_text_font (GdkFont* gfont)
{
- static GHashTable *font_cache_table = NULL;
- TextFont* tf;
- gpointer lu;
+ GtkTextFont* tf;
gint i;
if (!font_cache_table)
font_cache_table = g_hash_table_new (font_hash, (GCompareFunc) gdk_font_equal);
- lu = g_hash_table_lookup (font_cache_table, gfont);
-
- if (lu)
- return (TextFont*)lu;
-
- tf = g_new (TextFont, 1);
+ tf = g_hash_table_lookup (font_cache_table, gfont);
+ if (tf)
+ {
+ tf->ref_count++;
+ return tf;
+ }
+
+ tf = g_new (GtkTextFont, 1);
+ tf->ref_count = 1;
+
tf->gdk_font = gfont;
+ gdk_font_ref (gfont);
for(i = 0; i < 256; i += 1)
tf->char_widths[i] = gdk_char_width (gfont, (char)i);
@@ -2683,16 +2734,115 @@ get_text_font (GdkFont* gfont)
return tf;
}
+static void
+text_font_unref (GtkTextFont *text_font)
+{
+ text_font->ref_count--;
+ if (text_font->ref_count == 0)
+ {
+ g_hash_table_remove (font_cache_table, text_font->gdk_font);
+ gdk_font_unref (text_font->gdk_font);
+ g_free (text_font);
+ }
+}
+
static gint
text_properties_equal (TextProperty* prop, GdkFont* font, GdkColor *fore, GdkColor *back)
{
- return prop->font == get_text_font(font) &&
- gdk_color_equal(&prop->fore_color, fore) &&
- gdk_color_equal(&prop->back_color, back);
+ if (prop->flags & PROPERTY_FONT)
+ {
+ gboolean retval;
+ GtkTextFont *text_font;
+
+ if (!font)
+ return FALSE;
+
+ text_font = get_text_font (font);
+
+ retval = (prop->font == text_font);
+ text_font_unref (text_font);
+
+ if (!retval)
+ return FALSE;
+ }
+ else
+ if (font != NULL)
+ return FALSE;
+
+ if (prop->flags & PROPERTY_FOREGROUND)
+ {
+ if (!fore || !gdk_color_equal (&prop->fore_color, fore))
+ return FALSE;
+ }
+ else
+ if (fore != NULL)
+ return FALSE;
+
+ if (prop->flags & PROPERTY_BACKGROUND)
+ {
+ if (!back || !gdk_color_equal (&prop->fore_color, fore))
+ return FALSE;
+ }
+ else
+ if (fore != NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+realize_property (GtkText *text, TextProperty *prop)
+{
+ GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (text));
+
+ if (prop->flags & PROPERTY_FOREGROUND)
+ gdk_colormap_alloc_color (colormap, &prop->fore_color, FALSE, FALSE);
+
+ if (prop->flags & PROPERTY_BACKGROUND)
+ gdk_colormap_alloc_color (colormap, &prop->back_color, FALSE, FALSE);
+}
+
+static void
+realize_properties (GtkText *text)
+{
+ GList *tmp_list = text->text_properties;
+
+ while (tmp_list)
+ {
+ realize_property (text, tmp_list->data);
+
+ tmp_list = tmp_list->next;
+ }
+}
+
+static void
+unrealize_property (GtkText *text, TextProperty *prop)
+{
+ GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (text));
+
+ if (prop->flags & PROPERTY_FOREGROUND)
+ gdk_colormap_free_colors (colormap, &prop->fore_color, 1);
+
+ if (prop->flags & PROPERTY_BACKGROUND)
+ gdk_colormap_free_colors (colormap, &prop->back_color, 1);
+}
+
+static void
+unrealize_properties (GtkText *text)
+{
+ GList *tmp_list = text->text_properties;
+
+ while (tmp_list)
+ {
+ unrealize_property (text, tmp_list->data);
+
+ tmp_list = tmp_list->next;
+ }
}
static TextProperty*
-new_text_property (GdkFont* font, GdkColor* fore, GdkColor* back, guint length)
+new_text_property (GtkText *text, GdkFont *font, GdkColor* fore,
+ GdkColor* back, guint length)
{
TextProperty *prop;
@@ -2705,16 +2855,45 @@ new_text_property (GdkFont* font, GdkColor* fore, GdkColor* back, guint length)
}
prop = g_chunk_new(TextProperty, text_property_chunk);
+
+ prop->flags = 0;
+ if (font)
+ {
+ prop->flags |= PROPERTY_FONT;
+ prop->font = get_text_font (font);
+ }
+ else
+ prop->font = NULL;
- prop->font = get_text_font (font);
- prop->fore_color = *fore;
+ if (fore)
+ {
+ prop->flags |= PROPERTY_FOREGROUND;
+ prop->fore_color = *fore;
+ }
+
if (back)
- prop->back_color = *back;
+ {
+ prop->flags |= PROPERTY_BACKGROUND;
+ prop->back_color = *back;
+ }
+
prop->length = length;
-
+
+ if (GTK_WIDGET_REALIZED (text))
+ realize_property (text, prop);
+
return prop;
}
+static void
+destroy_text_property (TextProperty *prop)
+{
+ if (prop->font)
+ text_font_unref (prop->font);
+
+ g_mem_chunk_free (text_property_chunk, prop);
+}
+
/* Flop the memory between the point and the gap around like a
* dead fish. */
static void
@@ -2809,10 +2988,33 @@ insert_text_property (GtkText* text, GdkFont* font,
(forward_prop->length == 1))
{
/* Next property just has last position, take it over */
- forward_prop->font = get_text_font (font);
- forward_prop->fore_color = *fore;
- forward_prop->back_color = *back;
+
+ if (GTK_WIDGET_REALIZED (text))
+ unrealize_property (text, forward_prop);
+
+ forward_prop->flags = 0;
+ if (font)
+ {
+ forward_prop->flags |= PROPERTY_FONT;
+ forward_prop->font = get_text_font (font);
+ }
+ else
+ forward_prop->font = NULL;
+
+ if (fore)
+ {
+ forward_prop->flags |= PROPERTY_FOREGROUND;
+ forward_prop->fore_color = *fore;
+ }
+ if (back)
+ {
+ forward_prop->flags |= PROPERTY_BACKGROUND;
+ forward_prop->back_color = *back;
+ }
forward_prop->length += len;
+
+ if (GTK_WIDGET_REALIZED (text))
+ realize_property (text, forward_prop);
}
else
{
@@ -2826,9 +3028,9 @@ insert_text_property (GtkText* text, GdkFont* font,
if (new_prop->prev)
new_prop->prev->next = new_prop;
-
- new_prop->data = new_text_property (font, fore, back, len);
-
+
+ new_prop->data = new_text_property (text, font, fore, back, len);
+
SET_PROPERTY_MARK (mark, new_prop, 0);
}
}
@@ -2854,7 +3056,7 @@ insert_text_property (GtkText* text, GdkFont* font,
forward_prop->length -= 1;
new_prop = g_list_alloc();
- new_prop->data = new_text_property (font, fore, back, len+1);
+ new_prop->data = new_text_property (text, font, fore, back, len+1);
new_prop->prev = MARK_LIST_PTR(mark);
new_prop->next = NULL;
MARK_NEXT_LIST_PTR(mark) = new_prop;
@@ -2871,14 +3073,19 @@ insert_text_property (GtkText* text, GdkFont* font,
/* Set the new lengths according to where they are split. Construct
* two new properties. */
forward_prop->length = MARK_OFFSET(mark);
-
- new_prop_forward->data = new_text_property(forward_prop->font->gdk_font,
- &forward_prop->fore_color,
- &forward_prop->back_color,
- old_length - forward_prop->length);
-
- new_prop->data = new_text_property(font, fore, back, len);
-
+
+ new_prop_forward->data =
+ new_text_property(text,
+ forward_prop->flags & PROPERTY_FONT ?
+ forward_prop->font->gdk_font : NULL,
+ forward_prop->flags & PROPERTY_FOREGROUND ?
+ &forward_prop->fore_color : NULL,
+ forward_prop->flags & PROPERTY_BACKGROUND ?
+ &forward_prop->back_color : NULL,
+ old_length - forward_prop->length);
+
+ new_prop->data = new_text_property(text, font, fore, back, len);
+
/* Now splice things in. */
MARK_NEXT_LIST_PTR(mark) = new_prop;
new_prop->prev = MARK_LIST_PTR(mark);
@@ -2942,8 +3149,11 @@ delete_text_property (GtkText* text, guint nchars)
MARK_LIST_PTR (&text->point) = g_list_remove_link (tmp, tmp);
text->point.offset = 0;
-
- g_mem_chunk_free (text_property_chunk, prop);
+
+ if (GTK_WIDGET_REALIZED (text))
+ unrealize_property (text, prop);
+
+ destroy_text_property (prop);
g_list_free_1 (tmp);
prop = MARK_CURRENT_PROPERTY (&text->point);
@@ -2976,7 +3186,10 @@ delete_text_property (GtkText* text, guint nchars)
text->point.offset = MARK_CURRENT_PROPERTY(&text->point)->length - 1;
- g_mem_chunk_free (text_property_chunk, prop);
+ if (GTK_WIDGET_REALIZED (text))
+ unrealize_property (text, prop);
+
+ destroy_text_property (prop);
g_list_free_1 (tmp);
}
}
@@ -2984,17 +3197,12 @@ delete_text_property (GtkText* text, guint nchars)
static void
init_properties (GtkText *text)
{
- GtkWidget *widget = (GtkWidget *)text;
-
if (!text->text_properties)
{
text->text_properties = g_list_alloc();
text->text_properties->next = NULL;
text->text_properties->prev = NULL;
- text->text_properties->data = new_text_property (widget->style->font,
- &widget->style->text[GTK_STATE_NORMAL],
- &widget->style->base[GTK_STATE_NORMAL],
- 1);
+ text->text_properties->data = new_text_property (text, NULL, NULL, NULL, 1);
text->text_properties_end = text->text_properties;
SET_PROPERTY_MARK (&text->point, text->text_properties, 0);
@@ -3226,8 +3434,8 @@ find_char_width (GtkText* text, const GtkPropertyMark *mark, const TabStopMark *
return 0;
ch = GTK_TEXT_INDEX (text, mark->index);
- char_widths = MARK_CURRENT_TEXT_FONT (mark)->char_widths;
-
+ char_widths = MARK_CURRENT_TEXT_FONT (text, mark)->char_widths;
+
if (ch == '\t')
{
return tab_mark->to_next_tab * char_widths[' '];
@@ -3300,22 +3508,22 @@ find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_hei
#ifdef USE_XIM
if (gdk_im_ready() && editable->ic &&
- gdk_ic_get_style (editable->ic) & GdkIMPreeditPosition)
+ gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION)
{
GdkPoint spot;
spot.x = text->cursor_pos_x;
spot.y = text->cursor_pos_y - text->cursor_char_offset;
- if (MARK_CURRENT_FONT (&mark)->type == GDK_FONT_FONTSET)
+ if (MARK_CURRENT_FONT (text, &mark)->type == GDK_FONT_FONTSET)
gdk_ic_set_attr (editable->ic, "preeditAttributes",
- "fontSet", GDK_FONT_XFONT (MARK_CURRENT_FONT (&mark)),
+ "fontSet", GDK_FONT_XFONT (MARK_CURRENT_FONT (text, &mark)),
NULL);
gdk_ic_set_attr (editable->ic, "preeditAttributes",
"spotLocation", &spot,
"lineSpace", LINE_HEIGHT (*start_line),
- "foreground", MARK_CURRENT_FORE (&mark)->pixel,
- "background", MARK_CURRENT_BACK (&mark)->pixel,
+ "foreground", MARK_CURRENT_FORE (text, &mark)->pixel,
+ "background", MARK_CURRENT_BACK (text, &mark)->pixel,
NULL);
}
#endif
@@ -4219,8 +4427,8 @@ find_line_params (GtkText* text,
g_assert (lp.end.property);
ch = GTK_TEXT_INDEX (text, lp.end.index);
- font = MARK_CURRENT_FONT (&lp.end);
-
+ font = MARK_CURRENT_FONT (text, &lp.end);
+
if (ch == LINE_DELIM)
{
/* Newline doesn't count in computation of line height, even
@@ -4253,7 +4461,7 @@ find_line_params (GtkText* text,
{
/* Here's the tough case, a tab is wrapping. */
gint pixels_avail = max_display_pixels - lp.pixel_width;
- gint space_width = MARK_CURRENT_TEXT_FONT(&lp.end)->char_widths[' '];
+ gint space_width = MARK_CURRENT_TEXT_FONT(text, &lp.end)->char_widths[' '];
gint spaces_avail = pixels_avail / space_width;
if (spaces_avail == 0)
@@ -4320,8 +4528,8 @@ find_line_params (GtkText* text,
if (LAST_INDEX(text, lp.start))
{
/* Special case, empty last line. */
- font = MARK_CURRENT_FONT (&lp.end);
-
+ font = MARK_CURRENT_FONT (text, &lp.end);
+
lp.font_ascent = font->ascent;
lp.font_descent = font->descent;
}
@@ -4367,11 +4575,11 @@ mark_bg_gc (GtkText* text, const GtkPropertyMark *mark)
else
return GTK_WIDGET(text)->style->bg_gc[GTK_STATE_ACTIVE];
}
- else if (!gdk_color_equal(MARK_CURRENT_BACK (mark),
+ else if (!gdk_color_equal(MARK_CURRENT_BACK (text, mark),
&GTK_WIDGET(text)->style->base[GTK_STATE_NORMAL]))
{
- gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (mark));
+ gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (text, mark));
return text->gc;
}
return NULL;
@@ -4463,8 +4671,8 @@ draw_line (GtkText* text,
len = MIN (len, selection_start_pos - mark.index);
else if (mark.index < selection_end_pos)
len = MIN (len, selection_end_pos - mark.index);
-
- font = MARK_CURRENT_PROPERTY (&mark)->font->gdk_font;
+
+ font = MARK_CURRENT_FONT (text, &mark);
if (font->type == GDK_FONT_FONT)
{
gdk_gc_set_font (text->gc, font);
@@ -4506,11 +4714,11 @@ draw_line (GtkText* text,
}
else
{
- gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (&mark));
+ gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (text, &mark));
fg_gc = text->gc;
}
-
- gdk_draw_text (text->text_area, MARK_CURRENT_FONT (&mark),
+
+ gdk_draw_text (text->text_area, MARK_CURRENT_FONT (text, &mark),
fg_gc,
running_offset,
pixel_height,
@@ -4534,9 +4742,9 @@ draw_line (GtkText* text,
gdk_window_get_size (text->text_area, &pixels_remaining, NULL);
pixels_remaining -= (LINE_WRAP_ROOM + running_offset);
-
- space_width = MARK_CURRENT_TEXT_FONT(&mark)->char_widths[' '];
-
+
+ space_width = MARK_CURRENT_TEXT_FONT(text, &mark)->char_widths[' '];
+
spaces_avail = pixels_remaining / space_width;
spaces_avail = MIN (spaces_avail, tab_mark.to_next_tab);
@@ -4550,8 +4758,8 @@ draw_line (GtkText* text,
}
running_offset += tab_mark.to_next_tab *
- MARK_CURRENT_TEXT_FONT(&mark)->char_widths[' '];
-
+ MARK_CURRENT_TEXT_FONT(text, &mark)->char_widths[' '];
+
advance_tab_mark (text, &tab_mark, '\t');
}
@@ -4611,7 +4819,8 @@ static void
undraw_cursor (GtkText* text, gint absolute)
{
GtkEditable *editable = (GtkEditable *)text;
-
+ GdkGC *gc;
+
TDEBUG (("in undraw_cursor\n"));
if (absolute)
@@ -4624,10 +4833,11 @@ undraw_cursor (GtkText* text, gint absolute)
GdkFont* font;
g_assert(text->cursor_mark.property);
-
- font = MARK_CURRENT_FONT(&text->cursor_mark);
-
- if (GTK_WIDGET (text)->style->bg_pixmap[GTK_STATE_NORMAL])
+
+ font = MARK_CURRENT_FONT(text, &text->cursor_mark);
+ gc = mark_bg_gc (text, &text->cursor_mark);
+
+ if (!gc && (GTK_WIDGET (text)->style->bg_pixmap[GTK_STATE_NORMAL]))
{
GdkRectangle rect;
@@ -4640,8 +4850,12 @@ undraw_cursor (GtkText* text, gint absolute)
}
else
{
- gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (&text->cursor_mark));
- gdk_draw_line (text->text_area, text->gc, text->cursor_pos_x,
+ if (!gc)
+ {
+ gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (text, &text->cursor_mark));
+ gc = text->gc;
+ }
+ gdk_draw_line (text->text_area, gc, text->cursor_pos_x,
text->cursor_pos_y - text->cursor_char_offset, text->cursor_pos_x,
text->cursor_pos_y - text->cursor_char_offset - font->ascent);
}
@@ -4650,9 +4864,9 @@ undraw_cursor (GtkText* text, gint absolute)
{
if (font->type == GDK_FONT_FONT)
gdk_gc_set_font (text->gc, font);
-
- gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (&text->cursor_mark));
-
+
+ gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (text, &text->cursor_mark));
+
gdk_draw_text (text->text_area, font,
text->gc,
text->cursor_pos_x,
@@ -4670,7 +4884,7 @@ drawn_cursor_min (GtkText* text)
g_assert(text->cursor_mark.property);
- font = MARK_CURRENT_FONT(&text->cursor_mark);
+ font = MARK_CURRENT_FONT(text, &text->cursor_mark);
return text->cursor_pos_y - text->cursor_char_offset - font->ascent;
}
@@ -4682,7 +4896,7 @@ drawn_cursor_max (GtkText* text)
g_assert(text->cursor_mark.property);
- font = MARK_CURRENT_FONT(&text->cursor_mark);
+ font = MARK_CURRENT_FONT(text, &text->cursor_mark);
return text->cursor_pos_y - text->cursor_char_offset;
}
@@ -4705,9 +4919,9 @@ draw_cursor (GtkText* text, gint absolute)
GdkFont* font;
g_assert (text->cursor_mark.property);
-
- font = MARK_CURRENT_FONT (&text->cursor_mark);
-
+
+ font = MARK_CURRENT_FONT (text, &text->cursor_mark);
+
gdk_gc_set_foreground (text->gc, &GTK_WIDGET (text)->style->text[GTK_STATE_NORMAL]);
gdk_draw_line (text->text_area, text->gc, text->cursor_pos_x,
@@ -5072,8 +5286,20 @@ gtk_text_show_props (GtkText *text,
TextProperty *p = (TextProperty*)props->data;
proplen += p->length;
-
- g_message ("[%d,%p,%p,%ld,%ld] ", p->length, p, p->font, p->fore_color.pixel, p->back_color.pixel);
+
+ g_message ("[%d,%p,", p->length, p);
+ if (p->flags & PROPERTY_FONT)
+ g_message ("%p,", p->font);
+ else
+ g_message ("-,");
+ if (p->flags & PROPERTY_FOREGROUND)
+ g_message ("%ld, ", p->fore_color.pixel);
+ else
+ g_message ("-,");
+ if (p->flags & PROPERTY_BACKGROUND)
+ g_message ("%ld] ", p->back_color.pixel);
+ else
+ g_message ("-] ");
}
g_message ("\n");
diff --git a/gtk/gtktext.h b/gtk/gtktext.h
index 1de2de945..27f4689b7 100644
--- a/gtk/gtktext.h
+++ b/gtk/gtktext.h
@@ -24,7 +24,6 @@
#include <gtk/gtkadjustment.h>
#include <gtk/gtkeditable.h>
-
#ifdef __cplusplus
extern "C" {
#pragma }
@@ -37,7 +36,7 @@ extern "C" {
#define GTK_IS_TEXT(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_TEXT))
#define GTK_IS_TEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT))
-
+typedef struct _GtkTextFont GtkTextFont;
typedef struct _GtkPropertyMark GtkPropertyMark;
typedef struct _GtkText GtkText;
typedef struct _GtkTextClass GtkTextClass;
@@ -147,6 +146,8 @@ struct _GtkText
GList *tab_stops;
gint default_tab_width;
+ GtkTextFont *current_font; /* Text font for current style */
+
/* Timer used for auto-scrolling off ends */
gint timer;
diff --git a/gtk/gtktypebuiltins.h b/gtk/gtktypebuiltins.h
index d75f7b6c0..d8afc4718 100644
--- a/gtk/gtktypebuiltins.h
+++ b/gtk/gtktypebuiltins.h
@@ -55,6 +55,7 @@ extern GtkType GTK_TYPE_TOOLBAR_CHILD_TYPE;
extern GtkType GTK_TYPE_TREE_VIEW_MODE;
extern GtkType GTK_TYPE_FUNDAMENTAL_TYPE;
extern GtkType GTK_TYPE_WIDGET_FLAGS;
+extern GtkType GTK_TYPE_GDK_COLOR_INFO_FLAGS;
extern GtkType GTK_TYPE_GDK_DEBUG_FLAG;
extern GtkType GTK_TYPE_GDK_RGB_DITHER;
extern GtkType GTK_TYPE_GDK_WINDOW_TYPE;
diff --git a/gtk/gtktypebuiltins_evals.c b/gtk/gtktypebuiltins_evals.c
index 53d010f89..6bbef5a4b 100644
--- a/gtk/gtktypebuiltins_evals.c
+++ b/gtk/gtktypebuiltins_evals.c
@@ -438,6 +438,10 @@ static GtkEnumValue _gtk_widget_flags_values[] = {
{ GTK_BASIC, "GTK_BASIC", "basic" },
{ 0, NULL, NULL }
};
+static GtkEnumValue _gdk_color_info_flags_values[] = {
+ { GDK_COLOR_WRITEABLE, "GDK_COLOR_WRITEABLE", "writeable" },
+ { 0, NULL, NULL }
+};
static GtkEnumValue _gdk_debug_flag_values[] = {
{ GDK_DEBUG_MISC, "GDK_DEBUG_MISC", "misc" },
{ GDK_DEBUG_EVENTS, "GDK_DEBUG_EVENTS", "events" },
@@ -865,15 +869,17 @@ static GtkEnumValue _gdk_extension_mode_values[] = {
{ 0, NULL, NULL }
};
static GtkEnumValue _gdk_im_style_values[] = {
- { GdkIMPreeditArea, "GdkIMPreeditArea", "preedit-area" },
- { GdkIMPreeditCallbacks, "GdkIMPreeditCallbacks", "preedit-callbacks" },
- { GdkIMPreeditPosition, "GdkIMPreeditPosition", "preedit-position" },
- { GdkIMPreeditNothing, "GdkIMPreeditNothing", "preedit-nothing" },
- { GdkIMPreeditNone, "GdkIMPreeditNone", "preedit-none" },
- { GdkIMStatusArea, "GdkIMStatusArea", "status-area" },
- { GdkIMStatusCallbacks, "GdkIMStatusCallbacks", "status-callbacks" },
- { GdkIMStatusNothing, "GdkIMStatusNothing", "status-nothing" },
- { GdkIMStatusNone, "GdkIMStatusNone", "status-none" },
+ { GDK_IM_PREEDIT_AREA, "GDK_IM_PREEDIT_AREA", "preedit-area" },
+ { GDK_IM_PREEDIT_CALLBACKS, "GDK_IM_PREEDIT_CALLBACKS", "preedit-callbacks" },
+ { GDK_IM_PREEDIT_POSITION, "GDK_IM_PREEDIT_POSITION", "preedit-position" },
+ { GDK_IM_PREEDIT_NOTHING, "GDK_IM_PREEDIT_NOTHING", "preedit-nothing" },
+ { GDK_IM_PREEDIT_NONE, "GDK_IM_PREEDIT_NONE", "preedit-none" },
+ { GDK_IM_PREEDIT_MASK, "GDK_IM_PREEDIT_MASK", "preedit-mask" },
+ { GDK_IM_STATUS_AREA, "GDK_IM_STATUS_AREA", "status-area" },
+ { GDK_IM_STATUS_CALLBACKS, "GDK_IM_STATUS_CALLBACKS", "status-callbacks" },
+ { GDK_IM_STATUS_NOTHING, "GDK_IM_STATUS_NOTHING", "status-nothing" },
+ { GDK_IM_STATUS_NONE, "GDK_IM_STATUS_NONE", "status-none" },
+ { GDK_IM_STATUS_MASK, "GDK_IM_STATUS_MASK", "status-mask" },
{ 0, NULL, NULL }
};
static GtkEnumValue _gdk_wm_decoration_values[] = {
diff --git a/gtk/gtktypebuiltins_ids.c b/gtk/gtktypebuiltins_ids.c
index f348794a9..b13f05b46 100644
--- a/gtk/gtktypebuiltins_ids.c
+++ b/gtk/gtktypebuiltins_ids.c
@@ -110,6 +110,8 @@
GTK_TYPE_ENUM, _gtk_fundamental_type_values },
{ "GtkWidgetFlags", &GTK_TYPE_WIDGET_FLAGS,
GTK_TYPE_FLAGS, _gtk_widget_flags_values },
+ { "GdkColorInfoFlags", &GTK_TYPE_GDK_COLOR_INFO_FLAGS,
+ GTK_TYPE_FLAGS, _gdk_color_info_flags_values },
{ "GdkDebugFlag", &GTK_TYPE_GDK_DEBUG_FLAG,
GTK_TYPE_FLAGS, _gdk_debug_flag_values },
{ "GdkRgbDither", &GTK_TYPE_GDK_RGB_DITHER,
diff --git a/gtk/gtktypebuiltins_vars.c b/gtk/gtktypebuiltins_vars.c
index 921dfeb27..91b31a50c 100644
--- a/gtk/gtktypebuiltins_vars.c
+++ b/gtk/gtktypebuiltins_vars.c
@@ -55,6 +55,7 @@ GtkType GTK_TYPE_TOOLBAR_CHILD_TYPE = 0;
GtkType GTK_TYPE_TREE_VIEW_MODE = 0;
GtkType GTK_TYPE_FUNDAMENTAL_TYPE = 0;
GtkType GTK_TYPE_WIDGET_FLAGS = 0;
+GtkType GTK_TYPE_GDK_COLOR_INFO_FLAGS = 0;
GtkType GTK_TYPE_GDK_DEBUG_FLAG = 0;
GtkType GTK_TYPE_GDK_RGB_DITHER = 0;
GtkType GTK_TYPE_GDK_WINDOW_TYPE = 0;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index eb420ecde..ef1975664 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -3087,15 +3087,19 @@ gtk_widget_get_colormap (GtkWidget *widget)
g_return_val_if_fail (widget != NULL, NULL);
- if (!widget->window)
+ if (widget->window)
{
- colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
+ colormap = gdk_window_get_colormap (widget->window);
+ /* If window was destroyed previously, we'll get NULL here */
if (colormap)
return colormap;
- return gtk_widget_get_default_colormap ();
}
- return gdk_window_get_colormap (widget->window);
+ colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
+ if (colormap)
+ return colormap;
+
+ return gtk_widget_get_default_colormap ();
}
/*****************************************
@@ -3113,15 +3117,19 @@ gtk_widget_get_visual (GtkWidget *widget)
g_return_val_if_fail (widget != NULL, NULL);
- if (!widget->window)
+ if (widget->window)
{
- visual = gtk_object_get_data (GTK_OBJECT (widget), visual_key);
+ visual = gdk_window_get_visual (widget->window);
+ /* If window was destroyed previously, we'll get NULL here */
if (visual)
return visual;
- return gtk_widget_get_default_visual ();
}
- return gdk_window_get_visual (widget->window);
+ visual = gtk_object_get_data (GTK_OBJECT (widget), visual_key);
+ if (visual)
+ return visual;
+
+ return gtk_widget_get_default_visual ();
}
/*****************************************
diff --git a/gtk/testgtk.c b/gtk/testgtk.c
index 22cb8990c..f101c15a7 100644
--- a/gtk/testgtk.c
+++ b/gtk/testgtk.c
@@ -1759,6 +1759,8 @@ create_pixmap (void)
&style->bg[GTK_STATE_NORMAL],
"test.xpm");
pixmapwid = gtk_pixmap_new (pixmap, mask);
+ gdk_pixmap_unref (pixmap);
+ gdk_pixmap_unref (mask);
label = gtk_label_new ("Pixmap\ntest");
box3 = gtk_hbox_new (FALSE, 0);
@@ -5186,13 +5188,43 @@ text_toggle_word_wrap (GtkWidget *checkbutton,
GTK_TOGGLE_BUTTON(checkbutton)->active);
}
+struct {
+ GdkColor color;
+ gchar *name;
+} text_colors[] = {
+ { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
+ { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
+ { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
+ { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
+ { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" },
+ { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
+ { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
+ { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
+};
+
+int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
+
/*
* GtkText
*/
+void
+text_insert_random (GtkWidget *w, GtkText *text)
+{
+ int i;
+ char c;
+ for (i=0; i<10; i++)
+ {
+ c = 'A' + rand() % ('Z' - 'A');
+ gtk_text_set_point (text, rand() % gtk_text_get_length (text));
+ gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
+ }
+}
void
create_text (void)
{
+ int i, j;
+
static GtkWidget *window = NULL;
GtkWidget *box1;
GtkWidget *box2;
@@ -5204,6 +5236,7 @@ create_text (void)
GtkWidget *hscrollbar;
GtkWidget *vscrollbar;
GtkWidget *text;
+ GdkFont *font;
FILE *infile;
@@ -5259,7 +5292,27 @@ create_text (void)
gtk_text_freeze (GTK_TEXT (text));
- gtk_widget_realize (text);
+ font = gdk_font_load ("-adobe-courier-medium-r-normal--*-120-*-*-*-*-*-*");
+
+ for (i=0; i<ntext_colors; i++)
+ {
+ gtk_text_insert (GTK_TEXT (text), font, NULL, NULL,
+ text_colors[i].name, -1);
+ gtk_text_insert (GTK_TEXT (text), font, NULL, NULL, "\t", -1);
+
+ for (j=0; j<ntext_colors; j++)
+ {
+ gtk_text_insert (GTK_TEXT (text), font,
+ &text_colors[j].color, &text_colors[i].color,
+ "XYZ", -1);
+ }
+ gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
+ }
+
+ /* The Text widget will reference count the font, so we
+ * unreference it here
+ */
+ gdk_font_unref (font);
infile = fopen("testgtk.c", "r");
@@ -5281,13 +5334,6 @@ create_text (void)
fclose (infile);
}
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
- "And even ", -1);
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->bg[GTK_STATE_NORMAL], NULL,
- "colored", -1);
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
- "text", -1);
-
gtk_text_thaw (GTK_TEXT (text));
hbox = gtk_hbutton_box_new ();
@@ -5319,6 +5365,13 @@ create_text (void)
gtk_widget_show (box2);
+ button = gtk_button_new_with_label ("insert random");
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC(text_insert_random),
+ GTK_TEXT (text));
+ gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
diff --git a/gtk/testgtkrc b/gtk/testgtkrc
index 3427c0a87..e4e6ba72c 100644
--- a/gtk/testgtkrc
+++ b/gtk/testgtkrc
@@ -49,7 +49,7 @@ style "toggle_button" = "button"
style "text"
{
bg_pixmap[NORMAL] = "marble.xpm"
- text[NORMAL] = { 0.2, 0.2, 1.0 }
+ text[NORMAL] = { 1.0, 1.0, 1.0 }
fg[NORMAL] = { 1.0, 1.0, 1.0 }
base[NORMAL] = { 0.0, 0.0, 0.0 }
}
diff --git a/gtk/testinput.c b/gtk/testinput.c
index d2ea54cd2..ac8ff136a 100644
--- a/gtk/testinput.c
+++ b/gtk/testinput.c
@@ -369,6 +369,7 @@ main (int argc, char *argv[])
events for the drawing area */
gtk_widget_set_extension_events (drawing_area, GDK_EXTENSION_EVENTS_ALL);
+ GTK_WIDGET_SET_FLAGS (drawing_area, GTK_CAN_FOCUS);
gtk_widget_grab_focus (drawing_area);
/* .. And create some buttons */
diff --git a/tests/testgtk.c b/tests/testgtk.c
index 22cb8990c..f101c15a7 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -1759,6 +1759,8 @@ create_pixmap (void)
&style->bg[GTK_STATE_NORMAL],
"test.xpm");
pixmapwid = gtk_pixmap_new (pixmap, mask);
+ gdk_pixmap_unref (pixmap);
+ gdk_pixmap_unref (mask);
label = gtk_label_new ("Pixmap\ntest");
box3 = gtk_hbox_new (FALSE, 0);
@@ -5186,13 +5188,43 @@ text_toggle_word_wrap (GtkWidget *checkbutton,
GTK_TOGGLE_BUTTON(checkbutton)->active);
}
+struct {
+ GdkColor color;
+ gchar *name;
+} text_colors[] = {
+ { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
+ { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
+ { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
+ { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
+ { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" },
+ { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
+ { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
+ { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
+};
+
+int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
+
/*
* GtkText
*/
+void
+text_insert_random (GtkWidget *w, GtkText *text)
+{
+ int i;
+ char c;
+ for (i=0; i<10; i++)
+ {
+ c = 'A' + rand() % ('Z' - 'A');
+ gtk_text_set_point (text, rand() % gtk_text_get_length (text));
+ gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
+ }
+}
void
create_text (void)
{
+ int i, j;
+
static GtkWidget *window = NULL;
GtkWidget *box1;
GtkWidget *box2;
@@ -5204,6 +5236,7 @@ create_text (void)
GtkWidget *hscrollbar;
GtkWidget *vscrollbar;
GtkWidget *text;
+ GdkFont *font;
FILE *infile;
@@ -5259,7 +5292,27 @@ create_text (void)
gtk_text_freeze (GTK_TEXT (text));
- gtk_widget_realize (text);
+ font = gdk_font_load ("-adobe-courier-medium-r-normal--*-120-*-*-*-*-*-*");
+
+ for (i=0; i<ntext_colors; i++)
+ {
+ gtk_text_insert (GTK_TEXT (text), font, NULL, NULL,
+ text_colors[i].name, -1);
+ gtk_text_insert (GTK_TEXT (text), font, NULL, NULL, "\t", -1);
+
+ for (j=0; j<ntext_colors; j++)
+ {
+ gtk_text_insert (GTK_TEXT (text), font,
+ &text_colors[j].color, &text_colors[i].color,
+ "XYZ", -1);
+ }
+ gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
+ }
+
+ /* The Text widget will reference count the font, so we
+ * unreference it here
+ */
+ gdk_font_unref (font);
infile = fopen("testgtk.c", "r");
@@ -5281,13 +5334,6 @@ create_text (void)
fclose (infile);
}
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
- "And even ", -1);
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->bg[GTK_STATE_NORMAL], NULL,
- "colored", -1);
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
- "text", -1);
-
gtk_text_thaw (GTK_TEXT (text));
hbox = gtk_hbutton_box_new ();
@@ -5319,6 +5365,13 @@ create_text (void)
gtk_widget_show (box2);
+ button = gtk_button_new_with_label ("insert random");
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC(text_insert_random),
+ GTK_TEXT (text));
+ gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
diff --git a/tests/testgtkrc b/tests/testgtkrc
index 3427c0a87..e4e6ba72c 100644
--- a/tests/testgtkrc
+++ b/tests/testgtkrc
@@ -49,7 +49,7 @@ style "toggle_button" = "button"
style "text"
{
bg_pixmap[NORMAL] = "marble.xpm"
- text[NORMAL] = { 0.2, 0.2, 1.0 }
+ text[NORMAL] = { 1.0, 1.0, 1.0 }
fg[NORMAL] = { 1.0, 1.0, 1.0 }
base[NORMAL] = { 0.0, 0.0, 0.0 }
}
diff --git a/tests/testinput.c b/tests/testinput.c
index d2ea54cd2..ac8ff136a 100644
--- a/tests/testinput.c
+++ b/tests/testinput.c
@@ -369,6 +369,7 @@ main (int argc, char *argv[])
events for the drawing area */
gtk_widget_set_extension_events (drawing_area, GDK_EXTENSION_EVENTS_ALL);
+ GTK_WIDGET_SET_FLAGS (drawing_area, GTK_CAN_FOCUS);
gtk_widget_grab_focus (drawing_area);
/* .. And create some buttons */