Re: Virtualizing paint functions
- From: Anders Carlsson <andersca imendio com>
- To: Owen Taylor <otaylor redhat com>
- Cc: gtk-devel-list gnome org
- Subject: Re: Virtualizing paint functions
- Date: Mon, 10 Apr 2006 00:28:22 +0200
Owen Taylor skrev:
On Tue, 2006-04-04 at 00:12 +0200, Anders Carlsson wrote:
Owen Taylor skrev:
So:
if (GDK_IS_PAINTABLE(window)->impl))
{
GDK_PAINTABLE(impl)->invalidate_region(region);
return;
}
[ Current implementation ]
That *is* another way of doing backend customization from what we have
as well, but at least it's a way that fits into the general GObject
patterns.
Ah, that looks way better that the hack I had. When I was looking at
inheritance, I was concerned with not being able to provide a default
implementation.
I guess the remaining issue now is how to override
gdk_window_process_all_updates, without requiring copies of the function
in the different backend implementations.
Can you explain the issue here more?
Owen
The problem was that I wanted to override
gdk_window_process_all_updates, which is a void function. I have
everything pretty much working (aside from some issues with the Cairo
Quartz backend) since gdk_window_process_all_updates is normally called
from an idle func and Cocoa already calls the necessary repaint
functions in the mainloop anyway.
I've put together a patch which provides the necessary hooks for me in
the way you suggested. It's pretty non-obtrusive, and since it's an
implementation detail it can easily be changed later.
Regards,
Anders
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.7712
diff -u -p -r1.7712 ChangeLog
--- ChangeLog 7 Apr 2006 17:18:07 -0000 1.7712
+++ ChangeLog 9 Apr 2006 22:19:16 -0000
@@ -1,3 +1,15 @@
+2006-04-10 Anders Carlsson <andersca imendio com>
+
+ * gdk/gdkinternals.h:
+ * gdk/gdkwindow.c:
+ (_gdk_paintable_get_type):
+ (gdk_window_begin_paint_region):
+ (gdk_window_end_paint):
+ (gdk_window_process_updates):
+ (gdk_window_invalidate_maybe_recurse):
+ Add new GdkPaintable interface which implementation objects can
+ implement in order to override gdk painting functions.
+
2006-04-07 Hans Breuer <hans breuer org>
* gtk/makefile.msc.in tests/makefile.msc : updated
Index: gdk/gdkinternals.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkinternals.h,v
retrieving revision 1.40
diff -u -p -r1.40 gdkinternals.h
--- gdk/gdkinternals.h 3 Apr 2006 20:36:50 -0000 1.40
+++ gdk/gdkinternals.h 9 Apr 2006 22:19:16 -0000
@@ -337,6 +337,31 @@ void _gdk_windowing_window_destroy_forei
void _gdk_windowing_display_set_sm_client_id (GdkDisplay *display,
const gchar *sm_client_id);
+#define GDK_TYPE_PAINTABLE (_gdk_paintable_get_type ())
+#define GDK_IS_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PAINTABLE))
+#define GDK_PAINTABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GDK_TYPE_PAINTABLE, GdkPaintableIface))
+
+typedef struct _GdkPaintable GdkPaintable;
+typedef struct _GdkPaintableIface GdkPaintableIface;
+
+struct _GdkPaintableIface
+{
+ GTypeInterface g_iface;
+
+ void (* begin_paint_region) (GdkPaintable *paintable,
+ GdkRegion *region);
+ void (* end_paint) (GdkPaintable *paintable);
+
+ void (* invalidate_maybe_recurse) (GdkPaintable *paintable,
+ GdkRegion *region,
+ gboolean (*child_func) (GdkWindow *, gpointer),
+ gpointer user_data);
+ void (* process_updates) (GdkPaintable *paintable,
+ gboolean update_children);
+};
+
+GType _gdk_paintable_get_type (void) G_GNUC_CONST;
+
/* Implementation types */
GType _gdk_window_impl_get_type (void) G_GNUC_CONST;
GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST;
Index: gdk/gdkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.c,v
retrieving revision 1.182
diff -u -p -r1.182 gdkwindow.c
--- gdk/gdkwindow.c 4 Apr 2006 14:02:01 -0000 1.182
+++ gdk/gdkwindow.c 9 Apr 2006 22:19:16 -0000
@@ -192,6 +192,30 @@ static void gdk_window_clear_backing_rec
G_DEFINE_TYPE (GdkWindowObject, gdk_window_object, GDK_TYPE_DRAWABLE);
+GType
+_gdk_paintable_get_type (void)
+{
+ static GType paintable_type = 0;
+
+ if (!paintable_type)
+ {
+ static const GTypeInfo paintable_info =
+ {
+ sizeof (GdkPaintableIface), /* class_size */
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ };
+
+ paintable_type = g_type_register_static (G_TYPE_INTERFACE,
+ g_intern_static_string ("GdkPaintable"),
+ &paintable_info, 0);
+
+ g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
+ }
+
+ return paintable_type;
+}
+
static void
gdk_window_object_init (GdkWindowObject *window)
{
@@ -936,6 +960,13 @@ gdk_window_begin_paint_region (GdkWindow
if (GDK_WINDOW_DESTROYED (window))
return;
+ if (GDK_IS_PAINTABLE (private->impl) &&
+ GDK_PAINTABLE_GET_IFACE (private->impl)->begin_paint_region)
+ {
+ (* GDK_PAINTABLE_GET_IFACE (private->impl)->begin_paint_region) ((GdkPaintable *)private->impl, region);
+ return;
+ }
+
gdk_region_get_clipbox (region, &clip_box);
paint = g_new (GdkWindowPaint, 1);
@@ -997,6 +1028,13 @@ gdk_window_end_paint (GdkWindow *window)
if (GDK_WINDOW_DESTROYED (window))
return;
+ if (GDK_IS_PAINTABLE (private->impl) &&
+ GDK_PAINTABLE_GET_IFACE (private->impl)->end_paint)
+ {
+ (* GDK_PAINTABLE_GET_IFACE (private->impl)->end_paint) ((GdkPaintable *)private->impl);
+ return;
+ }
+
if (private->paint_stack == NULL)
{
g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
@@ -2350,6 +2388,13 @@ gdk_window_process_updates (GdkWindow *w
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
+ if (GDK_IS_PAINTABLE (private->impl) &&
+ GDK_PAINTABLE_GET_IFACE (private->impl)->process_updates)
+ {
+ (* GDK_PAINTABLE_GET_IFACE (private->impl)->process_updates) ((GdkPaintable *)private->impl, update_children);
+ return;
+ }
+
if (private->update_area && !private->update_freeze_count)
{
gdk_window_process_updates_internal (window);
@@ -2478,6 +2523,14 @@ gdk_window_invalidate_maybe_recurse (Gdk
if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
return;
+
+ if (GDK_IS_PAINTABLE (private->impl) &&
+ GDK_PAINTABLE_GET_IFACE (private->impl)->invalidate_maybe_recurse)
+ {
+ (* GDK_PAINTABLE_GET_IFACE (private->impl)->invalidate_maybe_recurse) ((GdkPaintable *)private->impl, region,
+ child_func, user_data);
+ return;
+ }
visible_region = gdk_drawable_get_visible_region (window);
gdk_region_intersect (visible_region, region);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]