Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <gtk/gtk.h>
- #include <cairo.h>
- #define WINDOW_W 200
- #define WINDOW_H 200
- static cairo_surface_t *scale_surface
- ( cairo_surface_t *old_surface, gdouble new_w, gdouble new_h,
- gboolean smooth )
- {
- gint old_width = cairo_image_surface_get_width(old_surface);
- gint old_height = cairo_image_surface_get_height(old_surface);
- cairo_surface_t *new_surface = cairo_surface_create_similar
- (old_surface, CAIRO_CONTENT_COLOR_ALPHA,
- (gint)(new_w), (gint)(new_h));
- cairo_t *cr = cairo_create (new_surface);
- cairo_scale (cr, new_w/old_width, new_h/old_height);
- cairo_set_source_surface (cr, old_surface, 0, 0);
- if (!smooth)
- {
- cairo_pattern_set_filter
- (cairo_get_source(cr), CAIRO_FILTER_NEAREST);
- }
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
- cairo_destroy (cr);
- return new_surface;
- }
- /* The expose event handler for the window.
- *
- * This function performs the actual compositing of the event box onto
- * the already-existing background of the window at 70% normal opacity.
- */
- static gboolean
- window_draw_event (GtkWidget *widget,
- cairo_t *cr,
- gpointer data)
- {
- GtkWidget *child;
- /* get our child (in this case, the event box) */
- child = gtk_bin_get_child (GTK_BIN (widget));
- /* draw the background image first */
- cairo_set_source_surface
- (cr, (cairo_surface_t*)data, 0, 0);
- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
- cairo_paint(cr);
- /* now draw the event box */
- gint border_width =
- gtk_container_get_border_width(GTK_CONTAINER(widget));
- gdk_cairo_set_source_window (cr, gtk_widget_get_window(child),
- border_width,
- border_width);
- /* composite, with a 70% opacity */
- cairo_paint_with_alpha (cr, 0.7);
- /* we're done */
- return FALSE;
- }
- int
- main (int argc, char **argv)
- {
- GtkWidget *window, *event, *button1, *button2, *checkbox, *box;
- GdkScreen *screen;
- GdkRGBA transparent = { 0, 0, 0, 0 };
- gtk_init (&argc, &argv);
- cairo_surface_t *bg_image =
- cairo_image_surface_create_from_png("background.png");
- cairo_surface_t *bg_scaled_image
- = scale_surface(bg_image, WINDOW_W, WINDOW_H, TRUE);
- cairo_surface_destroy(bg_image);
- /* Make the widgets */
- button1 = gtk_button_new_with_label ("Label");
- button2 = gtk_button_new_from_stock (GTK_STOCK_ABOUT);
- checkbox = gtk_check_button_new_with_label ("Checkbox");
- box = gtk_vbox_new(FALSE, 8);
- gtk_box_pack_start(GTK_BOX(box), button1, FALSE, FALSE, 8);
- gtk_box_pack_start(GTK_BOX(box), button2, FALSE, FALSE, 8);
- gtk_box_pack_start(GTK_BOX(box), checkbox, FALSE, FALSE, 8);
- event = gtk_event_box_new ();
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- screen = gtk_widget_get_screen (event);
- gtk_widget_override_background_color(event, 0, &transparent);
- /* Put them inside one another */
- gtk_container_set_border_width (GTK_CONTAINER (window), 10);
- gtk_container_add (GTK_CONTAINER (window), event);
- gtk_container_add (GTK_CONTAINER (event), box);
- /* Since rescaling the background is expensive, you better fix the widget size */
- gtk_widget_set_size_request(window, WINDOW_W, WINDOW_H);
- gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
- /* Realise and show everything */
- gtk_widget_show_all (window);
- /* Set the event box GdkWindow to be composited.
- * Obviously must be performed after event box is realised.
- */
- gdk_window_set_composited (gtk_widget_get_window(event), TRUE);
- /* Set up the compositing handler.
- * Note that we do _after_ so that the normal (red) background is drawn
- * by gtk before our compositing occurs.
- */
- g_signal_connect_after (window, "draw",
- G_CALLBACK (window_draw_event), bg_scaled_image);
- g_signal_connect_swapped(G_OBJECT(window), "destroy",
- G_CALLBACK(gtk_main_quit), G_OBJECT(window));
- gtk_main ();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement