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);
x = widget_x;
y = widget_y;
- if (offscreen_box->child1 && GTK_WIDGET_VISIBLE (offscreen_box->child1))
- y -= offscreen_box->child1->allocation.height;
+ if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1))
+ {
+ 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;
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;
x += child_area.width / 2;
y += child_area.height / 2;
- if (offscreen_box->child1 && GTK_WIDGET_VISIBLE (offscreen_box->child1))
- y += offscreen_box->child1->allocation.height;
+ if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1))
+ {
+ gtk_widget_get_allocation (offscreen_box->child1, &child_area);
+ y += child_area.height;
+ }
*x_out = x;
*y_out = y;
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,
static void
gtk_offscreen_box_init (GtkOffscreenBox *offscreen_box)
{
- GTK_WIDGET_UNSET_FLAGS (offscreen_box, GTK_NO_WINDOW);
+ gtk_widget_set_has_window (GTK_WIDGET (offscreen_box), TRUE);
}
GtkWidget *
/* First check for child 2 */
if (offscreen_box->child2 &&
- GTK_WIDGET_VISIBLE (offscreen_box->child2))
+ gtk_widget_get_visible (offscreen_box->child2))
{
to_child_2 (offscreen_box,
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)
return offscreen_box->offscreen_window2;
}
- if (offscreen_box->child1 && GTK_WIDGET_VISIBLE (offscreen_box->child1))
+ if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1))
{
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)
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;
- gint border_width;
+ guint border_width;
GtkRequisition child_requisition;
int start_y = 0;
- GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+ gtk_widget_set_realized (widget, TRUE);
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
- border_width = GTK_CONTAINER (widget)->border_width;
+ gtk_widget_get_allocation (widget, &allocation);
- 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;
+ 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
| 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;
/* Child 1 */
attributes.x = attributes.y = 0;
- if (offscreen_box->child1 && GTK_WIDGET_VISIBLE (offscreen_box->child1))
+ 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);
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",
/* Child 2 */
attributes.y = start_y;
child_requisition.width = child_requisition.height = 0;
- if (offscreen_box->child2 && GTK_WIDGET_VISIBLE (offscreen_box->child2))
+ 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);
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);
GtkOffscreenBox *offscreen_box = GTK_OFFSCREEN_BOX (container);
gboolean was_visible;
- was_visible = GTK_WIDGET_VISIBLE (widget);
+ was_visible = gtk_widget_get_visible (widget);
if (offscreen_box->child1 == widget)
{
offscreen_box->child1 = NULL;
- if (was_visible && GTK_WIDGET_VISIBLE (container))
+ if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
gtk_widget_queue_resize (GTK_WIDGET (container));
}
else if (offscreen_box->child2 == widget)
offscreen_box->child2 = NULL;
- if (was_visible && GTK_WIDGET_VISIBLE (container))
+ if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
gtk_widget_queue_resize (GTK_WIDGET (container));
}
}
{
GtkOffscreenBox *offscreen_box = GTK_OFFSCREEN_BOX (widget);
int w, h;
+ guint border_width;
w = 0;
h = 0;
- if (offscreen_box->child1 && GTK_WIDGET_VISIBLE (offscreen_box->child1))
+ if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1))
{
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;
}
- if (offscreen_box->child2 && GTK_WIDGET_VISIBLE (offscreen_box->child2))
+ if (offscreen_box->child2 && gtk_widget_get_visible (offscreen_box->child2))
{
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;
}
- requisition->width = GTK_CONTAINER (widget)->border_width * 2 + w;
- requisition->height = GTK_CONTAINER (widget)->border_width * 2 + h;
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+ requisition->width = border_width * 2 + w;
+ 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
GtkAllocation *allocation)
{
GtkOffscreenBox *offscreen_box;
- gint border_width;
gint start_y;
+ guint border_width;
- widget->allocation = *allocation;
offscreen_box = GTK_OFFSCREEN_BOX (widget);
- border_width = GTK_CONTAINER (widget)->border_width;
+ gtk_widget_set_allocation (widget, allocation);
- if (GTK_WIDGET_REALIZED (widget))
- gdk_window_move_resize (widget->window,
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (gtk_widget_get_window (widget),
allocation->x + border_width,
allocation->y + border_width,
allocation->width - border_width * 2,
start_y = 0;
- if (offscreen_box->child1 && GTK_WIDGET_VISIBLE (offscreen_box->child1))
+ if (offscreen_box->child1 && gtk_widget_get_visible (offscreen_box->child1))
{
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;
- if (GTK_WIDGET_REALIZED (widget))
+ if (gtk_widget_get_realized (widget))
gdk_window_move_resize (offscreen_box->offscreen_window1,
child_allocation.x,
child_allocation.y,
gtk_widget_size_allocate (offscreen_box->child1, &child_allocation);
}
- if (offscreen_box->child2 && GTK_WIDGET_VISIBLE (offscreen_box->child2))
+ if (offscreen_box->child2 && gtk_widget_get_visible (offscreen_box->child2))
{
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;
- if (GTK_WIDGET_REALIZED (widget))
+ if (gtk_widget_get_realized (widget))
gdk_window_move_resize (offscreen_box->offscreen_window2,
child_allocation.x,
child_allocation.y,
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_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_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;