2 #include "chimara-glk-private.h"
5 #define BUFFER_SIZE (1024)
7 extern GPrivate *glk_data_key;
8 void on_size_prepared(GdkPixbufLoader *loader, gint width, gint height, struct image_info *info);
10 static gboolean size_determined;
13 glk_image_get_info(glui32 image, glui32 *width, glui32 *height)
15 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
17 giblorb_err_t blorb_error = 0;
18 GError *pixbuf_error = NULL;
19 struct image_info *info = g_new0(struct image_info, 1);
20 info->resource_number = image;
23 //printf("glk_image_get_info(%d)\n", image);
25 /* Lookup the proper resource */
26 blorb_error = giblorb_load_resource(glk_data->resource_map, giblorb_method_FilePos, &res, giblorb_ID_Pict, image);
27 if(blorb_error != giblorb_err_None) {
28 WARNING_S( "Error loading resource", giblorb_get_error_message(blorb_error) );
32 if(width == NULL && height == NULL) {
33 /* No size requested, don't bother loading the image */
34 giblorb_unload_chunk(glk_data->resource_map, image);
38 /* Load the resource */
39 GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
40 g_signal_connect( loader, "size-prepared", G_CALLBACK(on_size_prepared), info );
41 glk_stream_set_position(glk_data->resource_file, res.data.startpos, seekmode_Start);
42 buffer = g_malloc( BUFFER_SIZE * sizeof(guchar) );
44 guint32 total_read = 0;
45 size_determined = FALSE;
46 while(total_read < res.length && !size_determined) {
47 guint32 num_read = glk_get_buffer_stream(glk_data->resource_file, (char *) buffer, BUFFER_SIZE);
49 if( !gdk_pixbuf_loader_write(loader, buffer, MIN(BUFFER_SIZE, num_read), &pixbuf_error) ) {
50 WARNING_S("Cannot read image", pixbuf_error->message);
51 giblorb_unload_chunk(glk_data->resource_map, image);
52 gdk_pixbuf_loader_close(loader, &pixbuf_error);
57 total_read += num_read;
59 giblorb_unload_chunk(glk_data->resource_map, image);
60 gdk_pixbuf_loader_close(loader, &pixbuf_error);
63 /* Determine the image dimensions */
64 if(!size_determined) {
65 WARNING("Cannot read image size: file data trimmed?");
73 *height =info->height;
76 //printf("size loaded: %d x %d\n", (int) *width, (int) *height);
82 on_size_prepared(GdkPixbufLoader *loader, gint width, gint height, struct image_info *info)
85 info->height = height;
86 size_determined = TRUE;
90 on_graphics_size_allocate(GtkWidget *widget, GtkAllocation *allocation, winid_t *win)
92 printf("size allocated: %dx%d\n", allocation->width, allocation->height);
96 glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2) {
97 VALID_WINDOW(win, return FALSE);
98 g_return_val_if_fail(win->type == wintype_Graphics, FALSE);
99 printf("Drawing image %d\n", (int)image);
101 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
102 giblorb_result_t res;
103 giblorb_err_t blorb_error = 0;
104 GError *pixbuf_error = NULL;
105 struct image_info *info = g_new0(struct image_info, 1);
106 info->resource_number = image;
110 //printf("glk_image_get_info(%d)\n", image);
112 /* Lookup the proper resource */
113 blorb_error = giblorb_load_resource(glk_data->resource_map, giblorb_method_FilePos, &res, giblorb_ID_Pict, image);
114 if(blorb_error != giblorb_err_None) {
115 WARNING_S( "Error loading resource", giblorb_get_error_message(blorb_error) );
119 /* Load the resource */
120 GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
121 glk_stream_set_position(glk_data->resource_file, res.data.startpos, seekmode_Start);
122 buffer = g_malloc( BUFFER_SIZE * sizeof(guchar) );
124 guint32 total_read = 0;
125 while(total_read < res.length) {
126 guint32 num_read = glk_get_buffer_stream(glk_data->resource_file, (char *) buffer, BUFFER_SIZE);
128 if( !gdk_pixbuf_loader_write(loader, buffer, MIN(BUFFER_SIZE, num_read), &pixbuf_error) ) {
129 WARNING_S("Cannot read image", pixbuf_error->message);
130 giblorb_unload_chunk(glk_data->resource_map, image);
131 gdk_pixbuf_loader_close(loader, &pixbuf_error);
136 total_read += num_read;
138 giblorb_unload_chunk(glk_data->resource_map, image);
141 gtk_image_get_pixmap( GTK_IMAGE(win->widget), &canvas, NULL );
143 WARNING("Could not get pixmap");
144 gdk_pixbuf_loader_close(loader, &pixbuf_error);
148 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
150 WARNING("Could not read image");
151 gdk_pixbuf_loader_close(loader, &pixbuf_error);
155 gdk_draw_pixbuf( GDK_DRAWABLE(canvas), NULL, pixbuf, 0, 0, val1, val2, -1, -1, GDK_RGB_DITHER_NONE, 0, 0 );
156 gdk_pixbuf_loader_close(loader, &pixbuf_error);
158 /* Update the screen */
159 gtk_widget_queue_draw(win->widget);
164 glk_image_draw_scaled(winid_t win, glui32 image, glsi32 val1, glsi32 val2, glui32 width, glui32 height)
170 glk_window_set_background_color(winid_t win, glui32 color) {
171 win->background_color = color;
175 glk_window_fill_rect(winid_t win, glui32 color, glsi32 left, glsi32 top, glui32 width, glui32 height)
177 VALID_WINDOW(win, return);
178 g_return_if_fail(win->type == wintype_Graphics);
181 gtk_image_get_pixmap( GTK_IMAGE(win->widget), &map, NULL );
182 gdk_draw_rectangle( GDK_DRAWABLE(map), win->widget->style->white_gc, TRUE, left, top, width, height);
183 gtk_widget_queue_draw(win->widget);
187 glk_window_erase_rect(winid_t win, glsi32 left, glsi32 top, glui32 width, glui32 height)
189 printf("erasing rect: %d %d %d %d\n", left, top, width, height);
190 glk_window_fill_rect(win, win->background_color, left, top, width, height);
193 void glk_window_flow_break(winid_t win)