diff options
Diffstat (limited to 'gtk/src/ghbcompositor.c')
-rw-r--r-- | gtk/src/ghbcompositor.c | 207 |
1 files changed, 193 insertions, 14 deletions
diff --git a/gtk/src/ghbcompositor.c b/gtk/src/ghbcompositor.c index 41ea67936..92f8fe2e8 100644 --- a/gtk/src/ghbcompositor.c +++ b/gtk/src/ghbcompositor.c @@ -45,12 +45,23 @@ enum { static void ghb_compositor_finalize (GObject *object); static void ghb_compositor_realize (GtkWidget *widget); static void ghb_compositor_unrealize (GtkWidget *widget); -static void ghb_compositor_size_request (GtkWidget *widget, - GtkRequisition *requisition); static void ghb_compositor_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +#if GTK_CHECK_VERSION(3, 0, 0) +static gboolean ghb_compositor_draw (GtkWidget *widget, + cairo_t *cr); +static void ghb_compositor_get_preferred_width(GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +static void ghb_compositor_get_preferred_height(GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +#else static gboolean ghb_compositor_expose (GtkWidget *widget, GdkEventExpose *event); +static void ghb_compositor_size_request (GtkWidget *widget, + GtkRequisition *requisition); +#endif static void ghb_compositor_set_property (GObject *object, guint prop_id, const GValue *value, @@ -93,14 +104,19 @@ ghb_compositor_class_init (GhbCompositorClass *class) gobject_class->set_property = ghb_compositor_set_property; gobject_class->get_property = ghb_compositor_get_property; +#if GTK_CHECK_VERSION(3, 0, 0) + widget_class->draw = ghb_compositor_draw; + widget_class->get_preferred_width = ghb_compositor_get_preferred_width; + widget_class->get_preferred_height = ghb_compositor_get_preferred_height; +#else widget_class->size_request = ghb_compositor_size_request; + widget_class->expose_event = ghb_compositor_expose; +#endif widget_class->size_allocate = ghb_compositor_size_allocate; widget_class->realize = ghb_compositor_realize; widget_class->unrealize = ghb_compositor_unrealize; - widget_class->expose_event = ghb_compositor_expose; - container_class->add = ghb_compositor_add; container_class->remove = ghb_compositor_remove; container_class->forall = ghb_compositor_forall; @@ -425,7 +441,7 @@ ghb_compositor_forall( GhbCompositorChild *cc; GList *link, *next; - for (link = compositor->children; link != NULL; link = link->next) + for (link = compositor->children; link != NULL; ) { // The callback may cause the link to be removed from the list. // So find next before calling callback @@ -487,11 +503,15 @@ ghb_compositor_realize (GtkWidget *widget) GdkWindow *window; if (visible_window) { - attributes.visual = gtk_widget_get_visual (widget); +#if GTK_CHECK_VERSION(3, 0, 0) + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; +#else + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; attributes.colormap = gtk_widget_get_colormap (widget); +#endif + attributes.visual = gtk_widget_get_visual (widget); attributes.wclass = GDK_INPUT_OUTPUT; - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, attributes_mask); @@ -505,11 +525,13 @@ ghb_compositor_realize (GtkWidget *widget) g_object_ref (window); } - widget->style = gtk_style_attach (widget->style, window); +#if !GTK_CHECK_VERSION(3, 0, 0) + gtk_widget_style_attach(widget); if (visible_window) gtk_style_set_background(widget->style, window, GTK_STATE_NORMAL); +#endif } static void @@ -518,6 +540,60 @@ ghb_compositor_unrealize (GtkWidget *widget) GTK_WIDGET_CLASS (ghb_compositor_parent_class)->unrealize (widget); } +#if GTK_CHECK_VERSION(3, 0, 0) +static void +ghb_compositor_get_preferred_width( + GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + GhbCompositor *compositor = GHB_COMPOSITOR (widget); + GList *link; + GhbCompositorChild *cc; + gint width = 0; + GtkRequisition min_size, size; + + for (link = compositor->children; link != NULL; link = link->next) + { + cc = (GhbCompositorChild*)link->data; + if (gtk_widget_get_visible(cc->widget)) + { + gtk_widget_get_preferred_size(cc->widget, &min_size, &size); + width = MAX(MAX(min_size.width, size.width), width); + } + } + + *minimum_size = width + gtk_container_get_border_width(GTK_CONTAINER (widget)) * 2; + *natural_size = width + gtk_container_get_border_width(GTK_CONTAINER (widget)) * 2; +} + +static void +ghb_compositor_get_preferred_height( + GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + GhbCompositor *compositor = GHB_COMPOSITOR (widget); + GList *link; + GhbCompositorChild *cc; + gint height = 0; + GtkRequisition min_size, size; + + for (link = compositor->children; link != NULL; link = link->next) + { + cc = (GhbCompositorChild*)link->data; + if (gtk_widget_get_visible(cc->widget)) + { + gtk_widget_get_preferred_size(cc->widget, &min_size, &size); + height = MAX(MAX(min_size.height, size.height), height); + } + } + + *minimum_size = height + gtk_container_get_border_width(GTK_CONTAINER (widget)) * 2; + *natural_size = height + gtk_container_get_border_width(GTK_CONTAINER (widget)) * 2; +} +#else + static void ghb_compositor_size_request( GtkWidget *widget, @@ -527,23 +603,24 @@ ghb_compositor_size_request( GList *link; GhbCompositorChild *cc; gint width = 0, height = 0; - GtkRequisition child_requisition; + GtkRequisition size; for (link = compositor->children; link != NULL; link = link->next) { cc = (GhbCompositorChild*)link->data; if (gtk_widget_get_visible(cc->widget)) { - gtk_widget_size_request(cc->widget, NULL); - gtk_widget_get_child_requisition(cc->widget, &child_requisition); - width = MAX(child_requisition.width, width); - height = MAX(child_requisition.height, height); + //gtk_widget_size_request(cc->widget, NULL); + gtk_widget_size_request(cc->widget, &size); + width = MAX(size.width, width); + height = MAX(size.height, height); } } requisition->width = width + gtk_container_get_border_width(GTK_CONTAINER (widget)) * 2; requisition->height = height + gtk_container_get_border_width(GTK_CONTAINER (widget)) * 2; } +#endif static void ghb_compositor_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -553,7 +630,7 @@ ghb_compositor_size_allocate (GtkWidget *widget, GtkAllocation *allocation) GhbCompositorChild *cc; GList *link; - widget->allocation = *allocation; + gtk_widget_set_allocation(widget, allocation); compositor = GHB_COMPOSITOR (widget); if (!gtk_widget_get_has_window(widget)) @@ -593,6 +670,90 @@ ghb_compositor_size_allocate (GtkWidget *widget, GtkAllocation *allocation) } } +#if 0 +static void showrects(cairo_region_t *region) +{ + cairo_rectangle_int_t rect; + int ii; + int count = cairo_region_num_rectangles(region); + + printf("rect count %d\n", count); + for (ii = 0; ii < count; ii++) + { + cairo_region_get_rectangle(region, ii, &rect); + printf("rect %d: %d,%d %dx%d\n", + ii, rect.x, rect.y, rect.width, rect.height); + } +} +#endif + +#if GTK_CHECK_VERSION(3, 0, 0) +static void +ghb_compositor_blend (GtkWidget *widget, cairo_t *cr) +{ + GhbCompositor *compositor = GHB_COMPOSITOR (widget); + GList *link, *draw; + cairo_region_t *region; + GtkWidget *child; + GhbCompositorChild *cc; + + if (compositor->children == NULL) return; + /* create a cairo context to draw to the window */ + + for (link = compositor->children; link != NULL; link = link->next) + { + cc = (GhbCompositorChild*)link->data; + for (draw = cc->drawables; draw != NULL; draw = draw->next) + { + GtkAllocation child_alloc; + + /* get our child */ + child = GTK_WIDGET(draw->data); + + if ( +//!gtk_cairo_should_draw_window(cr, gtk_widget_get_window(child)) || + !gtk_widget_get_visible(cc->widget) || + !gtk_widget_get_visible(child)) + continue; + + gtk_widget_get_allocation(child, &child_alloc); + cairo_save(cr); + + /* the source data is the (composited) event box */ + gdk_cairo_set_source_window(cr, gtk_widget_get_window(child), + child_alloc.x, + child_alloc.y); + + cairo_rectangle_int_t rect; + + rect.x = child_alloc.x; + rect.y = child_alloc.y; + rect.width = child_alloc.width; + rect.height = child_alloc.height; + + /* draw no more than our expose event intersects our child */ + region = cairo_region_create_rectangle(&rect); + + cairo_region_t *dregion = gdk_window_get_visible_region( + gtk_widget_get_window(child)); + cairo_region_translate(dregion, child_alloc.x, child_alloc.y); + cairo_region_intersect(region, dregion); + cairo_region_destroy(dregion); + + gdk_cairo_region(cr, region); + cairo_region_destroy(region); + cairo_clip(cr); + + /* composite, with an opacity */ + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_paint_with_alpha(cr, cc->opacity); + + cairo_restore(cr); + } + } + /* we're done */ +} +#else static void ghb_compositor_blend (GtkWidget *widget, GdkEventExpose *event) { @@ -631,6 +792,7 @@ ghb_compositor_blend (GtkWidget *widget, GdkEventExpose *event) gtk_widget_get_window(child)); gdk_region_offset(dregion, child->allocation.x, child->allocation.y); gdk_region_intersect (region, dregion); + gdk_region_destroy(dregion); gdk_cairo_region (cr, region); gdk_region_destroy(region); @@ -644,7 +806,23 @@ ghb_compositor_blend (GtkWidget *widget, GdkEventExpose *event) /* we're done */ cairo_destroy (cr); } +#endif +#if GTK_CHECK_VERSION(3, 0, 0) +static gboolean +ghb_compositor_draw(GtkWidget *widget, cairo_t *cr) +{ + if (gtk_widget_is_drawable(widget)) + { + if (gtk_widget_get_has_window(widget)) + ghb_compositor_blend (widget, cr); + + } + GTK_WIDGET_CLASS(ghb_compositor_parent_class)->draw(widget, cr); + + return FALSE; +} +#else static gboolean ghb_compositor_expose (GtkWidget *widget, GdkEventExpose *event) { @@ -659,3 +837,4 @@ ghb_compositor_expose (GtkWidget *widget, GdkEventExpose *event) return FALSE; } +#endif |