Bug 631599 - Allow to use arbitrary surfaces for offscreen windows
Add signal GdkWindow::create-surface which allows to use any surface type as storage for offscreen windows. Test the new signal in tests/gdkoffscreenbox.c
This commit is contained in:
parent
10c76c1c95
commit
9d9742f1e5
@ -550,6 +550,9 @@ GType gdk_offscreen_window_get_type (void);
|
|||||||
void _gdk_offscreen_window_new (GdkWindow *window,
|
void _gdk_offscreen_window_new (GdkWindow *window,
|
||||||
GdkWindowAttr *attributes,
|
GdkWindowAttr *attributes,
|
||||||
gint attributes_mask);
|
gint attributes_mask);
|
||||||
|
cairo_surface_t * _gdk_offscreen_window_create_surface (GdkWindow *window,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
|
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
|
@ -3,4 +3,5 @@ VOID:BOOLEAN
|
|||||||
VOID:POINTER,POINTER,POINTER
|
VOID:POINTER,POINTER,POINTER
|
||||||
OBJECT:VOID
|
OBJECT:VOID
|
||||||
OBJECT:DOUBLE,DOUBLE
|
OBJECT:DOUBLE,DOUBLE
|
||||||
|
BOXED:INT,INT
|
||||||
VOID:DOUBLE,DOUBLE,POINTER,POINTER
|
VOID:DOUBLE,DOUBLE,POINTER,POINTER
|
||||||
|
@ -113,17 +113,11 @@ get_surface (GdkOffscreenWindow *offscreen)
|
|||||||
if (! offscreen->surface)
|
if (! offscreen->surface)
|
||||||
{
|
{
|
||||||
GdkWindowObject *private = (GdkWindowObject *) offscreen->wrapper;
|
GdkWindowObject *private = (GdkWindowObject *) offscreen->wrapper;
|
||||||
cairo_surface_t *similar;
|
|
||||||
|
|
||||||
similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent);
|
g_signal_emit_by_name (private, "create-surface",
|
||||||
|
|
||||||
offscreen->surface = cairo_surface_create_similar (similar,
|
|
||||||
/* FIXME: use visual */
|
|
||||||
CAIRO_CONTENT_COLOR,
|
|
||||||
private->width,
|
private->width,
|
||||||
private->height);
|
private->height,
|
||||||
|
&offscreen->surface);
|
||||||
cairo_surface_destroy (similar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return offscreen->surface;
|
return offscreen->surface;
|
||||||
@ -155,6 +149,30 @@ gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable)
|
|||||||
return cairo_surface_reference (get_surface (offscreen));
|
return cairo_surface_reference (get_surface (offscreen));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_surface_t *
|
||||||
|
_gdk_offscreen_window_create_surface (GdkWindow *offscreen,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
GdkWindowObject *private = (GdkWindowObject *) offscreen;
|
||||||
|
cairo_surface_t *similar;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (private->impl), NULL);
|
||||||
|
|
||||||
|
similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent);
|
||||||
|
|
||||||
|
surface = cairo_surface_create_similar (similar,
|
||||||
|
/* FIXME: use visual */
|
||||||
|
CAIRO_CONTENT_COLOR,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
|
||||||
|
cairo_surface_destroy (similar);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gdk_offscreen_window_new (GdkWindow *window,
|
_gdk_offscreen_window_new (GdkWindow *window,
|
||||||
GdkWindowAttr *attributes,
|
GdkWindowAttr *attributes,
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <cairo-gobject.h>
|
||||||
|
|
||||||
#include "gdkwindow.h"
|
#include "gdkwindow.h"
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
@ -185,6 +187,7 @@ enum {
|
|||||||
PICK_EMBEDDED_CHILD, /* only called if children are embedded */
|
PICK_EMBEDDED_CHILD, /* only called if children are embedded */
|
||||||
TO_EMBEDDER,
|
TO_EMBEDDER,
|
||||||
FROM_EMBEDDER,
|
FROM_EMBEDDER,
|
||||||
|
CREATE_SURFACE,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -353,6 +356,18 @@ accumulate_get_window (GSignalInvocationHint *ihint,
|
|||||||
return g_value_get_object (handler_return) == NULL;
|
return g_value_get_object (handler_return) == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
create_surface_accumulator (GSignalInvocationHint *ihint,
|
||||||
|
GValue *return_accu,
|
||||||
|
const GValue *handler_return,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
g_value_copy (handler_return, return_accu);
|
||||||
|
|
||||||
|
/* Stop on the first non-NULL return value */
|
||||||
|
return g_value_get_boxed (handler_return) == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static GQuark quark_pointer_window = 0;
|
static GQuark quark_pointer_window = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -373,6 +388,8 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
|
|||||||
drawable_class->get_clip_region = gdk_window_get_clip_region;
|
drawable_class->get_clip_region = gdk_window_get_clip_region;
|
||||||
drawable_class->get_visible_region = gdk_window_get_visible_region;
|
drawable_class->get_visible_region = gdk_window_get_visible_region;
|
||||||
|
|
||||||
|
klass->create_surface = _gdk_offscreen_window_create_surface;
|
||||||
|
|
||||||
quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
|
quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
|
||||||
|
|
||||||
|
|
||||||
@ -476,6 +493,39 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
|
|||||||
G_TYPE_DOUBLE,
|
G_TYPE_DOUBLE,
|
||||||
G_TYPE_POINTER,
|
G_TYPE_POINTER,
|
||||||
G_TYPE_POINTER);
|
G_TYPE_POINTER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GdkWindow::create-surface:
|
||||||
|
* @window: the offscreen window on which the signal is emitted
|
||||||
|
* @width: the width of the offscreen surface to create
|
||||||
|
* @height: the height of the offscreen surface to create
|
||||||
|
*
|
||||||
|
* The ::create-surface signal is emitted when an offscreen window
|
||||||
|
* needs its surface (re)created, which happens either when the the
|
||||||
|
* window is first drawn to, or when the window is being
|
||||||
|
* resized. The first signal handler that returns a non-%NULL
|
||||||
|
* surface will stop any further signal emission, and its surface
|
||||||
|
* will be used.
|
||||||
|
*
|
||||||
|
* Note that it is not possible to access the window's previous
|
||||||
|
* surface from within any callback of this signal. Calling
|
||||||
|
* gdk_offscreen_window_get_surface() will lead to a crash.
|
||||||
|
*
|
||||||
|
* Returns: the newly created #cairo_surface_t for the offscreen window
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
signals[CREATE_SURFACE] =
|
||||||
|
g_signal_new (g_intern_static_string ("create-surface"),
|
||||||
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GdkWindowObjectClass, create_surface),
|
||||||
|
create_surface_accumulator, NULL,
|
||||||
|
_gdk_marshal_BOXED__INT_INT,
|
||||||
|
CAIRO_GOBJECT_TYPE_SURFACE,
|
||||||
|
2,
|
||||||
|
G_TYPE_INT,
|
||||||
|
G_TYPE_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -489,6 +489,10 @@ typedef struct _GdkWindowObjectClass GdkWindowObjectClass;
|
|||||||
struct _GdkWindowObjectClass
|
struct _GdkWindowObjectClass
|
||||||
{
|
{
|
||||||
GdkDrawableClass parent_class;
|
GdkDrawableClass parent_class;
|
||||||
|
|
||||||
|
cairo_surface_t * (* create_surface) (GdkWindow *window,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Windows
|
/* Windows
|
||||||
|
@ -234,6 +234,14 @@ offscreen_window_from_parent2 (GdkWindow *window,
|
|||||||
offscreen_x, offscreen_y);
|
offscreen_x, offscreen_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
gdk_offscreen_box_create_alpha_image_surface (GdkWindow *offscreen,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_offscreen_box_realize (GtkWidget *widget)
|
gtk_offscreen_box_realize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
@ -323,6 +331,10 @@ gtk_offscreen_box_realize (GtkWidget *widget)
|
|||||||
gtk_widget_set_parent_window (offscreen_box->child2, offscreen_box->offscreen_window2);
|
gtk_widget_set_parent_window (offscreen_box->child2, offscreen_box->offscreen_window2);
|
||||||
gdk_offscreen_window_set_embedder (offscreen_box->offscreen_window2,
|
gdk_offscreen_window_set_embedder (offscreen_box->offscreen_window2,
|
||||||
window);
|
window);
|
||||||
|
|
||||||
|
g_signal_connect (offscreen_box->offscreen_window2, "create-surface",
|
||||||
|
G_CALLBACK (gdk_offscreen_box_create_alpha_image_surface),
|
||||||
|
offscreen_box);
|
||||||
g_signal_connect (offscreen_box->offscreen_window2, "to-embedder",
|
g_signal_connect (offscreen_box->offscreen_window2, "to-embedder",
|
||||||
G_CALLBACK (offscreen_window_to_parent2), offscreen_box);
|
G_CALLBACK (offscreen_window_to_parent2), offscreen_box);
|
||||||
g_signal_connect (offscreen_box->offscreen_window2, "from-embedder",
|
g_signal_connect (offscreen_box->offscreen_window2, "from-embedder",
|
||||||
|
Loading…
Reference in New Issue
Block a user