Fixed ordering of the application of the styles
[rodin/chimara.git] / libchimara / gi_dispa.c
1 /* gi_dispa.c: Dispatch layer for Glk API, version 0.7.0.
2     Designed by Andrew Plotkin <erkyrath@eblong.com>
3     http://www.eblong.com/zarf/glk/index.html
4
5     This file is copyright 1998-2004 by Andrew Plotkin. You may copy,
6     distribute, and incorporate it into your own programs, by any means
7     and under any conditions, as long as you do not modify it. You may
8     also modify this file, incorporate it into your own programs,
9     and distribute the modified version, as long as you retain a notice
10     in your program or documentation which mentions my name and the URL
11     shown above.
12 */
13
14 /* This code should be linked into every Glk library, without change. 
15     Get the latest version from the URL above. */
16
17 #include "glk.h"
18 #include "gi_dispa.h"
19
20 #ifndef NULL
21 #define NULL 0
22 #endif
23
24 #define NUMCLASSES   \
25     (sizeof(class_table) / sizeof(gidispatch_intconst_t))
26
27 #define NUMINTCONSTANTS   \
28     (sizeof(intconstant_table) / sizeof(gidispatch_intconst_t))
29
30 #define NUMFUNCTIONS   \
31     (sizeof(function_table) / sizeof(gidispatch_function_t))
32
33 /* The constants in this table must be ordered alphabetically. */
34 static gidispatch_intconst_t class_table[] = {
35     { "fileref", (2) },   /* "Qc" */
36     { "schannel", (3) },  /* "Qd" */
37     { "stream", (1) },    /* "Qb" */
38     { "window", (0) },    /* "Qa" */
39 };
40
41 /* The constants in this table must be ordered alphabetically. */
42 static gidispatch_intconst_t intconstant_table[] = {
43     { "evtype_Arrange", (5)  },
44     { "evtype_CharInput", (2) },
45     { "evtype_Hyperlink", (8) },
46     { "evtype_LineInput", (3) },
47     { "evtype_MouseInput", (4) },
48     { "evtype_None", (0) },
49     { "evtype_Redraw", (6) },
50     { "evtype_SoundNotify", (7) },
51     { "evtype_Timer", (1) },
52     { "filemode_Read", (0x02) },
53     { "filemode_ReadWrite", (0x03) },
54     { "filemode_Write", (0x01) },
55     { "filemode_WriteAppend", (0x05) },
56     { "fileusage_BinaryMode", (0x000) },
57     { "fileusage_Data", (0x00) },
58     { "fileusage_InputRecord", (0x03) },
59     { "fileusage_SavedGame", (0x01) },
60     { "fileusage_TextMode",   (0x100) },
61     { "fileusage_Transcript", (0x02) },
62     { "fileusage_TypeMask", (0x0f) },
63     { "gestalt_CharInput", (1) },
64     { "gestalt_CharOutput", (3) },
65     { "gestalt_CharOutput_ApproxPrint", (1) },
66     { "gestalt_CharOutput_CannotPrint", (0) },
67     { "gestalt_CharOutput_ExactPrint", (2) },
68     { "gestalt_DrawImage", (7) },
69     { "gestalt_Graphics", (6) },
70     { "gestalt_GraphicsTransparency", (14) },
71     { "gestalt_HyperlinkInput", (12) },
72     { "gestalt_Hyperlinks", (11) },
73     { "gestalt_LineInput", (2) },
74     { "gestalt_MouseInput", (4) },
75     { "gestalt_Sound", (8) },
76     { "gestalt_SoundMusic", (13) },
77     { "gestalt_SoundNotify", (10) },
78     { "gestalt_SoundVolume", (9) },
79     { "gestalt_Timer", (5) },
80     { "gestalt_Unicode", (15) },
81     { "gestalt_Version", (0) },
82 #ifdef GLK_MODULE_IMAGE
83     { "imagealign_InlineCenter",  (0x03) },
84     { "imagealign_InlineDown",  (0x02) },
85     { "imagealign_MarginLeft",  (0x04) },
86     { "imagealign_MarginRight",  (0x05) },
87     { "imagealign_InlineUp",  (0x01) },
88 #endif /* GLK_MODULE_IMAGE */
89     { "keycode_Delete",   (0xfffffff9) },
90     { "keycode_Down",     (0xfffffffb) },
91     { "keycode_End",      (0xfffffff3) },
92     { "keycode_Escape",   (0xfffffff8) },
93     { "keycode_Func1",    (0xffffffef) },
94     { "keycode_Func10",   (0xffffffe6) },
95     { "keycode_Func11",   (0xffffffe5) },
96     { "keycode_Func12",   (0xffffffe4) },
97     { "keycode_Func2",    (0xffffffee) },
98     { "keycode_Func3",    (0xffffffed) },
99     { "keycode_Func4",    (0xffffffec) },
100     { "keycode_Func5",    (0xffffffeb) },
101     { "keycode_Func6",    (0xffffffea) },
102     { "keycode_Func7",    (0xffffffe9) },
103     { "keycode_Func8",    (0xffffffe8) },
104     { "keycode_Func9",    (0xffffffe7) },
105     { "keycode_Home",     (0xfffffff4) },
106     { "keycode_Left",     (0xfffffffe) },
107     { "keycode_MAXVAL",   (28)  },
108     { "keycode_PageDown", (0xfffffff5) },
109     { "keycode_PageUp",   (0xfffffff6) },
110     { "keycode_Return",   (0xfffffffa) },
111     { "keycode_Right",    (0xfffffffd) },
112     { "keycode_Tab",      (0xfffffff7) },
113     { "keycode_Unknown",  (0xffffffff) },
114     { "keycode_Up",       (0xfffffffc) },
115     { "seekmode_Current", (1) },
116     { "seekmode_End", (2) },
117     { "seekmode_Start", (0) },
118     { "style_Alert", (5) },
119     { "style_BlockQuote", (7) },
120     { "style_Emphasized", (1) },
121     { "style_Header", (3) },
122     { "style_Input", (8) },
123     { "style_NUMSTYLES", (11) },
124     { "style_Normal", (0) },
125     { "style_Note", (6) },
126     { "style_Preformatted", (2) },
127     { "style_Subheader", (4) },
128     { "style_User1", (9) },
129     { "style_User2", (10) },
130     { "stylehint_BackColor", (8) },
131     { "stylehint_Indentation", (0) },
132     { "stylehint_Justification", (2)  },
133     { "stylehint_NUMHINTS", (10) },
134     { "stylehint_Oblique", (5) },
135     { "stylehint_ParaIndentation", (1) },
136     { "stylehint_Proportional", (6) },
137     { "stylehint_ReverseColor", (9) },
138     { "stylehint_Size", (3) },
139     { "stylehint_TextColor", (7) },
140     { "stylehint_Weight", (4) },
141     { "stylehint_just_Centered", (2) },
142     { "stylehint_just_LeftFlush", (0) },
143     { "stylehint_just_LeftRight", (1) },
144     { "stylehint_just_RightFlush", (3) },
145     { "winmethod_Above", (0x02)  },
146     { "winmethod_Below", (0x03)  },
147     { "winmethod_DirMask", (0x0f) },
148     { "winmethod_DivisionMask", (0xf0) },
149     { "winmethod_Fixed", (0x10) },
150     { "winmethod_Left",  (0x00)  },
151     { "winmethod_Proportional", (0x20) },
152     { "winmethod_Right", (0x01)  },
153     { "wintype_AllTypes", (0)  },
154     { "wintype_Blank", (2)  },
155     { "wintype_Graphics", (5)  },
156     { "wintype_Pair", (1)  },
157     { "wintype_TextBuffer", (3) },
158     { "wintype_TextGrid", (4) },
159 };
160
161 /* The functions in this table must be ordered by id. */
162 static gidispatch_function_t function_table[] = {
163     { 0x0001, glk_exit, "exit" },
164     { 0x0002, glk_set_interrupt_handler, "set_interrupt_handler" },
165     { 0x0003, glk_tick, "tick" },
166     { 0x0004, glk_gestalt, "gestalt" },
167     { 0x0005, glk_gestalt_ext, "gestalt_ext" },
168     { 0x0020, glk_window_iterate, "window_iterate" },
169     { 0x0021, glk_window_get_rock, "window_get_rock" },
170     { 0x0022, glk_window_get_root, "window_get_root" },
171     { 0x0023, glk_window_open, "window_open" },
172     { 0x0024, glk_window_close, "window_close" },
173     { 0x0025, glk_window_get_size, "window_get_size" },
174     { 0x0026, glk_window_set_arrangement, "window_set_arrangement" },
175     { 0x0027, glk_window_get_arrangement, "window_get_arrangement" },
176     { 0x0028, glk_window_get_type, "window_get_type" },
177     { 0x0029, glk_window_get_parent, "window_get_parent" },
178     { 0x002A, glk_window_clear, "window_clear" },
179     { 0x002B, glk_window_move_cursor, "window_move_cursor" },
180     { 0x002C, glk_window_get_stream, "window_get_stream" },
181     { 0x002D, glk_window_set_echo_stream, "window_set_echo_stream" },
182     { 0x002E, glk_window_get_echo_stream, "window_get_echo_stream" },
183     { 0x002F, glk_set_window, "set_window" },
184     { 0x0030, glk_window_get_sibling, "window_get_sibling" },
185     { 0x0040, glk_stream_iterate, "stream_iterate" },
186     { 0x0041, glk_stream_get_rock, "stream_get_rock" },
187     { 0x0042, glk_stream_open_file, "stream_open_file" },
188     { 0x0043, glk_stream_open_memory, "stream_open_memory" },
189     { 0x0044, glk_stream_close, "stream_close" },
190     { 0x0045, glk_stream_set_position, "stream_set_position" },
191     { 0x0046, glk_stream_get_position, "stream_get_position" },
192     { 0x0047, glk_stream_set_current, "stream_set_current" },
193     { 0x0048, glk_stream_get_current, "stream_get_current" },
194     { 0x0060, glk_fileref_create_temp, "fileref_create_temp" },
195     { 0x0061, glk_fileref_create_by_name, "fileref_create_by_name" },
196     { 0x0062, glk_fileref_create_by_prompt, "fileref_create_by_prompt" },
197     { 0x0063, glk_fileref_destroy, "fileref_destroy" },
198     { 0x0064, glk_fileref_iterate, "fileref_iterate" },
199     { 0x0065, glk_fileref_get_rock, "fileref_get_rock" },
200     { 0x0066, glk_fileref_delete_file, "fileref_delete_file" },
201     { 0x0067, glk_fileref_does_file_exist, "fileref_does_file_exist" },
202     { 0x0068, glk_fileref_create_from_fileref, "fileref_create_from_fileref" },
203     { 0x0080, glk_put_char, "put_char" },
204     { 0x0081, glk_put_char_stream, "put_char_stream" },
205     { 0x0082, glk_put_string, "put_string" },
206     { 0x0083, glk_put_string_stream, "put_string_stream" },
207     { 0x0084, glk_put_buffer, "put_buffer" },
208     { 0x0085, glk_put_buffer_stream, "put_buffer_stream" },
209     { 0x0086, glk_set_style, "set_style" },
210     { 0x0087, glk_set_style_stream, "set_style_stream" },
211     { 0x0090, glk_get_char_stream, "get_char_stream" },
212     { 0x0091, glk_get_line_stream, "get_line_stream" },
213     { 0x0092, glk_get_buffer_stream, "get_buffer_stream" },
214     { 0x00A0, glk_char_to_lower, "char_to_lower" },
215     { 0x00A1, glk_char_to_upper, "char_to_upper" },
216     { 0x00B0, glk_stylehint_set, "stylehint_set" },
217     { 0x00B1, glk_stylehint_clear, "stylehint_clear" },
218     { 0x00B2, glk_style_distinguish, "style_distinguish" },
219     { 0x00B3, glk_style_measure, "style_measure" },
220     { 0x00C0, glk_select, "select" },
221     { 0x00C1, glk_select_poll, "select_poll" },
222     { 0x00D0, glk_request_line_event, "request_line_event" },
223     { 0x00D1, glk_cancel_line_event, "cancel_line_event" },
224     { 0x00D2, glk_request_char_event, "request_char_event" },
225     { 0x00D3, glk_cancel_char_event, "cancel_char_event" },
226     { 0x00D4, glk_request_mouse_event, "request_mouse_event" },
227     { 0x00D5, glk_cancel_mouse_event, "cancel_mouse_event" },
228     { 0x00D6, glk_request_timer_events, "request_timer_events" },
229 #ifdef GLK_MODULE_IMAGE
230     { 0x00E0, glk_image_get_info, "image_get_info" },
231     { 0x00E1, glk_image_draw, "image_draw" },
232     { 0x00E2, glk_image_draw_scaled, "image_draw_scaled" },
233     { 0x00E8, glk_window_flow_break, "window_flow_break" },
234     { 0x00E9, glk_window_erase_rect, "window_erase_rect" },
235     { 0x00EA, glk_window_fill_rect, "window_fill_rect" },
236     { 0x00EB, glk_window_set_background_color, "window_set_background_color" },
237 #endif /* GLK_MODULE_IMAGE */
238 #ifdef GLK_MODULE_SOUND
239     { 0x00F0, glk_schannel_iterate, "schannel_iterate" },
240     { 0x00F1, glk_schannel_get_rock, "schannel_get_rock" },
241     { 0x00F2, glk_schannel_create, "schannel_create" },
242     { 0x00F3, glk_schannel_destroy, "schannel_destroy" },
243     { 0x00F8, glk_schannel_play, "schannel_play" },
244     { 0x00F9, glk_schannel_play_ext, "schannel_play_ext" },
245     { 0x00FA, glk_schannel_stop, "schannel_stop" },
246     { 0x00FB, glk_schannel_set_volume, "schannel_set_volume" },
247     { 0x00FC, glk_sound_load_hint, "sound_load_hint" },
248 #endif /* GLK_MODULE_SOUND */
249 #ifdef GLK_MODULE_HYPERLINKS
250     { 0x0100, glk_set_hyperlink, "set_hyperlink" },
251     { 0x0101, glk_set_hyperlink_stream, "set_hyperlink_stream" },
252     { 0x0102, glk_request_hyperlink_event, "request_hyperlink_event" },
253     { 0x0103, glk_cancel_hyperlink_event, "cancel_hyperlink_event" },
254 #endif /* GLK_MODULE_HYPERLINKS */
255 #ifdef GLK_MODULE_UNICODE
256     { 0x0120, glk_buffer_to_lower_case_uni, "buffer_to_lower_case_uni" },
257     { 0x0121, glk_buffer_to_upper_case_uni, "buffer_to_upper_case_uni" },
258     { 0x0122, glk_buffer_to_title_case_uni, "buffer_to_title_case_uni" },
259     { 0x0128, glk_put_char_uni, "put_char_uni" },
260     { 0x0129, glk_put_string_uni, "put_string_uni" },
261     { 0x012A, glk_put_buffer_uni, "put_buffer_uni" },
262     { 0x012B, glk_put_char_stream_uni, "put_char_stream_uni" },
263     { 0x012C, glk_put_string_stream_uni, "put_string_stream_uni" },
264     { 0x012D, glk_put_buffer_stream_uni, "put_buffer_stream_uni" },
265     { 0x0130, glk_get_char_stream_uni, "get_char_stream_uni" },
266     { 0x0131, glk_get_buffer_stream_uni, "get_buffer_stream_uni" },
267     { 0x0132, glk_get_line_stream_uni, "get_line_stream_uni" },
268     { 0x0138, glk_stream_open_file_uni, "stream_open_file_uni" },
269     { 0x0139, glk_stream_open_memory_uni, "stream_open_memory_uni" },
270     { 0x0140, glk_request_char_event_uni, "request_char_event_uni" },
271     { 0x0141, glk_request_line_event_uni, "request_line_event_uni" },
272 #endif /* GLK_MODULE_UNICODE */
273 };
274
275 glui32 gidispatch_count_classes()
276 {
277     return NUMCLASSES;
278 }
279
280 gidispatch_intconst_t *gidispatch_get_class(glui32 index)
281 {
282     if (index < 0 || index >= NUMCLASSES)
283         return NULL;
284     return &(class_table[index]);
285 }
286
287 glui32 gidispatch_count_intconst()
288 {
289     return NUMINTCONSTANTS;
290 }
291
292 gidispatch_intconst_t *gidispatch_get_intconst(glui32 index)
293 {
294     if (index < 0 || index >= NUMINTCONSTANTS)
295         return NULL;
296     return &(intconstant_table[index]);
297 }
298
299 glui32 gidispatch_count_functions()
300 {
301     return NUMFUNCTIONS;
302 }
303
304 gidispatch_function_t *gidispatch_get_function(glui32 index)
305 {
306     if (index < 0 || index >= NUMFUNCTIONS)
307         return NULL;
308     return &(function_table[index]);
309 }
310
311 gidispatch_function_t *gidispatch_get_function_by_id(glui32 id)
312 {
313     int top, bot, val;
314     gidispatch_function_t *func;
315     
316     bot = 0;
317     top = NUMFUNCTIONS;
318     
319     while (1) {
320         val = (top+bot) / 2;
321         func = &(function_table[val]);
322         if (func->id == id)
323             return func;
324         if (bot >= top-1)
325             break;
326         if (func->id < id) {
327             bot = val+1;
328         }
329         else {
330             top = val;
331         }
332     }
333     
334     return NULL;
335 }
336
337 char *gidispatch_prototype(glui32 funcnum)
338 {
339     switch (funcnum) {
340         case 0x0001: /* exit */
341             return "0:";
342         case 0x0002: /* set_interrupt_handler */
343             /* cannot be invoked through dispatch layer */
344             return NULL;
345         case 0x0003: /* tick */
346             return "0:";
347         case 0x0004: /* gestalt */
348             return "3IuIu:Iu";
349         case 0x0005: /* gestalt_ext */
350             return "4IuIu&#Iu:Iu";
351         case 0x0020: /* window_iterate */
352             return "3Qa<Iu:Qa";
353         case 0x0021: /* window_get_rock */
354             return "2Qa:Iu";
355         case 0x0022: /* window_get_root */
356             return "1:Qa";
357         case 0x0023: /* window_open */
358             return "6QaIuIuIuIu:Qa";
359         case 0x0024: /* window_close */
360             return "2Qa<[2IuIu]:";
361         case 0x0025: /* window_get_size */
362             return "3Qa<Iu<Iu:";
363         case 0x0026: /* window_set_arrangement */
364             return "4QaIuIuQa:";
365         case 0x0027: /* window_get_arrangement */
366             return "4Qa<Iu<Iu<Qa:";
367         case 0x0028: /* window_get_type */
368             return "2Qa:Iu";
369         case 0x0029: /* window_get_parent */
370             return "2Qa:Qa";
371         case 0x002A: /* window_clear */
372             return "1Qa:";
373         case 0x002B: /* window_move_cursor */
374             return "3QaIuIu:";
375         case 0x002C: /* window_get_stream */
376             return "2Qa:Qb";
377         case 0x002D: /* window_set_echo_stream */
378             return "2QaQb:";
379         case 0x002E: /* window_get_echo_stream */
380             return "2Qa:Qb";
381         case 0x002F: /* set_window */
382             return "1Qa:";
383         case 0x0030: /* window_get_sibling */
384             return "2Qa:Qa";
385         case 0x0040: /* stream_iterate */
386             return "3Qb<Iu:Qb";
387         case 0x0041: /* stream_get_rock */
388             return "2Qb:Iu";
389         case 0x0042: /* stream_open_file */
390             return "4QcIuIu:Qb";
391         case 0x0043: /* stream_open_memory */
392             return "4&+#!CnIuIu:Qb";
393         case 0x0044: /* stream_close */
394             return "2Qb<[2IuIu]:";
395         case 0x0045: /* stream_set_position */
396             return "3QbIsIu:";
397         case 0x0046: /* stream_get_position */
398             return "2Qb:Iu";
399         case 0x0047: /* stream_set_current */
400             return "1Qb:";
401         case 0x0048: /* stream_get_current */
402             return "1:Qb";
403         case 0x0060: /* fileref_create_temp */
404             return "3IuIu:Qc";
405         case 0x0061: /* fileref_create_by_name */
406             return "4IuSIu:Qc";
407         case 0x0062: /* fileref_create_by_prompt */
408             return "4IuIuIu:Qc";
409         case 0x0063: /* fileref_destroy */
410             return "1Qc:";
411         case 0x0064: /* fileref_iterate */
412             return "3Qc<Iu:Qc";
413         case 0x0065: /* fileref_get_rock */
414             return "2Qc:Iu";
415         case 0x0066: /* fileref_delete_file */
416             return "1Qc:";
417         case 0x0067: /* fileref_does_file_exist */
418             return "2Qc:Iu";
419         case 0x0068: /* fileref_create_from_fileref */
420             return "4IuQcIu:Qc";
421         case 0x0080: /* put_char */
422             return "1Cu:";
423         case 0x0081: /* put_char_stream */
424             return "2QbCu:";
425         case 0x0082: /* put_string */
426             return "1S:";
427         case 0x0083: /* put_string_stream */
428             return "2QbS:";
429         case 0x0084: /* put_buffer */
430             return "1>+#Cn:";
431         case 0x0085: /* put_buffer_stream */
432             return "2Qb>+#Cn:"; 
433         case 0x0086: /* set_style */
434             return "1Iu:";
435         case 0x0087: /* set_style_stream */
436             return "2QbIu:";
437         case 0x0090: /* get_char_stream */
438             return "2Qb:Is";
439         case 0x0091: /* get_line_stream */
440             return "3Qb<+#Cn:Iu"; 
441         case 0x0092: /* get_buffer_stream */
442             return "3Qb<+#Cn:Iu"; 
443         case 0x00A0: /* char_to_lower */
444             return "2Cu:Cu";
445         case 0x00A1: /* char_to_upper */
446             return "2Cu:Cu";
447         case 0x00B0: /* stylehint_set */
448             return "4IuIuIuIs:";
449         case 0x00B1: /* stylehint_clear */
450             return "3IuIuIu:";
451         case 0x00B2: /* style_distinguish */
452             return "4QaIuIu:Iu";
453         case 0x00B3: /* style_measure */
454             return "5QaIuIu<Iu:Iu";
455         case 0x00C0: /* select */
456             return "1<+[4IuQaIuIu]:";
457         case 0x00C1: /* select_poll */
458             return "1<+[4IuQaIuIu]:";
459         case 0x00D0: /* request_line_event */
460             return "3Qa&+#!CnIu:";
461         case 0x00D1: /* cancel_line_event */
462             return "2Qa<[4IuQaIuIu]:";
463         case 0x00D2: /* request_char_event */
464             return "1Qa:";
465         case 0x00D3: /* cancel_char_event */
466             return "1Qa:";
467         case 0x00D4: /* request_mouse_event */
468             return "1Qa:";
469         case 0x00D5: /* cancel_mouse_event */
470             return "1Qa:";
471         case 0x00D6: /* request_timer_events */
472             return "1Iu:";
473
474 #ifdef GLK_MODULE_IMAGE
475         case 0x00E0: /* image_get_info */
476             return "4Iu<Iu<Iu:Iu";
477         case 0x00E1: /* image_draw */
478             return "5QaIuIsIs:Iu";
479         case 0x00E2: /* image_draw_scaled */
480             return "7QaIuIsIsIuIu:Iu";
481         case 0x00E8: /* window_flow_break */
482             return "1Qa:";
483         case 0x00E9: /* window_erase_rect */
484             return "5QaIsIsIuIu:";
485         case 0x00EA: /* window_fill_rect */
486             return "6QaIuIsIsIuIu:";
487         case 0x00EB: /* window_set_background_color */
488             return "2QaIu:";
489 #endif /* GLK_MODULE_IMAGE */
490
491 #ifdef GLK_MODULE_SOUND
492         case 0x00F0: /* schannel_iterate */
493             return "3Qd<Iu:Qd";
494         case 0x00F1: /* schannel_get_rock */
495             return "2Qd:Iu";
496         case 0x00F2: /* schannel_create */
497             return "2Iu:Qd";
498         case 0x00F3: /* schannel_destroy */
499             return "1Qd:";
500         case 0x00F8: /* schannel_play */
501             return "3QdIu:Iu";
502         case 0x00F9: /* schannel_play_ext */
503             return "5QdIuIuIu:Iu";
504         case 0x00FA: /* schannel_stop */
505             return "1Qd:";
506         case 0x00FB: /* schannel_set_volume */
507             return "2QdIu:";
508         case 0x00FC: /* sound_load_hint */
509             return "2IuIu:";
510 #endif /* GLK_MODULE_SOUND */
511
512 #ifdef GLK_MODULE_HYPERLINKS
513         case 0x0100: /* set_hyperlink */
514             return "1Iu:";
515         case 0x0101: /* set_hyperlink_stream */
516             return "2QbIu:";
517         case 0x0102: /* request_hyperlink_event */
518             return "1Qa:";
519         case 0x0103: /* cancel_hyperlink_event */
520             return "1Qa:";
521 #endif /* GLK_MODULE_HYPERLINKS */
522
523 #ifdef GLK_MODULE_UNICODE
524         case 0x0120: /* buffer_to_lower_case_uni */
525             return "3&+#IuIu:Iu";
526         case 0x0121: /* buffer_to_upper_case_uni */
527             return "3&+#IuIu:Iu";
528         case 0x0122: /* buffer_to_title_case_uni */
529             return "4&+#IuIuIu:Iu";
530         case 0x0128: /* put_char_uni */
531             return "1Iu:";
532         case 0x0129: /* put_string_uni */
533             return "1U:";
534         case 0x012A: /* put_buffer_uni */
535             return "1>+#Iu:";
536         case 0x012B: /* put_char_stream_uni */
537             return "2QbIu:";
538         case 0x012C: /* put_string_stream_uni */
539             return "2QbU:";
540         case 0x012D: /* put_buffer_stream_uni */
541             return "2Qb>+#Iu:"; 
542         case 0x0130: /* get_char_stream_uni */
543             return "2Qb:Is";
544         case 0x0131: /* get_buffer_stream_uni */
545             return "3Qb<+#Iu:Iu"; 
546         case 0x0132: /* get_line_stream_uni */
547             return "3Qb<+#Iu:Iu"; 
548         case 0x0138: /* stream_open_file_uni */
549             return "4QcIuIu:Qb";
550         case 0x0139: /* stream_open_memory_uni */
551             return "4&+#!IuIuIu:Qb";
552         case 0x0140: /* request_char_event_uni */
553             return "1Qa:";
554         case 0x0141: /* request_line_event_uni */
555             return "3Qa&+#!IuIu:";
556 #endif /* GLK_MODULE_UNICODE */
557             
558         default:
559             return NULL;
560     }
561 }
562
563 void gidispatch_call(glui32 funcnum, glui32 numargs, gluniversal_t *arglist)
564 {
565     switch (funcnum) {
566         case 0x0001: /* exit */
567             glk_exit();
568             break;
569         case 0x0002: /* set_interrupt_handler */
570             /* cannot be invoked through dispatch layer */
571             break;
572         case 0x0003: /* tick */
573             glk_tick();
574             break;
575         case 0x0004: /* gestalt */
576             arglist[3].uint = glk_gestalt(arglist[0].uint, arglist[1].uint);
577             break;
578         case 0x0005: /* gestalt_ext */
579             if (arglist[2].ptrflag) {
580                 arglist[6].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint,
581                     arglist[3].array, arglist[4].uint);
582             }
583             else {
584                 arglist[4].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint,
585                     NULL, 0);
586             }
587             break;
588         case 0x0020: /* window_iterate */
589             if (arglist[1].ptrflag) 
590                 arglist[4].opaqueref = glk_window_iterate(arglist[0].opaqueref, &arglist[2].uint);
591             else
592                 arglist[3].opaqueref = glk_window_iterate(arglist[0].opaqueref, NULL);
593             break;
594         case 0x0021: /* window_get_rock */
595             arglist[2].uint = glk_window_get_rock(arglist[0].opaqueref);
596             break;
597         case 0x0022: /* window_get_root */
598             arglist[1].opaqueref = glk_window_get_root();
599             break;
600         case 0x0023: /* window_open */
601             arglist[6].opaqueref = glk_window_open(arglist[0].opaqueref, arglist[1].uint, 
602                 arglist[2].uint, arglist[3].uint, arglist[4].uint);
603             break;
604         case 0x0024: /* window_close */
605             if (arglist[1].ptrflag) {
606                 stream_result_t dat;
607                 glk_window_close(arglist[0].opaqueref, &dat);
608                 arglist[2].uint = dat.readcount;
609                 arglist[3].uint = dat.writecount;
610             }
611             else {
612                 glk_window_close(arglist[0].opaqueref, NULL);
613             }
614             break;
615         case 0x0025: /* window_get_size */
616             {
617                 int ix = 1;
618                 glui32 *ptr1, *ptr2;
619                 if (!arglist[ix].ptrflag) {
620                     ptr1 = NULL;
621                 }
622                 else {
623                     ix++;
624                     ptr1 = &(arglist[ix].uint);
625                 }
626                 ix++;
627                 if (!arglist[ix].ptrflag) {
628                     ptr2 = NULL;
629                 }
630                 else {
631                     ix++;
632                     ptr2 = &(arglist[ix].uint);
633                 }
634                 ix++;
635                 glk_window_get_size(arglist[0].opaqueref, ptr1, ptr2);
636             }
637             break;
638         case 0x0026: /* window_set_arrangement */
639             glk_window_set_arrangement(arglist[0].opaqueref, arglist[1].uint, 
640                 arglist[2].uint, arglist[3].opaqueref);
641             break;
642         case 0x0027: /* window_get_arrangement */
643             {
644                 int ix = 1;
645                 glui32 *ptr1, *ptr2;
646                 winid_t *ptr3;
647                 if (!arglist[ix].ptrflag) {
648                     ptr1 = NULL;
649                 }
650                 else {
651                     ix++;
652                     ptr1 = &(arglist[ix].uint);
653                 }
654                 ix++;
655                 if (!arglist[ix].ptrflag) {
656                     ptr2 = NULL;
657                 }
658                 else {
659                     ix++;
660                     ptr2 = &(arglist[ix].uint);
661                 }
662                 ix++;
663                 if (!arglist[ix].ptrflag) {
664                     ptr3 = NULL;
665                 }
666                 else {
667                     ix++;
668                     ptr3 = (winid_t *)(&(arglist[ix].opaqueref));
669                 }
670                 ix++;
671                 glk_window_get_arrangement(arglist[0].opaqueref, ptr1, ptr2, ptr3);
672             }
673             break;
674         case 0x0028: /* window_get_type */
675             arglist[2].uint = glk_window_get_type(arglist[0].opaqueref);
676             break;
677         case 0x0029: /* window_get_parent */
678             arglist[2].opaqueref = glk_window_get_parent(arglist[0].opaqueref);
679             break;
680         case 0x002A: /* window_clear */
681             glk_window_clear(arglist[0].opaqueref);
682             break;
683         case 0x002B: /* window_move_cursor */
684             glk_window_move_cursor(arglist[0].opaqueref, arglist[1].uint, 
685                 arglist[2].uint);
686             break;
687         case 0x002C: /* window_get_stream */
688             arglist[2].opaqueref = glk_window_get_stream(arglist[0].opaqueref);
689             break;
690         case 0x002D: /* window_set_echo_stream */
691             glk_window_set_echo_stream(arglist[0].opaqueref, arglist[1].opaqueref);
692             break;
693         case 0x002E: /* window_get_echo_stream */
694             arglist[2].opaqueref = glk_window_get_echo_stream(arglist[0].opaqueref);
695             break;
696         case 0x002F: /* set_window */
697             glk_set_window(arglist[0].opaqueref);
698             break;
699         case 0x0030: /* window_get_sibling */
700             arglist[2].opaqueref = glk_window_get_sibling(arglist[0].opaqueref);
701             break;
702         case 0x0040: /* stream_iterate */
703             if (arglist[1].ptrflag) 
704                 arglist[4].opaqueref = glk_stream_iterate(arglist[0].opaqueref, &arglist[2].uint);
705             else
706                 arglist[3].opaqueref = glk_stream_iterate(arglist[0].opaqueref, NULL);
707             break;
708         case 0x0041: /* stream_get_rock */
709             arglist[2].uint = glk_stream_get_rock(arglist[0].opaqueref);
710             break;
711         case 0x0042: /* stream_open_file */
712             arglist[4].opaqueref = glk_stream_open_file(arglist[0].opaqueref, arglist[1].uint, 
713                 arglist[2].uint);
714             break;
715         case 0x0043: /* stream_open_memory */
716             if (arglist[0].ptrflag) 
717                 arglist[6].opaqueref = glk_stream_open_memory(arglist[1].array, 
718                     arglist[2].uint, arglist[3].uint, arglist[4].uint);
719             else
720                 arglist[4].opaqueref = glk_stream_open_memory(NULL, 
721                     0, arglist[1].uint, arglist[2].uint);
722             break;
723         case 0x0044: /* stream_close */
724             if (arglist[1].ptrflag) {
725                 stream_result_t dat;
726                 glk_stream_close(arglist[0].opaqueref, &dat);
727                 arglist[2].uint = dat.readcount;
728                 arglist[3].uint = dat.writecount;
729             }
730             else {
731                 glk_stream_close(arglist[0].opaqueref, NULL);
732             }
733             break;
734         case 0x0045: /* stream_set_position */
735             glk_stream_set_position(arglist[0].opaqueref, arglist[1].sint,
736                 arglist[2].uint);
737             break;
738         case 0x0046: /* stream_get_position */
739             arglist[2].uint = glk_stream_get_position(arglist[0].opaqueref);
740             break;
741         case 0x0047: /* stream_set_current */
742             glk_stream_set_current(arglist[0].opaqueref);
743             break;
744         case 0x0048: /* stream_get_current */
745             arglist[1].opaqueref = glk_stream_get_current();
746             break;
747         case 0x0060: /* fileref_create_temp */
748             arglist[3].opaqueref = glk_fileref_create_temp(arglist[0].uint, 
749                 arglist[1].uint);
750             break;
751         case 0x0061: /* fileref_create_by_name */
752             arglist[4].opaqueref = glk_fileref_create_by_name(arglist[0].uint, 
753                 arglist[1].charstr, arglist[2].uint);
754             break;
755         case 0x0062: /* fileref_create_by_prompt */
756             arglist[4].opaqueref = glk_fileref_create_by_prompt(arglist[0].uint, 
757                 arglist[1].uint, arglist[2].uint);
758             break;
759         case 0x0063: /* fileref_destroy */
760             glk_fileref_destroy(arglist[0].opaqueref);
761             break;
762         case 0x0064: /* fileref_iterate */
763             if (arglist[1].ptrflag) 
764                 arglist[4].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, &arglist[2].uint);
765             else
766                 arglist[3].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, NULL);
767             break;
768         case 0x0065: /* fileref_get_rock */
769             arglist[2].uint = glk_fileref_get_rock(arglist[0].opaqueref);
770             break;
771         case 0x0066: /* fileref_delete_file */
772             glk_fileref_delete_file(arglist[0].opaqueref);
773             break;
774         case 0x0067: /* fileref_does_file_exist */
775             arglist[2].uint = glk_fileref_does_file_exist(arglist[0].opaqueref);
776             break;
777         case 0x0068: /* fileref_create_from_fileref */
778             arglist[4].opaqueref = glk_fileref_create_from_fileref(arglist[0].uint, 
779                 arglist[1].opaqueref, arglist[2].uint);
780             break;
781         case 0x0080: /* put_char */
782             glk_put_char(arglist[0].uch);
783             break;
784         case 0x0081: /* put_char_stream */
785             glk_put_char_stream(arglist[0].opaqueref, arglist[1].uch);
786             break;
787         case 0x0082: /* put_string */
788             glk_put_string(arglist[0].charstr);
789             break;
790         case 0x0083: /* put_string_stream */
791             glk_put_string_stream(arglist[0].opaqueref, arglist[1].charstr);
792             break;
793         case 0x0084: /* put_buffer */
794             if (arglist[0].ptrflag) 
795                 glk_put_buffer(arglist[1].array, arglist[2].uint);
796             else
797                 glk_put_buffer(NULL, 0);
798             break;
799         case 0x0085: /* put_buffer_stream */
800             if (arglist[1].ptrflag) 
801                 glk_put_buffer_stream(arglist[0].opaqueref, 
802                     arglist[2].array, arglist[3].uint);
803             else
804                 glk_put_buffer_stream(arglist[0].opaqueref, 
805                     NULL, 0);
806             break;
807         case 0x0086: /* set_style */
808             glk_set_style(arglist[0].uint);
809             break;
810         case 0x0087: /* set_style_stream */
811             glk_set_style_stream(arglist[0].opaqueref, arglist[1].uint);
812             break;
813         case 0x0090: /* get_char_stream */
814             arglist[2].sint = glk_get_char_stream(arglist[0].opaqueref);
815             break;
816         case 0x0091: /* get_line_stream */
817             if (arglist[1].ptrflag) 
818                 arglist[5].uint = glk_get_line_stream(arglist[0].opaqueref, 
819                     arglist[2].array, arglist[3].uint);
820             else
821                 arglist[3].uint = glk_get_line_stream(arglist[0].opaqueref, 
822                     NULL, 0);
823             break;
824         case 0x0092: /* get_buffer_stream */
825             if (arglist[1].ptrflag) 
826                 arglist[5].uint = glk_get_buffer_stream(arglist[0].opaqueref, 
827                     arglist[2].array, arglist[3].uint);
828             else
829                 arglist[3].uint = glk_get_buffer_stream(arglist[0].opaqueref, 
830                     NULL, 0);
831             break;
832         case 0x00A0: /* char_to_lower */
833             arglist[2].uch = glk_char_to_lower(arglist[0].uch);
834             break;
835         case 0x00A1: /* char_to_upper */
836             arglist[2].uch = glk_char_to_upper(arglist[0].uch);
837             break;
838         case 0x00B0: /* stylehint_set */
839             glk_stylehint_set(arglist[0].uint, arglist[1].uint,
840                 arglist[2].uint, arglist[3].sint);
841             break;
842         case 0x00B1: /* stylehint_clear */
843             glk_stylehint_clear(arglist[0].uint, arglist[1].uint,
844                 arglist[2].uint);
845             break;
846         case 0x00B2: /* style_distinguish */
847             arglist[4].uint = glk_style_distinguish(arglist[0].opaqueref, arglist[1].uint,
848                 arglist[2].uint);
849             break;
850         case 0x00B3: /* style_measure */
851             if (arglist[3].ptrflag)
852                 arglist[6].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint,
853                     arglist[2].uint, &(arglist[4].uint));
854             else
855                 arglist[5].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint,
856                     arglist[2].uint, NULL);
857             break;
858         case 0x00C0: /* select */
859             if (arglist[0].ptrflag) {
860                 event_t dat;
861                 glk_select(&dat);
862                 arglist[1].uint = dat.type;
863                 arglist[2].opaqueref = dat.win;
864                 arglist[3].uint = dat.val1;
865                 arglist[4].uint = dat.val2;
866             }
867             else {
868                 glk_select(NULL);
869             }
870             break;
871         case 0x00C1: /* select_poll */
872             if (arglist[0].ptrflag) {
873                 event_t dat;
874                 glk_select_poll(&dat);
875                 arglist[1].uint = dat.type;
876                 arglist[2].opaqueref = dat.win;
877                 arglist[3].uint = dat.val1;
878                 arglist[4].uint = dat.val2;
879             }
880             else {
881                 glk_select_poll(NULL);
882             }
883             break;
884         case 0x00D0: /* request_line_event */
885             if (arglist[1].ptrflag)
886                 glk_request_line_event(arglist[0].opaqueref, arglist[2].array,
887                     arglist[3].uint, arglist[4].uint);
888             else
889                 glk_request_line_event(arglist[0].opaqueref, NULL,
890                     0, arglist[2].uint);
891             break;
892         case 0x00D1: /* cancel_line_event */
893             if (arglist[1].ptrflag) {
894                 event_t dat;
895                 glk_cancel_line_event(arglist[0].opaqueref, &dat);
896                 arglist[2].uint = dat.type;
897                 arglist[3].opaqueref = dat.win;
898                 arglist[4].uint = dat.val1;
899                 arglist[5].uint = dat.val2;
900             }
901             else {
902                 glk_cancel_line_event(arglist[0].opaqueref, NULL);
903             }
904             break;
905         case 0x00D2: /* request_char_event */
906             glk_request_char_event(arglist[0].opaqueref);
907             break;
908         case 0x00D3: /* cancel_char_event */
909             glk_cancel_char_event(arglist[0].opaqueref);
910             break;
911         case 0x00D4: /* request_mouse_event */
912             glk_request_mouse_event(arglist[0].opaqueref);
913             break;
914         case 0x00D5: /* cancel_mouse_event */
915             glk_cancel_mouse_event(arglist[0].opaqueref);
916             break;
917         case 0x00D6: /* request_timer_events */
918             glk_request_timer_events(arglist[0].uint);
919             break;
920
921 #ifdef GLK_MODULE_IMAGE
922         case 0x00E0: /* image_get_info */
923             {
924                 int ix = 1;
925                 glui32 *ptr1, *ptr2;
926                 if (!arglist[ix].ptrflag) {
927                     ptr1 = NULL;
928                 }
929                 else {
930                     ix++;
931                     ptr1 = &(arglist[ix].uint);
932                 }
933                 ix++;
934                 if (!arglist[ix].ptrflag) {
935                     ptr2 = NULL;
936                 }
937                 else {
938                     ix++;
939                     ptr2 = &(arglist[ix].uint);
940                 }
941                 ix++;
942                 ix++;
943                 arglist[ix].uint = glk_image_get_info(arglist[0].uint, ptr1, ptr2);
944             }
945             break;
946         case 0x00E1: /* image_draw */
947             arglist[5].uint = glk_image_draw(arglist[0].opaqueref, 
948                 arglist[1].uint,
949                 arglist[2].sint, arglist[3].sint);
950             break;
951         case 0x00E2: /* image_draw_scaled */
952             arglist[7].uint = glk_image_draw_scaled(arglist[0].opaqueref, 
953                 arglist[1].uint,
954                 arglist[2].sint, arglist[3].sint,
955                 arglist[4].uint, arglist[5].uint);
956             break;
957         case 0x00E8: /* window_flow_break */
958             glk_window_flow_break(arglist[0].opaqueref);
959             break;
960         case 0x00E9: /* window_erase_rect */
961             glk_window_erase_rect(arglist[0].opaqueref,
962                 arglist[1].sint, arglist[2].sint,
963                 arglist[3].uint, arglist[4].uint);
964             break;
965         case 0x00EA: /* window_fill_rect */
966             glk_window_fill_rect(arglist[0].opaqueref, arglist[1].uint,
967                 arglist[2].sint, arglist[3].sint,
968                 arglist[4].uint, arglist[5].uint);
969             break;
970         case 0x00EB: /* window_set_background_color */
971             glk_window_set_background_color(arglist[0].opaqueref, arglist[1].uint);
972             break;
973 #endif /* GLK_MODULE_IMAGE */
974
975 #ifdef GLK_MODULE_SOUND
976         case 0x00F0: /* schannel_iterate */
977             if (arglist[1].ptrflag) 
978                 arglist[4].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, &arglist[2].uint);
979             else
980                 arglist[3].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, NULL);
981             break;
982         case 0x00F1: /* schannel_get_rock */
983             arglist[2].uint = glk_schannel_get_rock(arglist[0].opaqueref);
984             break;
985         case 0x00F2: /* schannel_create */
986             arglist[2].opaqueref = glk_schannel_create(arglist[0].uint);
987             break;
988         case 0x00F3: /* schannel_destroy */
989             glk_schannel_destroy(arglist[0].opaqueref);
990             break;
991         case 0x00F8: /* schannel_play */
992             arglist[3].uint = glk_schannel_play(arglist[0].opaqueref, arglist[1].uint);
993             break;
994         case 0x00F9: /* schannel_play_ext */
995             arglist[5].uint = glk_schannel_play_ext(arglist[0].opaqueref, 
996                 arglist[1].uint, arglist[2].uint, arglist[3].uint);
997             break;
998         case 0x00FA: /* schannel_stop */
999             glk_schannel_stop(arglist[0].opaqueref);
1000             break;
1001         case 0x00FB: /* schannel_set_volume */
1002             glk_schannel_set_volume(arglist[0].opaqueref, arglist[1].uint);
1003             break;
1004         case 0x00FC: /* sound_load_hint */
1005             glk_sound_load_hint(arglist[0].uint, arglist[1].uint);
1006             break;
1007 #endif /* GLK_MODULE_SOUND */
1008
1009 #ifdef GLK_MODULE_HYPERLINKS
1010         case 0x0100: /* set_hyperlink */
1011             glk_set_hyperlink(arglist[0].uint);
1012             break;
1013         case 0x0101: /* set_hyperlink_stream */
1014             glk_set_hyperlink_stream(arglist[0].opaqueref, arglist[1].uint);
1015             break;
1016         case 0x0102: /* request_hyperlink_event */
1017             glk_request_hyperlink_event(arglist[0].opaqueref);
1018             break;
1019         case 0x0103: /* cancel_hyperlink_event */
1020             glk_cancel_hyperlink_event(arglist[0].opaqueref);
1021             break;
1022 #endif /* GLK_MODULE_HYPERLINKS */
1023             
1024 #ifdef GLK_MODULE_UNICODE
1025         case 0x0120: /* buffer_to_lower_case_uni */
1026             if (arglist[0].ptrflag) 
1027                 arglist[5].uint = glk_buffer_to_lower_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint);
1028             else
1029                 arglist[3].uint = glk_buffer_to_lower_case_uni(NULL, 0, arglist[1].uint);
1030             break;
1031         case 0x0121: /* buffer_to_upper_case_uni */
1032             if (arglist[0].ptrflag) 
1033                 arglist[5].uint = glk_buffer_to_upper_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint);
1034             else
1035                 arglist[3].uint = glk_buffer_to_upper_case_uni(NULL, 0, arglist[1].uint);
1036             break;
1037         case 0x0122: /* buffer_to_title_case_uni */
1038             if (arglist[0].ptrflag) 
1039                 arglist[6].uint = glk_buffer_to_title_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint);
1040             else
1041                 arglist[4].uint = glk_buffer_to_title_case_uni(NULL, 0, arglist[1].uint, arglist[2].uint);
1042             break;
1043         case 0x0128: /* put_char_uni */
1044             glk_put_char_uni(arglist[0].uint);
1045             break;
1046         case 0x0129: /* put_string_uni */
1047             glk_put_string_uni(arglist[0].unicharstr);
1048             break;
1049         case 0x012A: /* put_buffer_uni */
1050             if (arglist[0].ptrflag) 
1051                 glk_put_buffer_uni(arglist[1].array, arglist[2].uint);
1052             else
1053                 glk_put_buffer_uni(NULL, 0);
1054             break;
1055         case 0x012B: /* put_char_stream_uni */
1056             glk_put_char_stream_uni(arglist[0].opaqueref, arglist[1].uint);
1057             break;
1058         case 0x012C: /* put_string_stream_uni */
1059             glk_put_string_stream_uni(arglist[0].opaqueref, arglist[1].unicharstr);
1060             break;
1061         case 0x012D: /* put_buffer_stream_uni */
1062             if (arglist[1].ptrflag) 
1063                 glk_put_buffer_stream_uni(arglist[0].opaqueref, 
1064                     arglist[2].array, arglist[3].uint);
1065             else
1066                 glk_put_buffer_stream_uni(arglist[0].opaqueref, 
1067                     NULL, 0);
1068             break;
1069         case 0x0130: /* get_char_stream_uni */
1070             arglist[2].sint = glk_get_char_stream_uni(arglist[0].opaqueref);
1071             break;
1072         case 0x0131: /* get_buffer_stream_uni */
1073             if (arglist[1].ptrflag) 
1074                 arglist[5].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, 
1075                     arglist[2].array, arglist[3].uint);
1076             else
1077                 arglist[3].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, 
1078                     NULL, 0);
1079             break;
1080         case 0x0132: /* get_line_stream_uni */
1081             if (arglist[1].ptrflag) 
1082                 arglist[5].uint = glk_get_line_stream_uni(arglist[0].opaqueref, 
1083                     arglist[2].array, arglist[3].uint);
1084             else
1085                 arglist[3].uint = glk_get_line_stream_uni(arglist[0].opaqueref, 
1086                     NULL, 0);
1087             break;
1088         case 0x0138: /* stream_open_file_uni */
1089             arglist[4].opaqueref = glk_stream_open_file_uni(arglist[0].opaqueref, arglist[1].uint, 
1090                 arglist[2].uint);
1091             break;
1092         case 0x0139: /* stream_open_memory_uni */
1093             if (arglist[0].ptrflag) 
1094                 arglist[6].opaqueref = glk_stream_open_memory_uni(arglist[1].array, 
1095                     arglist[2].uint, arglist[3].uint, arglist[4].uint);
1096             else
1097                 arglist[4].opaqueref = glk_stream_open_memory_uni(NULL, 
1098                     0, arglist[1].uint, arglist[2].uint);
1099             break;
1100         case 0x0140: /* request_char_event_uni */
1101             glk_request_char_event_uni(arglist[0].opaqueref);
1102             break;
1103         case 0x0141: /* request_line_event_uni */
1104             if (arglist[1].ptrflag)
1105                 glk_request_line_event_uni(arglist[0].opaqueref, arglist[2].array,
1106                     arglist[3].uint, arglist[4].uint);
1107             else
1108                 glk_request_line_event_uni(arglist[0].opaqueref, NULL,
1109                     0, arglist[2].uint);
1110             break;
1111 #endif /* GLK_MODULE_UNICODE */
1112             
1113         default:
1114             /* do nothing */
1115             break;
1116     }
1117 }
1118