X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=tests%2Fgtkoffscreenbox.c;h=7aeb82cdfd397931dfee78f0bb742c790b4b3e04;hb=a6d741b6a46f78e4a71cdcaf8cd42ce19846dba8;hp=71b36db43c9199e9e1cdd194ed84a00b243828dd;hpb=3a10216dd01c8d10df235b88c8942b2fda15689b;p=~andy%2Fgtk diff --git a/tests/gtkoffscreenbox.c b/tests/gtkoffscreenbox.c index 71b36db43..7aeb82cdf 100644 --- a/tests/gtkoffscreenbox.c +++ b/tests/gtkoffscreenbox.c @@ -11,14 +11,18 @@ static void gtk_offscreen_box_realize (GtkWidget *widget); static void gtk_offscreen_box_unrealize (GtkWidget *widget); -static void gtk_offscreen_box_size_request (GtkWidget *widget, - GtkRequisition *requisition); +static void gtk_offscreen_box_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural); +static void gtk_offscreen_box_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural); static void gtk_offscreen_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static gboolean gtk_offscreen_box_damage (GtkWidget *widget, GdkEventExpose *event); -static gboolean gtk_offscreen_box_expose (GtkWidget *widget, - GdkEventExpose *offscreen); +static gboolean gtk_offscreen_box_draw (GtkWidget *widget, + cairo_t *cr); static void gtk_offscreen_box_add (GtkContainer *container, GtkWidget *child); @@ -48,9 +52,12 @@ to_child_2 (GtkOffscreenBox *offscreen_box, y = widget_y; if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1)) - y -= offscreen_box->child1->allocation.height; + { + gtk_widget_get_allocation (offscreen_box->child1, &child_area); + y -= child_area.height; + } - child_area = offscreen_box->child2->allocation; + gtk_widget_get_allocation (offscreen_box->child2, &child_area); x -= child_area.width / 2; y -= child_area.height / 2; @@ -79,7 +86,7 @@ to_parent_2 (GtkOffscreenBox *offscreen_box, double x, y, xr, yr; double cos_angle, sin_angle; - child_area = offscreen_box->child2->allocation; + gtk_widget_get_allocation (offscreen_box->child2, &child_area); x = offscreen_x; y = offscreen_y; @@ -99,7 +106,10 @@ to_parent_2 (GtkOffscreenBox *offscreen_box, y += child_area.height / 2; if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1)) - y += offscreen_box->child1->allocation.height; + { + gtk_widget_get_allocation (offscreen_box->child1, &child_area); + y += child_area.height; + } *x_out = x; *y_out = y; @@ -113,9 +123,10 @@ gtk_offscreen_box_class_init (GtkOffscreenBoxClass *klass) widget_class->realize = gtk_offscreen_box_realize; widget_class->unrealize = gtk_offscreen_box_unrealize; - widget_class->size_request = gtk_offscreen_box_size_request; + widget_class->get_preferred_width = gtk_offscreen_box_get_preferred_width; + widget_class->get_preferred_height = gtk_offscreen_box_get_preferred_height; widget_class->size_allocate = gtk_offscreen_box_size_allocate; - widget_class->expose_event = gtk_offscreen_box_expose; + widget_class->draw = gtk_offscreen_box_draw; g_signal_override_class_closure (g_signal_lookup ("damage-event", GTK_TYPE_WIDGET), GTK_TYPE_OFFSCREEN_BOX, @@ -156,7 +167,7 @@ pick_offscreen_child (GdkWindow *offscreen_window, widget_x, widget_y, &x, &y); - child_area = offscreen_box->child2->allocation; + gtk_widget_get_allocation (offscreen_box->child2, &child_area); if (x >= 0 && x < child_area.width && y >= 0 && y < child_area.height) @@ -168,7 +179,7 @@ pick_offscreen_child (GdkWindow *offscreen_window, x = widget_x; y = widget_y; - child_area = offscreen_box->child1->allocation; + gtk_widget_get_allocation (offscreen_box->child1, &child_area); if (x >= 0 && x < child_area.width && y >= 0 && y < child_area.height) @@ -228,10 +239,21 @@ offscreen_window_from_parent2 (GdkWindow *window, 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 gtk_offscreen_box_realize (GtkWidget *widget) { GtkOffscreenBox *offscreen_box = GTK_OFFSCREEN_BOX (widget); + GtkAllocation allocation, child_area; + GtkStyleContext *context; + GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; guint border_width; @@ -242,10 +264,12 @@ gtk_offscreen_box_realize (GtkWidget *widget) border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); - attributes.x = widget->allocation.x + border_width; - attributes.y = widget->allocation.y + border_width; - attributes.width = widget->allocation.width - 2 * border_width; - attributes.height = widget->allocation.height - 2 * border_width; + gtk_widget_get_allocation (widget, &allocation); + + attributes.x = allocation.x + border_width; + attributes.y = allocation.y + border_width; + attributes.width = allocation.width - 2 * border_width; + attributes.height = allocation.height - 2 * border_width; attributes.window_type = GDK_WINDOW_CHILD; attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK @@ -257,16 +281,16 @@ gtk_offscreen_box_realize (GtkWidget *widget) | GDK_LEAVE_NOTIFY_MASK; attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); attributes.wclass = GDK_INPUT_OUTPUT; - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); + 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 (widget->window, "pick-embedded-child", + g_signal_connect (window, "pick-embedded-child", G_CALLBACK (pick_offscreen_child), offscreen_box); attributes.window_type = GDK_WINDOW_OFFSCREEN; @@ -275,9 +299,11 @@ gtk_offscreen_box_realize (GtkWidget *widget) attributes.x = attributes.y = 0; if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1)) { - attributes.width = offscreen_box->child1->allocation.width; - attributes.height = offscreen_box->child1->allocation.height; - start_y += offscreen_box->child1->allocation.height; + gtk_widget_get_allocation (offscreen_box->child1, &child_area); + + attributes.width = child_area.width; + attributes.height = child_area.height; + start_y += child_area.height; } offscreen_box->offscreen_window1 = gdk_window_new (gtk_widget_get_root_window (widget), &attributes, attributes_mask); @@ -286,8 +312,8 @@ gtk_offscreen_box_realize (GtkWidget *widget) gtk_widget_set_parent_window (offscreen_box->child1, offscreen_box->offscreen_window1); gdk_offscreen_window_set_embedder (offscreen_box->offscreen_window1, - widget->window); - + window); + g_signal_connect (offscreen_box->offscreen_window1, "to-embedder", G_CALLBACK (offscreen_window_to_parent1), offscreen_box); g_signal_connect (offscreen_box->offscreen_window1, "from-embedder", @@ -298,8 +324,10 @@ gtk_offscreen_box_realize (GtkWidget *widget) child_requisition.width = child_requisition.height = 0; if (offscreen_box->child2 && gtk_widget_get_visible (offscreen_box->child2)) { - attributes.width = offscreen_box->child2->allocation.width; - attributes.height = offscreen_box->child2->allocation.height; + gtk_widget_get_allocation (offscreen_box->child2, &child_area); + + attributes.width = child_area.width; + attributes.height = child_area.height; } offscreen_box->offscreen_window2 = gdk_window_new (gtk_widget_get_root_window (widget), &attributes, attributes_mask); @@ -307,17 +335,20 @@ gtk_offscreen_box_realize (GtkWidget *widget) if (offscreen_box->child2) gtk_widget_set_parent_window (offscreen_box->child2, offscreen_box->offscreen_window2); gdk_offscreen_window_set_embedder (offscreen_box->offscreen_window2, - widget->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_CALLBACK (offscreen_window_to_parent2), offscreen_box); g_signal_connect (offscreen_box->offscreen_window2, "from-embedder", G_CALLBACK (offscreen_window_from_parent2), offscreen_box); - widget->style = gtk_style_attach (widget->style, widget->window); - - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); - gtk_style_set_background (widget->style, offscreen_box->offscreen_window1, GTK_STATE_NORMAL); - gtk_style_set_background (widget->style, offscreen_box->offscreen_window2, GTK_STATE_NORMAL); + context = gtk_widget_get_style_context (widget); + gtk_style_context_set_background (context, window); + gtk_style_context_set_background (context, offscreen_box->offscreen_window1); + gtk_style_context_set_background (context, offscreen_box->offscreen_window2); gdk_window_show (offscreen_box->offscreen_window1); gdk_window_show (offscreen_box->offscreen_window2); @@ -467,7 +498,8 @@ gtk_offscreen_box_size_request (GtkWidget *widget, { GtkRequisition child_requisition; - gtk_widget_size_request (offscreen_box->child1, &child_requisition); + gtk_widget_get_preferred_size ( (offscreen_box->child1), + &child_requisition, NULL); w = MAX (w, CHILD1_SIZE_SCALE * child_requisition.width); h += CHILD1_SIZE_SCALE * child_requisition.height; @@ -477,7 +509,8 @@ gtk_offscreen_box_size_request (GtkWidget *widget, { GtkRequisition child_requisition; - gtk_widget_size_request (offscreen_box->child2, &child_requisition); + gtk_widget_get_preferred_size ( (offscreen_box->child2), + &child_requisition, NULL); w = MAX (w, CHILD2_SIZE_SCALE * child_requisition.width); h += CHILD2_SIZE_SCALE * child_requisition.height; @@ -488,6 +521,30 @@ gtk_offscreen_box_size_request (GtkWidget *widget, requisition->height = border_width * 2 + h; } +static void +gtk_offscreen_box_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkRequisition requisition; + + gtk_offscreen_box_size_request (widget, &requisition); + + *minimum = *natural = requisition.width; +} + +static void +gtk_offscreen_box_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkRequisition requisition; + + gtk_offscreen_box_size_request (widget, &requisition); + + *minimum = *natural = requisition.height; +} + static void gtk_offscreen_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -496,13 +553,14 @@ gtk_offscreen_box_size_allocate (GtkWidget *widget, gint start_y; guint border_width; - widget->allocation = *allocation; offscreen_box = GTK_OFFSCREEN_BOX (widget); + gtk_widget_set_allocation (widget, allocation); + border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); if (gtk_widget_get_realized (widget)) - gdk_window_move_resize (widget->window, + gdk_window_move_resize (gtk_widget_get_window (widget), allocation->x + border_width, allocation->y + border_width, allocation->width - border_width * 2, @@ -515,10 +573,11 @@ gtk_offscreen_box_size_allocate (GtkWidget *widget, GtkRequisition child_requisition; GtkAllocation child_allocation; - gtk_widget_get_child_requisition (offscreen_box->child1, &child_requisition); + gtk_widget_get_preferred_size (offscreen_box->child1, + &child_requisition, NULL); child_allocation.x = child_requisition.width * (CHILD1_SIZE_SCALE - 1.0) / 2; child_allocation.y = start_y + child_requisition.height * (CHILD1_SIZE_SCALE - 1.0) / 2; - child_allocation.width = MAX (1, (gint) widget->allocation.width - 2 * border_width); + child_allocation.width = MAX (1, (gint) allocation->width - 2 * border_width); child_allocation.height = child_requisition.height; start_y += CHILD1_SIZE_SCALE * child_requisition.height; @@ -539,10 +598,11 @@ gtk_offscreen_box_size_allocate (GtkWidget *widget, GtkRequisition child_requisition; GtkAllocation child_allocation; - gtk_widget_get_child_requisition (offscreen_box->child2, &child_requisition); + gtk_widget_get_preferred_size (offscreen_box->child2, + &child_requisition, NULL); child_allocation.x = child_requisition.width * (CHILD2_SIZE_SCALE - 1.0) / 2; child_allocation.y = start_y + child_requisition.height * (CHILD2_SIZE_SCALE - 1.0) / 2; - child_allocation.width = MAX (1, (gint) widget->allocation.width - 2 * border_width); + child_allocation.width = MAX (1, (gint) allocation->width - 2 * border_width); child_allocation.height = child_requisition.height; start_y += CHILD2_SIZE_SCALE * child_requisition.height; @@ -563,92 +623,76 @@ static gboolean gtk_offscreen_box_damage (GtkWidget *widget, GdkEventExpose *event) { - gdk_window_invalidate_rect (widget->window, NULL, FALSE); + gdk_window_invalidate_rect (gtk_widget_get_window (widget), + NULL, FALSE); return TRUE; } static gboolean -gtk_offscreen_box_expose (GtkWidget *widget, - GdkEventExpose *event) +gtk_offscreen_box_draw (GtkWidget *widget, + cairo_t *cr) { GtkOffscreenBox *offscreen_box = GTK_OFFSCREEN_BOX (widget); + GdkWindow *window; + + window = gtk_widget_get_window (widget); + if (gtk_cairo_should_draw_window (cr, window)) + { + cairo_surface_t *surface; + GtkAllocation child_area; + + if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1)) + { + surface = gdk_offscreen_window_get_surface (offscreen_box->offscreen_window1); + + cairo_set_source_surface (cr, surface, 0, 0); + cairo_paint (cr); - if (gtk_widget_is_drawable (widget)) + gtk_widget_get_allocation (offscreen_box->child1, &child_area); + cairo_translate (cr, 0, child_area.height); + } + + if (offscreen_box->child2 && gtk_widget_get_visible (offscreen_box->child2)) + { + surface = gdk_offscreen_window_get_surface (offscreen_box->offscreen_window2); + + gtk_widget_get_allocation (offscreen_box->child2, &child_area); + + /* transform */ + cairo_translate (cr, child_area.width / 2, child_area.height / 2); + cairo_rotate (cr, offscreen_box->angle); + cairo_translate (cr, -child_area.width / 2, -child_area.height / 2); + + /* paint */ + cairo_set_source_surface (cr, surface, 0, 0); + cairo_paint (cr); + } + } + else if (gtk_cairo_should_draw_window (cr, offscreen_box->offscreen_window1)) + { + gtk_render_background (gtk_widget_get_style_context (widget), cr, + 0, 0, + + gdk_window_get_width (offscreen_box->offscreen_window1), + gdk_window_get_height (offscreen_box->offscreen_window1)); + + if (offscreen_box->child1) + gtk_container_propagate_draw (GTK_CONTAINER (widget), + offscreen_box->child1, + cr); + } + else if (gtk_cairo_should_draw_window (cr, offscreen_box->offscreen_window2)) { - if (event->window == widget->window) - { - GdkPixmap *pixmap; - GtkAllocation child_area; - cairo_t *cr; - int start_y = 0; - - if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1)) - { - pixmap = gdk_offscreen_window_get_pixmap (offscreen_box->offscreen_window1); - child_area = offscreen_box->child1->allocation; - - cr = gdk_cairo_create (widget->window); - - gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0); - cairo_paint (cr); - - cairo_destroy (cr); - - start_y += child_area.height; - } - - if (offscreen_box->child2 && gtk_widget_get_visible (offscreen_box->child2)) - { - gint w, h; - - pixmap = gdk_offscreen_window_get_pixmap (offscreen_box->offscreen_window2); - child_area = offscreen_box->child2->allocation; - - cr = gdk_cairo_create (widget->window); - - /* transform */ - cairo_translate (cr, 0, start_y); - cairo_translate (cr, child_area.width / 2, child_area.height / 2); - cairo_rotate (cr, offscreen_box->angle); - cairo_translate (cr, -child_area.width / 2, -child_area.height / 2); - - /* clip */ - gdk_drawable_get_size (pixmap, &w, &h); - cairo_rectangle (cr, 0, 0, w, h); - cairo_clip (cr); - - /* paint */ - gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0); - cairo_paint (cr); - - cairo_destroy (cr); - } - } - else if (event->window == offscreen_box->offscreen_window1) - { - gtk_paint_flat_box (widget->style, event->window, - GTK_STATE_NORMAL, GTK_SHADOW_NONE, - &event->area, widget, "blah", - 0, 0, -1, -1); - - if (offscreen_box->child1) - gtk_container_propagate_expose (GTK_CONTAINER (widget), - offscreen_box->child1, - event); - } - else if (event->window == offscreen_box->offscreen_window2) - { - gtk_paint_flat_box (widget->style, event->window, - GTK_STATE_NORMAL, GTK_SHADOW_NONE, - &event->area, widget, "blah", - 0, 0, -1, -1); - - if (offscreen_box->child2) - gtk_container_propagate_expose (GTK_CONTAINER (widget), - offscreen_box->child2, - event); - } + gtk_render_background (gtk_widget_get_style_context (widget), cr, + 0, 0, + gdk_window_get_width (offscreen_box->offscreen_window2), + gdk_window_get_height (offscreen_box->offscreen_window2)); + + if (offscreen_box->child2) + gtk_container_propagate_draw (GTK_CONTAINER (widget), + offscreen_box->child2, + cr); } return FALSE;