diff options
author | Owen Taylor <otaylor@redhat.com> | 1998-08-25 03:35:02 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 1998-08-25 03:35:02 +0000 |
commit | dfccba3826d182abeba12d9c96ec3a22fc878574 (patch) | |
tree | b95561d64d3b421615e9bae7d3db6e6e11dfe08a | |
parent | 4d24cab4f95f6cee1c51412ca15b4f0612401502 (diff) | |
download | gtk+-dfccba3826d182abeba12d9c96ec3a22fc878574.tar.gz |
Lot's of merges from main branch.
Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Fixed some remaining background drawing,
merges from main branch, cleanups.
50 files changed, 3040 insertions, 909 deletions
@@ -1,3 +1,8 @@ +Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/gtktext.c: Fixed some remaining background drawing, + merges from main branch, cleanups. + Mon Aug 24 10:55:51 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_draw_tab): Don't @@ -74,6 +79,104 @@ Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> * made gtkrc scanner append dir that gtkrc is read from to pixmap path. + +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 + + * gtk/gtkclist.c + * gtk/gtkmain.c: #if 0'd out some unused code + + * gtk/gtkobject.c: check for NULL object hash table in gtk_object_debug + +Mon Aug 24 02:36:53 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkarg.h: + * gtk/gtkarg.c: + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: + * gtk/gtkobject.h: + * gtk/gtkobject.c: + * gtk/gtkcontainer.h: + * gtk/gtkcontainer.c: + (gtk_object_new): + (gtk_object_set): + (gtk_widget_new): + (gtk_widget_set): + (gtk_container_add_with_args): + (gtk_container_child_set): + begin the parameter elipsis (...) after the first argument name. this + change is source compatible, since it was always required, even as NULL. + (gtk_args_collect): + (gtk_object_args_collect): + (gtk_container_child_args_collect): + changed prototypes to pass first_arg_name, also, pass va_list variable + by value (portability concerns). callers changed. + + * gtk/gtkargcollector.c: implemented gtk_arg_collect_value() as + a huge macro GTK_ARG_COLLECT_VALUE() <shrug>. this is needed because we + can't pass va_list variables by reference for portability reasons. + +Fri Aug 21 22:40:00 Raph Levien <raph@gtk.org> + + * gdk/gdkrgb.c: added calls to gdk_rgb_init in the get_cmap and + get_visual calls, so that it gets implicitly initialized. + +Fri Aug 21 13:06:04 1998 Stuart Parmenter <pavlov@gimp.org> + * gtk/gtkfeatures.h.in: added GTK_HAVE_FEATURES_1_1_2 for changes + such as GtkCTree function name changes Mon Aug 10 23:03:55 1998 The Rasterman <raster@redhat.com> * Fixed minor problem in gtkhandlebox.c with drawing, and some diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 9554dc3a22..7b94f6b1c8 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,8 @@ +Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/gtktext.c: Fixed some remaining background drawing, + merges from main branch, cleanups. + Mon Aug 24 10:55:51 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_draw_tab): Don't @@ -74,6 +79,104 @@ Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> * made gtkrc scanner append dir that gtkrc is read from to pixmap path. + +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 + + * gtk/gtkclist.c + * gtk/gtkmain.c: #if 0'd out some unused code + + * gtk/gtkobject.c: check for NULL object hash table in gtk_object_debug + +Mon Aug 24 02:36:53 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkarg.h: + * gtk/gtkarg.c: + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: + * gtk/gtkobject.h: + * gtk/gtkobject.c: + * gtk/gtkcontainer.h: + * gtk/gtkcontainer.c: + (gtk_object_new): + (gtk_object_set): + (gtk_widget_new): + (gtk_widget_set): + (gtk_container_add_with_args): + (gtk_container_child_set): + begin the parameter elipsis (...) after the first argument name. this + change is source compatible, since it was always required, even as NULL. + (gtk_args_collect): + (gtk_object_args_collect): + (gtk_container_child_args_collect): + changed prototypes to pass first_arg_name, also, pass va_list variable + by value (portability concerns). callers changed. + + * gtk/gtkargcollector.c: implemented gtk_arg_collect_value() as + a huge macro GTK_ARG_COLLECT_VALUE() <shrug>. this is needed because we + can't pass va_list variables by reference for portability reasons. + +Fri Aug 21 22:40:00 Raph Levien <raph@gtk.org> + + * gdk/gdkrgb.c: added calls to gdk_rgb_init in the get_cmap and + get_visual calls, so that it gets implicitly initialized. + +Fri Aug 21 13:06:04 1998 Stuart Parmenter <pavlov@gimp.org> + * gtk/gtkfeatures.h.in: added GTK_HAVE_FEATURES_1_1_2 for changes + such as GtkCTree function name changes Mon Aug 10 23:03:55 1998 The Rasterman <raster@redhat.com> * Fixed minor problem in gtkhandlebox.c with drawing, and some diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9554dc3a22..7b94f6b1c8 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,8 @@ +Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/gtktext.c: Fixed some remaining background drawing, + merges from main branch, cleanups. + Mon Aug 24 10:55:51 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_draw_tab): Don't @@ -74,6 +79,104 @@ Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> * made gtkrc scanner append dir that gtkrc is read from to pixmap path. + +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 + + * gtk/gtkclist.c + * gtk/gtkmain.c: #if 0'd out some unused code + + * gtk/gtkobject.c: check for NULL object hash table in gtk_object_debug + +Mon Aug 24 02:36:53 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkarg.h: + * gtk/gtkarg.c: + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: + * gtk/gtkobject.h: + * gtk/gtkobject.c: + * gtk/gtkcontainer.h: + * gtk/gtkcontainer.c: + (gtk_object_new): + (gtk_object_set): + (gtk_widget_new): + (gtk_widget_set): + (gtk_container_add_with_args): + (gtk_container_child_set): + begin the parameter elipsis (...) after the first argument name. this + change is source compatible, since it was always required, even as NULL. + (gtk_args_collect): + (gtk_object_args_collect): + (gtk_container_child_args_collect): + changed prototypes to pass first_arg_name, also, pass va_list variable + by value (portability concerns). callers changed. + + * gtk/gtkargcollector.c: implemented gtk_arg_collect_value() as + a huge macro GTK_ARG_COLLECT_VALUE() <shrug>. this is needed because we + can't pass va_list variables by reference for portability reasons. + +Fri Aug 21 22:40:00 Raph Levien <raph@gtk.org> + + * gdk/gdkrgb.c: added calls to gdk_rgb_init in the get_cmap and + get_visual calls, so that it gets implicitly initialized. + +Fri Aug 21 13:06:04 1998 Stuart Parmenter <pavlov@gimp.org> + * gtk/gtkfeatures.h.in: added GTK_HAVE_FEATURES_1_1_2 for changes + such as GtkCTree function name changes Mon Aug 10 23:03:55 1998 The Rasterman <raster@redhat.com> * Fixed minor problem in gtkhandlebox.c with drawing, and some diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 9554dc3a22..7b94f6b1c8 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,8 @@ +Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/gtktext.c: Fixed some remaining background drawing, + merges from main branch, cleanups. + Mon Aug 24 10:55:51 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_draw_tab): Don't @@ -74,6 +79,104 @@ Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> * made gtkrc scanner append dir that gtkrc is read from to pixmap path. + +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 + + * gtk/gtkclist.c + * gtk/gtkmain.c: #if 0'd out some unused code + + * gtk/gtkobject.c: check for NULL object hash table in gtk_object_debug + +Mon Aug 24 02:36:53 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkarg.h: + * gtk/gtkarg.c: + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: + * gtk/gtkobject.h: + * gtk/gtkobject.c: + * gtk/gtkcontainer.h: + * gtk/gtkcontainer.c: + (gtk_object_new): + (gtk_object_set): + (gtk_widget_new): + (gtk_widget_set): + (gtk_container_add_with_args): + (gtk_container_child_set): + begin the parameter elipsis (...) after the first argument name. this + change is source compatible, since it was always required, even as NULL. + (gtk_args_collect): + (gtk_object_args_collect): + (gtk_container_child_args_collect): + changed prototypes to pass first_arg_name, also, pass va_list variable + by value (portability concerns). callers changed. + + * gtk/gtkargcollector.c: implemented gtk_arg_collect_value() as + a huge macro GTK_ARG_COLLECT_VALUE() <shrug>. this is needed because we + can't pass va_list variables by reference for portability reasons. + +Fri Aug 21 22:40:00 Raph Levien <raph@gtk.org> + + * gdk/gdkrgb.c: added calls to gdk_rgb_init in the get_cmap and + get_visual calls, so that it gets implicitly initialized. + +Fri Aug 21 13:06:04 1998 Stuart Parmenter <pavlov@gimp.org> + * gtk/gtkfeatures.h.in: added GTK_HAVE_FEATURES_1_1_2 for changes + such as GtkCTree function name changes Mon Aug 10 23:03:55 1998 The Rasterman <raster@redhat.com> * Fixed minor problem in gtkhandlebox.c with drawing, and some diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 9554dc3a22..7b94f6b1c8 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,8 @@ +Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/gtktext.c: Fixed some remaining background drawing, + merges from main branch, cleanups. + Mon Aug 24 10:55:51 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_draw_tab): Don't @@ -74,6 +79,104 @@ Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> * made gtkrc scanner append dir that gtkrc is read from to pixmap path. + +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 + + * gtk/gtkclist.c + * gtk/gtkmain.c: #if 0'd out some unused code + + * gtk/gtkobject.c: check for NULL object hash table in gtk_object_debug + +Mon Aug 24 02:36:53 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkarg.h: + * gtk/gtkarg.c: + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: + * gtk/gtkobject.h: + * gtk/gtkobject.c: + * gtk/gtkcontainer.h: + * gtk/gtkcontainer.c: + (gtk_object_new): + (gtk_object_set): + (gtk_widget_new): + (gtk_widget_set): + (gtk_container_add_with_args): + (gtk_container_child_set): + begin the parameter elipsis (...) after the first argument name. this + change is source compatible, since it was always required, even as NULL. + (gtk_args_collect): + (gtk_object_args_collect): + (gtk_container_child_args_collect): + changed prototypes to pass first_arg_name, also, pass va_list variable + by value (portability concerns). callers changed. + + * gtk/gtkargcollector.c: implemented gtk_arg_collect_value() as + a huge macro GTK_ARG_COLLECT_VALUE() <shrug>. this is needed because we + can't pass va_list variables by reference for portability reasons. + +Fri Aug 21 22:40:00 Raph Levien <raph@gtk.org> + + * gdk/gdkrgb.c: added calls to gdk_rgb_init in the get_cmap and + get_visual calls, so that it gets implicitly initialized. + +Fri Aug 21 13:06:04 1998 Stuart Parmenter <pavlov@gimp.org> + * gtk/gtkfeatures.h.in: added GTK_HAVE_FEATURES_1_1_2 for changes + such as GtkCTree function name changes Mon Aug 10 23:03:55 1998 The Rasterman <raster@redhat.com> * Fixed minor problem in gtkhandlebox.c with drawing, and some diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 9554dc3a22..7b94f6b1c8 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,8 @@ +Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/gtktext.c: Fixed some remaining background drawing, + merges from main branch, cleanups. + Mon Aug 24 10:55:51 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_draw_tab): Don't @@ -74,6 +79,104 @@ Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> * made gtkrc scanner append dir that gtkrc is read from to pixmap path. + +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 + + * gtk/gtkclist.c + * gtk/gtkmain.c: #if 0'd out some unused code + + * gtk/gtkobject.c: check for NULL object hash table in gtk_object_debug + +Mon Aug 24 02:36:53 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkarg.h: + * gtk/gtkarg.c: + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: + * gtk/gtkobject.h: + * gtk/gtkobject.c: + * gtk/gtkcontainer.h: + * gtk/gtkcontainer.c: + (gtk_object_new): + (gtk_object_set): + (gtk_widget_new): + (gtk_widget_set): + (gtk_container_add_with_args): + (gtk_container_child_set): + begin the parameter elipsis (...) after the first argument name. this + change is source compatible, since it was always required, even as NULL. + (gtk_args_collect): + (gtk_object_args_collect): + (gtk_container_child_args_collect): + changed prototypes to pass first_arg_name, also, pass va_list variable + by value (portability concerns). callers changed. + + * gtk/gtkargcollector.c: implemented gtk_arg_collect_value() as + a huge macro GTK_ARG_COLLECT_VALUE() <shrug>. this is needed because we + can't pass va_list variables by reference for portability reasons. + +Fri Aug 21 22:40:00 Raph Levien <raph@gtk.org> + + * gdk/gdkrgb.c: added calls to gdk_rgb_init in the get_cmap and + get_visual calls, so that it gets implicitly initialized. + +Fri Aug 21 13:06:04 1998 Stuart Parmenter <pavlov@gimp.org> + * gtk/gtkfeatures.h.in: added GTK_HAVE_FEATURES_1_1_2 for changes + such as GtkCTree function name changes Mon Aug 10 23:03:55 1998 The Rasterman <raster@redhat.com> * Fixed minor problem in gtkhandlebox.c with drawing, and some diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 9554dc3a22..7b94f6b1c8 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,8 @@ +Mon Aug 24 23:37:26 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/gtktext.c: Fixed some remaining background drawing, + merges from main branch, cleanups. + Mon Aug 24 10:55:51 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_draw_tab): Don't @@ -74,6 +79,104 @@ Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> Thu Aug 20 18:27:29 EDT 1998 The Rasterman <raster@redhat.com> * made gtkrc scanner append dir that gtkrc is read from to pixmap path. + +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 + + * gtk/gtkclist.c + * gtk/gtkmain.c: #if 0'd out some unused code + + * gtk/gtkobject.c: check for NULL object hash table in gtk_object_debug + +Mon Aug 24 02:36:53 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkarg.h: + * gtk/gtkarg.c: + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: + * gtk/gtkobject.h: + * gtk/gtkobject.c: + * gtk/gtkcontainer.h: + * gtk/gtkcontainer.c: + (gtk_object_new): + (gtk_object_set): + (gtk_widget_new): + (gtk_widget_set): + (gtk_container_add_with_args): + (gtk_container_child_set): + begin the parameter elipsis (...) after the first argument name. this + change is source compatible, since it was always required, even as NULL. + (gtk_args_collect): + (gtk_object_args_collect): + (gtk_container_child_args_collect): + changed prototypes to pass first_arg_name, also, pass va_list variable + by value (portability concerns). callers changed. + + * gtk/gtkargcollector.c: implemented gtk_arg_collect_value() as + a huge macro GTK_ARG_COLLECT_VALUE() <shrug>. this is needed because we + can't pass va_list variables by reference for portability reasons. + +Fri Aug 21 22:40:00 Raph Levien <raph@gtk.org> + + * gdk/gdkrgb.c: added calls to gdk_rgb_init in the get_cmap and + get_visual calls, so that it gets implicitly initialized. + +Fri Aug 21 13:06:04 1998 Stuart Parmenter <pavlov@gimp.org> + * gtk/gtkfeatures.h.in: added GTK_HAVE_FEATURES_1_1_2 for changes + such as GtkCTree function name changes Mon Aug 10 23:03:55 1998 The Rasterman <raster@redhat.com> * Fixed minor problem in gtkhandlebox.c with drawing, and some @@ -270,9 +270,12 @@ Text/Edit widget: - "changed" emitted when doing deletes on empty Text widget. + - Delete IC in editable->unrealize, not editable->finalize? + Themes ====== - When a scale gets shown/hidden only queue a redraw on the non-window portion, not the whole area. + @@ -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; @@ -3760,34 +3760,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 */ } @@ -3813,39 +3813,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; } } } @@ -4150,13 +4150,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 @@ -4181,7 +4181,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 @@ -323,6 +323,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 */ @@ -471,6 +476,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); @@ -498,8 +519,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 @@ -741,22 +764,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 */ @@ -876,6 +904,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 b17e26a1c5..fa810473e6 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 9fdef0ffcc..dfaf4822c9 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 6e9889c3e4..9ed85a4663 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/gdkrgb.c b/gdk/gdkrgb.c index 0e6c0a2eaf..a4f11de5d9 100644 --- a/gdk/gdkrgb.c +++ b/gdk/gdkrgb.c @@ -2123,7 +2123,6 @@ gdk_rgb_convert_4 (GdkImage *image, gint r, g, b; guchar *dmp; gint dith; - guchar pix0, pix1; bptr = buf; bpl = image->bpl; @@ -2821,11 +2820,13 @@ gdk_rgb_ditherable (void) GdkColormap * gdk_rgb_get_cmap (void) { + gdk_rgb_init (); return image_info->cmap; } GdkVisual * gdk_rgb_get_visual (void) { + gdk_rgb_init (); return image_info->visual; } diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index 5ec44c2d4a..67f9fb3533 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 1e4fe2714e..275ca3aa98 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -705,8 +705,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 @@ -2568,3 +2570,13 @@ gdk_window_combine_child_shapes (GdkWindow *window) gdk_propagate_combine_shapes (private->xdisplay, private->xwindow); #endif } + +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 2f43fd85fe..fbe655d2ea 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 b17e26a1c5..fa810473e6 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 9273048c10..da5094634e 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; @@ -3760,34 +3760,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 */ } @@ -3813,39 +3813,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; } } } @@ -4150,13 +4150,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 @@ -4181,7 +4181,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 9fdef0ffcc..dfaf4822c9 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 1e4fe2714e..275ca3aa98 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -705,8 +705,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 @@ -2568,3 +2570,13 @@ gdk_window_combine_child_shapes (GdkWindow *window) gdk_propagate_combine_shapes (private->xdisplay, private->xwindow); #endif } + +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 2f43fd85fe..fbe655d2ea 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 024fcf5d0f..3183345398 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/gtkarg.c b/gtk/gtkarg.c index c61bc95d07..60ebdc1e4c 100644 --- a/gtk/gtkarg.c +++ b/gtk/gtkarg.c @@ -233,12 +233,12 @@ gtk_args_collect (GtkType object_type, GHashTable *arg_info_hash_table, GSList **arg_list_p, GSList **info_list_p, - gpointer var_args_p) + const gchar *first_arg_name, + va_list var_args) { GSList *arg_list; GSList *info_list; - gchar *arg_name; - va_list *var_args = var_args_p; + const gchar *arg_name; g_return_val_if_fail (arg_list_p != NULL, NULL); *arg_list_p = NULL; @@ -248,7 +248,7 @@ gtk_args_collect (GtkType object_type, arg_list = NULL; info_list = NULL; - arg_name = va_arg (*var_args, gchar*); + arg_name = first_arg_name; while (arg_name) { GtkArgInfo *info = NULL; @@ -262,8 +262,8 @@ gtk_args_collect (GtkType object_type, info_list = g_slist_prepend (info_list, info); arg = gtk_arg_new (info->type); - arg->name = arg_name; - error = gtk_arg_collect_value (GTK_FUNDAMENTAL_TYPE (arg->type), arg, var_args); + arg->name = (gchar*) arg_name; + GTK_ARG_COLLECT_VALUE (GTK_FUNDAMENTAL_TYPE (arg->type), arg, var_args, error); arg_list = g_slist_prepend (arg_list, arg); } if (error) @@ -273,7 +273,7 @@ gtk_args_collect (GtkType object_type, return error; } - arg_name = va_arg (*var_args, gchar*); + arg_name = va_arg (var_args, gchar*); } *arg_list_p = g_slist_reverse (arg_list); diff --git a/gtk/gtkarg.h b/gtk/gtkarg.h index 7d4e6f777a..5217c0a60a 100644 --- a/gtk/gtkarg.h +++ b/gtk/gtkarg.h @@ -60,7 +60,8 @@ gchar* gtk_args_collect (GtkType object_type, GHashTable *arg_info_hash_table, GSList **arg_list_p, GSList **info_list_p, - gpointer var_args_p); + const gchar *first_arg_name, + va_list var_args); void gtk_args_collect_cleanup (GSList *arg_list, GSList *info_list); gchar* gtk_arg_get_info (GtkType object_type, diff --git a/gtk/gtkargcollector.c b/gtk/gtkargcollector.c index 3067738062..32a0ec7847 100644 --- a/gtk/gtkargcollector.c +++ b/gtk/gtkargcollector.c @@ -17,144 +17,149 @@ * Boston, MA 02111-1307, USA. */ -/* collect a single argument value from a va_list +/* collect a single argument value from a va_list. + * this is implemented as a huge macro <shrug>, because we can't + * pass va_list variables by reference on some systems. + * the former prototype was: + * static inline gchar* + * gtk_arg_collect_value (GtkType fundamental_type, + * GtkArg *arg, + * va_list var_args); */ -static inline gchar* -gtk_arg_collect_value (GtkType fundamental_type, - GtkArg *arg, - va_list *var_args) -{ - gchar *error_msg; - - error_msg = NULL; - switch (fundamental_type) - { - case GTK_TYPE_INVALID: - error_msg = g_strdup ("invalid untyped argument"); - break; - - case GTK_TYPE_NONE: - /* we just ignore this type, since it arithmetically just requires - * us to not move the var_args pointer any further. callers need to - * check for the validity of GTK_TYPE_NONE themselves. - * - * error_msg = g_strdup ("invalid argument type `void'"); - */ - break; - - /* everything smaller than an int is guarranteed to be - * passed as an int - */ - case GTK_TYPE_CHAR: - GTK_VALUE_CHAR (*arg) = va_arg (*var_args, gint); - break; - case GTK_TYPE_UCHAR: - GTK_VALUE_UCHAR (*arg) = va_arg (*var_args, guint); - break; - case GTK_TYPE_BOOL: - GTK_VALUE_BOOL (*arg) = va_arg (*var_args, gint); - break; - case GTK_TYPE_INT: - GTK_VALUE_INT (*arg) = va_arg (*var_args, gint); - break; - case GTK_TYPE_UINT: - GTK_VALUE_UINT (*arg) = va_arg (*var_args, guint); - break; - case GTK_TYPE_ENUM: - GTK_VALUE_ENUM (*arg) = va_arg (*var_args, gint); - break; - case GTK_TYPE_FLAGS: - GTK_VALUE_FLAGS (*arg) = va_arg (*var_args, guint); - break; - - /* we collect longs as glongs since they differ in size with - * integers on some platforms - */ - case GTK_TYPE_LONG: - GTK_VALUE_LONG (*arg) = va_arg (*var_args, glong); - break; - case GTK_TYPE_ULONG: - GTK_VALUE_ULONG (*arg) = va_arg (*var_args, gulong); - break; - - /* floats are always passed as doubles - */ - case GTK_TYPE_FLOAT: - /* GTK_VALUE_FLOAT (*arg) = va_arg (*var_args, gfloat); */ - GTK_VALUE_FLOAT (*arg) = va_arg (*var_args, gdouble); - break; - case GTK_TYPE_DOUBLE: - GTK_VALUE_DOUBLE (*arg) = va_arg (*var_args, gdouble); - break; - - /* collect pointer values - */ - case GTK_TYPE_STRING: - GTK_VALUE_STRING (*arg) = va_arg (*var_args, gchar*); - break; - case GTK_TYPE_POINTER: - GTK_VALUE_POINTER (*arg) = va_arg (*var_args, gpointer); - break; - case GTK_TYPE_BOXED: - GTK_VALUE_BOXED (*arg) = va_arg (*var_args, gpointer); - break; - - /* structured types - */ - case GTK_TYPE_SIGNAL: - GTK_VALUE_SIGNAL (*arg).f = va_arg (*var_args, GtkSignalFunc); - GTK_VALUE_SIGNAL (*arg).d = va_arg (*var_args, gpointer); - break; - case GTK_TYPE_ARGS: - GTK_VALUE_ARGS (*arg).n_args = va_arg (*var_args, gint); - GTK_VALUE_ARGS (*arg).args = va_arg (*var_args, GtkArg*); - break; - case GTK_TYPE_FOREIGN: - GTK_VALUE_FOREIGN (*arg).data = va_arg (*var_args, gpointer); - GTK_VALUE_FOREIGN (*arg).notify = va_arg (*var_args, GtkDestroyNotify); - break; - case GTK_TYPE_CALLBACK: - GTK_VALUE_CALLBACK (*arg).marshal = va_arg (*var_args, GtkCallbackMarshal); - GTK_VALUE_CALLBACK (*arg).data = va_arg (*var_args, gpointer); - GTK_VALUE_CALLBACK (*arg).notify = va_arg (*var_args, GtkDestroyNotify); - break; - case GTK_TYPE_C_CALLBACK: - GTK_VALUE_C_CALLBACK (*arg).func = va_arg (*var_args, GtkFunction); - GTK_VALUE_C_CALLBACK (*arg).func_data = va_arg (*var_args, gpointer); - break; - - /* we do some extra sanity checking when collecting objects, - * i.e. if the object pointer is not NULL, we check whether we - * actually got an object pointer within the desired class branch. - */ - case GTK_TYPE_OBJECT: - GTK_VALUE_OBJECT (*arg) = va_arg (*var_args, GtkObject*); - if (GTK_VALUE_OBJECT (*arg) != NULL) - { - register GtkObject *object = GTK_VALUE_OBJECT (*arg); - - if (object->klass == NULL) - error_msg = g_strconcat ("invalid unclassed object pointer for argument type `", - gtk_type_name (arg->type), - "'", - NULL); - else if (!gtk_type_is_a (GTK_OBJECT_TYPE (object), arg->type)) - error_msg = g_strconcat ("invalid object `", - gtk_type_name (GTK_OBJECT_TYPE (object)), - "' for argument type `", - gtk_type_name (arg->type), - "'", - NULL); - } - break; - - default: - error_msg = g_strconcat ("unsupported argument type `", - gtk_type_name (arg->type), - "'", - NULL); - break; - } - - return error_msg; -} +#define GTK_ARG_COLLECT_VALUE(_ft, arg, var_args, _error) \ +G_STMT_START { \ + GtkType fundamental_type = _ft; \ + gchar *error_msg; \ + \ + error_msg = NULL; \ + switch (fundamental_type) \ + { \ + case GTK_TYPE_INVALID: \ + error_msg = g_strdup ("invalid untyped argument"); \ + break; \ + \ + case GTK_TYPE_NONE: \ + /* we just ignore this type, since it arithmetically just requires \ + * us to not move the var_args pointer any further. callers need to \ + * check for the validity of GTK_TYPE_NONE themselves. \ + * \ + * error_msg = g_strdup ("invalid argument type `void'"); \ + */ \ + break; \ + \ + /* everything smaller than an int is guarranteed to be \ + * passed as an int \ + */ \ + case GTK_TYPE_CHAR: \ + GTK_VALUE_CHAR (*arg) = va_arg (var_args, gint); \ + break; \ + case GTK_TYPE_UCHAR: \ + GTK_VALUE_UCHAR (*arg) = va_arg (var_args, guint); \ + break; \ + case GTK_TYPE_BOOL: \ + GTK_VALUE_BOOL (*arg) = va_arg (var_args, gint); \ + break; \ + case GTK_TYPE_INT: \ + GTK_VALUE_INT (*arg) = va_arg (var_args, gint); \ + break; \ + case GTK_TYPE_UINT: \ + GTK_VALUE_UINT (*arg) = va_arg (var_args, guint); \ + break; \ + case GTK_TYPE_ENUM: \ + GTK_VALUE_ENUM (*arg) = va_arg (var_args, gint); \ + break; \ + case GTK_TYPE_FLAGS: \ + GTK_VALUE_FLAGS (*arg) = va_arg (var_args, guint); \ + break; \ + \ + /* we collect longs as glongs since they differ in size with \ + * integers on some platforms \ + */ \ + case GTK_TYPE_LONG: \ + GTK_VALUE_LONG (*arg) = va_arg (var_args, glong); \ + break; \ + case GTK_TYPE_ULONG: \ + GTK_VALUE_ULONG (*arg) = va_arg (var_args, gulong); \ + break; \ + \ + /* floats are always passed as doubles \ + */ \ + case GTK_TYPE_FLOAT: \ + /* GTK_VALUE_FLOAT (*arg) = va_arg (var_args, gfloat); */ \ + GTK_VALUE_FLOAT (*arg) = va_arg (var_args, gdouble); \ + break; \ + case GTK_TYPE_DOUBLE: \ + GTK_VALUE_DOUBLE (*arg) = va_arg (var_args, gdouble); \ + break; \ + \ + /* collect pointer values \ + */ \ + case GTK_TYPE_STRING: \ + GTK_VALUE_STRING (*arg) = va_arg (var_args, gchar*); \ + break; \ + case GTK_TYPE_POINTER: \ + GTK_VALUE_POINTER (*arg) = va_arg (var_args, gpointer); \ + break; \ + case GTK_TYPE_BOXED: \ + GTK_VALUE_BOXED (*arg) = va_arg (var_args, gpointer); \ + break; \ + \ + /* structured types \ + */ \ + case GTK_TYPE_SIGNAL: \ + GTK_VALUE_SIGNAL (*arg).f = va_arg (var_args, GtkSignalFunc); \ + GTK_VALUE_SIGNAL (*arg).d = va_arg (var_args, gpointer); \ + break; \ + case GTK_TYPE_ARGS: \ + GTK_VALUE_ARGS (*arg).n_args = va_arg (var_args, gint); \ + GTK_VALUE_ARGS (*arg).args = va_arg (var_args, GtkArg*); \ + break; \ + case GTK_TYPE_FOREIGN: \ + GTK_VALUE_FOREIGN (*arg).data = va_arg (var_args, gpointer); \ + GTK_VALUE_FOREIGN (*arg).notify = va_arg (var_args, GtkDestroyNotify); \ + break; \ + case GTK_TYPE_CALLBACK: \ + GTK_VALUE_CALLBACK (*arg).marshal = va_arg (var_args, GtkCallbackMarshal); \ + GTK_VALUE_CALLBACK (*arg).data = va_arg (var_args, gpointer); \ + GTK_VALUE_CALLBACK (*arg).notify = va_arg (var_args, GtkDestroyNotify); \ + break; \ + case GTK_TYPE_C_CALLBACK: \ + GTK_VALUE_C_CALLBACK (*arg).func = va_arg (var_args, GtkFunction); \ + GTK_VALUE_C_CALLBACK (*arg).func_data = va_arg (var_args, gpointer); \ + break; \ + \ + /* we do some extra sanity checking when collecting objects, \ + * i.e. if the object pointer is not NULL, we check whether we \ + * actually got an object pointer within the desired class branch. \ + */ \ + case GTK_TYPE_OBJECT: \ + GTK_VALUE_OBJECT (*arg) = va_arg (var_args, GtkObject*); \ + if (GTK_VALUE_OBJECT (*arg) != NULL) \ + { \ + register GtkObject *object = GTK_VALUE_OBJECT (*arg); \ + \ + if (object->klass == NULL) \ + error_msg = g_strconcat ("invalid unclassed object pointer for argument type `", \ + gtk_type_name (arg->type), \ + "'", \ + NULL); \ + else if (!gtk_type_is_a (GTK_OBJECT_TYPE (object), arg->type)) \ + error_msg = g_strconcat ("invalid object `", \ + gtk_type_name (GTK_OBJECT_TYPE (object)), \ + "' for argument type `", \ + gtk_type_name (arg->type), \ + "'", \ + NULL); \ + } \ + break; \ + \ + default: \ + error_msg = g_strconcat ("unsupported argument type `", \ + gtk_type_name (arg->type), \ + "'", \ + NULL); \ + break; \ + } \ + \ + _error = error_msg; /* return error_msg; */ \ +} G_STMT_END diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c index 172890dbb4..371eae1ece 100644 --- a/gtk/gtkclist.c +++ b/gtk/gtkclist.c @@ -2087,6 +2087,7 @@ gtk_clist_row_is_visible (GtkCList * clist, return GTK_VISIBILITY_FULL; } +#if 0 static GtkAdjustment* gtk_clist_get_vadjustment (GtkCList * clist) { @@ -2104,6 +2105,7 @@ gtk_clist_get_hadjustment (GtkCList * clist) return gtk_range_get_adjustment (GTK_RANGE (clist->hscrollbar)); } +#endif void gtk_clist_set_policy (GtkCList * clist, diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 8f3696f32e..2bcc30b83f 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -250,6 +250,7 @@ gtk_container_child_type (GtkContainer *container) void gtk_container_add_with_args (GtkContainer *container, GtkWidget *widget, + const gchar *first_arg_name, ...) { g_return_if_fail (container != NULL); @@ -270,11 +271,12 @@ gtk_container_add_with_args (GtkContainer *container, GSList *info_list = NULL; gchar *error; - va_start (var_args, widget); + va_start (var_args, first_arg_name); error = gtk_container_child_args_collect (GTK_OBJECT_TYPE (container), &arg_list, &info_list, - &var_args); + first_arg_name, + var_args); va_end (var_args); if (error) @@ -375,6 +377,7 @@ gtk_container_child_getv (GtkContainer *container, void gtk_container_child_set (GtkContainer *container, GtkWidget *child, + const gchar *first_arg_name, ...) { va_list var_args; @@ -388,11 +391,12 @@ gtk_container_child_set (GtkContainer *container, g_return_if_fail (GTK_IS_WIDGET (child)); g_return_if_fail (child->parent != NULL); - va_start (var_args, child); + va_start (var_args, first_arg_name); error = gtk_container_child_args_collect (GTK_OBJECT_TYPE (container), &arg_list, &info_list, - &var_args); + first_arg_name, + var_args); va_end (var_args); if (error) @@ -541,13 +545,15 @@ gchar* gtk_container_child_args_collect (GtkType object_type, GSList **arg_list_p, GSList **info_list_p, - gpointer var_args_p) + const gchar *first_arg_name, + va_list var_args) { return gtk_args_collect (object_type, container_child_arg_info_ht, arg_list_p, info_list_p, - var_args_p); + first_arg_name, + var_args); } gchar* diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h index 8fe0babcef..aecd268f48 100644 --- a/gtk/gtkcontainer.h +++ b/gtk/gtkcontainer.h @@ -174,6 +174,7 @@ void gtk_container_child_setv (GtkContainer *container, */ void gtk_container_add_with_args (GtkContainer *container, GtkWidget *widget, + const gchar *first_arg_name, ...); void gtk_container_addv (GtkContainer *container, GtkWidget *widget, @@ -181,6 +182,7 @@ void gtk_container_addv (GtkContainer *container, GtkArg *args); void gtk_container_child_set (GtkContainer *container, GtkWidget *child, + const gchar *first_arg_name, ...); @@ -199,7 +201,8 @@ void gtk_container_arg_get (GtkContainer *container, gchar* gtk_container_child_args_collect (GtkType object_type, GSList **arg_list_p, GSList **info_list_p, - gpointer var_args_p); + const gchar *first_arg_name, + va_list args); gchar* gtk_container_child_arg_get_info (GtkType object_type, const gchar *arg_name, GtkArgInfo **info_p); diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 5fbe881a88..0e34a2b073 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -588,17 +588,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"); @@ -765,7 +765,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; @@ -1452,7 +1452,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/gtkitemfactory.c b/gtk/gtkitemfactory.c index 33d9f11db5..74054e8b22 100644 --- a/gtk/gtkitemfactory.c +++ b/gtk/gtkitemfactory.c @@ -1481,7 +1481,7 @@ gtk_item_factory_parse_statement (GScanner *scanner, parser_func = scanner->value.v_symbol; - /* check whether this is a GtkItemFactory symbol... + /* check whether this is a GtkItemFactory symbol. */ if (parser_func == gtk_item_factory_parse_menu_path) expected_token = parser_func (scanner, class); diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 2d67476563..28ecb3410f 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -116,10 +116,12 @@ static void gtk_handle_idle (void); static void gtk_handle_timer (void); static void gtk_propagate_event (GtkWidget *widget, GdkEvent *event); +#if 0 static void gtk_error (gchar *str); static void gtk_warning (gchar *str); static void gtk_message (gchar *str); static void gtk_print (gchar *str); +#endif static gint gtk_idle_remove_from_list (GList **list, guint tag, @@ -1788,6 +1790,7 @@ gtk_propagate_event (GtkWidget *widget, } +#if 0 static void gtk_error (gchar *str) { @@ -1898,4 +1901,4 @@ gtk_print (gchar *str) if (!GTK_WIDGET_VISIBLE (window)) gtk_widget_show (window); } - +#endif diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h index 8600627dd0..856eb27887 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/gtkobject.c b/gtk/gtkobject.c index f94b485d46..d65aeea23a 100644 --- a/gtk/gtkobject.c +++ b/gtk/gtkobject.c @@ -105,7 +105,8 @@ gtk_object_debug_foreach (gpointer key, gpointer value, gpointer user_data) static void gtk_object_debug (void) { - g_hash_table_foreach (living_objs_ht, gtk_object_debug_foreach, NULL); + if (living_objs_ht) + g_hash_table_foreach (living_objs_ht, gtk_object_debug_foreach, NULL); g_message ("living objects count = %d", obj_count); } @@ -621,7 +622,8 @@ gtk_object_notify_weaks (GtkObject *object) ****************************************************/ GtkObject* -gtk_object_new (GtkType object_type, +gtk_object_new (GtkType object_type, + const gchar *first_arg_name, ...) { GtkObject *object; @@ -634,11 +636,12 @@ gtk_object_new (GtkType object_type, object = gtk_type_new (object_type); - va_start (var_args, object_type); + va_start (var_args, first_arg_name); error = gtk_object_args_collect (GTK_OBJECT_TYPE (object), &arg_list, &info_list, - &var_args); + first_arg_name, + var_args); va_end (var_args); if (error) @@ -719,6 +722,7 @@ gtk_object_getv (GtkObject *object, void gtk_object_set (GtkObject *object, + const gchar *first_arg_name, ...) { va_list var_args; @@ -729,11 +733,12 @@ gtk_object_set (GtkObject *object, g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_OBJECT (object)); - va_start (var_args, object); + va_start (var_args, first_arg_name); error = gtk_object_args_collect (GTK_OBJECT_TYPE (object), &arg_list, &info_list, - &var_args); + first_arg_name, + var_args); va_end (var_args); if (error) @@ -878,13 +883,15 @@ gchar* gtk_object_args_collect (GtkType object_type, GSList **arg_list_p, GSList **info_list_p, - gpointer var_args_p) + const gchar *first_arg_name, + va_list var_args) { return gtk_args_collect (object_type, object_arg_info_ht, arg_list_p, info_list_p, - var_args_p); + first_arg_name, + var_args); } gchar* diff --git a/gtk/gtkobject.h b/gtk/gtkobject.h index fd38e30d75..3fe07f24db 100644 --- a/gtk/gtkobject.h +++ b/gtk/gtkobject.h @@ -242,6 +242,7 @@ guint gtk_object_class_user_signal_newv (GtkObjectClass *klass, guint nparams, GtkType *params); GtkObject* gtk_object_new (GtkType type, + const gchar *first_arg_name, ...); GtkObject* gtk_object_newv (GtkType object_type, guint n_args, @@ -272,6 +273,7 @@ void gtk_object_getv (GtkObject *object, * more than one c-function argument. */ void gtk_object_set (GtkObject *object, + const gchar *first_arg_name, ...); void gtk_object_setv (GtkObject *object, guint n_args, @@ -372,7 +374,8 @@ void gtk_object_arg_get (GtkObject *object, gchar* gtk_object_args_collect (GtkType object_type, GSList **arg_list_p, GSList **info_list_p, - gpointer var_args_p); + const gchar *first_arg_name, + va_list var_args); gchar* gtk_object_arg_get_info (GtkType object_type, const gchar *arg_name, GtkArgInfo **info_p); diff --git a/gtk/gtksignal.c b/gtk/gtksignal.c index 1830c741bc..b3488f8f6b 100644 --- a/gtk/gtksignal.c +++ b/gtk/gtksignal.c @@ -1780,9 +1780,10 @@ gtk_signal_collect_params (GtkArg *params, params->type = *(param_types++); params->name = NULL; - error = gtk_arg_collect_value (GTK_FUNDAMENTAL_TYPE (params->type), - params, - &var_args); + GTK_ARG_COLLECT_VALUE (GTK_FUNDAMENTAL_TYPE (params->type), + params, + var_args, + error); if (error) { failed = TRUE; diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 43c9fbe0f0..b69c80cc45 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 = >K_WIDGET (text)->style->text[GTK_STATE_NORMAL]; - if (back == NULL) - back = >K_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); } @@ -1392,7 +1430,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; @@ -1696,14 +1734,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; } @@ -2642,31 +2686,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); @@ -2676,16 +2727,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; @@ -2698,16 +2848,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 @@ -2802,10 +2981,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 { @@ -2819,9 +3021,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); } } @@ -2847,7 +3049,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; @@ -2864,14 +3066,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); @@ -2935,8 +3142,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); @@ -2968,8 +3178,11 @@ delete_text_property (GtkText* text, guint nchars) MARK_NEXT_LIST_PTR(&text->point) = NULL; text->point.offset = MARK_CURRENT_PROPERTY(&text->point)->length - 1; + + if (GTK_WIDGET_REALIZED (text)) + unrealize_property (text, prop); - g_mem_chunk_free (text_property_chunk, prop); + destroy_text_property (prop); g_list_free_1 (tmp); } } @@ -2977,17 +3190,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); @@ -3219,8 +3427,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[' ']; @@ -3293,22 +3501,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 @@ -4212,8 +4420,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 @@ -4246,7 +4454,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) @@ -4313,8 +4521,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; } @@ -4342,40 +4550,49 @@ expand_scratch_buffer (GtkText* text, guint len) } } -/* Returns a GC to draw a background for the text at a mark, - * or NULL, if the mark's background is NULL - * - * Side effect: modifies text->gc +/* Side effect: modifies text->gc */ -static GdkGC * -mark_bg_gc (GtkText* text, const GtkPropertyMark *mark, GtkStateType *state) + +static void +draw_bg_rect (GtkText* text, GtkPropertyMark *mark, + gint x, gint y, gint width, gint height, + gboolean already_cleared) { GtkEditable *editable = GTK_EDITABLE(text); - *state = GTK_STATE_NORMAL; - if ((mark->index >= MIN(editable->selection_start_pos, editable->selection_end_pos) && mark->index < MAX(editable->selection_start_pos, editable->selection_end_pos))) { - if (editable->has_selection) - { - *state = GTK_STATE_SELECTED; - return GTK_WIDGET(text)->style->bg_gc[GTK_STATE_SELECTED]; - } - else - { - *state = GTK_STATE_ACTIVE; - return GTK_WIDGET(text)->style->bg_gc[GTK_STATE_ACTIVE]; - } + gtk_paint_flat_box(GTK_WIDGET(text)->style, text->text_area, + editable->has_selection ? + GTK_STATE_SELECTED : GTK_STATE_ACTIVE, + GTK_SHADOW_NONE, + NULL, GTK_WIDGET(text), "text", + x, y, width, height); } - else if (!gdk_color_equal(MARK_CURRENT_BACK (mark), + else if (!gdk_color_equal(MARK_CURRENT_BACK (text, mark), >K_WIDGET(text)->style->base[GTK_STATE_NORMAL])) { - gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (mark)); - return text->gc; + gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (text, mark)); + + gdk_draw_rectangle (text->text_area, + text->gc, + TRUE, x, y, width, height); + } + else if (GTK_WIDGET (text)->style->bg_pixmap[GTK_STATE_NORMAL]) + { + GdkRectangle rect; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + clear_area (text, &rect); } - return NULL; + else if (!already_cleared) + gdk_window_clear_area (text->text_area, x, y, width, height); } static void @@ -4388,8 +4605,7 @@ draw_line (GtkText* text, gint len = 0; guint running_offset = lp->tab_cont.pixel_offset; guchar* buffer; - GdkGC *fg_gc, *bg_gc; - GtkStateType bg_state; + GdkGC *fg_gc; GtkEditable *editable = GTK_EDITABLE(text); @@ -4425,36 +4641,8 @@ draw_line (GtkText* text, if (running_offset > 0) { - bg_gc = mark_bg_gc (text, &mark, &bg_state); - - if (bg_gc) - { - if (bg_state != GTK_STATE_NORMAL) - gtk_paint_flat_box(GTK_WIDGET(text)->style, text->text_area, - bg_state, GTK_SHADOW_NONE, - NULL, GTK_WIDGET(text), "text", - 0, pixel_start_height, - running_offset, LINE_HEIGHT (*lp)); - else - gdk_draw_rectangle (text->text_area, - bg_gc, - TRUE, - 0, - pixel_start_height, - running_offset, - LINE_HEIGHT (*lp)); - } - else if (GTK_WIDGET (text)->style->bg_pixmap[GTK_STATE_NORMAL]) - { - GdkRectangle rect; - - rect.x = 0; - rect.y = pixel_start_height; - rect.width = running_offset; - rect.height = LINE_HEIGHT (*lp); - - clear_area (text, &rect); - } + draw_bg_rect (text, &mark, 0, pixel_start_height, running_offset, + LINE_HEIGHT (*lp), TRUE); } for (; chars > 0; chars -= len, buffer += len, len = 0) @@ -4474,8 +4662,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); @@ -4486,37 +4674,8 @@ draw_line (GtkText* text, else pixel_width = gdk_text_width (font, (gchar*) buffer, len); - bg_gc = mark_bg_gc (text, &mark, &bg_state); - if (bg_gc) - { - if (bg_state != GTK_STATE_NORMAL) - { - gtk_paint_flat_box(GTK_WIDGET(text)->style, text->text_area, - bg_state, GTK_SHADOW_NONE, - NULL, GTK_WIDGET(text), "text", - running_offset, pixel_start_height, - pixel_width, LINE_HEIGHT (*lp)); - } - else - gdk_draw_rectangle (text->text_area, - bg_gc, - TRUE, - running_offset, - pixel_start_height, - pixel_width, - LINE_HEIGHT(*lp)); - } - else if (GTK_WIDGET (text)->style->bg_pixmap[GTK_STATE_NORMAL]) - { - GdkRectangle rect; - - rect.x = running_offset; - rect.y = pixel_start_height; - rect.width = pixel_width; - rect.height = LINE_HEIGHT (*lp); - - clear_area (text, &rect); - } + draw_bg_rect (text, &mark, running_offset, pixel_start_height, + pixel_width, LINE_HEIGHT (*lp), TRUE); if ((mark.index >= selection_start_pos) && (mark.index < selection_end_pos)) @@ -4528,11 +4687,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, @@ -4545,42 +4704,26 @@ draw_line (GtkText* text, } else { + gint pixels_remaining; + gint space_width; + gint spaces_avail; + len = 1; - bg_gc = mark_bg_gc (text, &mark, &bg_state); - if (bg_gc) - { - gint pixels_remaining; - gint space_width; - gint spaces_avail; - - 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[' ']; - - spaces_avail = pixels_remaining / space_width; - spaces_avail = MIN (spaces_avail, tab_mark.to_next_tab); - - if (bg_state != GTK_STATE_NORMAL) - gtk_paint_flat_box(GTK_WIDGET(text)->style, text->text_area, - bg_state, GTK_SHADOW_NONE, - NULL, GTK_WIDGET(text), "text", - running_offset, pixel_start_height, - spaces_avail * space_width, LINE_HEIGHT (*lp)); - else - gdk_draw_rectangle (text->text_area, - bg_gc, - TRUE, - running_offset, - pixel_start_height, - spaces_avail * space_width, - LINE_HEIGHT (*lp)); - } + gdk_window_get_size (text->text_area, &pixels_remaining, NULL); + pixels_remaining -= (LINE_WRAP_ROOM + running_offset); - running_offset += tab_mark.to_next_tab * - 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); + + draw_bg_rect (text, &mark, running_offset, pixel_start_height, + spaces_avail * space_width, LINE_HEIGHT (*lp), TRUE); + + running_offset += tab_mark.to_next_tab * + MARK_CURRENT_TEXT_FONT(text, &mark)->char_widths[' ']; + advance_tab_mark (text, &tab_mark, '\t'); } @@ -4640,7 +4783,7 @@ static void undraw_cursor (GtkText* text, gint absolute) { GtkEditable *editable = (GtkEditable *)text; - + TDEBUG (("in undraw_cursor\n")); if (absolute) @@ -4653,35 +4796,21 @@ 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]) - { - GdkRectangle rect; - - rect.x = text->cursor_pos_x; - rect.y = text->cursor_pos_y - text->cursor_char_offset - font->ascent; - rect.width = 1; - rect.height = font->ascent + 1; /* @@@ I add one here because draw_line is inclusive, right? */ - - clear_area (text, &rect); - } - 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, - text->cursor_pos_y - text->cursor_char_offset, text->cursor_pos_x, - text->cursor_pos_y - text->cursor_char_offset - font->ascent); - } + + font = MARK_CURRENT_FONT(text, &text->cursor_mark); + + draw_bg_rect (text, &text->cursor_mark, + text->cursor_pos_x, + text->cursor_pos_y - text->cursor_char_offset - font->ascent, + 1, font->ascent + 1, FALSE); if (text->cursor_char) { 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, @@ -4699,7 +4828,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; } @@ -4711,7 +4840,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; } @@ -4734,9 +4863,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, >K_WIDGET (text)->style->text[GTK_STATE_NORMAL]); gdk_draw_line (text->text_area, text->gc, text->cursor_pos_x, @@ -5101,8 +5230,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 1de2de945a..27f4689b7e 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 d75f7b6c01..d8afc47183 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 53d010f897..6bbef5a4b2 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 f348794a93..b13f05b46e 100644 --- a/gtk/gtktypebuiltins_ids.c +++ b/gtk/gtktypebuiltins_ids.c @@ -110,6 +110,8 @@ GTK_TYPE_ENUM, _gtk_fundamental_type_values }, { "GtkWidgetFlags", >K_TYPE_WIDGET_FLAGS, GTK_TYPE_FLAGS, _gtk_widget_flags_values }, + { "GdkColorInfoFlags", >K_TYPE_GDK_COLOR_INFO_FLAGS, + GTK_TYPE_FLAGS, _gdk_color_info_flags_values }, { "GdkDebugFlag", >K_TYPE_GDK_DEBUG_FLAG, GTK_TYPE_FLAGS, _gdk_debug_flag_values }, { "GdkRgbDither", >K_TYPE_GDK_RGB_DITHER, diff --git a/gtk/gtktypebuiltins_vars.c b/gtk/gtktypebuiltins_vars.c index 921dfeb271..91b31a50c0 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 ad37aa1084..530c7883dc 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -955,7 +955,8 @@ gtk_widget_init (GtkWidget *widget) *****************************************/ GtkWidget* -gtk_widget_new (guint widget_type, +gtk_widget_new (GtkType widget_type, + const gchar *first_arg_name, ...) { GtkObject *object; @@ -968,11 +969,12 @@ gtk_widget_new (guint widget_type, object = gtk_type_new (widget_type); - va_start (var_args, widget_type); + va_start (var_args, first_arg_name); error = gtk_object_args_collect (GTK_OBJECT_TYPE (object), &arg_list, &info_list, - &var_args); + first_arg_name, + var_args); va_end (var_args); if (error) @@ -1008,7 +1010,7 @@ gtk_widget_new (guint widget_type, *****************************************/ GtkWidget* -gtk_widget_newv (guint type, +gtk_widget_newv (GtkType type, guint nargs, GtkArg *args) { @@ -1060,7 +1062,8 @@ gtk_widget_getv (GtkWidget *widget, *****************************************/ void -gtk_widget_set (GtkWidget *widget, +gtk_widget_set (GtkWidget *widget, + const gchar *first_arg_name, ...) { GtkObject *object; @@ -1074,11 +1077,12 @@ gtk_widget_set (GtkWidget *widget, object = GTK_OBJECT (widget); - va_start (var_args, widget); + va_start (var_args, first_arg_name); error = gtk_object_args_collect (GTK_OBJECT_TYPE (object), &arg_list, &info_list, - &var_args); + first_arg_name, + var_args); va_end (var_args); if (error) @@ -3477,15 +3481,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 (); } /***************************************** @@ -3503,15 +3511,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/gtkwidget.h b/gtk/gtkwidget.h index 150a5ce08f..a7e73470f7 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -362,9 +362,10 @@ struct _GtkWidgetShapeInfo GtkType gtk_widget_get_type (void); -GtkWidget* gtk_widget_new (guint type, +GtkWidget* gtk_widget_new (GtkType type, + const gchar *first_arg_name, ...); -GtkWidget* gtk_widget_newv (guint type, +GtkWidget* gtk_widget_newv (GtkType type, guint nargs, GtkArg *args); void gtk_widget_ref (GtkWidget *widget); @@ -378,6 +379,7 @@ void gtk_widget_getv (GtkWidget *widget, guint nargs, GtkArg *args); void gtk_widget_set (GtkWidget *widget, + const gchar *first_arg_name, ...); void gtk_widget_setv (GtkWidget *widget, guint nargs, diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 22cb8990cf..f101c15a7a 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 531cd5bcee..13b5df99fb 100644 --- a/gtk/testgtkrc +++ b/gtk/testgtkrc @@ -10,7 +10,7 @@ # widget <widget_set> style <style_name> # widget_class <widget_class_set> style <style_name> -include "/usr/share/gtk/themes/win95/gtkrc" +include "/opt/themes/share/gtk/themes/metal/gtkrc" binding "test1" { diff --git a/gtk/testinput.c b/gtk/testinput.c index d2ea54cd25..ac8ff136a0 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 22cb8990cf..f101c15a7a 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 531cd5bcee..13b5df99fb 100644 --- a/tests/testgtkrc +++ b/tests/testgtkrc @@ -10,7 +10,7 @@ # widget <widget_set> style <style_name> # widget_class <widget_class_set> style <style_name> -include "/usr/share/gtk/themes/win95/gtkrc" +include "/opt/themes/share/gtk/themes/metal/gtkrc" binding "test1" { diff --git a/tests/testinput.c b/tests/testinput.c index d2ea54cd25..ac8ff136a0 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 */ |