Re: Virtualizing paint functions



Owen Taylor skrev:
Do you mean you want to *optionally* override it? That is, allow a
backend to override gdk_window_process_updates() but not process_all_updates()?

I didn't really want to have to modify the other backends in order to support this, so if you don't need to override it you shouldn't need to.
Probably the easy thing to do would be have a default implementation
_gdk_window_process_all_updates() that backends could chain to, but
I'm not quite sure how maintenance of the list of dirty windows
would work if the backend has overridden invalidate_region() and
process_updates()

I guess one option is to keep a list of windows around and traverse it in process_all_updates. Since we know (at least this is the case for OS X) that the windows are invalidated when the window hits the main loop, we could schedule an idle and just free the list in the idle. I think that should be "Good Enough"...
+      (* GDK_PAINTABLE_GET_IFACE (private->impl)->begin_paint_region) ((GdkPaintable *)private->impl, region);

Nit - can simply write:

         GDK_PAINTABLE_GET_IFACE (private->impl)->begin_paint_region ((GdkPaintable *)private->impl, region);

And we normally do this - there is no reason for the extra dereference
clutter. Also, the style is generally to write the cast here as GDK_PAINTABLE() - the cast checks aren't compiled in in production code.

OK, new patch attached.

Regards,
Anders
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.7713
diff -u -p -r1.7713 ChangeLog
--- ChangeLog	10 Apr 2006 00:21:53 -0000	1.7713
+++ ChangeLog	10 Apr 2006 17:41:50 -0000
@@ -1,3 +1,15 @@
+2006-04-11  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-10 Vladimer Sichinava  <vlsichinava gmail com>
 
         * configure.in: Added "ka" (Georgian) to ALL_LINGUAS
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	10 Apr 2006 17:41:50 -0000
@@ -337,6 +337,32 @@ 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_PAINTABLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PAINTABLE, GdkPaintable))
+#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	10 Apr 2006 17:41:51 -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 (GDK_PAINTABLE (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 (GDK_PAINTABLE (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 (GDK_PAINTABLE (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 (GDK_PAINTABLE (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]