[gtk+] quartz: Emulate root window as 1x1 bitmap



commit 8970b174dc274104ff86733a48b0e05e33791431
Author: Kristian Rietveld <kris gtk org>
Date:   Mon Oct 4 11:43:16 2010 +0200

    quartz: Emulate root window as 1x1 bitmap
    
    We subclass GdkWindowImplQuartz into a new GdkRootWindowImplQuartz,
    and override the get_context method in order to do this cleanly.
    Also made release_context a virtual method, since the root window has
    to release its CGContextRef differently compared to normal windows.

 gdk/quartz/gdkdrawable-quartz.c |   34 ++++++--------
 gdk/quartz/gdkdrawable-quartz.h |    2 +
 gdk/quartz/gdkwindow-quartz.c   |   96 ++++++++++++++++++++++++++++++++++++++-
 gdk/quartz/gdkwindow-quartz.h   |   27 +++++++++++
 4 files changed, 138 insertions(+), 21 deletions(-)
---
diff --git a/gdk/quartz/gdkdrawable-quartz.c b/gdk/quartz/gdkdrawable-quartz.c
index 8c6a141..b199136 100644
--- a/gdk/quartz/gdkdrawable-quartz.c
+++ b/gdk/quartz/gdkdrawable-quartz.c
@@ -167,6 +167,20 @@ gdk_quartz_drawable_get_context (GdkDrawable *drawable,
   return GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->get_context (drawable, antialias);
 }
 
+void
+gdk_quartz_drawable_release_context (GdkDrawable  *drawable, 
+				     CGContextRef  cg_context)
+{
+  if (!GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->release_context)
+    {
+      g_warning ("%s doesn't implement GdkDrawableImplQuartzClass::release_context()",
+                 G_OBJECT_TYPE_NAME (drawable));
+      return;
+    }
+
+  GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->release_context (drawable, cg_context);
+}
+
 /* Help preventing "beam sync penalty" where CG makes all graphics code
  * block until the next vsync if we try to flush (including call display on
  * a view) too often. We do this by limiting the manual flushing done
@@ -213,26 +227,6 @@ _gdk_quartz_drawable_flush (GdkDrawable *drawable)
 }
 
 void
-gdk_quartz_drawable_release_context (GdkDrawable  *drawable, 
-				     CGContextRef  cg_context)
-{
-  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
-    {
-      GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
-
-      CGContextRestoreGState (cg_context);
-      CGContextSetAllowsAntialiasing (cg_context, TRUE);
-
-      /* See comment in gdk_quartz_drawable_get_context(). */
-      if (window_impl->in_paint_rect_count == 0)
-        {
-          _gdk_quartz_drawable_flush (drawable);
-          [window_impl->view unlockFocus];
-        }
-    }
-}
-
-void
 _gdk_quartz_drawable_finish (GdkDrawable *drawable)
 {
   GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
diff --git a/gdk/quartz/gdkdrawable-quartz.h b/gdk/quartz/gdkdrawable-quartz.h
index 52a9bef..24d17d8 100644
--- a/gdk/quartz/gdkdrawable-quartz.h
+++ b/gdk/quartz/gdkdrawable-quartz.h
@@ -56,6 +56,8 @@ struct _GdkDrawableImplQuartzClass
   /* vtable */
   CGContextRef (*get_context) (GdkDrawable* drawable,
 			       gboolean     antialias);
+  void         (*release_context) (GdkDrawable  *drawable,
+                                   CGContextRef  cg_context);
 };
 
 GType        gdk_drawable_impl_quartz_get_type   (void);
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index ffdc83b..6a58347 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -30,6 +30,7 @@
 #include "gdkinputprivate.h"
 
 static gpointer parent_class;
+static gpointer root_window_parent_class;
 
 static GSList   *update_nswindows;
 static gboolean  in_process_all_updates = FALSE;
@@ -142,6 +143,23 @@ gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
 }
 
 static void
+gdk_window_impl_quartz_release_context (GdkDrawable  *drawable,
+                                        CGContextRef  cg_context)
+{
+  GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
+
+  CGContextRestoreGState (cg_context);
+  CGContextSetAllowsAntialiasing (cg_context, TRUE);
+
+  /* See comment in gdk_quartz_drawable_get_context(). */
+  if (window_impl->in_paint_rect_count == 0)
+    {
+      _gdk_quartz_drawable_flush (drawable);
+      [window_impl->view unlockFocus];
+    }
+}
+
+static void
 check_grab_unmap (GdkWindow *window)
 {
   GList *list, *l;
@@ -214,6 +232,7 @@ gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
   object_class->finalize = gdk_window_impl_quartz_finalize;
 
   drawable_quartz_class->get_context = gdk_window_impl_quartz_get_context;
+  drawable_quartz_class->release_context = gdk_window_impl_quartz_release_context;
 }
 
 static void
@@ -1009,7 +1028,7 @@ _gdk_windowing_window_init (void)
   _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
 
   private = (GdkWindowObject *)_gdk_root;
-  private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
+  private->impl = g_object_new (_gdk_root_window_impl_quartz_get_type (), NULL);
   private->impl_window = private;
   private->visual = gdk_screen_get_system_visual (_gdk_screen);
 
@@ -2968,3 +2987,78 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->translate = _gdk_quartz_window_translate;
   iface->destroy = _gdk_quartz_window_destroy;
 }
+
+
+static CGContextRef
+gdk_root_window_impl_quartz_get_context (GdkDrawable *drawable,
+                                         gboolean     antialias)
+{
+  GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
+  CGColorSpaceRef colorspace;
+  CGContextRef cg_context;
+
+  if (GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
+    return NULL;
+
+  /* We do not have the notion of a root window on OS X.  We fake this
+   * by creating a 1x1 bitmap and return a context to that.
+   */
+  colorspace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
+  cg_context = CGBitmapContextCreate (NULL,
+                                      1, 1, 8, 4, colorspace,
+                                      kCGImageAlphaPremultipliedLast);
+  CGColorSpaceRelease (colorspace);
+
+  return cg_context;
+}
+
+static void
+gdk_root_window_impl_quartz_release_context (GdkDrawable  *drawable,
+                                             CGContextRef  cg_context)
+{
+  CGContextRelease (cg_context);
+}
+
+static void
+gdk_root_window_impl_quartz_class_init (GdkRootWindowImplQuartzClass *klass)
+{
+  GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
+
+  root_window_parent_class = g_type_class_peek_parent (klass);
+
+  drawable_quartz_class->get_context = gdk_root_window_impl_quartz_get_context;
+  drawable_quartz_class->release_context = gdk_root_window_impl_quartz_release_context;
+}
+
+static void
+gdk_root_window_impl_quartz_init (GdkRootWindowImplQuartz *impl)
+{
+}
+
+GType
+_gdk_root_window_impl_quartz_get_type (void)
+{
+  static GType object_type = 0;
+
+  if (!object_type)
+    {
+      const GTypeInfo object_info =
+        {
+          sizeof (GdkRootWindowImplQuartzClass),
+          (GBaseInitFunc) NULL,
+          (GBaseFinalizeFunc) NULL,
+          (GClassInitFunc) gdk_root_window_impl_quartz_class_init,
+          NULL,           /* class_finalize */
+          NULL,           /* class_data */
+          sizeof (GdkRootWindowImplQuartz),
+          0,              /* n_preallocs */
+          (GInstanceInitFunc) gdk_root_window_impl_quartz_init,
+        };
+
+      object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL_QUARTZ,
+                                            "GdkRootWindowQuartz",
+                                            &object_info, 0);
+    }
+
+  return object_type;
+}
diff --git a/gdk/quartz/gdkwindow-quartz.h b/gdk/quartz/gdkwindow-quartz.h
index c022b99..b591eeb 100644
--- a/gdk/quartz/gdkwindow-quartz.h
+++ b/gdk/quartz/gdkwindow-quartz.h
@@ -69,6 +69,33 @@ struct _GdkWindowImplQuartzClass
 
 GType _gdk_window_impl_quartz_get_type (void);
 
+
+/* Root window implementation for Quartz
+ */
+
+typedef struct _GdkRootWindowImplQuartz GdkRootWindowImplQuartz;
+typedef struct _GdkRootWindowImplQuartzClass GdkRootWindowImplQuartzClass;
+
+#define GDK_TYPE_ROOT_WINDOW_IMPL_QUARTZ              (_gdk_root_window_impl_quartz_get_type ())
+#define GDK_ROOT_WINDOW_IMPL_QUARTZ(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_ROOT_WINDOW_IMPL_QUARTZ, GdkRootWindowImplQuartz))
+#define GDK_ROOT_WINDOW_IMPL_QUARTZ_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_ROOT_WINDOW_IMPL_QUARTZ, GdkRootWindowImplQuartzClass))
+#define GDK_IS_ROOT_WINDOW_IMPL_QUARTZ(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_ROOT_WINDOW_IMPL_QUARTZ))
+#define GDK_IS_ROOT_WINDOW_IMPL_QUARTZ_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_ROOT_WINDOW_IMPL_QUARTZ))
+#define GDK_ROOT_WINDOW_IMPL_QUARTZ_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_ROOT_WINDOW_IMPL_QUARTZ, GdkRootWindowImplQuartzClass))
+
+struct _GdkRootWindowImplQuartz
+{
+  GdkWindowImplQuartz parent_instance;
+};
+ 
+struct _GdkRootWindowImplQuartzClass 
+{
+  GdkWindowImplQuartzClass parent_class;
+};
+
+GType _gdk_root_window_impl_quartz_get_type (void);
+
+
 G_END_DECLS
 
 #endif /* __GDK_WINDOW_QUARTZ_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]