1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software{} you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation{} either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY{} without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program{} if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "glk/glk_api.h"
24 
25 namespace Glk {
26 
27 
28 #define NUMCLASSES   \
29 	(sizeof(class_table) / sizeof(gidispatch_intconst_t))
30 
31 #define NUMINTCONSTANTS   \
32 	(sizeof(intconstant_table) / sizeof(gidispatch_intconst_t))
33 
34 /**
35  * The constants in this table must be ordered alphabetically.
36  */
37 static const gidispatch_intconst_t class_table[] = {
38 	{ "fileref", (2) },   /* "Qc" */
39 	{ "schannel", (3) },  /* "Qd" */
40 	{ "stream", (1) },    /* "Qb" */
41 	{ "window", (0) },    /* "Qa" */
42 };
43 
44 /**
45  * The constants in this table must be ordered alphabetically.
46  */
47 static const gidispatch_intconst_t intconstant_table[] = {
48 	{ "evtype_Arrange", (5)  },
49 	{ "evtype_CharInput", (2) },
50 	{ "evtype_Hyperlink", (8) },
51 	{ "evtype_LineInput", (3) },
52 	{ "evtype_MouseInput", (4) },
53 	{ "evtype_None", (0) },
54 	{ "evtype_Redraw", (6) },
55 	{ "evtype_SoundNotify", (7) },
56 	{ "evtype_Timer", (1) },
57 	{ "evtype_VolumeNotify", (9) },
58 
59 	{ "filemode_Read", (0x02) },
60 	{ "filemode_ReadWrite", (0x03) },
61 	{ "filemode_Write", (0x01) },
62 	{ "filemode_WriteAppend", (0x05) },
63 
64 	{ "fileusage_BinaryMode", (0x000) },
65 	{ "fileusage_Data", (0x00) },
66 	{ "fileusage_InputRecord", (0x03) },
67 	{ "fileusage_SavedGame", (0x01) },
68 	{ "fileusage_TextMode",   (0x100) },
69 	{ "fileusage_Transcript", (0x02) },
70 	{ "fileusage_TypeMask", (0x0f) },
71 
72 	{ "gestalt_CharInput", (1) },
73 	{ "gestalt_CharOutput", (3) },
74 	{ "gestalt_CharOutput_ApproxPrint", (1) },
75 	{ "gestalt_CharOutput_CannotPrint", (0) },
76 	{ "gestalt_CharOutput_ExactPrint", (2) },
77 	{ "gestalt_DateTime", (20) },
78 	{ "gestalt_DrawImage", (7) },
79 	{ "gestalt_GarglkText", (0x1100) },
80 	{ "gestalt_Graphics", (6) },
81 	{ "gestalt_GraphicsTransparency", (14) },
82 	{ "gestalt_HyperlinkInput", (12) },
83 	{ "gestalt_Hyperlinks", (11) },
84 	{ "gestalt_LineInput", (2) },
85 	{ "gestalt_LineInputEcho", (17) },
86 	{ "gestalt_LineTerminatorKey", (19) },
87 	{ "gestalt_LineTerminators", (18) },
88 	{ "gestalt_MouseInput", (4) },
89 	{ "gestalt_Sound", (8) },
90 	{ "gestalt_Sound2", (21) },
91 	{ "gestalt_SoundMusic", (13) },
92 	{ "gestalt_SoundNotify", (10) },
93 	{ "gestalt_SoundVolume", (9) },
94 	{ "gestalt_Timer", (5) },
95 	{ "gestalt_Unicode", (15) },
96 	{ "gestalt_UnicodeNorm", (16) },
97 	{ "gestalt_Version", (0) },
98 
99 	{ "imagealign_InlineCenter",  (0x03) },
100 	{ "imagealign_InlineDown",  (0x02) },
101 	{ "imagealign_MarginLeft",  (0x04) },
102 	{ "imagealign_MarginRight",  (0x05) },
103 	{ "imagealign_InlineUp",  (0x01) },
104 
105 	{ "keycode_Delete",   (0xfffffff9) },
106 	{ "keycode_Down",     (0xfffffffb) },
107 	{ "keycode_End",      (0xfffffff3) },
108 	{ "keycode_Escape",   (0xfffffff8) },
109 	{ "keycode_Func1",    (0xffffffef) },
110 	{ "keycode_Func10",   (0xffffffe6) },
111 	{ "keycode_Func11",   (0xffffffe5) },
112 	{ "keycode_Func12",   (0xffffffe4) },
113 	{ "keycode_Func2",    (0xffffffee) },
114 	{ "keycode_Func3",    (0xffffffed) },
115 	{ "keycode_Func4",    (0xffffffec) },
116 	{ "keycode_Func5",    (0xffffffeb) },
117 	{ "keycode_Func6",    (0xffffffea) },
118 	{ "keycode_Func7",    (0xffffffe9) },
119 	{ "keycode_Func8",    (0xffffffe8) },
120 	{ "keycode_Func9",    (0xffffffe7) },
121 	{ "keycode_Home",     (0xfffffff4) },
122 	{ "keycode_Left",     (0xfffffffe) },
123 	{ "keycode_MAXVAL",   (28)  },
124 	{ "keycode_PageDown", (0xfffffff5) },
125 	{ "keycode_PageUp",   (0xfffffff6) },
126 	{ "keycode_Return",   (0xfffffffa) },
127 	{ "keycode_Right",    (0xfffffffd) },
128 	{ "keycode_Tab",      (0xfffffff7) },
129 	{ "keycode_Unknown",  (0xffffffff) },
130 	{ "keycode_Up",       (0xfffffffc) },
131 
132 	{ "seekmode_Current", (1) },
133 	{ "seekmode_End", (2) },
134 	{ "seekmode_Start", (0) },
135 
136 	{ "style_Alert", (5) },
137 	{ "style_BlockQuote", (7) },
138 	{ "style_Emphasized", (1) },
139 	{ "style_Header", (3) },
140 	{ "style_Input", (8) },
141 	{ "style_NUMSTYLES", (11) },
142 	{ "style_Normal", (0) },
143 	{ "style_Note", (6) },
144 	{ "style_Preformatted", (2) },
145 	{ "style_Subheader", (4) },
146 	{ "style_User1", (9) },
147 	{ "style_User2", (10) },
148 	{ "stylehint_BackColor", (8) },
149 	{ "stylehint_Indentation", (0) },
150 	{ "stylehint_Justification", (2)  },
151 	{ "stylehint_NUMHINTS", (10) },
152 	{ "stylehint_Oblique", (5) },
153 	{ "stylehint_ParaIndentation", (1) },
154 	{ "stylehint_Proportional", (6) },
155 	{ "stylehint_ReverseColor", (9) },
156 	{ "stylehint_Size", (3) },
157 	{ "stylehint_TextColor", (7) },
158 	{ "stylehint_Weight", (4) },
159 	{ "stylehint_just_Centered", (2) },
160 	{ "stylehint_just_LeftFlush", (0) },
161 	{ "stylehint_just_LeftRight", (1) },
162 	{ "stylehint_just_RightFlush", (3) },
163 
164 	{ "winmethod_Above", (0x02)  },
165 	{ "winmethod_Below", (0x03)  },
166 	{ "winmethod_Border", (0x000)  },
167 	{ "winmethod_BorderMask", (0x100)  },
168 	{ "winmethod_DirMask", (0x0f) },
169 	{ "winmethod_DivisionMask", (0xf0) },
170 	{ "winmethod_Fixed", (0x10) },
171 	{ "winmethod_Left",  (0x00)  },
172 	{ "winmethod_NoBorder", (0x100)  },
173 	{ "winmethod_Proportional", (0x20) },
174 	{ "winmethod_Right", (0x01)  },
175 
176 	{ "wintype_AllTypes", (0)  },
177 	{ "wintype_Blank", (2)  },
178 	{ "wintype_Graphics", (5)  },
179 	{ "wintype_Pair", (1)  },
180 	{ "wintype_TextBuffer", (3) },
181 	{ "wintype_TextGrid", (4) },
182 };
183 
gidispatch_set_object_registry(gidispatch_rock_t (* regi)(void * obj,uint objclass),void (* unregi)(void * obj,uint objclass,gidispatch_rock_t objrock))184 void GlkAPI::gidispatch_set_object_registry(gidispatch_rock_t(*regi)(void *obj, uint objclass),
185 		void(*unregi)(void *obj, uint objclass, gidispatch_rock_t objrock)) {
186 	Window *win;
187 	Stream *str;
188 	frefid_t fref;
189 
190 	gli_register_obj = regi;
191 	gli_unregister_obj = unregi;
192 
193 	if (gli_register_obj)
194 	{
195 		/* It's now necessary to go through all existing objects, and register
196 			them. */
197 		for (win = glk_window_iterate(nullptr, nullptr);
198 			win;
199 			win = glk_window_iterate(win, nullptr))
200 		{
201 			win->_dispRock = (*gli_register_obj)(win, gidisp_Class_Window);
202 		}
203 		for (str = glk_stream_iterate(nullptr, nullptr);
204 			str;
205 			str = glk_stream_iterate(str, nullptr))
206 		{
207 			str->_dispRock = (*gli_register_obj)(str, gidisp_Class_Stream);
208 		}
209 		for (fref = glk_fileref_iterate(nullptr, nullptr);
210 			fref;
211 			fref = glk_fileref_iterate(fref, nullptr))
212 		{
213 			fref->_dispRock = (*gli_register_obj)(fref, gidisp_Class_Fileref);
214 		}
215 	}
216 }
217 
gidispatch_set_retained_registry(gidispatch_rock_t (* regi)(void * array,uint len,const char * typecode),void (* unregi)(void * array,uint len,const char * typecode,gidispatch_rock_t objrock))218 void GlkAPI::gidispatch_set_retained_registry(gidispatch_rock_t(*regi)(void *array, uint len, const char *typecode),
219 		void(*unregi)(void *array, uint len, const char *typecode, gidispatch_rock_t objrock)) {
220 	gli_register_arr = regi;
221 	gli_unregister_arr = unregi;
222 }
223 
gidispatch_count_classes() const224 uint32 GlkAPI::gidispatch_count_classes() const {
225 	return NUMCLASSES;
226 }
227 
gidispatch_get_class(uint32 index) const228 const gidispatch_intconst_t *GlkAPI::gidispatch_get_class(uint32 index) const {
229 	if (index >= NUMCLASSES)
230 		return nullptr;
231 	return &(class_table[index]);
232 }
233 
gidispatch_count_intconst() const234 uint32 GlkAPI::gidispatch_count_intconst() const {
235 	return NUMINTCONSTANTS;
236 }
237 
gidispatch_get_intconst(uint32 index) const238 const gidispatch_intconst_t *GlkAPI::gidispatch_get_intconst(uint32 index) const {
239 	if (index >= NUMINTCONSTANTS)
240 		return nullptr;
241 	return &(intconstant_table[index]);
242 }
243 
gidispatch_prototype(uint32 funcnum) const244 const char *GlkAPI::gidispatch_prototype(uint32 funcnum) const {
245 	switch (funcnum) {
246 		case 0x0001: /* exit */
247 			return "0:";
248 		case 0x0002: /* set_interrupt_handler */
249 			/* cannot be invoked through dispatch layer */
250 			return nullptr;
251 		case 0x0003: /* tick */
252 			return "0:";
253 		case 0x0004: /* gestalt */
254 			return "3IuIu:Iu";
255 		case 0x0005: /* gestalt_ext */
256 			return "4IuIu&#Iu:Iu";
257 		case 0x0020: /* window_iterate */
258 			return "3Qa<Iu:Qa";
259 		case 0x0021: /* window_get_rock */
260 			return "2Qa:Iu";
261 		case 0x0022: /* window_get_root */
262 			return "1:Qa";
263 		case 0x0023: /* window_open */
264 			return "6QaIuIuIuIu:Qa";
265 		case 0x0024: /* window_close */
266 			return "2Qa<[2IuIu]:";
267 		case 0x0025: /* window_get_size */
268 			return "3Qa<Iu<Iu:";
269 		case 0x0026: /* window_set_arrangement */
270 			return "4QaIuIuQa:";
271 		case 0x0027: /* window_get_arrangement */
272 			return "4Qa<Iu<Iu<Qa:";
273 		case 0x0028: /* window_get_type */
274 			return "2Qa:Iu";
275 		case 0x0029: /* window_get_parent */
276 			return "2Qa:Qa";
277 		case 0x002A: /* window_clear */
278 			return "1Qa:";
279 		case 0x002B: /* window_move_cursor */
280 			return "3QaIuIu:";
281 		case 0x002C: /* window_get_stream */
282 			return "2Qa:Qb";
283 		case 0x002D: /* window_set_echo_stream */
284 			return "2QaQb:";
285 		case 0x002E: /* window_get_echo_stream */
286 			return "2Qa:Qb";
287 		case 0x002F: /* set_window */
288 			return "1Qa:";
289 		case 0x0030: /* window_get_sibling */
290 			return "2Qa:Qa";
291 		case 0x0040: /* stream_iterate */
292 			return "3Qb<Iu:Qb";
293 		case 0x0041: /* stream_get_rock */
294 			return "2Qb:Iu";
295 		case 0x0042: /* stream_open_file */
296 			return "4QcIuIu:Qb";
297 		case 0x0043: /* stream_open_memory */
298 			return "4&#!CnIuIu:Qb";
299 		case 0x0044: /* stream_close */
300 			return "2Qb<[2IuIu]:";
301 		case 0x0045: /* stream_set_position */
302 			return "3QbIsIu:";
303 		case 0x0046: /* stream_get_position */
304 			return "2Qb:Iu";
305 		case 0x0047: /* stream_set_current */
306 			return "1Qb:";
307 		case 0x0048: /* stream_get_current */
308 			return "1:Qb";
309 		case 0x0060: /* fileref_create_temp */
310 			return "3IuIu:Qc";
311 		case 0x0061: /* fileref_create_by_name */
312 			return "4IuSIu:Qc";
313 		case 0x0062: /* fileref_create_by_prompt */
314 			return "4IuIuIu:Qc";
315 		case 0x0063: /* fileref_destroy */
316 			return "1Qc:";
317 		case 0x0064: /* fileref_iterate */
318 			return "3Qc<Iu:Qc";
319 		case 0x0065: /* fileref_get_rock */
320 			return "2Qc:Iu";
321 		case 0x0066: /* fileref_delete_file */
322 			return "1Qc:";
323 		case 0x0067: /* fileref_does_file_exist */
324 			return "2Qc:Iu";
325 		case 0x0068: /* fileref_create_from_fileref */
326 			return "4IuQcIu:Qc";
327 		case 0x0080: /* put_char */
328 			return "1Cu:";
329 		case 0x0081: /* put_char_stream */
330 			return "2QbCu:";
331 		case 0x0082: /* put_string */
332 			return "1S:";
333 		case 0x0083: /* put_string_stream */
334 			return "2QbS:";
335 		case 0x0084: /* put_buffer */
336 			return "1>+#Cn:";
337 		case 0x0085: /* put_buffer_stream */
338 			return "2Qb>+#Cn:";
339 		case 0x0086: /* set_style */
340 			return "1Iu:";
341 		case 0x0087: /* set_style_stream */
342 			return "2QbIu:";
343 		case 0x0090: /* get_char_stream */
344 			return "2Qb:Is";
345 		case 0x0091: /* get_line_stream */
346 			return "3Qb<+#Cn:Iu";
347 		case 0x0092: /* get_buffer_stream */
348 			return "3Qb<+#Cn:Iu";
349 		case 0x00A0: /* char_to_lower */
350 			return "2Cu:Cu";
351 		case 0x00A1: /* char_to_upper */
352 			return "2Cu:Cu";
353 		case 0x00B0: /* stylehint_set */
354 			return "4IuIuIuIs:";
355 		case 0x00B1: /* stylehint_clear */
356 			return "3IuIuIu:";
357 		case 0x00B2: /* style_distinguish */
358 			return "4QaIuIu:Iu";
359 		case 0x00B3: /* style_measure */
360 			return "5QaIuIu<Iu:Iu";
361 		case 0x00C0: /* select */
362 			return "1<+[4IuQaIuIu]:";
363 		case 0x00C1: /* select_poll */
364 			return "1<+[4IuQaIuIu]:";
365 		case 0x00D0: /* request_line_event */
366 			return "3Qa&+#!CnIu:";
367 		case 0x00D1: /* cancel_line_event */
368 			return "2Qa<[4IuQaIuIu]:";
369 		case 0x00D2: /* request_char_event */
370 			return "1Qa:";
371 		case 0x00D3: /* cancel_char_event */
372 			return "1Qa:";
373 		case 0x00D4: /* request_mouse_event */
374 			return "1Qa:";
375 		case 0x00D5: /* cancel_mouse_event */
376 			return "1Qa:";
377 		case 0x00D6: /* request_timer_events */
378 			return "1Iu:";
379 
380 #ifdef GLK_MODULE_IMAGE
381 		case 0x00E0: /* image_get_info */
382 			return "4Iu<Iu<Iu:Iu";
383 		case 0x00E1: /* image_draw */
384 			return "5QaIuIsIs:Iu";
385 		case 0x00E2: /* image_draw_scaled */
386 			return "7QaIuIsIsIuIu:Iu";
387 		case 0x00E8: /* window_flow_break */
388 			return "1Qa:";
389 		case 0x00E9: /* window_erase_rect */
390 			return "5QaIsIsIuIu:";
391 		case 0x00EA: /* window_fill_rect */
392 			return "6QaIuIsIsIuIu:";
393 		case 0x00EB: /* window_set_background_color */
394 			return "2QaIu:";
395 #endif /* GLK_MODULE_IMAGE */
396 
397 #ifdef GLK_MODULE_SOUND
398 		case 0x00F0: /* schannel_iterate */
399 			return "3Qd<Iu:Qd";
400 		case 0x00F1: /* schannel_get_rock */
401 			return "2Qd:Iu";
402 		case 0x00F2: /* schannel_create */
403 			return "2Iu:Qd";
404 		case 0x00F3: /* schannel_destroy */
405 			return "1Qd:";
406 		case 0x00F8: /* schannel_play */
407 			return "3QdIu:Iu";
408 		case 0x00F9: /* schannel_play_ext */
409 			return "5QdIuIuIu:Iu";
410 		case 0x00FA: /* schannel_stop */
411 			return "1Qd:";
412 		case 0x00FB: /* schannel_set_volume */
413 			return "2QdIu:";
414 		case 0x00FC: /* sound_load_hint */
415 			return "2IuIu:";
416 
417 #ifdef GLK_MODULE_SOUND2
418 		case 0x00F4: /* schannel_create_ext */
419 			return "3IuIu:Qd";
420 		case 0x00F7: /* schannel_play_multi */
421 			return "4>+#Qd>+#IuIu:Iu";
422 		case 0x00FD: /* schannel_set_volume_ext */
423 			return "4QdIuIuIu:";
424 		case 0x00FE: /* schannel_pause */
425 			return "1Qd:";
426 		case 0x00FF: /* schannel_unpause */
427 			return "1Qd:";
428 #endif /* GLK_MODULE_SOUND2 */
429 #endif /* GLK_MODULE_SOUND */
430 
431 #ifdef GLK_MODULE_HYPERLINKS
432 		case 0x0100: /* set_hyperlink */
433 			return "1Iu:";
434 		case 0x0101: /* set_hyperlink_stream */
435 			return "2QbIu:";
436 		case 0x0102: /* request_hyperlink_event */
437 			return "1Qa:";
438 		case 0x0103: /* cancel_hyperlink_event */
439 			return "1Qa:";
440 #endif /* GLK_MODULE_HYPERLINKS */
441 
442 #ifdef GLK_MODULE_UNICODE
443 		case 0x0120: /* buffer_to_lower_case_uni */
444 			return "3&+#IuIu:Iu";
445 		case 0x0121: /* buffer_to_upper_case_uni */
446 			return "3&+#IuIu:Iu";
447 		case 0x0122: /* buffer_to_title_case_uni */
448 			return "4&+#IuIuIu:Iu";
449 		case 0x0128: /* put_char_uni */
450 			return "1Iu:";
451 		case 0x0129: /* put_string_uni */
452 			return "1U:";
453 		case 0x012A: /* put_buffer_uni */
454 			return "1>+#Iu:";
455 		case 0x012B: /* put_char_stream_uni */
456 			return "2QbIu:";
457 		case 0x012C: /* put_string_stream_uni */
458 			return "2QbU:";
459 		case 0x012D: /* put_buffer_stream_uni */
460 			return "2Qb>+#Iu:";
461 		case 0x0130: /* get_char_stream_uni */
462 			return "2Qb:Is";
463 		case 0x0131: /* get_buffer_stream_uni */
464 			return "3Qb<+#Iu:Iu";
465 		case 0x0132: /* get_line_stream_uni */
466 			return "3Qb<+#Iu:Iu";
467 		case 0x0138: /* stream_open_file_uni */
468 			return "4QcIuIu:Qb";
469 		case 0x0139: /* stream_open_memory_uni */
470 			return "4&#!IuIuIu:Qb";
471 		case 0x0140: /* request_char_event_uni */
472 			return "1Qa:";
473 		case 0x0141: /* request_line_event_uni */
474 			return "3Qa&+#!IuIu:";
475 #endif /* GLK_MODULE_UNICODE */
476 
477 #ifdef GLK_MODULE_UNICODE_NORM
478 		case 0x0123: /* buffer_canon_decompose_uni */
479 			return "3&+#IuIu:Iu";
480 		case 0x0124: /* buffer_canon_normalize_uni */
481 			return "3&+#IuIu:Iu";
482 #endif /* GLK_MODULE_UNICODE_NORM */
483 
484 #ifdef GLK_MODULE_LINE_ECHO
485 		case 0x0150: /* set_echo_line_event */
486 			return "2QaIu:";
487 #endif /* GLK_MODULE_LINE_ECHO */
488 
489 #ifdef GLK_MODULE_LINE_TERMINATORS
490 		case 0x0151: /* set_terminators_line_event */
491 			return "2Qa>#Iu:";
492 #endif /* GLK_MODULE_LINE_TERMINATORS */
493 
494 #ifdef GLK_MODULE_DATETIME
495 		case 0x0160: /* current_time */
496 			return "1<+[3IsIuIs]:";
497 		case 0x0161: /* current_simple_time */
498 			return "2Iu:Is";
499 		case 0x0168: /* time_to_date_utc */
500 			return "2>+[3IsIuIs]<+[8IsIsIsIsIsIsIsIs]:";
501 		case 0x0169: /* time_to_date_local */
502 			return "2>+[3IsIuIs]<+[8IsIsIsIsIsIsIsIs]:";
503 		case 0x016A: /* simple_time_to_date_utc */
504 			return "3IsIu<+[8IsIsIsIsIsIsIsIs]:";
505 		case 0x016B: /* simple_time_to_date_local */
506 			return "3IsIu<+[8IsIsIsIsIsIsIsIs]:";
507 		case 0x016C: /* date_to_time_utc */
508 			return "2>+[8IsIsIsIsIsIsIsIs]<+[3IsIuIs]:";
509 		case 0x016D: /* date_to_time_local */
510 			return "2>+[8IsIsIsIsIsIsIsIs]<+[3IsIuIs]:";
511 		case 0x016E: /* date_to_simple_time_utc */
512 			return "3>+[8IsIsIsIsIsIsIsIs]Iu:Is";
513 		case 0x016F: /* date_to_simple_time_local */
514 			return "3>+[8IsIsIsIsIsIsIsIs]Iu:Is";
515 #endif /* GLK_MODULE_DATETIME */
516 
517 #ifdef GLK_MODULE_GARGLKTEXT
518 		case 0x1100: /* garglk_set_zcolors */
519 			return "2IuIu:";
520 		case 0x1101: /* garglk_set_zcolors_stream */
521 			return "3QbIuIu:";
522 		case 0x1102: /* garglk_set_reversevideo */
523 			return "1Iu:";
524 		case 0x1103: /* garglk_set_reversevideo_stream */
525 			return "2QbIu:";
526 #endif /* GLK_MODULE_GARGLKTEXT */
527 
528 		default:
529 			return nullptr;
530 	}
531 }
532 
gidispatch_call(uint32 funcnum,uint32 numargs,gluniversal_t * arglist)533 void GlkAPI::gidispatch_call(uint32 funcnum, uint32 numargs, gluniversal_t *arglist) {
534 	switch (funcnum) {
535 		case 0x0001: /* exit */
536 			glk_exit();
537 			break;
538 		case 0x0002: /* set_interrupt_handler */
539 			/* cannot be invoked through dispatch layer */
540 			break;
541 		case 0x0003: /* tick */
542 			glk_tick();
543 			break;
544 		case 0x0004: /* gestalt */
545 			arglist[3]._uint = glk_gestalt(arglist[0]._uint, arglist[1]._uint);
546 			break;
547 		case 0x0005: /* gestalt_ext */
548 			if (arglist[2]._ptrflag) {
549 				arglist[6]._uint = glk_gestalt_ext(arglist[0]._uint, arglist[1]._uint,
550 					(uint *)arglist[3]._array, arglist[4]._uint);
551 			} else {
552 				arglist[4]._uint = glk_gestalt_ext(arglist[0]._uint, arglist[1]._uint,
553 					nullptr, 0);
554 			}
555 			break;
556 		case 0x0020: /* window_iterate */
557 			if (arglist[1]._ptrflag)
558 				arglist[4]._opaqueref = glk_window_iterate((Window *)arglist[0]._opaqueref, &arglist[2]._uint);
559 			else
560 				arglist[3]._opaqueref = glk_window_iterate((Window *)arglist[0]._opaqueref, nullptr);
561 			break;
562 		case 0x0021: /* window_get_rock */
563 			arglist[2]._uint = glk_window_get_rock((Window *)arglist[0]._opaqueref);
564 			break;
565 		case 0x0022: /* window_get_root */
566 			arglist[1]._opaqueref = glk_window_get_root();
567 			break;
568 		case 0x0023: /* window_open */
569 			arglist[6]._opaqueref = glk_window_open((Window *)arglist[0]._opaqueref, arglist[1]._uint,
570 				arglist[2]._uint, arglist[3]._uint, arglist[4]._uint);
571 			break;
572 		case 0x0024: /* window_close */
573 			if (arglist[1]._ptrflag) {
574 				stream_result_t dat;
575 				glk_window_close((Window *)arglist[0]._opaqueref, &dat);
576 				arglist[2]._uint = dat._readCount;
577 				arglist[3]._uint = dat._writeCount;
578 			} else {
579 				glk_window_close((Window *)arglist[0]._opaqueref, nullptr);
580 			}
581 			break;
582 		case 0x0025: /* window_get_size */
583 			{
584 				int ix = 1;
585 				uint *ptr1, *ptr2;
586 				if (!arglist[ix]._ptrflag) {
587 					ptr1 = nullptr;
588 				} else {
589 					ix++;
590 					ptr1 = &(arglist[ix]._uint);
591 				}
592 				ix++;
593 				if (!arglist[ix]._ptrflag) {
594 					ptr2 = nullptr;
595 				} else {
596 					ix++;
597 					ptr2 = &(arglist[ix]._uint);
598 				}
599 				ix++;
600 				glk_window_get_size((Window *)arglist[0]._opaqueref, ptr1, ptr2);
601 				break;
602 			}
603 		case 0x0026: /* window_set_arrangement */
604 			glk_window_set_arrangement((Window *)arglist[0]._opaqueref, arglist[1]._uint,
605 				arglist[2]._uint, (Window *)arglist[3]._opaqueref);
606 			break;
607 		case 0x0027: /* window_get_arrangement */
608 			{
609 				int ix = 1;
610 				uint *ptr1, *ptr2;
611 				winid_t *ptr3;
612 				if (!arglist[ix]._ptrflag) {
613 					ptr1 = nullptr;
614 				} else {
615 					ix++;
616 					ptr1 = &(arglist[ix]._uint);
617 				}
618 				ix++;
619 				if (!arglist[ix]._ptrflag) {
620 					ptr2 = nullptr;
621 				} else {
622 					ix++;
623 					ptr2 = &(arglist[ix]._uint);
624 				}
625 				ix++;
626 				if (!arglist[ix]._ptrflag) {
627 					ptr3 = nullptr;
628 				} else {
629 					ix++;
630 					ptr3 = (winid_t *)(&(arglist[ix]._opaqueref));
631 				}
632 				ix++;
633 				glk_window_get_arrangement((Window *)arglist[0]._opaqueref, ptr1, ptr2, ptr3);
634 			}
635 			break;
636 		case 0x0028: /* window_get_type */
637 			arglist[2]._uint = glk_window_get_type((Window *)arglist[0]._opaqueref);
638 			break;
639 		case 0x0029: /* window_get_parent */
640 			arglist[2]._opaqueref = glk_window_get_parent((Window *)arglist[0]._opaqueref);
641 			break;
642 		case 0x002A: /* window_clear */
643 			glk_window_clear((Window *)arglist[0]._opaqueref);
644 			break;
645 		case 0x002B: /* window_move_cursor */
646 			glk_window_move_cursor((Window *)arglist[0]._opaqueref, arglist[1]._uint,
647 				arglist[2]._uint);
648 			break;
649 		case 0x002C: /* window_get_stream */
650 			arglist[2]._opaqueref = glk_window_get_stream((Window *)arglist[0]._opaqueref);
651 			break;
652 		case 0x002D: /* window_set_echo_stream */
653 			glk_window_set_echo_stream((Window *)arglist[0]._opaqueref, (Stream *)arglist[1]._opaqueref);
654 			break;
655 		case 0x002E: /* window_get_echo_stream */
656 			arglist[2]._opaqueref = glk_window_get_echo_stream((Window *)arglist[0]._opaqueref);
657 			break;
658 		case 0x002F: /* set_window */
659 			glk_set_window((Window *)arglist[0]._opaqueref);
660 			break;
661 		case 0x0030: /* window_get_sibling */
662 			arglist[2]._opaqueref = glk_window_get_sibling((Window *)arglist[0]._opaqueref);
663 			break;
664 		case 0x0040: /* stream_iterate */
665 			if (arglist[1]._ptrflag)
666 				arglist[4]._opaqueref = glk_stream_iterate((Stream *)arglist[0]._opaqueref, &arglist[2]._uint);
667 			else
668 				arglist[3]._opaqueref = glk_stream_iterate((Stream *)arglist[0]._opaqueref, nullptr);
669 			break;
670 		case 0x0041: /* stream_get_rock */
671 			arglist[2]._uint = glk_stream_get_rock((Stream *)arglist[0]._opaqueref);
672 			break;
673 		case 0x0042: /* stream_open_file */
674 			arglist[4]._opaqueref = glk_stream_open_file((frefid_t)arglist[0]._opaqueref, (FileMode)arglist[1]._uint,
675 				arglist[2]._uint);
676 			break;
677 		case 0x0043: /* stream_open_memory */
678 			if (arglist[0]._ptrflag)
679 				arglist[6]._opaqueref = glk_stream_open_memory((char *)arglist[1]._array,
680 					arglist[2]._uint, (FileMode)arglist[3]._uint, arglist[4]._uint);
681 			else
682 				arglist[4]._opaqueref = glk_stream_open_memory(nullptr, 0, (FileMode)arglist[1]._uint, arglist[2]._uint);
683 			break;
684 		case 0x0044: /* stream_close */
685 			if (arglist[1]._ptrflag) {
686 				stream_result_t dat;
687 				glk_stream_close((Stream *)arglist[0]._opaqueref, &dat);
688 				arglist[2]._uint = dat._readCount;
689 				arglist[3]._uint = dat._writeCount;
690 			} else {
691 				glk_stream_close((Stream *)arglist[0]._opaqueref, nullptr);
692 			}
693 			break;
694 		case 0x0045: /* stream_set_position */
695 			glk_stream_set_position((Stream *)arglist[0]._opaqueref, arglist[1]._sint,
696 				arglist[2]._uint);
697 			break;
698 		case 0x0046: /* stream_get_position */
699 			arglist[2]._uint = glk_stream_get_position((Stream *)arglist[0]._opaqueref);
700 			break;
701 		case 0x0047: /* stream_set_current */
702 			glk_stream_set_current((Stream *)arglist[0]._opaqueref);
703 			break;
704 		case 0x0048: /* stream_get_current */
705 			arglist[1]._opaqueref = glk_stream_get_current();
706 			break;
707 		case 0x0060: /* fileref_create_temp */
708 			arglist[3]._opaqueref = glk_fileref_create_temp(arglist[0]._uint,
709 				arglist[1]._uint);
710 			break;
711 		case 0x0061: /* fileref_create_by_name */
712 			arglist[4]._opaqueref = glk_fileref_create_by_name(arglist[0]._uint,
713 				arglist[1]._charstr, arglist[2]._uint);
714 			break;
715 		case 0x0062: /* fileref_create_by_prompt */
716 			arglist[4]._opaqueref = glk_fileref_create_by_prompt(arglist[0]._uint, (FileMode)arglist[1]._uint, arglist[2]._uint);
717 			break;
718 		case 0x0063: /* fileref_destroy */
719 			glk_fileref_destroy((frefid_t)arglist[0]._opaqueref);
720 			break;
721 		case 0x0064: /* fileref_iterate */
722 			if (arglist[1]._ptrflag)
723 				arglist[4]._opaqueref = glk_fileref_iterate((frefid_t)arglist[0]._opaqueref, &arglist[2]._uint);
724 			else
725 				arglist[3]._opaqueref = glk_fileref_iterate((frefid_t)arglist[0]._opaqueref, nullptr);
726 			break;
727 		case 0x0065: /* fileref_get_rock */
728 			arglist[2]._uint = glk_fileref_get_rock((frefid_t)arglist[0]._opaqueref);
729 			break;
730 		case 0x0066: /* fileref_delete_file */
731 			glk_fileref_delete_file((frefid_t)arglist[0]._opaqueref);
732 			break;
733 		case 0x0067: /* fileref_does_file_exist */
734 			arglist[2]._uint = glk_fileref_does_file_exist((frefid_t)arglist[0]._opaqueref);
735 			break;
736 		case 0x0068: /* fileref_create_from_fileref */
737 			arglist[4]._opaqueref = glk_fileref_create_from_fileref(arglist[0]._uint, (frefid_t)arglist[1]._opaqueref, arglist[2]._uint);
738 			break;
739 		case 0x0080: /* put_char */
740 			glk_put_char(arglist[0]._uch);
741 			break;
742 		case 0x0081: /* put_char_stream */
743 			glk_put_char_stream((Stream *)arglist[0]._opaqueref, arglist[1]._uch);
744 			break;
745 		case 0x0082: /* put_string */
746 			glk_put_string(arglist[0]._charstr);
747 			break;
748 		case 0x0083: /* put_string_stream */
749 			glk_put_string_stream((Stream *)arglist[0]._opaqueref, arglist[1]._charstr);
750 			break;
751 		case 0x0084: /* put_buffer */
752 			if (arglist[0]._ptrflag)
753 				glk_put_buffer((const char *)arglist[1]._array, arglist[2]._uint);
754 			else
755 				glk_put_buffer(nullptr, 0);
756 			break;
757 		case 0x0085: /* put_buffer_stream */
758 			if (arglist[1]._ptrflag)
759 				glk_put_buffer_stream((Stream *)arglist[0]._opaqueref, (const char *)arglist[2]._array, arglist[3]._uint);
760 			else
761 				glk_put_buffer_stream((Stream *)arglist[0]._opaqueref,
762 					nullptr, 0);
763 			break;
764 		case 0x0086: /* set_style */
765 			glk_set_style(arglist[0]._uint);
766 			break;
767 		case 0x0087: /* set_style_stream */
768 			glk_set_style_stream((Stream *)arglist[0]._opaqueref, arglist[1]._uint);
769 			break;
770 		case 0x0090: /* get_char_stream */
771 			arglist[2]._sint = glk_get_char_stream((Stream *)arglist[0]._opaqueref);
772 			break;
773 		case 0x0091: /* get_line_stream */
774 			if (arglist[1]._ptrflag)
775 				arglist[5]._uint = glk_get_line_stream((Stream *)arglist[0]._opaqueref, (char *)arglist[2]._array, arglist[3]._uint);
776 			else
777 				arglist[3]._uint = glk_get_line_stream((Stream *)arglist[0]._opaqueref,
778 					nullptr, 0);
779 			break;
780 		case 0x0092: /* get_buffer_stream */
781 			if (arglist[1]._ptrflag)
782 				arglist[5]._uint = glk_get_buffer_stream((Stream *)arglist[0]._opaqueref, (char *)arglist[2]._array, arglist[3]._uint);
783 			else
784 				arglist[3]._uint = glk_get_buffer_stream((Stream *)arglist[0]._opaqueref,
785 					nullptr, 0);
786 			break;
787 		case 0x00A0: /* char_to_lower */
788 			arglist[2]._uch = glk_char_to_lower(arglist[0]._uch);
789 			break;
790 		case 0x00A1: /* char_to_upper */
791 			arglist[2]._uch = glk_char_to_upper(arglist[0]._uch);
792 			break;
793 		case 0x00B0: /* stylehint_set */
794 			glk_stylehint_set(arglist[0]._uint, arglist[1]._uint,
795 				arglist[2]._uint, arglist[3]._sint);
796 			break;
797 		case 0x00B1: /* stylehint_clear */
798 			glk_stylehint_clear(arglist[0]._uint, arglist[1]._uint,
799 				arglist[2]._uint);
800 			break;
801 		case 0x00B2: /* style_distinguish */
802 			arglist[4]._uint = glk_style_distinguish((Window *)arglist[0]._opaqueref, arglist[1]._uint,
803 				arglist[2]._uint);
804 			break;
805 		case 0x00B3: /* style_measure */
806 			if (arglist[3]._ptrflag)
807 				arglist[6]._uint = glk_style_measure((Window *)arglist[0]._opaqueref, arglist[1]._uint,
808 					arglist[2]._uint, &(arglist[4]._uint));
809 			else
810 				arglist[5]._uint = glk_style_measure((Window *)arglist[0]._opaqueref, arglist[1]._uint,
811 					arglist[2]._uint, nullptr);
812 			break;
813 		case 0x00C0: /* select */
814 			if (arglist[0]._ptrflag) {
815 				event_t dat;
816 				glk_select(&dat);
817 				arglist[1]._uint = dat.type;
818 				arglist[2]._opaqueref = dat.window;
819 				arglist[3]._uint = dat.val1;
820 				arglist[4]._uint = dat.val2;
821 			} else {
822 				glk_select(nullptr);
823 			}
824 			break;
825 		case 0x00C1: /* select_poll */
826 			if (arglist[0]._ptrflag) {
827 				event_t dat;
828 				glk_select_poll(&dat);
829 				arglist[1]._uint = dat.type;
830 				arglist[2]._opaqueref = dat.window;
831 				arglist[3]._uint = dat.val1;
832 				arglist[4]._uint = dat.val2;
833 			} else {
834 				glk_select_poll(nullptr);
835 			}
836 			break;
837 		case 0x00D0: /* request_line_event */
838 			if (arglist[1]._ptrflag)
839 				glk_request_line_event((Window *)arglist[0]._opaqueref, (char *)arglist[2]._array,
840 					arglist[3]._uint, arglist[4]._uint);
841 			else
842 				glk_request_line_event((Window *)arglist[0]._opaqueref, nullptr,
843 					0, arglist[2]._uint);
844 			break;
845 		case 0x00D1: /* cancel_line_event */
846 			if (arglist[1]._ptrflag) {
847 				event_t dat;
848 				glk_cancel_line_event((Window *)arglist[0]._opaqueref, &dat);
849 				arglist[2]._uint = dat.type;
850 				arglist[3]._opaqueref = dat.window;
851 				arglist[4]._uint = dat.val1;
852 				arglist[5]._uint = dat.val2;
853 			} else {
854 				glk_cancel_line_event((Window *)arglist[0]._opaqueref, nullptr);
855 			}
856 			break;
857 		case 0x00D2: /* request_char_event */
858 			glk_request_char_event((Window *)arglist[0]._opaqueref);
859 			break;
860 		case 0x00D3: /* cancel_char_event */
861 			glk_cancel_char_event((Window *)arglist[0]._opaqueref);
862 			break;
863 		case 0x00D4: /* request_mouse_event */
864 			glk_request_mouse_event((Window *)arglist[0]._opaqueref);
865 			break;
866 		case 0x00D5: /* cancel_mouse_event */
867 			glk_cancel_mouse_event((Window *)arglist[0]._opaqueref);
868 			break;
869 		case 0x00D6: /* request_timer_events */
870 			glk_request_timer_events(arglist[0]._uint);
871 			break;
872 
873 #ifdef GLK_MODULE_IMAGE
874 		case 0x00E0: /* image_get_info */
875 			{
876 				int ix = 1;
877 				uint *ptr1, *ptr2;
878 				if (!arglist[ix]._ptrflag) {
879 					ptr1 = nullptr;
880 				} else {
881 					ix++;
882 					ptr1 = &(arglist[ix]._uint);
883 				}
884 				ix++;
885 				if (!arglist[ix]._ptrflag) {
886 					ptr2 = nullptr;
887 				} else {
888 					ix++;
889 					ptr2 = &(arglist[ix]._uint);
890 				}
891 				ix++;
892 				ix++;
893 				arglist[ix]._uint = glk_image_get_info(arglist[0]._uint, ptr1, ptr2);
894 			}
895 			break;
896 		case 0x00E1: /* image_draw */
897 			arglist[5]._uint = glk_image_draw((Window *)arglist[0]._opaqueref,
898 				arglist[1]._uint,
899 				arglist[2]._sint, arglist[3]._sint);
900 			break;
901 		case 0x00E2: /* image_draw_scaled */
902 			arglist[7]._uint = glk_image_draw_scaled((Window *)arglist[0]._opaqueref,
903 				arglist[1]._uint,
904 				arglist[2]._sint, arglist[3]._sint,
905 				arglist[4]._uint, arglist[5]._uint);
906 			break;
907 		case 0x00E8: /* window_flow_break */
908 			glk_window_flow_break((Window *)arglist[0]._opaqueref);
909 			break;
910 		case 0x00E9: /* window_erase_rect */
911 			glk_window_erase_rect((Window *)arglist[0]._opaqueref,
912 				arglist[1]._sint, arglist[2]._sint,
913 				arglist[3]._uint, arglist[4]._uint);
914 			break;
915 		case 0x00EA: /* window_fill_rect */
916 			glk_window_fill_rect((Window *)arglist[0]._opaqueref, arglist[1]._uint,
917 				arglist[2]._sint, arglist[3]._sint,
918 				arglist[4]._uint, arglist[5]._uint);
919 			break;
920 		case 0x00EB: /* window_set_background_color */
921 			glk_window_set_background_color((Window *)arglist[0]._opaqueref, arglist[1]._uint);
922 			break;
923 #endif /* GLK_MODULE_IMAGE */
924 
925 #ifdef GLK_MODULE_SOUND
926 		case 0x00F0: /* schannel_iterate */
927 			if (arglist[1]._ptrflag)
928 				arglist[4]._opaqueref = glk_schannel_iterate((schanid_t)arglist[0]._opaqueref, &arglist[2]._uint);
929 			else
930 				arglist[3]._opaqueref = glk_schannel_iterate((schanid_t)arglist[0]._opaqueref, nullptr);
931 			break;
932 		case 0x00F1: /* schannel_get_rock */
933 			arglist[2]._uint = glk_schannel_get_rock((schanid_t)arglist[0]._opaqueref);
934 			break;
935 		case 0x00F2: /* schannel_create */
936 			arglist[2]._opaqueref = glk_schannel_create(arglist[0]._uint);
937 			break;
938 		case 0x00F3: /* schannel_destroy */
939 			glk_schannel_destroy((schanid_t)arglist[0]._opaqueref);
940 			break;
941 		case 0x00F8: /* schannel_play */
942 			arglist[3]._uint = glk_schannel_play((schanid_t)arglist[0]._opaqueref, arglist[1]._uint);
943 			break;
944 		case 0x00F9: /* schannel_play_ext */
945 			arglist[5]._uint = glk_schannel_play_ext((schanid_t)arglist[0]._opaqueref,
946 				arglist[1]._uint, arglist[2]._uint, arglist[3]._uint);
947 			break;
948 		case 0x00FA: /* schannel_stop */
949 			glk_schannel_stop((schanid_t)arglist[0]._opaqueref);
950 			break;
951 		case 0x00FB: /* schannel_set_volume */
952 			glk_schannel_set_volume((schanid_t)arglist[0]._opaqueref, arglist[1]._uint);
953 			break;
954 		case 0x00FC: /* sound_load_hint */
955 			glk_sound_load_hint(arglist[0]._uint, arglist[1]._uint);
956 			break;
957 
958 #ifdef GLK_MODULE_SOUND2
959 		case 0x00F4: /* schannel_create_ext */
960 			arglist[3]._opaqueref = glk_schannel_create_ext(arglist[0]._uint, arglist[1]._uint);
961 			break;
962 		case 0x00F7: /* schannel_play_multi */
963 			if (arglist[0]._ptrflag && arglist[3]._ptrflag)
964 				arglist[8]._uint = glk_schannel_play_multi((schanid_t *)arglist[1]._array, arglist[2]._uint, (uint *)arglist[4]._array, arglist[5]._uint, arglist[6]._uint);
965 			else if (arglist[0]._ptrflag)
966 				arglist[6]._uint = glk_schannel_play_multi((schanid_t *)arglist[1]._array, arglist[2]._uint, nullptr, 0, arglist[4]._uint);
967 			else if (arglist[1]._ptrflag)
968 				arglist[6]._uint = glk_schannel_play_multi(nullptr, 0, (uint *)arglist[2]._array, arglist[3]._uint, arglist[4]._uint);
969 			else
970 				arglist[4]._uint = glk_schannel_play_multi(nullptr, 0, nullptr, 0, arglist[2]._uint);
971 			break;
972 		case 0x00FD: /* schannel_set_volume_ext */
973 			glk_schannel_set_volume_ext((schanid_t)arglist[0]._opaqueref, arglist[1]._uint, arglist[2]._uint, arglist[3]._uint);
974 			break;
975 		case 0x00FE: /* schannel_pause */
976 			glk_schannel_pause((schanid_t)arglist[0]._opaqueref);
977 			break;
978 		case 0x00FF: /* schannel_unpause */
979 			glk_schannel_unpause((schanid_t)arglist[0]._opaqueref);
980 			break;
981 #endif /* GLK_MODULE_SOUND2 */
982 #endif /* GLK_MODULE_SOUND */
983 
984 #ifdef GLK_MODULE_HYPERLINKS
985 		case 0x0100: /* set_hyperlink */
986 			glk_set_hyperlink(arglist[0]._uint);
987 			break;
988 		case 0x0101: /* set_hyperlink_stream */
989 			glk_set_hyperlink_stream((strid_t)arglist[0]._opaqueref, arglist[1]._uint);
990 			break;
991 		case 0x0102: /* request_hyperlink_event */
992 			glk_request_hyperlink_event((Window *)arglist[0]._opaqueref);
993 			break;
994 		case 0x0103: /* cancel_hyperlink_event */
995 			glk_cancel_hyperlink_event((Window *)arglist[0]._opaqueref);
996 			break;
997 #endif /* GLK_MODULE_HYPERLINKS */
998 
999 #ifdef GLK_MODULE_UNICODE
1000 		case 0x0120: /* buffer_to_lower_case_uni */
1001 			if (arglist[0]._ptrflag)
1002 				arglist[5]._uint = glk_buffer_to_lower_case_uni((uint32 *)arglist[1]._array, arglist[2]._uint, arglist[3]._uint);
1003 			else
1004 				arglist[3]._uint = glk_buffer_to_lower_case_uni(nullptr, 0, arglist[1]._uint);
1005 			break;
1006 		case 0x0121: /* buffer_to_upper_case_uni */
1007 			if (arglist[0]._ptrflag)
1008 				arglist[5]._uint = glk_buffer_to_upper_case_uni((uint32 *)arglist[1]._array, arglist[2]._uint, arglist[3]._uint);
1009 			else
1010 				arglist[3]._uint = glk_buffer_to_upper_case_uni(nullptr, 0, arglist[1]._uint);
1011 			break;
1012 		case 0x0122: /* buffer_to_title_case_uni */
1013 			if (arglist[0]._ptrflag)
1014 				arglist[6]._uint = glk_buffer_to_title_case_uni((uint32 *)arglist[1]._array, arglist[2]._uint, arglist[3]._uint, arglist[4]._uint);
1015 			else
1016 				arglist[4]._uint = glk_buffer_to_title_case_uni(nullptr, 0, arglist[1]._uint, arglist[2]._uint);
1017 			break;
1018 		case 0x0128: /* put_char_uni */
1019 			glk_put_char_uni(arglist[0]._uint);
1020 			break;
1021 		case 0x0129: /* put_string_uni */
1022 			glk_put_string_uni(arglist[0]._unicharstr);
1023 			break;
1024 		case 0x012A: /* put_buffer_uni */
1025 			if (arglist[0]._ptrflag)
1026 				glk_put_buffer_uni((const uint32 *)arglist[1]._array, arglist[2]._uint);
1027 			else
1028 				glk_put_buffer_uni(nullptr, 0);
1029 			break;
1030 		case 0x012B: /* put_char_stream_uni */
1031 			glk_put_char_stream_uni((strid_t)arglist[0]._opaqueref, arglist[1]._uint);
1032 			break;
1033 		case 0x012C: /* put_string_stream_uni */
1034 			glk_put_string_stream_uni((strid_t)arglist[0]._opaqueref, arglist[1]._unicharstr);
1035 			break;
1036 		case 0x012D: /* put_buffer_stream_uni */
1037 			if (arglist[1]._ptrflag)
1038 				glk_put_buffer_stream_uni((strid_t)arglist[0]._opaqueref, (const uint32 *)arglist[2]._array, arglist[3]._uint);
1039 			else
1040 				glk_put_buffer_stream_uni((strid_t)arglist[0]._opaqueref, nullptr, 0);
1041 			break;
1042 		case 0x0130: /* get_char_stream_uni */
1043 			arglist[2]._sint = glk_get_char_stream_uni((strid_t)arglist[0]._opaqueref);
1044 			break;
1045 		case 0x0131: /* get_buffer_stream_uni */
1046 			if (arglist[1]._ptrflag)
1047 				arglist[5]._uint = glk_get_buffer_stream_uni((strid_t)arglist[0]._opaqueref,
1048 					(uint32 *)arglist[2]._array, arglist[3]._uint);
1049 			else
1050 				arglist[3]._uint = glk_get_buffer_stream_uni((strid_t)arglist[0]._opaqueref, nullptr, 0);
1051 			break;
1052 		case 0x0132: /* get_line_stream_uni */
1053 			if (arglist[1]._ptrflag)
1054 				arglist[5]._uint = glk_get_line_stream_uni((strid_t)arglist[0]._opaqueref,
1055 					(uint32 *)arglist[2]._array, arglist[3]._uint);
1056 			else
1057 				arglist[3]._uint = glk_get_line_stream_uni((strid_t)arglist[0]._opaqueref, nullptr, 0);
1058 			break;
1059 		case 0x0138: /* stream_open_file_uni */
1060 			arglist[4]._opaqueref = glk_stream_open_file_uni((frefid_t)arglist[0]._opaqueref, (FileMode)arglist[1]._uint,
1061 				arglist[2]._uint);
1062 			break;
1063 		case 0x0139: /* stream_open_memory_uni */
1064 			if (arglist[0]._ptrflag)
1065 				arglist[6]._opaqueref = glk_stream_open_memory_uni((uint32 *)arglist[1]._array,
1066 					arglist[2]._uint, (FileMode)arglist[3]._uint, arglist[4]._uint);
1067 			else
1068 				arglist[4]._opaqueref = glk_stream_open_memory_uni(nullptr, 0, (FileMode)arglist[1]._uint, arglist[2]._uint);
1069 			break;
1070 		case 0x0140: /* request_char_event_uni */
1071 			glk_request_char_event_uni((Window *)arglist[0]._opaqueref);
1072 			break;
1073 		case 0x0141: /* request_line_event_uni */
1074 			if (arglist[1]._ptrflag)
1075 				glk_request_line_event_uni((Window *)arglist[0]._opaqueref, (uint32 *)arglist[2]._array,
1076 					arglist[3]._uint, arglist[4]._uint);
1077 			else
1078 				glk_request_line_event_uni((Window *)arglist[0]._opaqueref, nullptr,
1079 					0, arglist[2]._uint);
1080 			break;
1081 #endif /* GLK_MODULE_UNICODE */
1082 
1083 #ifdef GLK_MODULE_UNICODE_NORM
1084 		case 0x0123: /* buffer_canon_decompose_uni */
1085 			if (arglist[0]._ptrflag)
1086 				arglist[5]._uint = glk_buffer_canon_decompose_uni((uint32 *)arglist[1]._array, arglist[2]._uint, arglist[3]._uint);
1087 			else
1088 				arglist[3]._uint = glk_buffer_canon_decompose_uni(nullptr, 0, arglist[1]._uint);
1089 			break;
1090 		case 0x0124: /* buffer_canon_normalize_uni */
1091 			if (arglist[0]._ptrflag)
1092 				arglist[5]._uint = glk_buffer_canon_normalize_uni((uint32 *)arglist[1]._array, arglist[2]._uint, arglist[3]._uint);
1093 			else
1094 				arglist[3]._uint = glk_buffer_canon_normalize_uni(nullptr, 0, arglist[1]._uint);
1095 			break;
1096 #endif /* GLK_MODULE_UNICODE_NORM */
1097 
1098 #ifdef GLK_MODULE_LINE_ECHO
1099 		case 0x0150: /* set_echo_line_event */
1100 			glk_set_echo_line_event((Window *)arglist[0]._opaqueref, arglist[1]._uint);
1101 			break;
1102 #endif /* GLK_MODULE_LINE_ECHO */
1103 
1104 #ifdef GLK_MODULE_LINE_TERMINATORS
1105 		case 0x0151: /* set_terminators_line_event */
1106 			if (arglist[1]._ptrflag)
1107 				glk_set_terminators_line_event((Window *)arglist[0]._opaqueref, (const uint32 *)arglist[2]._array, arglist[3]._uint);
1108 			else
1109 				glk_set_terminators_line_event((Window *)arglist[0]._opaqueref,
1110 					nullptr, 0);
1111 			break;
1112 #endif /* GLK_MODULE_LINE_TERMINATORS */
1113 
1114 #ifdef GLK_MODULE_DATETIME
1115 		case 0x0160: /* current_time */
1116 			if (arglist[0]._ptrflag) {
1117 				glktimeval_t dat;
1118 				glk_current_time(&dat);
1119 				arglist[1]._sint = dat.high_sec;
1120 				arglist[2]._uint = dat.low_sec;
1121 				arglist[3]._sint = dat.microsec;
1122 			} else {
1123 				glk_current_time(nullptr);
1124 			}
1125 			break;
1126 		case 0x0161: /* current_simple_time */
1127 			arglist[2]._sint = glk_current_simple_time(arglist[0]._uint);
1128 			break;
1129 		case 0x0168: /* time_to_date_utc */ {
1130 			glktimeval_t timeval;
1131 			glktimeval_t *timeptr = nullptr;
1132 			glkdate_t date;
1133 			glkdate_t *dateptr = nullptr;
1134 			int ix = 0;
1135 			if (arglist[ix++]._ptrflag) {
1136 				timeptr = &timeval;
1137 				timeval.high_sec = arglist[ix++]._sint;
1138 				timeval.low_sec = arglist[ix++]._uint;
1139 				timeval.microsec = arglist[ix++]._sint;
1140 			}
1141 			if (arglist[ix++]._ptrflag) {
1142 				dateptr = &date;
1143 			}
1144 			glk_time_to_date_utc(timeptr, dateptr);
1145 			if (dateptr) {
1146 				arglist[ix++]._sint = date.year;
1147 				arglist[ix++]._sint = date.month;
1148 				arglist[ix++]._sint = date.day;
1149 				arglist[ix++]._sint = date.weekday;
1150 				arglist[ix++]._sint = date.hour;
1151 				arglist[ix++]._sint = date.minute;
1152 				arglist[ix++]._sint = date.second;
1153 				arglist[ix++]._sint = date.microsec;
1154 			}
1155 			}
1156 			break;
1157 		case 0x0169: /* time_to_date_local */ {
1158 			glktimeval_t timeval;
1159 			glktimeval_t *timeptr = nullptr;
1160 			glkdate_t date;
1161 			glkdate_t *dateptr = nullptr;
1162 			int ix = 0;
1163 			if (arglist[ix++]._ptrflag) {
1164 				timeptr = &timeval;
1165 				timeval.high_sec = arglist[ix++]._sint;
1166 				timeval.low_sec = arglist[ix++]._uint;
1167 				timeval.microsec = arglist[ix++]._sint;
1168 			}
1169 			if (arglist[ix++]._ptrflag) {
1170 				dateptr = &date;
1171 			}
1172 			glk_time_to_date_local(timeptr, dateptr);
1173 			if (dateptr) {
1174 				arglist[ix++]._sint = date.year;
1175 				arglist[ix++]._sint = date.month;
1176 				arglist[ix++]._sint = date.day;
1177 				arglist[ix++]._sint = date.weekday;
1178 				arglist[ix++]._sint = date.hour;
1179 				arglist[ix++]._sint = date.minute;
1180 				arglist[ix++]._sint = date.second;
1181 				arglist[ix++]._sint = date.microsec;
1182 			}
1183 			}
1184 			break;
1185 		case 0x016A: /* simple_time_to_date_utc */ {
1186 			glkdate_t date;
1187 			glkdate_t *dateptr = nullptr;
1188 			int ix = 2;
1189 			if (arglist[ix++]._ptrflag) {
1190 				dateptr = &date;
1191 			}
1192 			glk_simple_time_to_date_utc(arglist[0]._sint, arglist[1]._uint, dateptr);
1193 			if (dateptr) {
1194 				arglist[ix++]._sint = date.year;
1195 				arglist[ix++]._sint = date.month;
1196 				arglist[ix++]._sint = date.day;
1197 				arglist[ix++]._sint = date.weekday;
1198 				arglist[ix++]._sint = date.hour;
1199 				arglist[ix++]._sint = date.minute;
1200 				arglist[ix++]._sint = date.second;
1201 				arglist[ix++]._sint = date.microsec;
1202 			}
1203 			}
1204 			break;
1205 		case 0x016B: /* simple_time_to_date_local */ {
1206 			glkdate_t date;
1207 			glkdate_t *dateptr = nullptr;
1208 			int ix = 2;
1209 			if (arglist[ix++]._ptrflag) {
1210 				dateptr = &date;
1211 			}
1212 			glk_simple_time_to_date_local(arglist[0]._sint, arglist[1]._uint, dateptr);
1213 			if (dateptr) {
1214 				arglist[ix++]._sint = date.year;
1215 				arglist[ix++]._sint = date.month;
1216 				arglist[ix++]._sint = date.day;
1217 				arglist[ix++]._sint = date.weekday;
1218 				arglist[ix++]._sint = date.hour;
1219 				arglist[ix++]._sint = date.minute;
1220 				arglist[ix++]._sint = date.second;
1221 				arglist[ix++]._sint = date.microsec;
1222 			}
1223 			}
1224 			break;
1225 		case 0x016C: /* date_to_time_utc */ {
1226 			glkdate_t date;
1227 			glkdate_t *dateptr = nullptr;
1228 			glktimeval_t timeval;
1229 			glktimeval_t *timeptr = nullptr;
1230 			timeval.high_sec = timeval.low_sec = timeval.microsec = 0;
1231 
1232 			int ix = 0;
1233 			if (arglist[ix++]._ptrflag) {
1234 				dateptr = &date;
1235 				date.year = arglist[ix++]._sint;
1236 				date.month = arglist[ix++]._sint;
1237 				date.day = arglist[ix++]._sint;
1238 				date.weekday = arglist[ix++]._sint;
1239 				date.hour = arglist[ix++]._sint;
1240 				date.minute = arglist[ix++]._sint;
1241 				date.second = arglist[ix++]._sint;
1242 				date.microsec = arglist[ix++]._sint;
1243 			}
1244 			if (arglist[ix++]._ptrflag) {
1245 				timeptr = &timeval;
1246 			}
1247 			glk_date_to_time_utc(dateptr, timeptr);
1248 			if (timeptr) {
1249 				arglist[ix++]._sint = timeval.high_sec;
1250 				arglist[ix++]._uint = timeval.low_sec;
1251 				arglist[ix++]._sint = timeval.microsec;
1252 			}
1253 			}
1254 			break;
1255 		case 0x016D: /* date_to_time_local */ {
1256 			glkdate_t date;
1257 			glkdate_t *dateptr = nullptr;
1258 			glktimeval_t timeval;
1259 			glktimeval_t *timeptr = nullptr;
1260 			timeval.high_sec = timeval.low_sec = timeval.microsec = 0;
1261 
1262 			int ix = 0;
1263 			if (arglist[ix++]._ptrflag) {
1264 				dateptr = &date;
1265 				date.year = arglist[ix++]._sint;
1266 				date.month = arglist[ix++]._sint;
1267 				date.day = arglist[ix++]._sint;
1268 				date.weekday = arglist[ix++]._sint;
1269 				date.hour = arglist[ix++]._sint;
1270 				date.minute = arglist[ix++]._sint;
1271 				date.second = arglist[ix++]._sint;
1272 				date.microsec = arglist[ix++]._sint;
1273 			}
1274 			if (arglist[ix++]._ptrflag) {
1275 				timeptr = &timeval;
1276 			}
1277 			glk_date_to_time_local(dateptr, timeptr);
1278 			if (timeptr) {
1279 				arglist[ix++]._sint = timeval.high_sec;
1280 				arglist[ix++]._uint = timeval.low_sec;
1281 				arglist[ix++]._sint = timeval.microsec;
1282 			}
1283 			}
1284 			break;
1285 		case 0x016E: /* date_to_simple_time_utc */ {
1286 			glkdate_t date;
1287 			glkdate_t *dateptr = nullptr;
1288 			int ix = 0;
1289 			if (arglist[ix++]._ptrflag) {
1290 				dateptr = &date;
1291 				date.year = arglist[ix++]._sint;
1292 				date.month = arglist[ix++]._sint;
1293 				date.day = arglist[ix++]._sint;
1294 				date.weekday = arglist[ix++]._sint;
1295 				date.hour = arglist[ix++]._sint;
1296 				date.minute = arglist[ix++]._sint;
1297 				date.second = arglist[ix++]._sint;
1298 				date.microsec = arglist[ix++]._sint;
1299 			}
1300 			arglist[ix+2]._sint = glk_date_to_simple_time_utc(dateptr, arglist[ix]._uint);
1301 			}
1302 			break;
1303 		case 0x016F: /* date_to_simple_time_local */ {
1304 			glkdate_t date;
1305 			glkdate_t *dateptr = nullptr;
1306 			int ix = 0;
1307 			if (arglist[ix++]._ptrflag) {
1308 				dateptr = &date;
1309 				date.year = arglist[ix++]._sint;
1310 				date.month = arglist[ix++]._sint;
1311 				date.day = arglist[ix++]._sint;
1312 				date.weekday = arglist[ix++]._sint;
1313 				date.hour = arglist[ix++]._sint;
1314 				date.minute = arglist[ix++]._sint;
1315 				date.second = arglist[ix++]._sint;
1316 				date.microsec = arglist[ix++]._sint;
1317 			}
1318 			arglist[ix+2]._sint = glk_date_to_simple_time_local(dateptr, arglist[ix]._uint);
1319 			}
1320 			break;
1321 #endif /* GLK_MODULE_DATETIME */
1322 
1323 #ifdef GLK_MODULE_GARGLKTEXT
1324 		case 0x1100: /* garglk_set_zcolors */
1325 			garglk_set_zcolors( arglist[0]._uint, arglist[1]._uint );
1326 			break;
1327 		case 0x1101: /* garglk_set_zcolors_stream */
1328 			garglk_set_zcolors_stream((strid_t)arglist[0]._opaqueref, arglist[1]._uint, arglist[2]._uint );
1329 			break;
1330 		case 0x1102: /* garglk_set_reversevideo */
1331 			garglk_set_reversevideo( arglist[0]._uint );
1332 			break;
1333 		case 0x1103: /* garglk_set_reversevideo_stream */
1334 			garglk_set_reversevideo_stream((strid_t)arglist[0]._opaqueref, arglist[1]._uint );
1335 			break;
1336 #endif /* GLK_MODULE_GARGLKTEXT */
1337 
1338 		default:
1339 			/* do nothing */
1340 			break;
1341 	}
1342 }
1343 
gidispatch_get_objrock(void * obj,uint objclass)1344 gidispatch_rock_t GlkAPI::gidispatch_get_objrock(void *obj, uint objclass) {
1345 	switch (objclass) {
1346 	case gidisp_Class_Window:
1347 		return ((Window *)obj)->_dispRock;
1348 	case gidisp_Class_Stream:
1349 		return ((Stream *)obj)->_dispRock;
1350 	case gidisp_Class_Fileref:
1351 		return ((FileReference *)obj)->_dispRock;
1352 	case gidisp_Class_Schannel:
1353 		return ((SoundChannel *)obj)->_dispRock;
1354 	default: {
1355 		gidispatch_rock_t dummy;
1356 		dummy.num = 0;
1357 		return dummy;
1358 	}
1359 	}
1360 }
1361 
1362 } // End of namespace Glk
1363