[gtk+/client-side-windows] Add signals for offscreen window embedding



commit e1b52da0ab2edeba36925e1a2cc54d71771895cd
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Jun 4 20:15:29 2009 +0200

    Add signals for offscreen window embedding
    
    3 signals are for offscreen windows
    get-offscreen-parent: Get the parent window an offscreen is embedded in
    to-parent: Convert coordinates from offscreen to parent
    from-parent: Convert coordinates from parent to offscreen
    
    1 signal is for the window embedding offscreens:
    pick-offscreen-child: This picks what (if any) offscreen is at a specific position
    
    The last signal is only used if you call gdk_window_set_has_offscreen_children
    to tell gdk that the window has embedded offscreen children.
    Add get-pointer signal for offscreen window pointer getting
    
    Apps using offscreen windows can connect to get-pointer on offscreen
    windows in order to make gdk_window_get_pointer() return correct
    values.
    
    Add get-offscreen-parent signal
    
    Add signals for from-parent and to-parent coordinate mapping
    
    Add pick-offscreen-child signal
---
 gdk/Makefile.am          |    2 +-
 gdk/gdkinternals.h       |    1 +
 gdk/gdkmarshalers.list   |    4 ++
 gdk/gdkoffscreenwindow.c |   83 ++++++++++++++++++++-----------------------
 gdk/gdkwindow.c          |   88 ++++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkwindow.h          |    3 ++
 6 files changed, 136 insertions(+), 45 deletions(-)

diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index 1e96242..c3c8afa 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -152,10 +152,10 @@ gdk_built_sources =				\
 gdkincludedir = $(includedir)/gtk-2.0/gdk
 gdkinclude_HEADERS = $(gdk_public_h_sources) $(gdk_built_public_sources)
 
-# gdkmarshalers.c is not here because it is currently an empty file
 common_sources =                \
 	$(gdk_c_sources)	\
 	gdkenumtypes.c		\
+	gdkmarshalers.c		\
 	gdkmarshalers.h
 
 libgdk_directfb_2_0_la_SOURCES = $(common_sources) 
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index f8b5990..288f518 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -259,6 +259,7 @@ struct _GdkWindowObject
   guint effective_visibility : 2;
   guint visibility : 2; /* The visibility wrt the toplevel (i.e. based on clip_region) */
   guint native_visibility : 2; /* the native visibility of a impl windows */
+  guint has_offscreen_children : 1;
 
   GdkWindowPaint *implicit_paint;
   GdkInputWindow *input_window; /* only set for impl windows */
diff --git a/gdk/gdkmarshalers.list b/gdk/gdkmarshalers.list
index 3c0b1ff..ea36bae 100644
--- a/gdk/gdkmarshalers.list
+++ b/gdk/gdkmarshalers.list
@@ -1,2 +1,6 @@
 VOID:OBJECT
 VOID:BOOLEAN
+VOID:POINTER,POINTER,POINTER
+OBJECT:VOID
+OBJECT:DOUBLE,DOUBLE
+VOID:DOUBLE,DOUBLE,POINTER,POINTER
diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c
index c68f72a..beeb3d1 100644
--- a/gdk/gdkoffscreenwindow.c
+++ b/gdk/gdkoffscreenwindow.c
@@ -77,8 +77,8 @@ static void       gdk_offscreen_window_impl_iface_init    (GdkWindowImplIface
 static void       gdk_offscreen_window_hide               (GdkWindow                  *window);
 
 G_DEFINE_TYPE_WITH_CODE (GdkOffscreenWindow,
-                         gdk_offscreen_window,
-                         GDK_TYPE_DRAWABLE,
+			 gdk_offscreen_window,
+			 GDK_TYPE_DRAWABLE,
 			 G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL,
 						gdk_offscreen_window_impl_iface_init));
 
@@ -94,7 +94,7 @@ gdk_offscreen_window_finalize (GObject *object)
   offscreen->cursor = NULL;
 
   gdk_pixmap_unref (offscreen->pixmap);
-  
+
   G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object);
 }
 
@@ -122,7 +122,7 @@ gdk_offscreen_window_destroy (GdkWindow *window,
 
 static gboolean
 is_parent_of (GdkWindow *parent,
-              GdkWindow *child)
+	      GdkWindow *child)
 {
   GdkWindow *w;
 
@@ -161,18 +161,18 @@ gdk_offscreen_window_copy_to_image (GdkDrawable    *drawable,
   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
 
   return gdk_drawable_copy_to_image (offscreen->pixmap,
-                                     image,
-                                     src_x,
-                                     src_y,
-                                     dest_x, dest_y,
-                                     width, height);
+				     image,
+				     src_x,
+				     src_y,
+				     dest_x, dest_y,
+				     width, height);
 }
 
 static cairo_surface_t *
 gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable)
 {
   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  
+
   return _gdk_drawable_ref_cairo_surface (offscreen->pixmap);
 }
 
@@ -258,7 +258,7 @@ add_damage (GdkOffscreenWindow *offscreen,
 {
   GdkRectangle rect;
   GdkRegion *damage;
-  
+
   rect.x = x;
   rect.y = y;
   rect.width = w;
@@ -291,7 +291,7 @@ gdk_offscreen_window_draw_drawable (GdkDrawable *drawable,
 {
   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
   GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  
+
   gdk_draw_drawable (real_drawable, gc,
 		     src, xsrc, ysrc,
 		     xdest, ydest,
@@ -316,7 +316,7 @@ gdk_offscreen_window_draw_rectangle (GdkDrawable  *drawable,
 		      gc, filled, x, y, width, height);
 
   add_damage (offscreen, x, y, width, height);
-  
+
 }
 
 static void
@@ -354,7 +354,7 @@ gdk_offscreen_window_draw_polygon (GdkDrawable  *drawable,
 {
   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
   GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  
+
   gdk_draw_polygon (real_drawable,
 		    gc,
 		    filled,
@@ -364,10 +364,10 @@ gdk_offscreen_window_draw_polygon (GdkDrawable  *drawable,
   if (npoints > 0)
     {
       int min_x, min_y, max_x, max_y, i;
-      
+
       min_x = max_x = points[0].x;
       min_y = max_y = points[0].y;
-      
+
 	for (i = 1; i < npoints; i++)
 	  {
 	    min_x = MIN (min_x, points[i].x);
@@ -375,7 +375,7 @@ gdk_offscreen_window_draw_polygon (GdkDrawable  *drawable,
 	    min_y = MIN (min_y, points[i].y);
 	    max_y = MAX (max_y, points[i].y);
 	  }
-	
+
 	add_damage (offscreen, min_x, min_y,
 		    max_x - min_x,
 		    max_y - min_y);
@@ -450,10 +450,10 @@ gdk_offscreen_window_draw_points (GdkDrawable  *drawable,
   if (npoints > 0)
     {
       int min_x, min_y, max_x, max_y, i;
-      
+
       min_x = max_x = points[0].x;
       min_y = max_y = points[0].y;
-      
+
 	for (i = 1; i < npoints; i++)
 	  {
 	    min_x = MIN (min_x, points[i].x);
@@ -461,7 +461,7 @@ gdk_offscreen_window_draw_points (GdkDrawable  *drawable,
 	    min_y = MIN (min_y, points[i].y);
 	    max_y = MAX (max_y, points[i].y);
 	  }
-	
+
 	add_damage (offscreen, min_x, min_y,
 		    max_x - min_x,
 		    max_y - min_y);
@@ -485,10 +485,10 @@ gdk_offscreen_window_draw_segments (GdkDrawable  *drawable,
   if (nsegs > 0)
     {
       int min_x, min_y, max_x, max_y, i;
-      
+
       min_x = max_x = segs[0].x1;
       min_y = max_y = segs[0].y1;
-      
+
 	for (i = 1; i < nsegs; i++)
 	  {
 	    min_x = MIN (min_x, segs[i].x1);
@@ -500,7 +500,7 @@ gdk_offscreen_window_draw_segments (GdkDrawable  *drawable,
 	    min_y = MIN (min_y, segs[i].y2);
 	    max_y = MAX (max_y, segs[i].y2);
 	  }
-	
+
 	add_damage (offscreen, min_x, min_y,
 		    max_x - min_x,
 		    max_y - min_y);
@@ -573,7 +573,7 @@ gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable,
 {
   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
   GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  
+
   gdk_draw_pixbuf (real_drawable,
 		   gc,
 		   pixbuf,
@@ -591,7 +591,7 @@ gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable,
 
 }
 
-void 
+void
 _gdk_offscreen_window_new (GdkWindow     *window,
 			   GdkScreen     *screen,
 			   GdkVisual     *visual,
@@ -606,7 +606,7 @@ _gdk_offscreen_window_new (GdkWindow     *window,
 
   if (attributes->wclass != GDK_INPUT_OUTPUT)
     return; /* Can't support input only offscreens */
-  
+
   private = (GdkWindowObject *)window;
 
   if (private->parent != NULL && GDK_WINDOW_DESTROYED (private->parent))
@@ -655,7 +655,7 @@ gdk_offscreen_window_reparent (GdkWindow *window,
       /* No input-output children of input-only windows */
       if (new_parent_private->input_only && !private->input_only)
 	return FALSE;
-      
+
       /* Don't create loops in hierarchy */
       if (is_parent_of (window, new_parent))
 	return FALSE;
@@ -681,7 +681,7 @@ gdk_offscreen_window_reparent (GdkWindow *window,
   _gdk_syntesize_crossing_events_for_geometry_change (window);
   if (old_parent)
     _gdk_syntesize_crossing_events_for_geometry_change (GDK_WINDOW (old_parent));
-  
+
   return was_mapped;
 }
 
@@ -704,12 +704,7 @@ gdk_offscreen_window_get_pointer (GdkWindow       *window,
 				  gint            *y,
 				  GdkModifierType *mask)
 {
-  *x = 0;
-  *y = 0;
-  *mask = 0;
-
-  /* TODO: Implement this by signal emission */
-
+  /* TODO: Base on signals */
   return TRUE;
 }
 
@@ -728,12 +723,12 @@ gdk_window_get_offscreen_pixmap (GdkWindow *window)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkOffscreenWindow *offscreen;
-  
+
   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
 
   if (!GDK_IS_OFFSCREEN_WINDOW (private->impl))
     return NULL;
-  
+
   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
   return offscreen->pixmap;
 }
@@ -789,7 +784,7 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window,
     {
       private->width = width;
       private->height = height;
-      
+
       old_pixmap = offscreen->pixmap;
       offscreen->pixmap = gdk_pixmap_new (GDK_DRAWABLE (old_pixmap),
 					  width,
@@ -804,7 +799,7 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window,
 			 -1, -1);
       g_object_unref (old_pixmap);
     }
-  
+
   if (GDK_WINDOW_IS_MAPPED (private))
     {
       // TODO: Only invalidate new area, i.e. for larger windows
@@ -815,11 +810,11 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window,
 
 static void
 gdk_offscreen_window_move_resize (GdkWindow *window,
-                                  gboolean   with_move,
+				  gboolean   with_move,
 				  gint       x,
-                                  gint       y,
+				  gint       y,
 				  gint       width,
-                                  gint       height)
+				  gint       height)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkOffscreenWindow *offscreen;
@@ -952,9 +947,9 @@ gdk_offscreen_window_set_back_pixmap (GdkWindow *window,
 
 static void
 gdk_offscreen_window_shape_combine_region (GdkWindow       *window,
-                                           const GdkRegion *shape_region,
-                                           gint             offset_x,
-                                           gint             offset_y)
+					   const GdkRegion *shape_region,
+					   gint             offset_x,
+					   gint             offset_y)
 {
 }
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index d85c067..178a4ec 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -33,6 +33,7 @@
 #include "gdkpixmap.h"
 #include "gdkdrawable.h"
 #include "gdkscreen.h"
+#include "gdkmarshalers.h"
 #include "gdkalias.h"
 
 #undef DEBUG_WINDOW_PRINTING
@@ -120,6 +121,14 @@
 /* This adds a local value to the GdkVisibilityState enum */
 #define GDK_VISIBILITY_NOT_VIEWABLE 3
 
+enum {
+  GET_OFFSCREEN_PARENT,
+  PICK_OFFSCREEN_CHILD, /* only called if has_offscreen_children */
+  TO_PARENT,
+  FROM_PARENT,
+  LAST_SIGNAL
+};
+
 struct _GdkWindowPaint
 {
   GdkRegion *region;
@@ -305,6 +314,8 @@ static void do_move_region_bits_on_impl (GdkWindowObject *private,
 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
 static void move_native_children (GdkWindowObject *private);
 
+static guint signals[LAST_SIGNAL] = { 0 };
+
 static gpointer parent_class = NULL;
 
 static const cairo_user_data_key_t gdk_window_cairo_key;
@@ -376,6 +387,17 @@ gdk_window_init (GdkWindowObject *window)
   window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
 }
 
+static gboolean
+accumulate_get_parent	(GSignalInvocationHint *ihint,
+			 GValue		       *return_accu,
+			 const GValue	       *handler_return,
+			 gpointer               data)
+{
+  g_value_copy (handler_return, return_accu);
+  /* Continue while returning NULL */
+  return g_value_get_pointer (handler_return) == NULL;
+}
+
 static GQuark quark_pointer_window = 0;
 
 static void
@@ -419,6 +441,54 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
   drawable_class->get_source_drawable = gdk_window_get_source_drawable;
 
   quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
+
+
+  signals[GET_OFFSCREEN_PARENT] =
+    g_signal_new (g_intern_static_string ("get-offscreen-parent"),
+		  G_OBJECT_CLASS_TYPE (object_class),
+		  G_SIGNAL_RUN_LAST,
+		  0,
+		  accumulate_get_parent, NULL,
+		  gdk_marshal_OBJECT__VOID,
+		  GDK_TYPE_WINDOW,
+		  0);
+  signals[PICK_OFFSCREEN_CHILD] =
+    g_signal_new (g_intern_static_string ("pick-offscreen-child"),
+		  G_OBJECT_CLASS_TYPE (object_class),
+		  G_SIGNAL_RUN_LAST,
+		  0,
+		  accumulate_get_parent, NULL,
+		  gdk_marshal_OBJECT__DOUBLE_DOUBLE,
+		  GDK_TYPE_WINDOW,
+		  2,
+		  G_TYPE_DOUBLE,
+		  G_TYPE_DOUBLE);
+  signals[TO_PARENT] =
+    g_signal_new (g_intern_static_string ("to-parent"),
+		  G_OBJECT_CLASS_TYPE (object_class),
+		  G_SIGNAL_RUN_LAST,
+		  0,
+		  NULL, NULL,
+		  gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
+		  G_TYPE_NONE,
+		  4,
+		  G_TYPE_DOUBLE,
+		  G_TYPE_DOUBLE,
+		  G_TYPE_POINTER,
+		  G_TYPE_POINTER);
+  signals[FROM_PARENT] =
+    g_signal_new (g_intern_static_string ("from-parent"),
+		  G_OBJECT_CLASS_TYPE (object_class),
+		  G_SIGNAL_RUN_LAST,
+		  0,
+		  NULL, NULL,
+		  gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
+		  G_TYPE_NONE,
+		  4,
+		  G_TYPE_DOUBLE,
+		  G_TYPE_DOUBLE,
+		  G_TYPE_POINTER,
+		  G_TYPE_POINTER);
 }
 
 static void
@@ -8365,6 +8435,24 @@ _gdk_display_set_window_under_pointer (GdkDisplay *display,
 }
 
 void
+gdk_window_set_has_offscreen_children (GdkWindow *window,
+				       gboolean has_offscreen_children)
+{
+  GdkWindowObject *private = (GdkWindowObject *)window;
+
+  private->has_offscreen_children = !!has_offscreen_children;
+}
+
+gboolean
+gdk_window_get_has_offscreen_children (GdkWindow *window)
+{
+  GdkWindowObject *private = (GdkWindowObject *)window;
+
+  return private->has_offscreen_children;
+}
+
+
+void
 _gdk_syntesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
 {
   GdkDisplay *display;
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index bb2ef8c..5fefc92 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -656,6 +656,9 @@ GdkWindow *gdk_get_default_root_window (void);
 
 /* Offscreen redirection */
 GdkPixmap *gdk_window_get_offscreen_pixmap   (GdkWindow     *window);
+void       gdk_window_set_has_offscreen_children (GdkWindow     *window,
+						  gboolean       has_offscreen_children);
+gboolean   gdk_window_get_has_offscreen_children (GdkWindow     *window);
 
 void       gdk_window_redirect_to_drawable   (GdkWindow     *window,
                                               GdkDrawable   *drawable,



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