Re: Problem displaying image with alpha channel in a transparent window



Le mercredi 23 juillet 2008 à 17:42 +0200, Yann Droneaud a écrit :

> Fixed program is test-gdkpixbuf-cairo.c
> 

Error: Missing cairo_t *cr declaration.

Here is the definitive source code.

Sorry.

-- 
Yann Droneaud <ydroneaud mandriva com> 


/* test-gdkpixbuf-cairo.c - draw a RGBA image in a window using Cairo
 *
 * Yann Droneaud <ydroneaud mandriva com>
 * 
 */

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>

#include <gdk-pixbuf/gdk-pixbuf.h>

static void
realize_signal(GtkWidget *widget,
	       gpointer   data)
{
  gdk_window_set_back_pixmap(widget->window, NULL, FALSE);

  return;
}

static void
destroy_signal(GtkWidget *widget,
	       gpointer   data)
{
  gtk_main_quit();
  
  return;
}

static gboolean
button_press_event(GtkWidget *widget,
		   GdkEventButton *event,
		   gpointer data)
{
  if (event->button == 1 && (event->state & GDK_CONTROL_MASK)) {

    gtk_window_begin_move_drag(GTK_WINDOW(widget),
			       (gint) event->button,
			       (gint) event->x_root, 
			       (gint) event->y_root,
			       event->time);

    return TRUE;
  }

  return FALSE;
}

static gboolean
key_press_event(GtkWidget *widget,
		GdkEventKey *event,
		gpointer data)
{
  /* handle move if mouse button is pressed and later ctrl is hit */
  if ((event->keyval == GDK_Control_L ||
       event->keyval == GDK_Control_R) && 
      (event->state & GDK_BUTTON1_MASK)) {

    gint x;
    gint y;
    
    gdk_display_get_pointer(gdk_display_get_default(), 
			    NULL, /* screen */
			    &x,
			    &y, 
			    NULL); /* state */

    gtk_window_begin_move_drag(GTK_WINDOW(widget),
			       (gint) 1, /* first button, see mask */
			       x, 
			       y,
			       event->time);

    return TRUE;
  }

  if (event->keyval == GDK_Escape) {
    gtk_main_quit();

    return TRUE;
  }

  return FALSE; /* event not handled */
}

static gboolean
expose_event(GtkWidget *widget, 
	     GdkEventExpose *event,
	     gpointer data)
{
  GdkPixbuf *pixbuf = (GdkPixbuf *) data;
  cairo_t *cr;

  cr = gdk_cairo_create(widget->window);

  gdk_cairo_region(cr, event->region);    

  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);

  gdk_cairo_set_source_pixbuf(cr, pixbuf, 0.0, 0.0);

  cairo_paint(cr);

  cairo_destroy(cr);

  return TRUE;
}

int 
main(int   argc,
     char *argv[])
{
  GdkScreen *screen;

  GtkWidget *window;

  GdkColormap *colormap; 

  const char *color_name = NULL;
  GdkColor color;

  const char *pixbuf_name = NULL;
  GdkPixbuf *pixbuf;

  GError *error = NULL;

  gtk_init (&argc, &argv);

  if (argc > 1 && argv[1] != NULL && *argv[1] != '\0') {
    pixbuf_name = argv[1];
  }

  if (argc > 2 && argv[2] != NULL && *argv[2] != '\0') {
    color_name = argv[2];
  }

  if (pixbuf_name == NULL) {
    g_printerr("missing parameter\n");
    return 1;
  }

  /* get RGBA colormap */
  screen = gdk_screen_get_default();
  colormap = gdk_screen_get_rgba_colormap(screen);
  if (colormap == NULL) {
    g_printerr("no RGBA colormap\n");
    return 1;
  }

  /* use the RGBA colormap */
  gtk_widget_set_default_colormap(colormap);
  
  /* load the pixbuf */
  pixbuf = gdk_pixbuf_new_from_file(argv[1], &error);
  if (pixbuf == NULL) {
    g_printerr("can't load pixbuf\n");
    return 1;
  }
  
  /* check pixbuf format */
  if (gdk_pixbuf_get_has_alpha(pixbuf) != TRUE ||
      gdk_pixbuf_get_n_channels(pixbuf) != 4 ||
      gdk_pixbuf_get_bits_per_sample(pixbuf) != 8) {
    g_printerr("incorrect pixbuf format !\n");
    return 1;
  }

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_widget_set_app_paintable(window, TRUE);
  gtk_widget_set_double_buffered(window, FALSE);

  /* unneeded, see gtk_widget_set_default_colormap() */  
  gtk_widget_set_colormap(window, colormap);

  gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
  gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

  gtk_window_set_title(GTK_WINDOW(window), "simple");

  gtk_widget_set_size_request(window,
			      gdk_pixbuf_get_width(pixbuf),
			      gdk_pixbuf_get_height(pixbuf));

  if (color_name != NULL) {
    gdk_color_parse(color_name, &color);
    gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color);
  }

  g_signal_connect_after(G_OBJECT(window), "realize",
			 G_CALLBACK(realize_signal), NULL);

  g_signal_connect(G_OBJECT(window), "destroy",
		   G_CALLBACK(destroy_signal), NULL);

  g_signal_connect(G_OBJECT(window), "key_press_event",
		   G_CALLBACK(key_press_event), NULL);

  g_signal_connect(G_OBJECT(window), "button_press_event",
		   G_CALLBACK(button_press_event), NULL);

  g_signal_connect(G_OBJECT(window), "expose_event",  
		   G_CALLBACK(expose_event), pixbuf);

  gtk_widget_add_events(window,
			GDK_EXPOSURE_MASK
			| GDK_BUTTON_PRESS_MASK
			| GDK_KEY_PRESS_MASK);

  gtk_widget_show(window);
  
  gtk_main ();
  
  return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]