コード例 #1
0
ファイル: cgmisc.c プロジェクト: BGCX262/zvm-hg-to-git
void gidispatch_set_object_registry(
    gidispatch_rock_t (*regi)(void *obj, glui32 objclass), 
    void (*unregi)(void *obj, glui32 objclass, gidispatch_rock_t objrock))
{
    window_t *win;
    stream_t *str;
    fileref_t *fref;
    
    gli_register_obj = regi;
    gli_unregister_obj = unregi;
    
    if (gli_register_obj) {
        /* It's now necessary to go through all existing objects, and register
            them. */
        for (win = glk_window_iterate(NULL, NULL); 
            win;
            win = glk_window_iterate(win, NULL)) {
            win->disprock = (*gli_register_obj)(win, gidisp_Class_Window);
        }
        for (str = glk_stream_iterate(NULL, NULL); 
            str;
            str = glk_stream_iterate(str, NULL)) {
            str->disprock = (*gli_register_obj)(str, gidisp_Class_Stream);
        }
        for (fref = glk_fileref_iterate(NULL, NULL); 
            fref;
            fref = glk_fileref_iterate(fref, NULL)) {
            fref->disprock = (*gli_register_obj)(fref, gidisp_Class_Fileref);
        }
    }
}
コード例 #2
0
ファイル: glk.c プロジェクト: chimara/Chimara
/**
 * glk_exit:
 *
 * If you want to shut down your program in the middle of your `glk_main()`
 * function, you can call glk_exit().
 *
 * This function does not return.
 *
 * If you print some text to a window and then shut down your program, you can
 * assume that the player will be able to read it. Most likely the Glk library
 * will give a “`Hit any key to exit`” prompt.
 * (There are other possiblities, however.
 * A terminal-window version of Glk might simply exit and leave the last screen
 * state visible in the terminal window.)
 *
 * <note><para>
 * You should only shut down your program with glk_exit() or by returning from
 * your <function>glk_main()</function> function. If you call the ANSI
 * <function>exit()</function> function, bad things may happen. Some versions of
 * the Glk library may be designed for multiple sessions, for example, and you
 * would be cutting off all the sessions instead of just yours. You would
 * probably also prevent final text from being visible to the player.
 * </para></note>
 *
 * > # Chimara #
 * > If there are any windows open at the time glk_exit() is called, then
 * > Chimara will leave them open.
 * > This way, the final text remains visible.
 * > Note that bad things most definitely <emphasis>will</emphasis> happen if
 * > you use the ANSI `exit()`.
 */
void
glk_exit(void)
{
    ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);

    shutdown_glk_pre();

    /* Find the biggest text buffer window */
    winid_t win, largewin = NULL;
    glui32 largearea = 0;
    for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL)) {
        if(win->type == wintype_TextBuffer) {
            glui32 w, h;
            if(!largewin) {
                largewin = win;
                glk_window_get_size(largewin, &w, &h);
                largearea = w * h;
            } else {
                glk_window_get_size(win, &w, &h);
                if(w * h > largearea) {
                    largewin = win;
                    largearea = w * h;
                }
            }
        }
    }
    if(largewin) {
        glk_set_window(largewin);
        glk_set_style(style_Alert);
        glk_put_string("\n");
        glk_put_string(glk_data->final_message);
        glk_put_string("\n");
        flush_window_buffer(largewin);
    }

    /* Wait for a keypress if any text grid or buffer windows are open */
    gboolean should_wait = FALSE;
    g_mutex_lock(&glk_data->shutdown_lock);
    for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL)) {
        if(win->type == wintype_TextGrid || win->type == wintype_TextBuffer) {
            g_signal_handler_unblock(win->widget, win->shutdown_keypress_handler);
            should_wait = TRUE;
        }
    }
    if (should_wait)
        g_cond_wait(&glk_data->shutdown_key_pressed, &glk_data->shutdown_lock);
    g_mutex_unlock(&glk_data->shutdown_lock);

    shutdown_glk_post();

    gdk_threads_add_idle((GSourceFunc)emit_stopped_signal, glk_data->self);

    g_thread_exit(NULL);
}
コード例 #3
0
/* 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);
}
コード例 #4
0
/**
 * gidispatch_set_object_registry:
 * @regi: Function to call whenever an opaque object is created.
 * @unregi: Function to call whenever an opaque object is destroyed.
 *
 * The Glk API refers to opaque objects by pointer; but a VM probably cannot 
 * store pointers to native memory. Therefore, a VM program will want to keep a
 * VM-accessible collection of opaque objects.
 * 
 * <note><para>
 *   For example, it might keep a hash table for each opaque object class,
 *   mapping integer identifiers to object pointers.
 * </para></note>
 * 
 * To make this possible, a Glk library must implement 
 * gidispatch_set_object_registry().
 * 
 * Your program calls gidispatch_set_object_registry() early (before it begins
 * actually executing VM code.) You pass in two function pointers, matching the
 * following prototypes:
 * |[<!--language="C"-->
 * gidispatch_rock_t my_vm_reg_object(void *obj, glui32 objclass);
 * void my_vm_unreg_object(void *obj, glui32 objclass, gidispatch_rock_t objrock);
 * ]|
 * 
 * Whenever the Glk library creates an object, it will call
 * `my_vm_reg_object<!---->()`.
 * It will pass the object pointer and the class number (from 0
 * to <inlineequation><mathphrase>N - 1</mathphrase><alt>N -
 * 1</alt></inlineequation>, where N is the value returned by
 * gidispatch_count_classes().)
 *
 * You can return any value in the #gidispatch_rock_t object; the library will
 * stash this away inside the object.
 * 
 * <note><para>
 *   Note that this is entirely separate from the regular Glk rock, which is
 *   always a #glui32 and can be set independently.
 * </para></note>
 * 
 * Whenever the Glk library destroys an object, it will call
 * `my_vm_unreg_object<!---->()`.
 * It passes you the object pointer, class number, and the object rock.
 *
 * One significant detail: It is possible that some Glk objects will already
 * exist when your glk_main() function is called.
 * 
 * <note><para>
 *   For example, MacGlk can open a stream when the user double-clicks a file;
 *   this occurs before glk_main().
 * </para></note>
 * 
 * So when you call gidispatch_set_object_registry(), it may immediately call
 * your `my_vm_reg_object<!---->()` callback, notifying you of the existing
 * objects.
 * You must be prepared for this possibility.
 *
 * <note><para>
 *   If you are keeping hash tables, for example, create them before you call
 *   gidispatch_set_object_registry().
 * </para></note>
 */
void 
gidispatch_set_object_registry(gidispatch_rock_t (*regi)(void *obj, glui32 objclass), void (*unregi)(void *obj, glui32 objclass, gidispatch_rock_t objrock))
{
	ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
	winid_t win;
    strid_t str;
    frefid_t fref;
    
    glk_data->register_obj = regi;
    glk_data->unregister_obj = unregi;
    
    if(glk_data->register_obj) 
	{
        /* It's now necessary to go through all existing objects, and register them. */
        for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL))
            win->disprock = (*glk_data->register_obj)(win, gidisp_Class_Window);
        for(str = glk_stream_iterate(NULL, NULL); str; str = glk_stream_iterate(str, NULL))
            str->disprock = (*glk_data->register_obj)(str, gidisp_Class_Stream);
        for(fref = glk_fileref_iterate(NULL, NULL); fref; fref = glk_fileref_iterate(fref, NULL))
            fref->disprock = (*glk_data->register_obj)(fref, gidisp_Class_Fileref);
    }
}
コード例 #5
0
ファイル: glkjni.c プロジェクト: sussman/twisty
void gidispatch_set_object_registry(
    gidispatch_rock_t (*regi)(void *obj, glui32 objclass),
    void (*unregi)(void *obj, glui32 objclass, gidispatch_rock_t objrock))
{
    winid_t win;
    strid_t str;
    frefid_t fref;
    schanid_t schan;

    gli_register_obj = regi;
    gli_unregister_obj = unregi;

    if (gli_register_obj) {
        /* It's now necessary to go through all existing objects, and register
            them. */
        for (win = glk_window_iterate(NULL, NULL);
            win;
            win = glk_window_iterate(win, NULL)) {
            gli_win_set_disprock(win);
        }
        for (str = glk_stream_iterate(NULL, NULL);
            str;
            str = glk_stream_iterate(str, NULL)) {
            gli_str_set_disprock(str);
        }
        for (fref = glk_fileref_iterate(NULL, NULL);
            fref;
            fref = glk_fileref_iterate(fref, NULL)) {
            gli_fref_set_disprock(fref);
        }
        for (schan = glk_schannel_iterate(NULL, NULL);
            schan;
            schan = glk_schannel_iterate(schan, NULL)) {
            gli_schan_set_disprock(schan);
        }
    }
}
コード例 #6
0
ファイル: multiwin.c プロジェクト: chimara/Chimara
/* This draws some corner decorations in *every* key window -- the
    one created at startup, and any later ones. It finds them all
    with glk_window_iterate. */
static void draw_keywins(void)
{
    winid_t win;
    glui32 rock;
    glui32 width, height;

    for (win = glk_window_iterate(NULL, &rock);
            win;
            win = glk_window_iterate(win, &rock)) {
        if (rock == KEYWINROCK) {
            glk_set_window(win);
            glk_window_clear(win);
            glk_window_get_size(win, &width, &height);
            glk_window_move_cursor(win, 0, 0);
            glk_put_char('O');
            glk_window_move_cursor(win, width-1, 0);
            glk_put_char('O');
            glk_window_move_cursor(win, 0, height-1);
            glk_put_char('O');
            glk_window_move_cursor(win, width-1, height-1);
            glk_put_char('O');
        }
    }
}
コード例 #7
0
ファイル: gui.c プロジェクト: abrobston/gtkglk
void gglk_object_tree_update(void)
{
    GtkTreeView *tree;
    GtkTreeStore *store;
    GtkTreeSelection *select;
    GtkTreeIter iter;
    winid_t win;
    strid_t str;
    frefid_t fref;
    GHashTable *streams;

    if(!win_glk_objects)
	return;

    gglk_bindings = g_hash_table_new(NULL, NULL);
    
    tree = GTK_TREE_VIEW(lookup_widget(win_glk_objects, "treeview1"));
    store = GTK_TREE_STORE(gtk_tree_view_get_model(tree));
    gtk_tree_store_clear(store);
    
    gglk_tree_store_populate_win(glk_window_get_root(), store, NULL);

    streams = g_hash_table_new(NULL, NULL);
    win = NULL;
    while((win = glk_window_iterate(win, NULL)) != NULL) {
	str = glk_window_get_stream(win);
	g_hash_table_insert(streams, str, win);
    }
    str = NULL;
    while((str = glk_stream_iterate(str, NULL)) != NULL) {
	win = g_hash_table_lookup(streams, str);
	if(!win)
	    gglk_tree_store_populate_str(str, store, NULL);
    }
    g_hash_table_destroy(streams);

    fref = NULL;
    while((fref = glk_fileref_iterate(fref, NULL)) != NULL) {
	gglk_tree_store_populate_fref(fref, store, NULL);
    }
    gtk_tree_view_expand_all(tree);

    select = gtk_tree_view_get_selection(tree);
    if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
	gtk_tree_selection_select_iter(select, &iter);
}
コード例 #8
0
ファイル: dispatch.c プロジェクト: castaway/glknew
void gidispatch_call(glui32 funcnum, glui32 numargs, gluniversal_t *arglist)
{
  gidispatch_function_t *gidispatch_function;
  char *prototype;
  int argument = 0;
  int slot = 0;
  
  gidispatch_function = gidispatch_get_function_by_id(funcnum);
  prototype = gidispatch_prototype(funcnum);
  printf("DEBUG: dispatch call name=%s, prototype=%s, numargs=%u -- ", gidispatch_function->name, prototype, (unsigned int)numargs);
  
  if (strcmp(prototype, "4IuIuIuIs") == 0) {
    printf("%u, %u, %u, %d\n", arglist[0].uint, arglist[1].uint, arglist[2].uint, arglist[3].sint);
  } else if (strcmp(prototype, "3IuIu:Iu") == 0) {
    printf("%u, %u, returning a glui32\n", arglist[0].uint, arglist[1].uint);
  } else if (strcmp(prototype, "3Qa<Iu:Qa") == 0) {
    printf("win at %p, outref to a glui32, returning a winid_t\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "3Qc<Iu:Qc") == 0) {
    printf("fileref at %p, outref to a glui32, returning a frefid_t\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "1Qa:") == 0) {
    printf("win at %p\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "6QaIuIuIuIu:Qa") == 0) {
    printf("win at %p, %u, %u, %u, %u, returning a winid_t\n", arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, arglist[3].uint, arglist[4].uint);
  } else if (strcmp(prototype, "4IuIuIuIs:") == 0) {
    printf("%u, %u, %u, %d\n", arglist[0].uint, arglist[1].uint, arglist[2].uint, arglist[3].sint);
  } else if (strcmp(prototype, "1Qb:") == 0) {
    printf("stream at %p\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "1Iu:") == 0) {
    printf("%u\n", arglist[0].uint);
  } else if (strcmp(prototype, "2Qb<[2IuIu]:") == 0) {
    printf("stream at %p, some struct stuff here\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "3IuIuIu:") == 0) {
    printf("%u, %u, %u\n", arglist[0].uint, arglist[1].uint, arglist[2].uint);
  } else if (strcmp(prototype, "1:Qb") == 0) {
    printf("returning a strid_t\n");
  } else if (strcmp(prototype, "4&+#!IuIuIu:Qb") == 0) {
    printf("retained, nonnull, array of glui32 at %p for length %u, %u, %u, returning a strid_t\n", arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint);
  } else if (strcmp(prototype, "2Qc:Iu") == 0) {
    printf("fileref at %p, returning a glui32\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "1<+[4IuQaIuIu]:") == 0) {
    printf("some struct stuff here, nonnull\n");
  } else if (strcmp(prototype, "1:Qb") == 0) {
    printf("returning a strid_t\n");
  } else if (strcmp(prototype, "2Qb:Is") == 0) {
    printf("stream at %p, returning a glsi32\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "2Qc:Iu") == 0) {
    printf("fileref at %p, returning a glui32\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "3Qa&+#!CnIu:") == 0) {
    printf("win at %p, retained, nonnull, array of char at %p for length %u, %u\n", arglist[0].opaqueref, arglist[2].array, arglist[3].uint, arglist[4].uint);
  } else if (strcmp(prototype, "3Qb<Iu:Qb") == 0) {
    printf("stream at %p, outref to a glui32, returning a strid_t\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "4&+#!CnIuIu:Qb") == 0) {
    printf("retained, nonnull, array of char at %p for length %u, %u, %u, returning a strid_t\n", arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint);
  } else if (strcmp(prototype, "4&+#!IuIuIu:Qb") == 0) {
    printf("retained, nonnull, array of glui32 at %p for length %u, %u, %u, returning a strid_t\n", arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint);
  } else if (strcmp(prototype, "4IuSIu:Qc") == 0) {
    printf("%u, %s, %u, returning a frefid_t\n", arglist[0].uint, arglist[1].charstr, arglist[2].uint);
  } else if (strcmp(prototype, "4QcIuIu:Qb") == 0) {
    printf("fileref at %p, %u, %u, returning a strid_t\n", arglist[0].opaqueref, arglist[1].uint, arglist[2].uint);
  } else if (strcmp(prototype, "3Qa<Iu<Iu:") == 0) {
    printf("win at %p, outref to a glui32, outref to a glui32\n", arglist[0].opaqueref);
  } else if (strcmp(prototype, "6QaIuIsIsIuIu:") == 0) {
    printf("win at %p, %u, %d, %d, %u, %u\n", arglist[0].opaqueref, arglist[1].uint, arglist[2].sint, arglist[3].sint, arglist[4].uint, arglist[5].uint);
  } else if (strcmp(prototype, "4Iu<Iu<Iu:Iu") == 0) {
    printf("%u, outref to a glui32, outref to a glui32, returning a glui32\n", arglist[0].uint);
  } else {
    printf("unhandled prototype\n");
  }
  
  switch (funcnum) {
  case 0x0004: /* gestalt */
    arglist[3].uint = glk_gestalt(arglist[0].uint, arglist[1].uint);
    break;
  case 0x0005: /* gestalt_ext */
    if (arglist[2].ptrflag) {
      arglist[6].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint,
                                        arglist[3].array, arglist[4].uint);
    }
    else {
      arglist[4].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint,
                                        NULL, 0);
    }
    break;
  case 0x0020: /* window_iterate */
    if (arglist[1].ptrflag) 
      arglist[4].opaqueref = glk_window_iterate(arglist[0].opaqueref, &arglist[2].uint);
    else
      arglist[3].opaqueref = glk_window_iterate(arglist[0].opaqueref, NULL);
    break;
  case 0x0023: /* window_open */
    arglist[6].opaqueref = glk_window_open(arglist[0].opaqueref, arglist[1].uint, 
                                           arglist[2].uint, arglist[3].uint, arglist[4].uint);
    break;

  case 0x0025: /* window_get_size */
    {
      int ix = 1;
      glui32 *ptr1, *ptr2;
      if (!arglist[ix].ptrflag) {
        ptr1 = NULL;
      }
      else {
        ix++;
        ptr1 = &(arglist[ix].uint);
      }
      ix++;
      if (!arglist[ix].ptrflag) {
        ptr2 = NULL;
      }
      else {
        ix++;
        ptr2 = &(arglist[ix].uint);
      }
      ix++;
      glk_window_get_size(arglist[0].opaqueref, ptr1, ptr2);
    }
    break;
  case 0x0028: /* window_get_type */
    arglist[2].uint = glk_window_get_type(arglist[0].opaqueref);
    break;
  case 0x002A: /* window_clear */
    glk_window_clear(arglist[0].opaqueref);
    break;
  case 0x002B: /* window_move_cursor */
    glk_window_move_cursor(arglist[0].opaqueref, arglist[1].uint, 
                           arglist[2].uint);
    break;
  case 0x002F: /* set_window */
    glk_set_window(arglist[0].opaqueref);
    break;
    
  case 0x0040: /* stream_iterate */
    if (arglist[1].ptrflag) 
      arglist[4].opaqueref = glk_stream_iterate(arglist[0].opaqueref, &arglist[2].uint);
    else
      arglist[3].opaqueref = glk_stream_iterate(arglist[0].opaqueref, NULL);
    break;
  case 0x0042: /* stream_open_file */
    arglist[4].opaqueref = glk_stream_open_file(arglist[0].opaqueref, arglist[1].uint, 
                                                arglist[2].uint);
    break;
  case 0x0043: /* stream_open_memory */
    if (arglist[0].ptrflag) 
      arglist[6].opaqueref = glk_stream_open_memory(arglist[1].array, 
                                                    arglist[2].uint, arglist[3].uint, arglist[4].uint);
    else
      arglist[4].opaqueref = glk_stream_open_memory(NULL, 
                                                    0, arglist[1].uint, arglist[2].uint);
    break;
  case 0x0044: /* stream_close */
    if (arglist[1].ptrflag) {
      stream_result_t dat;
      glk_stream_close(arglist[0].opaqueref, &dat);
      arglist[2].uint = dat.readcount;
      arglist[3].uint = dat.writecount;
    }
    else {
      glk_stream_close(arglist[0].opaqueref, NULL);
    }
    break;
  case 0x0047: /* stream_set_current */
    glk_stream_set_current(arglist[0].opaqueref);
    break;
  case 0x0048: /* stream_get_current */
    arglist[1].opaqueref = glk_stream_get_current();
    break;

  case 0x0061: /* fileref_create_by_name */
    arglist[4].opaqueref = glk_fileref_create_by_name(arglist[0].uint, 
                                                      arglist[1].charstr, arglist[2].uint);
    break;
  case 0x0062: /* fileref_create_by_prompt */
    arglist[4].opaqueref = glk_fileref_create_by_prompt(arglist[0].uint, 
                                                        arglist[1].uint, arglist[2].uint);
    break;
  case 0x0067: /* fileref_does_file_exist */
    arglist[2].uint = glk_fileref_does_file_exist(arglist[0].opaqueref);
    break;

  case 0x0086: /* set_style */
    glk_set_style(arglist[0].uint);
    break;
  case 0x0087: /* set_style_stream */
    glk_set_style_stream(arglist[0].opaqueref, arglist[1].uint);
    break;
    
  case 0x0090: /* get_char_stream */
    arglist[2].sint = glk_get_char_stream(arglist[0].opaqueref);
    break;

  case 0x00B0: /* stylehint_set */
    glk_stylehint_set(arglist[0].uint, arglist[1].uint,
                      arglist[2].uint, arglist[3].sint);
    break;
    
  case 0x00C0: /* select */
    if (arglist[0].ptrflag) {
      event_t dat;
      glk_select(&dat);
      arglist[1].uint = dat.type;
      arglist[2].opaqueref = dat.win;
      arglist[3].uint = dat.val1;
      arglist[4].uint = dat.val2;
    }
    else {
      glk_select(NULL);
    }
    break;
  
  case 0x00D0: /* request_line_event */
    if (arglist[1].ptrflag)
      glk_request_line_event(arglist[0].opaqueref, arglist[2].array,
                             arglist[3].uint, arglist[4].uint);
    else
      glk_request_line_event(arglist[0].opaqueref, NULL,
                             0, arglist[2].uint);
    break;
  case 0x00D2: /* request_char_event */
    glk_request_char_event(arglist[0].opaqueref);
    break;
    
  case 0x00E0: /* image_get_info */
    {
      int ix = 1;
      glui32 *ptr1, *ptr2;
      if (!arglist[ix].ptrflag) {
        ptr1 = NULL;
      }
      else {
        ix++;
        ptr1 = &(arglist[ix].uint);
      }
      ix++;
      if (!arglist[ix].ptrflag) {
        ptr2 = NULL;
      }
      else {
        ix++;
        ptr2 = &(arglist[ix].uint);
      }
      ix++;
      ix++;
      arglist[ix].uint = glk_image_get_info(arglist[0].uint, ptr1, ptr2);
    }
    break;
  case 0x00E1: /* image_draw */
    arglist[5].uint = glk_image_draw(arglist[0].opaqueref, 
                                     arglist[1].uint,
                                     arglist[2].sint, arglist[3].sint);
    break;
  case 0x00E2: /* image_draw_scaled */
    arglist[7].uint = glk_image_draw_scaled(arglist[0].opaqueref, 
                                            arglist[1].uint,
                                            arglist[2].sint, arglist[3].sint,
                                            arglist[4].uint, arglist[5].uint);
    break;
  case 0x00EA: /* window_fill_rect */
    glk_window_fill_rect(arglist[0].opaqueref, arglist[1].uint,
                         arglist[2].sint, arglist[3].sint,
                         arglist[4].uint, arglist[5].uint);
    break;


  case 0x0128: /* put_char_uni */
    glk_put_char_uni(arglist[0].uint);
    break;
  case 0x0139: /* stream_open_memory_uni */
    if (arglist[0].ptrflag) 
      arglist[6].opaqueref = glk_stream_open_memory_uni(arglist[1].array, 
                                                        arglist[2].uint, arglist[3].uint, arglist[4].uint);
    else
      arglist[4].opaqueref = glk_stream_open_memory_uni(NULL, 
                                                        0, arglist[1].uint, arglist[2].uint);
    break;
    
  default:
    printf("Unhandled call to %s via dispatch\n", gidispatch_function->name);
#if 0
  case 0x0001: /* exit */
    glk_exit();
    break;
  case 0x0002: /* set_interrupt_handler */
    /* cannot be invoked through dispatch layer */
    break;
  case 0x0003: /* tick */
    glk_tick();
    break;
  case 0x0021: /* window_get_rock */
    arglist[2].uint = glk_window_get_rock(arglist[0].opaqueref);
    break;
  case 0x0022: /* window_get_root */
    arglist[1].opaqueref = glk_window_get_root();
    break;
  case 0x0024: /* window_close */
    if (arglist[1].ptrflag) {
      stream_result_t dat;
      glk_window_close(arglist[0].opaqueref, &dat);
      arglist[2].uint = dat.readcount;
      arglist[3].uint = dat.writecount;
    }
    else {
      glk_window_close(arglist[0].opaqueref, NULL);
    }
    break;
  case 0x0026: /* window_set_arrangement */
    glk_window_set_arrangement(arglist[0].opaqueref, arglist[1].uint, 
                               arglist[2].uint, arglist[3].opaqueref);
    break;
  case 0x0027: /* window_get_arrangement */
    {
      int ix = 1;
      glui32 *ptr1, *ptr2;
      winid_t *ptr3;
      if (!arglist[ix].ptrflag) {
        ptr1 = NULL;
      }
      else {
        ix++;
        ptr1 = &(arglist[ix].uint);
      }
      ix++;
      if (!arglist[ix].ptrflag) {
        ptr2 = NULL;
      }
      else {
        ix++;
        ptr2 = &(arglist[ix].uint);
      }
      ix++;
      if (!arglist[ix].ptrflag) {
        ptr3 = NULL;
      }
      else {
        ix++;
        ptr3 = (winid_t *)(&(arglist[ix].opaqueref));
      }
      ix++;
      glk_window_get_arrangement(arglist[0].opaqueref, ptr1, ptr2, ptr3);
    }
    break;
  case 0x0029: /* window_get_parent */
    arglist[2].opaqueref = glk_window_get_parent(arglist[0].opaqueref);
    break;
  case 0x002C: /* window_get_stream */
    arglist[2].opaqueref = glk_window_get_stream(arglist[0].opaqueref);
    break;
  case 0x002D: /* window_set_echo_stream */
    glk_window_set_echo_stream(arglist[0].opaqueref, arglist[1].opaqueref);
    break;
  case 0x002E: /* window_get_echo_stream */
    arglist[2].opaqueref = glk_window_get_echo_stream(arglist[0].opaqueref);
    break;
  case 0x0030: /* window_get_sibling */
    arglist[2].opaqueref = glk_window_get_sibling(arglist[0].opaqueref);
    break;
  case 0x0041: /* stream_get_rock */
    arglist[2].uint = glk_stream_get_rock(arglist[0].opaqueref);
    break;
  case 0x0045: /* stream_set_position */
    glk_stream_set_position(arglist[0].opaqueref, arglist[1].sint,
                            arglist[2].uint);
    break;
  case 0x0046: /* stream_get_position */
    arglist[2].uint = glk_stream_get_position(arglist[0].opaqueref);
    break;
  case 0x0048: /* stream_get_current */
    arglist[1].opaqueref = glk_stream_get_current();
    break;
  case 0x0060: /* fileref_create_temp */
    arglist[3].opaqueref = glk_fileref_create_temp(arglist[0].uint, 
                                                   arglist[1].uint);
    break;
  case 0x0063: /* fileref_destroy */
    glk_fileref_destroy(arglist[0].opaqueref);
    break;
  case 0x0064: /* fileref_iterate */
    if (arglist[1].ptrflag) 
      arglist[4].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, &arglist[2].uint);
    else
      arglist[3].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, NULL);
    break;
  case 0x0065: /* fileref_get_rock */
    arglist[2].uint = glk_fileref_get_rock(arglist[0].opaqueref);
    break;
  case 0x0066: /* fileref_delete_file */
    glk_fileref_delete_file(arglist[0].opaqueref);
    break;
  case 0x0068: /* fileref_create_from_fileref */
    arglist[4].opaqueref = glk_fileref_create_from_fileref(arglist[0].uint, 
                                                           arglist[1].opaqueref, arglist[2].uint);
    break;
  case 0x0080: /* put_char */
    glk_put_char(arglist[0].uch);
    break;
  case 0x0081: /* put_char_stream */
    glk_put_char_stream(arglist[0].opaqueref, arglist[1].uch);
    break;
  case 0x0082: /* put_string */
    glk_put_string(arglist[0].charstr);
    break;
  case 0x0083: /* put_string_stream */
    glk_put_string_stream(arglist[0].opaqueref, arglist[1].charstr);
    break;
  case 0x0084: /* put_buffer */
    if (arglist[0].ptrflag) 
      glk_put_buffer(arglist[1].array, arglist[2].uint);
    else
      glk_put_buffer(NULL, 0);
    break;
  case 0x0085: /* put_buffer_stream */
    if (arglist[1].ptrflag) 
      glk_put_buffer_stream(arglist[0].opaqueref, 
                            arglist[2].array, arglist[3].uint);
    else
      glk_put_buffer_stream(arglist[0].opaqueref, 
                            NULL, 0);
    break;
  case 0x0091: /* get_line_stream */
    if (arglist[1].ptrflag) 
      arglist[5].uint = glk_get_line_stream(arglist[0].opaqueref, 
                                            arglist[2].array, arglist[3].uint);
    else
      arglist[3].uint = glk_get_line_stream(arglist[0].opaqueref, 
                                            NULL, 0);
    break;
  case 0x0092: /* get_buffer_stream */
    if (arglist[1].ptrflag) 
      arglist[5].uint = glk_get_buffer_stream(arglist[0].opaqueref, 
                                              arglist[2].array, arglist[3].uint);
    else
      arglist[3].uint = glk_get_buffer_stream(arglist[0].opaqueref, 
                                              NULL, 0);
    break;
  case 0x00A0: /* char_to_lower */
    arglist[2].uch = glk_char_to_lower(arglist[0].uch);
    break;
  case 0x00A1: /* char_to_upper */
    arglist[2].uch = glk_char_to_upper(arglist[0].uch);
    break;
  case 0x00B1: /* stylehint_clear */
    glk_stylehint_clear(arglist[0].uint, arglist[1].uint,
                        arglist[2].uint);
    break;
  case 0x00B2: /* style_distinguish */
    arglist[4].uint = glk_style_distinguish(arglist[0].opaqueref, arglist[1].uint,
                                            arglist[2].uint);
    break;
  case 0x00B3: /* style_measure */
    if (arglist[3].ptrflag)
      arglist[6].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint,
                                          arglist[2].uint, &(arglist[4].uint));
    else
      arglist[5].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint,
                                          arglist[2].uint, NULL);
    break;
  case 0x00C1: /* select_poll */
    if (arglist[0].ptrflag) {
      event_t dat;
      glk_select_poll(&dat);
      arglist[1].uint = dat.type;
      arglist[2].opaqueref = dat.win;
      arglist[3].uint = dat.val1;
      arglist[4].uint = dat.val2;
    }
    else {
      glk_select_poll(NULL);
    }
    break;
  case 0x00D1: /* cancel_line_event */
    if (arglist[1].ptrflag) {
      event_t dat;
      glk_cancel_line_event(arglist[0].opaqueref, &dat);
      arglist[2].uint = dat.type;
      arglist[3].opaqueref = dat.win;
      arglist[4].uint = dat.val1;
      arglist[5].uint = dat.val2;
    }
    else {
      glk_cancel_line_event(arglist[0].opaqueref, NULL);
    }
    break;
  case 0x00D3: /* cancel_char_event */
    glk_cancel_char_event(arglist[0].opaqueref);
    break;
  case 0x00D4: /* request_mouse_event */
    glk_request_mouse_event(arglist[0].opaqueref);
    break;
  case 0x00D5: /* cancel_mouse_event */
    glk_cancel_mouse_event(arglist[0].opaqueref);
    break;
  case 0x00D6: /* request_timer_events */
    glk_request_timer_events(arglist[0].uint);
    break;

#ifdef GLK_MODULE_IMAGE
  case 0x00E8: /* window_flow_break */
    glk_window_flow_break(arglist[0].opaqueref);
    break;
  case 0x00E9: /* window_erase_rect */
    glk_window_erase_rect(arglist[0].opaqueref,
                          arglist[1].sint, arglist[2].sint,
                          arglist[3].uint, arglist[4].uint);
    break;
  case 0x00EB: /* window_set_background_color */
    glk_window_set_background_color(arglist[0].opaqueref, arglist[1].uint);
    break;
#endif /* GLK_MODULE_IMAGE */

#ifdef GLK_MODULE_SOUND
  case 0x00F0: /* schannel_iterate */
    if (arglist[1].ptrflag) 
      arglist[4].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, &arglist[2].uint);
    else
      arglist[3].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, NULL);
    break;
  case 0x00F1: /* schannel_get_rock */
    arglist[2].uint = glk_schannel_get_rock(arglist[0].opaqueref);
    break;
  case 0x00F2: /* schannel_create */
    arglist[2].opaqueref = glk_schannel_create(arglist[0].uint);
    break;
  case 0x00F3: /* schannel_destroy */
    glk_schannel_destroy(arglist[0].opaqueref);
    break;
  case 0x00F8: /* schannel_play */
    arglist[3].uint = glk_schannel_play(arglist[0].opaqueref, arglist[1].uint);
    break;
  case 0x00F9: /* schannel_play_ext */
    arglist[5].uint = glk_schannel_play_ext(arglist[0].opaqueref, 
                                            arglist[1].uint, arglist[2].uint, arglist[3].uint);
    break;
  case 0x00FA: /* schannel_stop */
    glk_schannel_stop(arglist[0].opaqueref);
    break;
  case 0x00FB: /* schannel_set_volume */
    glk_schannel_set_volume(arglist[0].opaqueref, arglist[1].uint);
    break;
  case 0x00FC: /* sound_load_hint */
    glk_sound_load_hint(arglist[0].uint, arglist[1].uint);
    break;
#endif /* GLK_MODULE_SOUND */

#ifdef GLK_MODULE_HYPERLINKS
  case 0x0100: /* set_hyperlink */
    glk_set_hyperlink(arglist[0].uint);
    break;
  case 0x0101: /* set_hyperlink_stream */
    glk_set_hyperlink_stream(arglist[0].opaqueref, arglist[1].uint);
    break;
  case 0x0102: /* request_hyperlink_event */
    glk_request_hyperlink_event(arglist[0].opaqueref);
    break;
  case 0x0103: /* cancel_hyperlink_event */
    glk_cancel_hyperlink_event(arglist[0].opaqueref);
    break;
#endif /* GLK_MODULE_HYPERLINKS */
            
#ifdef GLK_MODULE_UNICODE
  case 0x0120: /* buffer_to_lower_case_uni */
    if (arglist[0].ptrflag) 
      arglist[5].uint = glk_buffer_to_lower_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint);
    else
      arglist[3].uint = glk_buffer_to_lower_case_uni(NULL, 0, arglist[1].uint);
    break;
  case 0x0121: /* buffer_to_upper_case_uni */
    if (arglist[0].ptrflag) 
      arglist[5].uint = glk_buffer_to_upper_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint);
    else
      arglist[3].uint = glk_buffer_to_upper_case_uni(NULL, 0, arglist[1].uint);
    break;
  case 0x0122: /* buffer_to_title_case_uni */
    if (arglist[0].ptrflag) 
      arglist[6].uint = glk_buffer_to_title_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint);
    else
      arglist[4].uint = glk_buffer_to_title_case_uni(NULL, 0, arglist[1].uint, arglist[2].uint);
    break;
  case 0x0129: /* put_string_uni */
    glk_put_string_uni(arglist[0].unicharstr);
    break;
  case 0x012A: /* put_buffer_uni */
    if (arglist[0].ptrflag) 
      glk_put_buffer_uni(arglist[1].array, arglist[2].uint);
    else
      glk_put_buffer_uni(NULL, 0);
    break;
  case 0x012B: /* put_char_stream_uni */
    glk_put_char_stream_uni(arglist[0].opaqueref, arglist[1].uint);
    break;
  case 0x012C: /* put_string_stream_uni */
    glk_put_string_stream_uni(arglist[0].opaqueref, arglist[1].unicharstr);
    break;
  case 0x012D: /* put_buffer_stream_uni */
    if (arglist[1].ptrflag) 
      glk_put_buffer_stream_uni(arglist[0].opaqueref, 
                                arglist[2].array, arglist[3].uint);
    else
      glk_put_buffer_stream_uni(arglist[0].opaqueref, 
                                NULL, 0);
    break;
  case 0x0130: /* get_char_stream_uni */
    arglist[2].sint = glk_get_char_stream_uni(arglist[0].opaqueref);
    break;
  case 0x0131: /* get_buffer_stream_uni */
    if (arglist[1].ptrflag) 
      arglist[5].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, 
                                                  arglist[2].array, arglist[3].uint);
    else
      arglist[3].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, 
                                                  NULL, 0);
    break;
  case 0x0132: /* get_line_stream_uni */
    if (arglist[1].ptrflag) 
      arglist[5].uint = glk_get_line_stream_uni(arglist[0].opaqueref, 
                                                arglist[2].array, arglist[3].uint);
    else
      arglist[3].uint = glk_get_line_stream_uni(arglist[0].opaqueref, 
                                                NULL, 0);
    break;
  case 0x0138: /* stream_open_file_uni */
    arglist[4].opaqueref = glk_stream_open_file_uni(arglist[0].opaqueref, arglist[1].uint, 
                                                    arglist[2].uint);
    break;
  case 0x0140: /* request_char_event_uni */
    glk_request_char_event_uni(arglist[0].opaqueref);
    break;
  case 0x0141: /* request_line_event_uni */
    if (arglist[1].ptrflag)
      glk_request_line_event_uni(arglist[0].opaqueref, arglist[2].array,
                                 arglist[3].uint, arglist[4].uint);
    else
      glk_request_line_event_uni(arglist[0].opaqueref, NULL,
                                 0, arglist[2].uint);
    break;
#endif /* GLK_MODULE_UNICODE */
#endif /* 0 */
  }
}