void glkjni_c_shutdown(void) { gli_register_obj = NULL; gli_unregister_obj = NULL; gli_register_arr = NULL; gli_unregister_arr = NULL; giblorb_destroy_map(blorbmap); }
/* Internal function: shut down all requests and anything not necessary while showing the last displayed configuration of windows. */ void shutdown_glk_pre(void) { ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); /* Stop any timers */ glk_request_timer_events(0); /* Cancel any pending input requests and flush all window buffers */ winid_t win; for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL)) { switch(win->input_request_type) { case INPUT_REQUEST_CHARACTER: case INPUT_REQUEST_CHARACTER_UNICODE: glk_cancel_char_event(win); break; case INPUT_REQUEST_LINE: case INPUT_REQUEST_LINE_UNICODE: glk_cancel_line_event(win, NULL); break; case INPUT_REQUEST_NONE: default: ; /* TODO: Handle mouse and hyperlink requests */ } flush_window_buffer(win); } /* Close any open resource files */ if(glk_data->resource_map != NULL) { giblorb_destroy_map(glk_data->resource_map); glk_data->resource_map = NULL; glk_stream_close(glk_data->resource_file, NULL); } /* Empty the input queues */ while(g_async_queue_try_pop(glk_data->char_input_queue)) ; while(g_async_queue_try_pop(glk_data->line_input_queue)) ; /* Wait for any pending window rearrange */ g_mutex_lock(&glk_data->arrange_lock); if(glk_data->needs_rearrange) g_cond_wait(&glk_data->rearranged, &glk_data->arrange_lock); g_mutex_unlock(&glk_data->arrange_lock); }
/** * giblorb_set_resource_map: * @file: The file stream to read the resource map from * * This function tells the library that the file is indeed the Blorby source * of all resource goodness. Whenever your program calls an image or sound * function, such as glk_image_draw(), the library will search this file for * the resource you request. * * Do <emphasis>not</emphasis> close the stream after calling this function. * The library is responsible for closing the stream at shutdown time. * * Returns: a Blorb error code. */ giblorb_err_t giblorb_set_resource_map(strid_t file) { ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); giblorb_map_t *newmap; /* create map allocates memory */ giblorb_err_t error = giblorb_create_map(file, &newmap); if(error != giblorb_err_None) { g_free(newmap); return error; } /* Check if there was already an existing resource map */ if(glk_data->resource_map != NULL) { WARNING("Overwriting existing resource map.\n"); giblorb_destroy_map(glk_data->resource_map); glk_stream_close(glk_data->resource_file, NULL); } glk_data->resource_map = newmap; glk_data->resource_file = file; return giblorb_err_None; }
giblorb_err_t giblorb_create_map(strid_t file, giblorb_map_t **newmap) { giblorb_err_t err; giblorb_map_t *map; glui32 readlen; glui32 nextpos, totallength; giblorb_chunkdesc_t *chunks; int chunks_size, numchunks; char buffer[16]; *newmap = NULL; if (!lib_inited) { err = giblorb_initialize(); if (err) return err; lib_inited = TRUE; } /* First, chew through the file and index the chunks. */ glk_stream_set_position(file, 0, seekmode_Start); readlen = glk_get_buffer_stream(file, buffer, 12); if (readlen != 12) return giblorb_err_Read; if (giblorb_native4(buffer+0) != giblorb_ID_FORM) return giblorb_err_Format; if (giblorb_native4(buffer+8) != giblorb_ID_IFRS) return giblorb_err_Format; totallength = giblorb_native4(buffer+4) + 8; nextpos = 12; chunks_size = 8; numchunks = 0; chunks = (giblorb_chunkdesc_t *)giblorb_malloc(sizeof(giblorb_chunkdesc_t) * chunks_size); while (nextpos < totallength) { glui32 type, len; int chunum; giblorb_chunkdesc_t *chu; glk_stream_set_position(file, nextpos, seekmode_Start); readlen = glk_get_buffer_stream(file, buffer, 8); if (readlen != 8) return giblorb_err_Read; type = giblorb_native4(buffer+0); len = giblorb_native4(buffer+4); if (numchunks >= chunks_size) { chunks_size *= 2; chunks = (giblorb_chunkdesc_t *)giblorb_realloc(chunks, sizeof(giblorb_chunkdesc_t) * chunks_size); } chunum = numchunks; chu = &(chunks[chunum]); numchunks++; chu->type = type; chu->startpos = nextpos; if (type == giblorb_ID_FORM) { chu->datpos = nextpos; chu->len = len+8; } else { chu->datpos = nextpos+8; chu->len = len; } chu->ptr = NULL; chu->auxdatnum = -1; nextpos = nextpos + len + 8; if (nextpos & 1) nextpos++; if (nextpos > totallength) return giblorb_err_Format; } /* The basic IFF structure seems to be ok, and we have a list of chunks. Now we allocate the map structure itself. */ map = (giblorb_map_t *)giblorb_malloc(sizeof(giblorb_map_t)); if (!map) { giblorb_free(chunks); return giblorb_err_Alloc; } map->inited = giblorb_Inited_Magic; map->file = file; map->chunks = chunks; map->numchunks = numchunks; map->resources = NULL; map->ressorted = NULL; map->numresources = 0; /*map->releasenum = 0; map->zheader = NULL; map->resolution = NULL; map->palettechunk = -1; map->palette = NULL; map->auxsound = NULL; map->auxpict = NULL;*/ /* Now we do everything else involved in loading the Blorb file, such as building resource lists. */ err = giblorb_initialize_map(map); if (err) { giblorb_destroy_map(map); return err; } *newmap = map; return giblorb_err_None; }
giblorb_err_t wrap_gib_destroy_map(giblorb_map_t *map) { return giblorb_destroy_map(map); }