diff options
author | Alexander Larsson <alexl@redhat.com> | 2016-10-25 09:54:37 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2016-10-25 09:54:37 +0200 |
commit | 70935f09526ba9f1d0b2f6af10e18712df73eda9 (patch) | |
tree | 5faccfc562bcf8dee34ebbd6424d86f31af236c5 /demos | |
parent | 639898000e8e1f8bf1a72b778978a2c8e30c2d9b (diff) | |
download | gtk+-70935f09526ba9f1d0b2f6af10e18712df73eda9.tar.gz |
Drop support for offscreen GdkWindowswip/alexl/no-offscreen
These complicate a lot of GdkWindow internals to implement features
that not a lot of apps use, and will be better achieved using gsk.
So, we just drop it all.
Diffstat (limited to 'demos')
-rw-r--r-- | demos/gtk-demo/Makefile.am | 2 | ||||
-rw-r--r-- | demos/gtk-demo/demo.gresource.xml | 2 | ||||
-rw-r--r-- | demos/gtk-demo/offscreen_window.c | 586 | ||||
-rw-r--r-- | demos/gtk-demo/offscreen_window2.c | 503 |
4 files changed, 0 insertions, 1093 deletions
diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index f470fc8172..b873418b2b 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -43,8 +43,6 @@ demos_base = \ markup.c \ menus.c \ modelbutton.c \ - offscreen_window.c \ - offscreen_window2.c \ overlay.c \ overlay2.c \ panes.c \ diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index f0c7201f3c..3bd3d9f968 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -167,8 +167,6 @@ <file>markup.c</file> <file>menus.c</file> <file>modelbutton.c</file> - <file>offscreen_window.c</file> - <file>offscreen_window2.c</file> <file>overlay.c</file> <file>overlay2.c</file> <file>pagesetup.c</file> diff --git a/demos/gtk-demo/offscreen_window.c b/demos/gtk-demo/offscreen_window.c deleted file mode 100644 index 1affe04d1b..0000000000 --- a/demos/gtk-demo/offscreen_window.c +++ /dev/null @@ -1,586 +0,0 @@ -/* Offscreen Windows/Rotated Button - * - * Offscreen windows can be used to transform parts of a widget - * hierarchy. Note that the rotated button is fully functional. - */ -#include <math.h> -#include <gtk/gtk.h> - -#define GTK_TYPE_ROTATED_BIN (gtk_rotated_bin_get_type ()) -#define GTK_ROTATED_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ROTATED_BIN, GtkRotatedBin)) -#define GTK_ROTATED_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ROTATED_BIN, GtkRotatedBinClass)) -#define GTK_IS_ROTATED_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ROTATED_BIN)) -#define GTK_IS_ROTATED_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ROTATED_BIN)) -#define GTK_ROTATED_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ROTATED_BIN, GtkRotatedBinClass)) - -typedef struct _GtkRotatedBin GtkRotatedBin; -typedef struct _GtkRotatedBinClass GtkRotatedBinClass; - -struct _GtkRotatedBin -{ - GtkContainer container; - - GtkWidget *child; - GdkWindow *offscreen_window; - gdouble angle; -}; - -struct _GtkRotatedBinClass -{ - GtkContainerClass parent_class; -}; - -GType gtk_rotated_bin_get_type (void) G_GNUC_CONST; -GtkWidget* gtk_rotated_bin_new (void); -void gtk_rotated_bin_set_angle (GtkRotatedBin *bin, - gdouble angle); - -/*** implementation ***/ - -static void gtk_rotated_bin_realize (GtkWidget *widget); -static void gtk_rotated_bin_unrealize (GtkWidget *widget); -static void gtk_rotated_bin_measure (GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline); -static void gtk_rotated_bin_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean gtk_rotated_bin_damage (GtkWidget *widget, - GdkEventExpose *event); -static gboolean gtk_rotated_bin_draw (GtkWidget *widget, - cairo_t *cr); - -static void gtk_rotated_bin_add (GtkContainer *container, - GtkWidget *child); -static void gtk_rotated_bin_remove (GtkContainer *container, - GtkWidget *widget); -static void gtk_rotated_bin_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); -static GType gtk_rotated_bin_child_type (GtkContainer *container); - -G_DEFINE_TYPE (GtkRotatedBin, gtk_rotated_bin, GTK_TYPE_CONTAINER); - -static void -to_child (GtkRotatedBin *bin, - double widget_x, - double widget_y, - double *x_out, - double *y_out) -{ - GtkAllocation child_area; - double x, y, xr, yr; - double c, s; - double w, h; - - s = sin (bin->angle); - c = cos (bin->angle); - gtk_widget_get_allocation (bin->child, &child_area); - - w = c * child_area.width + s * child_area.height; - h = s * child_area.width + c * child_area.height; - - x = widget_x; - y = widget_y; - - x -= (w - child_area.width) / 2; - y -= (h - child_area.height) / 2; - - x -= child_area.width / 2; - y -= child_area.height / 2; - - xr = x * c + y * s; - yr = y * c - x * s; - x = xr; - y = yr; - - x += child_area.width / 2; - y += child_area.height / 2; - - *x_out = x; - *y_out = y; -} - -static void -to_parent (GtkRotatedBin *bin, - double offscreen_x, - double offscreen_y, - double *x_out, - double *y_out) -{ - GtkAllocation child_area; - double x, y, xr, yr; - double c, s; - double w, h; - - s = sin (bin->angle); - c = cos (bin->angle); - gtk_widget_get_allocation (bin->child, &child_area); - - w = c * child_area.width + s * child_area.height; - h = s * child_area.width + c * child_area.height; - - x = offscreen_x; - y = offscreen_y; - - x -= child_area.width / 2; - y -= child_area.height / 2; - - xr = x * c - y * s; - yr = x * s + y * c; - x = xr; - y = yr; - - x += child_area.width / 2; - y += child_area.height / 2; - - x -= (w - child_area.width) / 2; - y -= (h - child_area.height) / 2; - - *x_out = x; - *y_out = y; -} - -static void -gtk_rotated_bin_class_init (GtkRotatedBinClass *klass) -{ - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); - - widget_class->realize = gtk_rotated_bin_realize; - widget_class->unrealize = gtk_rotated_bin_unrealize; - widget_class->measure = gtk_rotated_bin_measure; - widget_class->size_allocate = gtk_rotated_bin_size_allocate; - widget_class->draw = gtk_rotated_bin_draw; - - g_signal_override_class_closure (g_signal_lookup ("damage-event", GTK_TYPE_WIDGET), - GTK_TYPE_ROTATED_BIN, - g_cclosure_new (G_CALLBACK (gtk_rotated_bin_damage), - NULL, NULL)); - - container_class->add = gtk_rotated_bin_add; - container_class->remove = gtk_rotated_bin_remove; - container_class->forall = gtk_rotated_bin_forall; - container_class->child_type = gtk_rotated_bin_child_type; -} - -static void -gtk_rotated_bin_init (GtkRotatedBin *bin) -{ - gtk_widget_set_has_window (GTK_WIDGET (bin), TRUE); -} - -GtkWidget * -gtk_rotated_bin_new (void) -{ - return g_object_new (GTK_TYPE_ROTATED_BIN, NULL); -} - -static GdkWindow * -pick_offscreen_child (GdkWindow *offscreen_window, - double widget_x, - double widget_y, - GtkRotatedBin *bin) -{ - GtkAllocation child_area; - double x, y; - - if (bin->child && gtk_widget_get_visible (bin->child)) - { - to_child (bin, widget_x, widget_y, &x, &y); - - gtk_widget_get_allocation (bin->child, &child_area); - - if (x >= 0 && x < child_area.width && - y >= 0 && y < child_area.height) - return bin->offscreen_window; - } - - return NULL; -} - -static void -offscreen_window_to_parent (GdkWindow *offscreen_window, - double offscreen_x, - double offscreen_y, - double *parent_x, - double *parent_y, - GtkRotatedBin *bin) -{ - to_parent (bin, offscreen_x, offscreen_y, parent_x, parent_y); -} - -static void -offscreen_window_from_parent (GdkWindow *window, - double parent_x, - double parent_y, - double *offscreen_x, - double *offscreen_y, - GtkRotatedBin *bin) -{ - to_child (bin, parent_x, parent_y, offscreen_x, offscreen_y); -} - -static void -gtk_rotated_bin_realize (GtkWidget *widget) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); - GtkAllocation allocation; - GdkWindow *window; - GdkWindowAttr attributes; - gint attributes_mask; - GtkRequisition child_requisition; - - gtk_widget_set_realized (widget, TRUE); - - gtk_widget_get_allocation (widget, &allocation); - - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.event_mask = gtk_widget_get_events (widget) - | GDK_EXPOSURE_MASK - | GDK_POINTER_MOTION_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_SCROLL_MASK - | GDK_ENTER_NOTIFY_MASK - | GDK_LEAVE_NOTIFY_MASK; - - attributes.wclass = GDK_INPUT_OUTPUT; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, widget); - g_signal_connect (window, "pick-embedded-child", - G_CALLBACK (pick_offscreen_child), bin); - - attributes.window_type = GDK_WINDOW_OFFSCREEN; - - child_requisition.width = child_requisition.height = 0; - if (bin->child && gtk_widget_get_visible (bin->child)) - { - GtkAllocation child_allocation; - - gtk_widget_get_allocation (bin->child, &child_allocation); - attributes.width = child_allocation.width; - attributes.height = child_allocation.height; - } - bin->offscreen_window = gdk_window_new (gdk_screen_get_root_window (gtk_widget_get_screen (widget)), - &attributes, attributes_mask); - gdk_window_set_user_data (bin->offscreen_window, widget); - if (bin->child) - gtk_widget_set_parent_window (bin->child, bin->offscreen_window); - gdk_offscreen_window_set_embedder (bin->offscreen_window, window); - g_signal_connect (bin->offscreen_window, "to-embedder", - G_CALLBACK (offscreen_window_to_parent), bin); - g_signal_connect (bin->offscreen_window, "from-embedder", - G_CALLBACK (offscreen_window_from_parent), bin); - - gdk_window_show (bin->offscreen_window); -} - -static void -gtk_rotated_bin_unrealize (GtkWidget *widget) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); - - gdk_window_set_user_data (bin->offscreen_window, NULL); - gdk_window_destroy (bin->offscreen_window); - bin->offscreen_window = NULL; - - GTK_WIDGET_CLASS (gtk_rotated_bin_parent_class)->unrealize (widget); -} - -static GType -gtk_rotated_bin_child_type (GtkContainer *container) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (container); - - if (bin->child) - return G_TYPE_NONE; - - return GTK_TYPE_WIDGET; -} - -static void -gtk_rotated_bin_add (GtkContainer *container, - GtkWidget *widget) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (container); - - if (!bin->child) - { - gtk_widget_set_parent_window (widget, bin->offscreen_window); - gtk_widget_set_parent (widget, GTK_WIDGET (bin)); - bin->child = widget; - } - else - g_warning ("GtkRotatedBin cannot have more than one child"); -} - -static void -gtk_rotated_bin_remove (GtkContainer *container, - GtkWidget *widget) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (container); - gboolean was_visible; - - was_visible = gtk_widget_get_visible (widget); - - if (bin->child == widget) - { - gtk_widget_unparent (widget); - - bin->child = NULL; - - if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container))) - gtk_widget_queue_resize (GTK_WIDGET (container)); - } -} - -static void -gtk_rotated_bin_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (container); - - g_return_if_fail (callback != NULL); - - if (bin->child) - (*callback) (bin->child, callback_data); -} - -void -gtk_rotated_bin_set_angle (GtkRotatedBin *bin, - gdouble angle) -{ - g_return_if_fail (GTK_IS_ROTATED_BIN (bin)); - - bin->angle = angle; - gtk_widget_queue_resize (GTK_WIDGET (bin)); - - gdk_window_geometry_changed (bin->offscreen_window); -} - -static void -gtk_rotated_bin_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); - GtkRequisition child_requisition; - double s, c; - - child_requisition.width = 0; - child_requisition.height = 0; - - if (bin->child && gtk_widget_get_visible (bin->child)) - gtk_widget_get_preferred_size ( (bin->child), - &child_requisition, NULL); - - s = sin (bin->angle); - c = cos (bin->angle); - requisition->width = c * child_requisition.width + s * child_requisition.height; - requisition->height = s * child_requisition.width + c * child_requisition.height; -} - -static void -gtk_rotated_bin_measure (GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline) -{ - GtkRequisition requisition; - - gtk_rotated_bin_size_request (widget, &requisition); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - *minimum = *natural = requisition.width; - else - *minimum = *natural = requisition.height; -} - -static void -gtk_rotated_bin_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); - gint w, h; - gdouble s, c; - - gtk_widget_set_allocation (widget, allocation); - - w = allocation->width; - h = allocation->height; - - if (gtk_widget_get_realized (widget)) - gdk_window_move_resize (gtk_widget_get_window (widget), - allocation->x, - allocation->y, - w, h); - - if (bin->child && gtk_widget_get_visible (bin->child)) - { - GtkRequisition child_requisition; - GtkAllocation child_allocation; - - s = sin (bin->angle); - c = cos (bin->angle); - - gtk_widget_get_preferred_size (bin->child, - &child_requisition, NULL); - child_allocation.x = 0; - child_allocation.y = 0; - child_allocation.height = child_requisition.height; - if (c == 0.0) - child_allocation.width = h / s; - else if (s == 0.0) - child_allocation.width = w / c; - else - child_allocation.width = MIN ((w - s * child_allocation.height) / c, - (h - c * child_allocation.height) / s); - - if (gtk_widget_get_realized (widget)) - gdk_window_move_resize (bin->offscreen_window, - child_allocation.x, - child_allocation.y, - child_allocation.width, - child_allocation.height); - - child_allocation.x = child_allocation.y = 0; - gtk_widget_size_allocate (bin->child, &child_allocation); - } -} - -static gboolean -gtk_rotated_bin_damage (GtkWidget *widget, - GdkEventExpose *event) -{ - gdk_window_invalidate_rect (gtk_widget_get_window (widget), - NULL, FALSE); - - return TRUE; -} - -static gboolean -gtk_rotated_bin_draw (GtkWidget *widget, - cairo_t *cr) -{ - GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); - GdkWindow *window; - gdouble s, c; - gdouble w, h; - - window = gtk_widget_get_window (widget); - if (gtk_cairo_should_draw_window (cr, window)) - { - cairo_surface_t *surface; - GtkAllocation child_area; - - if (bin->child && gtk_widget_get_visible (bin->child)) - { - surface = gdk_offscreen_window_get_surface (bin->offscreen_window); - gtk_widget_get_allocation (bin->child, &child_area); - - /* transform */ - s = sin (bin->angle); - c = cos (bin->angle); - w = c * child_area.width + s * child_area.height; - h = s * child_area.width + c * child_area.height; - - cairo_translate (cr, (w - child_area.width) / 2, (h - child_area.height) / 2); - cairo_translate (cr, child_area.width / 2, child_area.height / 2); - cairo_rotate (cr, bin->angle); - cairo_translate (cr, -child_area.width / 2, -child_area.height / 2); - - /* clip */ - cairo_rectangle (cr, - 0, 0, - gdk_window_get_width (bin->offscreen_window), - gdk_window_get_height (bin->offscreen_window)); - cairo_clip (cr); - /* paint */ - cairo_set_source_surface (cr, surface, 0, 0); - cairo_paint (cr); - } - } - if (gtk_cairo_should_draw_window (cr, bin->offscreen_window)) - { - gtk_render_background (gtk_widget_get_style_context (widget), - cr, - 0, 0, - gdk_window_get_width (bin->offscreen_window), - gdk_window_get_height (bin->offscreen_window)); - - if (bin->child) - gtk_container_propagate_draw (GTK_CONTAINER (widget), - bin->child, - cr); - } - - return FALSE; -} - -/*** ***/ - -static void -scale_changed (GtkRange *range, - GtkRotatedBin *bin) -{ - gtk_rotated_bin_set_angle (bin, gtk_range_get_value (range)); -} - -GtkWidget * -do_offscreen_window (GtkWidget *do_widget) -{ - static GtkWidget *window = NULL; - - if (!window) - { - GtkWidget *bin, *vbox, *scale, *button; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_screen (GTK_WINDOW (window), - gtk_widget_get_screen (do_widget)); - gtk_window_set_title (GTK_WINDOW (window), "Rotated Button"); - - g_signal_connect (window, "destroy", - G_CALLBACK (gtk_widget_destroyed), &window); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, - 0, G_PI/2, 0.01); - gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); - - button = gtk_button_new_with_label ("A Button"); - bin = gtk_rotated_bin_new (); - - g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed), bin); - - gtk_container_add (GTK_CONTAINER (window), vbox); - gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE); - gtk_box_pack_start (GTK_BOX (vbox), bin, TRUE, TRUE); - gtk_container_add (GTK_CONTAINER (bin), button); - } - - if (!gtk_widget_get_visible (window)) - gtk_widget_show_all (window); - else - gtk_widget_destroy (window); - - return window; -} diff --git a/demos/gtk-demo/offscreen_window2.c b/demos/gtk-demo/offscreen_window2.c deleted file mode 100644 index 22bbe5237e..0000000000 --- a/demos/gtk-demo/offscreen_window2.c +++ /dev/null @@ -1,503 +0,0 @@ -/* Offscreen Windows/Effects - * - * Offscreen windows can be used to render elements multiple times to achieve - * various effects. - */ -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#define GTK_TYPE_MIRROR_BIN (gtk_mirror_bin_get_type ()) -#define GTK_MIRROR_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MIRROR_BIN, GtkMirrorBin)) -#define GTK_MIRROR_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MIRROR_BIN, GtkMirrorBinClass)) -#define GTK_IS_MIRROR_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MIRROR_BIN)) -#define GTK_IS_MIRROR_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MIRROR_BIN)) -#define GTK_MIRROR_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MIRROR_BIN, GtkMirrorBinClass)) - -typedef struct _GtkMirrorBin GtkMirrorBin; -typedef struct _GtkMirrorBinClass GtkMirrorBinClass; - -struct _GtkMirrorBin -{ - GtkContainer container; - - GtkWidget *child; - GdkWindow *offscreen_window; -}; - -struct _GtkMirrorBinClass -{ - GtkContainerClass parent_class; -}; - -GType gtk_mirror_bin_get_type (void) G_GNUC_CONST; -GtkWidget* gtk_mirror_bin_new (void); - -/*** implementation ***/ - -static void gtk_mirror_bin_realize (GtkWidget *widget); -static void gtk_mirror_bin_unrealize (GtkWidget *widget); -static void gtk_mirror_bin_measure (GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline); -static void gtk_mirror_bin_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean gtk_mirror_bin_damage (GtkWidget *widget, - GdkEventExpose *event); -static gboolean gtk_mirror_bin_draw (GtkWidget *widget, - cairo_t *cr); - -static void gtk_mirror_bin_add (GtkContainer *container, - GtkWidget *child); -static void gtk_mirror_bin_remove (GtkContainer *container, - GtkWidget *widget); -static void gtk_mirror_bin_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); -static GType gtk_mirror_bin_child_type (GtkContainer *container); - -G_DEFINE_TYPE (GtkMirrorBin, gtk_mirror_bin, GTK_TYPE_CONTAINER); - -static void -to_child (GtkMirrorBin *bin, - double widget_x, - double widget_y, - double *x_out, - double *y_out) -{ - *x_out = widget_x; - *y_out = widget_y; -} - -static void -to_parent (GtkMirrorBin *bin, - double offscreen_x, - double offscreen_y, - double *x_out, - double *y_out) -{ - *x_out = offscreen_x; - *y_out = offscreen_y; -} - -static void -gtk_mirror_bin_class_init (GtkMirrorBinClass *klass) -{ - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); - - widget_class->realize = gtk_mirror_bin_realize; - widget_class->unrealize = gtk_mirror_bin_unrealize; - widget_class->measure = gtk_mirror_bin_measure; - widget_class->size_allocate = gtk_mirror_bin_size_allocate; - widget_class->draw = gtk_mirror_bin_draw; - - g_signal_override_class_closure (g_signal_lookup ("damage-event", GTK_TYPE_WIDGET), - GTK_TYPE_MIRROR_BIN, - g_cclosure_new (G_CALLBACK (gtk_mirror_bin_damage), - NULL, NULL)); - - container_class->add = gtk_mirror_bin_add; - container_class->remove = gtk_mirror_bin_remove; - container_class->forall = gtk_mirror_bin_forall; - container_class->child_type = gtk_mirror_bin_child_type; -} - -static void -gtk_mirror_bin_init (GtkMirrorBin *bin) -{ - gtk_widget_set_has_window (GTK_WIDGET (bin), TRUE); -} - -GtkWidget * -gtk_mirror_bin_new (void) -{ - return g_object_new (GTK_TYPE_MIRROR_BIN, NULL); -} - -static GdkWindow * -pick_offscreen_child (GdkWindow *offscreen_window, - double widget_x, - double widget_y, - GtkMirrorBin *bin) -{ - GtkAllocation child_area; - double x, y; - - if (bin->child && gtk_widget_get_visible (bin->child)) - { - to_child (bin, widget_x, widget_y, &x, &y); - - gtk_widget_get_allocation (bin->child, &child_area); - - if (x >= 0 && x < child_area.width && - y >= 0 && y < child_area.height) - return bin->offscreen_window; - } - - return NULL; -} - -static void -offscreen_window_to_parent (GdkWindow *offscreen_window, - double offscreen_x, - double offscreen_y, - double *parent_x, - double *parent_y, - GtkMirrorBin *bin) -{ - to_parent (bin, offscreen_x, offscreen_y, parent_x, parent_y); -} - -static void -offscreen_window_from_parent (GdkWindow *window, - double parent_x, - double parent_y, - double *offscreen_x, - double *offscreen_y, - GtkMirrorBin *bin) -{ - to_child (bin, parent_x, parent_y, offscreen_x, offscreen_y); -} - -static void -gtk_mirror_bin_realize (GtkWidget *widget) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); - GtkAllocation allocation; - GdkWindow *window; - GdkWindowAttr attributes; - gint attributes_mask; - GtkRequisition child_requisition; - - gtk_widget_set_realized (widget, TRUE); - - gtk_widget_get_allocation (widget, &allocation); - - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.event_mask = gtk_widget_get_events (widget) - | GDK_EXPOSURE_MASK - | GDK_POINTER_MOTION_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_SCROLL_MASK - | GDK_ENTER_NOTIFY_MASK - | GDK_LEAVE_NOTIFY_MASK; - - attributes.wclass = GDK_INPUT_OUTPUT; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, widget); - g_signal_connect (window, "pick-embedded-child", - G_CALLBACK (pick_offscreen_child), bin); - - attributes.window_type = GDK_WINDOW_OFFSCREEN; - - child_requisition.width = child_requisition.height = 0; - if (bin->child && gtk_widget_get_visible (bin->child)) - { - GtkAllocation child_allocation; - - gtk_widget_get_allocation (bin->child, &child_allocation); - attributes.width = child_allocation.width; - attributes.height = child_allocation.height; - } - bin->offscreen_window = gdk_window_new (gdk_screen_get_root_window (gtk_widget_get_screen (widget)), - &attributes, attributes_mask); - gdk_window_set_user_data (bin->offscreen_window, widget); - if (bin->child) - gtk_widget_set_parent_window (bin->child, bin->offscreen_window); - gdk_offscreen_window_set_embedder (bin->offscreen_window, window); - g_signal_connect (bin->offscreen_window, "to-embedder", - G_CALLBACK (offscreen_window_to_parent), bin); - g_signal_connect (bin->offscreen_window, "from-embedder", - G_CALLBACK (offscreen_window_from_parent), bin); - - gdk_window_show (bin->offscreen_window); -} - -static void -gtk_mirror_bin_unrealize (GtkWidget *widget) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); - - gdk_window_set_user_data (bin->offscreen_window, NULL); - gdk_window_destroy (bin->offscreen_window); - bin->offscreen_window = NULL; - - GTK_WIDGET_CLASS (gtk_mirror_bin_parent_class)->unrealize (widget); -} - -static GType -gtk_mirror_bin_child_type (GtkContainer *container) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (container); - - if (bin->child) - return G_TYPE_NONE; - - return GTK_TYPE_WIDGET; -} - -static void -gtk_mirror_bin_add (GtkContainer *container, - GtkWidget *widget) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (container); - - if (!bin->child) - { - gtk_widget_set_parent_window (widget, bin->offscreen_window); - gtk_widget_set_parent (widget, GTK_WIDGET (bin)); - bin->child = widget; - } - else - g_warning ("GtkMirrorBin cannot have more than one child"); -} - -static void -gtk_mirror_bin_remove (GtkContainer *container, - GtkWidget *widget) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (container); - gboolean was_visible; - - was_visible = gtk_widget_get_visible (widget); - - if (bin->child == widget) - { - gtk_widget_unparent (widget); - - bin->child = NULL; - - if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container))) - gtk_widget_queue_resize (GTK_WIDGET (container)); - } -} - -static void -gtk_mirror_bin_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (container); - - g_return_if_fail (callback != NULL); - - if (bin->child) - (*callback) (bin->child, callback_data); -} - -static void -gtk_mirror_bin_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); - GtkRequisition child_requisition; - - child_requisition.width = 0; - child_requisition.height = 0; - - if (bin->child && gtk_widget_get_visible (bin->child)) - gtk_widget_get_preferred_size ( (bin->child), - &child_requisition, NULL); - - requisition->width = child_requisition.width + 10; - requisition->height = child_requisition.height * 2 + 10; -} - -static void -gtk_mirror_bin_measure (GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline) -{ - GtkRequisition requisition; - - gtk_mirror_bin_size_request (widget, &requisition); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - *minimum = *natural = requisition.width; - else - *minimum = *natural = requisition.height; -} - -static void -gtk_mirror_bin_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); - gint w, h; - - gtk_widget_set_allocation (widget, allocation); - - w = allocation->width; - h = allocation->height; - - if (gtk_widget_get_realized (widget)) - gdk_window_move_resize (gtk_widget_get_window (widget), - allocation->x, - allocation->y, - w, h); - - if (bin->child && gtk_widget_get_visible (bin->child)) - { - GtkRequisition child_requisition; - GtkAllocation child_allocation; - - gtk_widget_get_preferred_size (bin->child, - &child_requisition, NULL); - child_allocation.x = 0; - child_allocation.y = 0; - child_allocation.height = child_requisition.height; - child_allocation.width = child_requisition.width; - - if (gtk_widget_get_realized (widget)) - gdk_window_move_resize (bin->offscreen_window, - allocation->x, - allocation->y, - child_allocation.width, child_allocation.height); - gtk_widget_size_allocate (bin->child, &child_allocation); - } -} - -static gboolean -gtk_mirror_bin_damage (GtkWidget *widget, - GdkEventExpose *event) -{ - gdk_window_invalidate_rect (gtk_widget_get_window (widget), - NULL, FALSE); - - return TRUE; -} - -static gboolean -gtk_mirror_bin_draw (GtkWidget *widget, - cairo_t *cr) -{ - GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); - GdkWindow *window; - - window = gtk_widget_get_window (widget); - if (gtk_cairo_should_draw_window (cr, window)) - { - cairo_surface_t *surface; - cairo_matrix_t matrix; - cairo_pattern_t *mask; - int height; - - if (bin->child && gtk_widget_get_visible (bin->child)) - { - surface = gdk_offscreen_window_get_surface (bin->offscreen_window); - height = gdk_window_get_height (bin->offscreen_window); - - /* paint the offscreen child */ - cairo_set_source_surface (cr, surface, 0, 0); - cairo_paint (cr); - - cairo_matrix_init (&matrix, 1.0, 0.0, 0.3, 1.0, 0.0, 0.0); - cairo_matrix_scale (&matrix, 1.0, -1.0); - cairo_matrix_translate (&matrix, -10, - 3 * height - 10); - cairo_transform (cr, &matrix); - - cairo_set_source_surface (cr, surface, 0, height); - - /* create linear gradient as mask-pattern to fade out the source */ - mask = cairo_pattern_create_linear (0.0, height, 0.0, 2*height); - cairo_pattern_add_color_stop_rgba (mask, 0.0, 0.0, 0.0, 0.0, 0.0); - cairo_pattern_add_color_stop_rgba (mask, 0.25, 0.0, 0.0, 0.0, 0.01); - cairo_pattern_add_color_stop_rgba (mask, 0.5, 0.0, 0.0, 0.0, 0.25); - cairo_pattern_add_color_stop_rgba (mask, 0.75, 0.0, 0.0, 0.0, 0.5); - cairo_pattern_add_color_stop_rgba (mask, 1.0, 0.0, 0.0, 0.0, 1.0); - - /* paint the reflection */ - cairo_mask (cr, mask); - - cairo_pattern_destroy (mask); - } - } - else if (gtk_cairo_should_draw_window (cr, bin->offscreen_window)) - { - gtk_render_background (gtk_widget_get_style_context (widget), - cr, - 0, 0, - gdk_window_get_width (bin->offscreen_window), - gdk_window_get_height (bin->offscreen_window)); - - if (bin->child) - gtk_container_propagate_draw (GTK_CONTAINER (widget), - bin->child, - cr); - } - - return FALSE; -} - -/*** ***/ - -GtkWidget * -do_offscreen_window2 (GtkWidget *do_widget) -{ - static GtkWidget *window = NULL; - - if (!window) - { - GtkWidget *bin, *vbox; - GtkWidget *hbox, *entry, *applybutton, *backbutton; - GtkSizeGroup *group; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_screen (GTK_WINDOW (window), - gtk_widget_get_screen (do_widget)); - gtk_window_set_title (GTK_WINDOW (window), "Effects"); - - g_signal_connect (window, "destroy", - G_CALLBACK (gtk_widget_destroyed), &window); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - bin = gtk_mirror_bin_new (); - - group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - backbutton = gtk_button_new (); - gtk_container_add (GTK_CONTAINER (backbutton), - gtk_image_new_from_icon_name ("go-previous", 4)); - gtk_size_group_add_widget (group, backbutton); - entry = gtk_entry_new (); - gtk_size_group_add_widget (group, entry); - applybutton = gtk_button_new_with_label (_("Apply")); - gtk_size_group_add_widget (group, applybutton); - - gtk_container_add (GTK_CONTAINER (window), vbox); - gtk_box_pack_start (GTK_BOX (vbox), bin, TRUE, TRUE); - gtk_container_add (GTK_CONTAINER (bin), hbox); - gtk_box_pack_start (GTK_BOX (hbox), backbutton, FALSE, FALSE); - gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE); - gtk_box_pack_start (GTK_BOX (hbox), applybutton, FALSE, FALSE); - } - - if (!gtk_widget_get_visible (window)) - gtk_widget_show_all (window); - else - gtk_widget_destroy (window); - - return window; -} |