NoPaste

gtk alpha demo

von ren22

Dein Code:
  1. #include <gtk/gtk.h>
  2. #include <gdk/gdkscreen.h>
  3. #include <cairo.h>
  4.  
  5. /*
  6.  * This program shows you how to create semi-transparent windows,
  7.  * without any of the historical screenshot hacks. It requires
  8.  * a modern system, with a compositing manager. I use xcompmgr
  9.  * and the nvidia drivers with RenderAccel, and it works well.
  10.  *
  11.  * I'll take you through each step as we go. Minimal GTK+ knowledge is
  12.  * assumed.
  13.  *
  14.  * gcc alphademo.c -o alphademo $( pkg-config --cflags --libs gtk+-2.0 )
  15.  *
  16.  * https://web.archive.org/web/20121027002505/http://plan99.net/~mike/files/alphademo.c
  17.  */
  18.  
  19. static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer user_data);
  20. static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
  21. static void clicked(GtkWindow *win, GdkEventButton *event, gpointer user_data);
  22.  
  23. int main(int argc, char **argv)
  24. {
  25.     /* boilerplate initialization code */
  26.     gtk_init(&argc, &argv);
  27.  
  28.     GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  29.     gtk_window_set_title(GTK_WINDOW(window), "Alpha Demo");
  30.     g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL);
  31.  
  32.  
  33.     /* Tell GTK+ that we want to draw the windows background ourself.
  34.      * If we don't do this then GTK+ will clear the window to the
  35.      * opaque theme default color, which isn't what we want.
  36.      */
  37.     gtk_widget_set_app_paintable(window, TRUE);
  38.  
  39.     /* We need to handle two events ourself: "expose-event" and "screen-changed".
  40.      *
  41.      * The X server sends us an expose event when the window becomes
  42.      * visible on screen. It means we need to draw the contents.  On a
  43.      * composited desktop expose is normally only sent when the window
  44.      * is put on the screen. On a non-composited desktop it can be
  45.      * sent whenever the window is uncovered by another.
  46.      *
  47.      * The screen-changed event means the display to which we are
  48.      * drawing changed. GTK+ supports migration of running
  49.      * applications between X servers, which might not support the
  50.      * same features, so we need to check each time.
  51.      */
  52.  
  53.     g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(expose), NULL);
  54.     g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL);
  55.  
  56.     /* toggle title bar on click - we add the mask to tell X we are interested in this event */
  57.     gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
  58.     gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
  59.     g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);
  60.  
  61.     /* initialize for the current display */
  62.     screen_changed(window, NULL, NULL);
  63.  
  64.     /* Run the program */
  65.     gtk_widget_show_all(window);
  66.     gtk_main();
  67.  
  68.     return 0;
  69. }
  70.  
  71.  
  72. /* Only some X servers support alpha channels. Always have a fallback */
  73. gboolean supports_alpha = FALSE;
  74.  
  75. static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer userdata)
  76. {
  77.     /* To check if the display supports alpha channels, get the colormap */
  78.     GdkScreen *screen = gtk_widget_get_screen(widget);
  79.     GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
  80.  
  81.     if (!colormap)
  82.     {
  83.         printf("Your screen does not support alpha channels!\n");
  84.         colormap = gdk_screen_get_rgb_colormap(screen);
  85.         supports_alpha = FALSE;
  86.     }
  87.     else
  88.     {
  89.         printf("Your screen supports alpha channels!\n");
  90.         supports_alpha = TRUE;
  91.     }
  92.  
  93.     /* Now we have a colormap appropriate for the screen, use it */
  94.     gtk_widget_set_colormap(widget, colormap);
  95. }
  96.  
  97. /* This is called when we need to draw the windows contents */
  98. static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer userdata)
  99. {
  100.     cairo_t *cr = gdk_cairo_create(widget->window);
  101.  
  102.     //if (supports_alpha)
  103.     //    cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
  104.     //else
  105.     //    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
  106.  
  107.     /* draw the background */
  108.     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  109.     //cairo_paint (cr);
  110.  
  111.     /* draw a circle */
  112.     int width, height;
  113.     gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
  114.  
  115.     cairo_surface_t *img;
  116.     int imgw, imgh;
  117.     char *imgpath;
  118.  
  119.     imgpath = "./test.png";
  120.     if (imgpath == NULL) {
  121.         fprintf(stderr, "usage: see image.png\n");
  122.         exit(1);
  123.     }
  124.  
  125.     /* load image and get dimantions */
  126.     img = cairo_image_surface_create_from_png(imgpath);
  127.     if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS)
  128.         errx(1, "load image");
  129.     imgw = cairo_image_surface_get_width(img);
  130.     imgh = cairo_image_surface_get_height(img);
  131.  
  132.     gtk_window_resize(GTK_WINDOW(widget), imgw, imgh);
  133.  
  134.     cairo_set_source_surface(cr, img, 0, 0);
  135.  
  136.     cairo_paint (cr);
  137.  
  138.     cairo_destroy(cr);
  139.     return FALSE;
  140. }
  141.  
  142. static void clicked(GtkWindow *win, GdkEventButton *event, gpointer user_data)
  143. {
  144.     /* toggle window manager frames */
  145.     gtk_window_set_decorated(win, !gtk_window_get_decorated(win));
  146. }

Quellcode

Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. Alternativ kannst du den gesamten Eintrag auch als Datei herunterladen.