Re: GdkPixmap and GdkPixbuf




Well, I can't see why this variant crashes -- so I compiled
it and run under valgrind, and it didn't crash and valgrind
even didn't print any (relevant) error.  If other image
formats crash too for you, you probably have to use debugger
to find out what's going on...


OK, lets start from the beginning.

I tried it running it in two computers. One running centrino processor
with 512MB of memory and the other is an AthlonXP with 512 MB too. I
am using in both gtk+-2.6.7 with the latest glib.

I compiled the c file (find the source code in the end of the message) with:
 $ gcc -g -o canvas canvas2.c `pkg-config gtk+-2.0 --cflags --libs`
`pkg-config gdk-2.0 --cflags --libs` `pkg-config gdk-pixbuf-2.0
--cflags --libs` `pkg-config gdk-pixbuf-xlib-2.0 --cflags --libs`
`pkg-config gdk-x11-2.0 --cflags --libs` `pkg-config gtk+-x11-2.0
--cflags --libs`

with no complains. Although even the "simple" 
$ gcc -g -o canvas canvas2.c `pkg-config gtk+-2.0 --cflags --libs`
compiles fine.

The output of
$ valgrind --tool=memcheck --leak-check=yes ./canvas
is:

==6451== Memcheck, a memory error detector for x86-linux.
==6451== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==6451== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==6451== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==6451== For more details, rerun with: -v
==6451==
==6451== Syscall param write(buf) contains uninitialised or
unaddressable byte(s)
==6451==    at 0x9BD2D3: __write_nocancel (in /lib/tls/libc-2.3.5.so)
==6451==    by 0xAAE312: _X11TransWrite (in /usr/X11R6/lib/libX11.so.6.2)
==6451==    by 0xA923F2: (within /usr/X11R6/lib/libX11.so.6.2)
==6451==    by 0xA9247A: _XReply (in /usr/X11R6/lib/libX11.so.6.2)
==6451==  Address 0x1BDCD0A8 is 128 bytes inside a block of size 16384 alloc'd
==6451==    at 0x1B90640D: calloc (vg_replace_malloc.c:176)
==6451==    by 0xA82835: XOpenDisplay (in /usr/X11R6/lib/libX11.so.6.2)
==6451==    by 0x1BBC7213: IA__gdk_display_open (gdkdisplay-x11.c:165)
==6451==    by 0x1BBAB548: IA__gdk_display_open_default_libgtk_only (gdk.c:272)
configure_event
==6451==
==6451== Syscall param write(buf) contains uninitialised or
unaddressable byte(s)
==6451==    at 0x9BD2D3: __write_nocancel (in /lib/tls/libc-2.3.5.so)
==6451==    by 0xAAE312: _X11TransWrite (in /usr/X11R6/lib/libX11.so.6.2)
==6451==    by 0xA923F2: (within /usr/X11R6/lib/libX11.so.6.2)
==6451==    by 0xA9366D: _XEventsQueued (in /usr/X11R6/lib/libX11.so.6.2)
==6451==  Address 0x1BDCD678 is 1616 bytes inside a block of size 16384 alloc'd
==6451==    at 0x1B90640D: calloc (vg_replace_malloc.c:176)
==6451==    by 0xA82835: XOpenDisplay (in /usr/X11R6/lib/libX11.so.6.2)
==6451==    by 0x1BBC7213: IA__gdk_display_open (gdkdisplay-x11.c:165)
==6451==    by 0x1BBAB548: IA__gdk_display_open_default_libgtk_only (gdk.c:272)
expose_event
===========
Saving image...
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1BC2F701: collect_save_options (gdk-pixbuf-io.c:1318)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==    by 0x1BCB9F72: IA__g_cclosure_marshal_VOID__VOID (gmarshal.c:77)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1BD0E8B8: IA__g_strdup (gstrfuncs.c:88)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==
==6451== Use of uninitialised value of size 4
==6451==    at 0x1BD0E8C5: IA__g_strdup (gstrfuncs.c:90)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B9056BE: memcpy (mac_replace_strmem.c:81)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B905728: memcpy (mac_replace_strmem.c:84)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B9056CA: memcpy (mac_replace_strmem.c:69)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B9056D3: memcpy (mac_replace_strmem.c:281)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B905730: memcpy (mac_replace_strmem.c:294)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Use of uninitialised value of size 4
==6451==    at 0x1B90573C: memcpy (mac_replace_strmem.c:298)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1BD0E8B8: IA__g_strdup (gstrfuncs.c:88)
==6451==    by 0x1BC2F763: collect_save_options (gdk-pixbuf-io.c:1313)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==
==6451== Use of uninitialised value of size 4
==6451==    at 0x1BD0E8C5: IA__g_strdup (gstrfuncs.c:90)
==6451==    by 0x1BC2F763: collect_save_options (gdk-pixbuf-io.c:1313)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B9056BE: memcpy (mac_replace_strmem.c:81)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F763: collect_save_options (gdk-pixbuf-io.c:1313)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B9056CA: memcpy (mac_replace_strmem.c:69)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F763: collect_save_options (gdk-pixbuf-io.c:1313)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1B9056D3: memcpy (mac_replace_strmem.c:281)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F763: collect_save_options (gdk-pixbuf-io.c:1313)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Use of uninitialised value of size 4
==6451==    at 0x1B905708: memcpy (mac_replace_strmem.c:292)
==6451==    by 0x1BD0E8E2: IA__g_strdup (gstrfuncs.c:92)
==6451==    by 0x1BC2F763: collect_save_options (gdk-pixbuf-io.c:1313)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1BC2F795: collect_save_options (gdk-pixbuf-io.c:1318)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==    by 0x1BCB9F72: IA__g_cclosure_marshal_VOID__VOID (gmarshal.c:77)
==6451==
==6451== Conditional jump or move depends on uninitialised value(s)
==6451==    at 0x1BD0E8C5: IA__g_strdup (gstrfuncs.c:90)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==
==6451== Invalid read of size 1
==6451==    at 0x1BD0E8C5: IA__g_strdup (gstrfuncs.c:90)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==  Address 0x258 is not stack'd, malloc'd or (recently) free'd
==6451==
==6451== Process terminating with default action of signal 11 (SIGSEGV)
==6451==  Access not within mapped region at address 0x258
==6451==    at 0x1BD0E8C5: IA__g_strdup (gstrfuncs.c:90)
==6451==    by 0x1BC2F74E: collect_save_options (gdk-pixbuf-io.c:1312)
==6451==    by 0x1BC2FAE8: IA__gdk_pixbuf_save (gdk-pixbuf-io.c:1587)
==6451==    by 0x8048DE9: save_image (canvas2.c:19)
==6451==
==6451== ERROR SUMMARY: 54 errors from 20 contexts (suppressed: 61 from 2)
==6451== malloc/free: in use at exit: 2320289 bytes in 37570 blocks.
==6451== malloc/free: 164136 allocs, 126566 frees, 9704888 bytes allocated.
==6451== For a detailed leak analysis,  rerun with: --leak-check=yes
==6451== For counts of detected errors, rerun with: -v
Segmentation fault


and the source file once more is:
#include <gtk/gtk.h>
#include <gdk/gdk.h>


/* Backing pixmap for drawing area */
static GdkPixmap *pixmap = NULL;


static void
save_image(GtkWidget* widget, gpointer user_data)
{
  GtkRequisition canvasSize;
  GdkPixbuf* pixbuf=NULL;

  g_print("Saving image...\n");
  
  gtk_widget_size_request(GTK_WIDGET(user_data), &canvasSize);
  pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(pixmap),
GDK_COLORSPACE_RGB, 0, 0, 0, 0, canvasSize.width, canvasSize.height);
  gdk_pixbuf_save(pixbuf, "tempo", "bmp", NULL);
  g_object_unref(pixbuf);
}


/* Draw a rectangle on the screen */
static void
draw_brush (GtkWidget *widget, gdouble x, gdouble y)
{
  g_print("draw_brush\n");

  GdkRectangle update_rect;

  update_rect.x = x - 5;
  update_rect.y = y - 5;
  update_rect.width = 10;
  update_rect.height = 10;
  gdk_draw_rectangle (pixmap,
                      widget->style->black_gc,
                      TRUE,
                      update_rect.x, update_rect.y,
                      update_rect.width, update_rect.height);
  gtk_widget_queue_draw_area (widget,                 
                              update_rect.x, update_rect.y,
                              update_rect.width, update_rect.height);

}


/* Redraw the screen from the backing pixmap */
static gboolean
expose_event( GtkWidget *widget, GdkEventExpose *event )
{
  g_print("expose_event\n");

  gdk_draw_drawable(widget->window,
                    widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                    pixmap,
                    event->area.x, event->area.y,
                    event->area.x, event->area.y,
                    event->area.width, event->area.height);

  return FALSE;
}




/* Create a new backing pixmap of the appropriate size */
static gboolean
configure_event( GtkWidget *widget, GdkEventConfigure *event )
{
  g_print("configure_event\n");

  if (pixmap)
    g_object_unref(pixmap);

  pixmap = gdk_pixmap_new(widget->window,
                          widget->allocation.width,
                          widget->allocation.height,
                          -1);
  gdk_draw_rectangle (pixmap,
                      widget->style->white_gc,
                      TRUE,
                      0, 0,
                      widget->allocation.width,
                      widget->allocation.height);

  return TRUE;
}


static gboolean
button_press_event( GtkWidget *widget, GdkEventButton *event )
{
  g_print("button_press_event\n");

  if (event->button == 1 && pixmap != NULL)
      draw_brush (widget, event->x, event->y);

  return TRUE;
}

static gboolean
motion_notify_event( GtkWidget *widget, GdkEventMotion *event )
{
  int x, y;
  GdkModifierType state;

  g_print("motion_notify_event\n");

  if (event->is_hint)
    gdk_window_get_pointer (event->window, &x, &y, &state);
  else
    {
      x = event->x;
      y = event->y;
      state = event->state;
    }
    
  if (state & GDK_BUTTON1_MASK && pixmap != NULL)
    draw_brush (widget, x, y);

  return TRUE;
}


int
main(int argc, char *argv[])
{
  GtkWidget* main;
  GtkWidget* drawing_area;
  GtkWidget* vbox1;
  GtkWidget* buttonSave;

  gtk_set_locale ();
  gtk_init (&argc, &argv);
  
  main = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(main), "Drawing area");
  
  vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox1);
  gtk_container_add (GTK_CONTAINER (main), vbox1);
  
  drawing_area = gtk_drawing_area_new();
  gtk_widget_set_size_request(GTK_WIDGET(drawing_area), 600, 400);
  gtk_box_pack_start (GTK_BOX (vbox1), drawing_area, TRUE, TRUE, 0);
  
  buttonSave = gtk_button_new_from_stock ("gtk-save");
  gtk_box_pack_start (GTK_BOX (vbox1), buttonSave, FALSE, FALSE, 0);

  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
                      (GtkSignalFunc) expose_event, NULL);
  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
                      (GtkSignalFunc) configure_event, NULL);
  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
                      (GtkSignalFunc) motion_notify_event, NULL);
  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
                      (GtkSignalFunc) button_press_event, NULL);
  gtk_signal_connect (GTK_OBJECT (buttonSave), "clicked",
                      (GtkSignalFunc) save_image, drawing_area);

  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
                         | GDK_LEAVE_NOTIFY_MASK
                         | GDK_BUTTON_PRESS_MASK
                         | GDK_POINTER_MOTION_MASK
                         | GDK_POINTER_MOTION_HINT_MASK);

  gtk_widget_show(vbox1);
  gtk_widget_show(drawing_area);
  gtk_widget_show(buttonSave);
  gtk_widget_show(main);
  gtk_main();
  return 0;
}


Can someone please give me a hand, as I have no clue what is going on.
If more information is needed please ask me, but I am not familiar
with valgrind.

Cheers



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