Getting cryptic error message:
authorMarijn van Vliet <marijn.vanvliet@med.kuleuven.be>
Fri, 29 Jan 2010 21:13:34 +0000 (21:13 +0000)
committerMarijn van Vliet <marijn.vanvliet@med.kuleuven.be>
Fri, 29 Jan 2010 21:13:34 +0000 (21:13 +0000)
lt-chimara: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0
why??

git-svn-id: http://lassie.dyndns-server.com/svn/gargoyle-gtk@218 ddfedd41-794f-dd11-ae45-00112f111e67

libchimara/graphics.c

index f94b90c8616fa81699ad42aefd3e5b0e5e676b06..fda5ad6847026dbd8d25de3e0749b3ad34e4b56b 100644 (file)
@@ -6,8 +6,10 @@
 
 extern GPrivate *glk_data_key;
 void on_size_prepared(GdkPixbufLoader *loader, gint width, gint height, struct image_info *info);
+void on_pixbuf_closed(GdkPixbufLoader *loader, gpointer data);
 
 static gboolean size_determined;
+static gboolean image_loaded;
 
 glui32
 glk_image_get_info(glui32 image, glui32 *width, glui32 *height)
@@ -61,11 +63,12 @@ glk_image_get_info(glui32 image, glui32 *width, glui32 *height)
        g_free(buffer);
 
        /* Determine the image dimensions */
-       if(!size_determined) {
-               WARNING("Cannot read image size");
-               g_free(info);
-               return FALSE;
+       g_mutex_lock(glk_data->resource_lock);
+       while(!size_determined) {
+               /* Wait for the PixbufLoader to finish reading the image size */
+               g_cond_wait(glk_data->resource_info_available, glk_data->resource_lock);
        }
+       g_mutex_unlock(glk_data->resource_lock);
 
        if(width != NULL)
                *width = info->width;
@@ -79,52 +82,21 @@ glk_image_get_info(glui32 image, glui32 *width, glui32 *height)
 void
 on_size_prepared(GdkPixbufLoader *loader, gint width, gint height, struct image_info *info)
 {
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
+       g_mutex_lock(glk_data->resource_lock);
        info->width = width;
        info->height = height;
        size_determined = TRUE;
-}
-
-/*** Called when the graphics window is resized. Resize the backing pixmap if necessary ***/
-void
-on_graphics_size_allocate(GtkWidget *widget, GtkAllocation *allocation, winid_t win)
-{
-       printf("allocate to: %dx%d\n", allocation->width, allocation->height);
-       GdkPixmap *oldmap;
-       gtk_image_get_pixmap( GTK_IMAGE(widget), &oldmap, NULL );
-       gint oldwidth = 0;
-       gint oldheight = 0;
-       /* Determine whether a pixmap exists with the correct size */
-       gboolean needs_resize = FALSE;
-       if(oldmap == NULL)
-               needs_resize = TRUE;
-       else {
-               gdk_drawable_get_size( GDK_DRAWABLE(oldmap), &oldwidth, &oldheight );
-               if(oldwidth != allocation->width || oldheight != allocation->height)
-                       needs_resize = TRUE;
-       }
-
-       if(needs_resize) {
-               printf("needs resize\n");
-               /* Create a new pixmap */
-               GdkPixmap *newmap = gdk_pixmap_new(widget->window, allocation->width, allocation->height, -1);
-               gdk_draw_rectangle( GDK_DRAWABLE(newmap), widget->style->white_gc, TRUE, 0, 0, allocation->width, allocation->height);
-
-               /* Copy the contents of the old pixmap */
-               if(oldmap != NULL)
-                       gdk_draw_drawable( GDK_DRAWABLE(newmap), widget->style->white_gc, GDK_DRAWABLE(oldmap), 0, 0, 0, 0, oldwidth, oldheight);
-               
-               /* Use the new pixmap */
-               gtk_image_set_from_pixmap( GTK_IMAGE(widget), newmap, NULL );
-               g_object_unref(newmap);
-       }
+       g_cond_broadcast(glk_data->resource_info_available);
+       g_mutex_unlock(glk_data->resource_lock);
 }
 
 glui32
-glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2) {
+glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2)
+{
        VALID_WINDOW(win, return FALSE);
        g_return_val_if_fail(win->type == wintype_Graphics, FALSE);
-       printf("Drawing image %d\n", (int)image);
 
        ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
        giblorb_result_t res;
@@ -144,10 +116,12 @@ glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2) {
 
        /* Load the resource */
        GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+       g_signal_connect( loader, "closed", G_CALLBACK(on_pixbuf_closed), NULL ); 
        glk_stream_set_position(glk_data->resource_file, res.data.startpos, seekmode_Start);
        buffer = g_malloc( BUFFER_SIZE * sizeof(guchar) );
 
        guint32 total_read = 0;
+       image_loaded = FALSE;
        while(total_read < res.length) {
                guint32 num_read = glk_get_buffer_stream(glk_data->resource_file, (char *) buffer, BUFFER_SIZE);
 
@@ -161,27 +135,42 @@ glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2) {
 
                total_read += num_read;
        }
-       printf("Loading done\n");
+
+       if( !gdk_pixbuf_loader_close(loader, &pixbuf_error) ) {
+               WARNING_S("Cannot read image", pixbuf_error->message);
+               giblorb_unload_chunk(glk_data->resource_map, image);
+               g_free(buffer);
+               return FALSE;
+       }
+
+       if(!image_loaded) {
+               /* Wait for the PixbufLoader to finish loading the image */
+               g_mutex_lock(glk_data->resource_lock);
+               while(!image_loaded) {
+                       g_cond_wait(glk_data->resource_loaded, glk_data->resource_lock);
+               }
+               g_mutex_unlock(glk_data->resource_lock);
+       }
+
        giblorb_unload_chunk(glk_data->resource_map, image);
        g_free(buffer);
 
        gtk_image_get_pixmap( GTK_IMAGE(win->widget), &canvas, NULL );
        if(canvas == NULL) {
                WARNING("Could not get pixmap");
-               gdk_pixbuf_loader_close(loader, &pixbuf_error);
                return FALSE;
        }
 
        GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
        if(pixbuf == NULL) {
                WARNING("Could not read image");
-               gdk_pixbuf_loader_close(loader, &pixbuf_error);
                return FALSE;
        }
 
-       // TODO: FIX hang?
+       printf("Drawing image %d\n", (int)image);
+
+       // TODO: fix hang
        gdk_draw_pixbuf( GDK_DRAWABLE(canvas), NULL, pixbuf, 0, 0, val1, val2, -1, -1, GDK_RGB_DITHER_NONE, 0, 0 );
-       gdk_pixbuf_loader_close(loader, &pixbuf_error);
 
        /* Update the screen */
        gtk_widget_queue_draw(win->widget);
@@ -189,6 +178,19 @@ glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2) {
        return TRUE;
 }
 
+void
+on_pixbuf_closed(GdkPixbufLoader *loader, gpointer data)
+{
+       printf("closed\n");
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
+       g_mutex_lock(glk_data->resource_lock);
+       image_loaded = TRUE;
+       g_cond_broadcast(glk_data->resource_loaded);
+       g_mutex_unlock(glk_data->resource_lock);
+}
+
+
 glui32
 glk_image_draw_scaled(winid_t win, glui32 image, glsi32 val1, glsi32 val2, glui32 width, glui32 height)
 {
@@ -222,3 +224,40 @@ glk_window_erase_rect(winid_t win, glsi32 left, glsi32 top, glui32 width, glui32
 void glk_window_flow_break(winid_t win)
 {
 }
+
+/*** Called when the graphics window is resized. Resize the backing pixmap if necessary ***/
+void
+on_graphics_size_allocate(GtkWidget *widget, GtkAllocation *allocation, winid_t win)
+{
+       printf("allocate to: %dx%d\n", allocation->width, allocation->height);
+       GdkPixmap *oldmap;
+       gtk_image_get_pixmap( GTK_IMAGE(widget), &oldmap, NULL );
+       gint oldwidth = 0;
+       gint oldheight = 0;
+       /* Determine whether a pixmap exists with the correct size */
+       gboolean needs_resize = FALSE;
+       if(oldmap == NULL)
+               needs_resize = TRUE;
+       else {
+               gdk_drawable_get_size( GDK_DRAWABLE(oldmap), &oldwidth, &oldheight );
+               if(oldwidth != allocation->width || oldheight != allocation->height)
+                       needs_resize = TRUE;
+       }
+
+       if(needs_resize) {
+               printf("needs resize\n");
+               /* Create a new pixmap */
+               GdkPixmap *newmap = gdk_pixmap_new(widget->window, allocation->width, allocation->height, -1);
+               gdk_draw_rectangle( GDK_DRAWABLE(newmap), widget->style->white_gc, TRUE, 0, 0, allocation->width, allocation->height);
+
+               /* Copy the contents of the old pixmap */
+               if(oldmap != NULL)
+                       gdk_draw_drawable( GDK_DRAWABLE(newmap), widget->style->white_gc, GDK_DRAWABLE(oldmap), 0, 0, 0, 0, oldwidth, oldheight);
+               
+               /* Use the new pixmap */
+               gtk_image_set_from_pixmap( GTK_IMAGE(widget), newmap, NULL );
+               g_object_unref(newmap);
+       }
+}
+