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");
73 *height =info->height;
80 on_size_prepared(GdkPixbufLoader *loader, gint width, gint height, struct image_info *info)
83 info->height = height;
84 size_determined = TRUE;
87 /*** Called when the graphics window is resized. Resize the backing pixmap if necessary ***/
89 on_graphics_size_allocate(GtkWidget *widget, GtkAllocation *allocation, winid_t win)
91 printf("allocate to: %dx%d\n", allocation->width, allocation->height);
93 gtk_image_get_pixmap( GTK_IMAGE(widget), &oldmap, NULL );
97 /* Determine whether a pixmap exists with the correct size */
98 gboolean needs_resize = FALSE;
102 gdk_drawable_get_size( GDK_DRAWABLE(oldmap), &oldwidth, &oldheight );
103 if(oldwidth != allocation->width || oldheight != allocation->height)
108 printf("needs resize\n");
109 /* Create a new pixmap */
110 GdkPixmap *newmap = gdk_pixmap_new(widget->window, allocation->width, allocation->height, -1);
111 gdk_draw_rectangle( GDK_DRAWABLE(newmap), widget->style->white_gc, TRUE, 0, 0, allocation->width, allocation->height);
113 /* Copy the contents of the old pixmap */
115 gdk_draw_drawable( GDK_DRAWABLE(newmap), widget->style->white_gc, GDK_DRAWABLE(oldmap), 0, 0, 0, 0, oldwidth, oldheight);
117 /* Use the new pixmap */
118 gtk_image_set_from_pixmap( GTK_IMAGE(widget), newmap, NULL );
119 g_object_unref(newmap);
124 glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2) {
125 VALID_WINDOW(win, return FALSE);
126 g_return_val_if_fail(win->type == wintype_Graphics, FALSE);
127 printf("Drawing image %d\n", (int)image);
129 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
130 giblorb_result_t res;
131 giblorb_err_t blorb_error = 0;
132 GError *pixbuf_error = NULL;
133 struct image_info *info = g_new0(struct image_info, 1);
134 info->resource_number = image;
138 /* Lookup the proper resource */
139 blorb_error = giblorb_load_resource(glk_data->resource_map, giblorb_method_FilePos, &res, giblorb_ID_Pict, image);
140 if(blorb_error != giblorb_err_None) {
141 WARNING_S( "Error loading resource", giblorb_get_error_message(blorb_error) );
145 /* Load the resource */
146 GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
147 glk_stream_set_position(glk_data->resource_file, res.data.startpos, seekmode_Start);
148 buffer = g_malloc( BUFFER_SIZE * sizeof(guchar) );
150 guint32 total_read = 0;
151 while(total_read < res.length) {
152 guint32 num_read = glk_get_buffer_stream(glk_data->resource_file, (char *) buffer, BUFFER_SIZE);
154 if( !gdk_pixbuf_loader_write(loader, buffer, MIN(BUFFER_SIZE, num_read), &pixbuf_error) ) {
155 WARNING_S("Cannot read image", pixbuf_error->message);
156 giblorb_unload_chunk(glk_data->resource_map, image);
157 gdk_pixbuf_loader_close(loader, &pixbuf_error);
162 total_read += num_read;
164 printf("Loading done\n");
165 giblorb_unload_chunk(glk_data->resource_map, image);
168 gtk_image_get_pixmap( GTK_IMAGE(win->widget), &canvas, NULL );
170 WARNING("Could not get pixmap");
171 gdk_pixbuf_loader_close(loader, &pixbuf_error);
175 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
177 WARNING("Could not read image");
178 gdk_pixbuf_loader_close(loader, &pixbuf_error);
183 gdk_draw_pixbuf( GDK_DRAWABLE(canvas), NULL, pixbuf, 0, 0, val1, val2, -1, -1, GDK_RGB_DITHER_NONE, 0, 0 );
184 gdk_pixbuf_loader_close(loader, &pixbuf_error);
186 /* Update the screen */
187 gtk_widget_queue_draw(win->widget);
193 glk_image_draw_scaled(winid_t win, glui32 image, glsi32 val1, glsi32 val2, glui32 width, glui32 height)
199 glk_window_set_background_color(winid_t win, glui32 color) {
200 win->background_color = color;
204 glk_window_fill_rect(winid_t win, glui32 color, glsi32 left, glsi32 top, glui32 width, glui32 height)
206 VALID_WINDOW(win, return);
207 g_return_if_fail(win->type == wintype_Graphics);
210 gtk_image_get_pixmap( GTK_IMAGE(win->widget), &map, NULL );
211 gdk_draw_rectangle( GDK_DRAWABLE(map), win->widget->style->white_gc, TRUE, left, top, width, height);
212 gtk_widget_queue_draw(win->widget);
216 glk_window_erase_rect(winid_t win, glsi32 left, glsi32 top, glui32 width, glui32 height)
218 printf("erasing rect: %d %d %d %d\n", left, top, width, height);
219 glk_window_fill_rect(win, win->background_color, left, top, width, height);
222 void glk_window_flow_break(winid_t win)