-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGlk Window Wrappers.i7x
2232 lines (1760 loc) · 113 KB
/
Glk Window Wrappers.i7x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Version 1 of Glk Window Wrappers (for Glulx only) by Brady Garvin begins here.
"Facilities for adding Glk windows around story content regardless of the story's windowing code."
Include Runtime Checks by Brady Garvin.
Include Low-Level Operations by Brady Garvin.
Include Low-Level Text by Brady Garvin.
Include Low-Level Linked Lists by Brady Garvin.
Include Low-Level Hash Tables by Brady Garvin.
Include Glk Interception by Brady Garvin.
Use authorial modesty.
Book "Copyright and License"
[Copyright 2013 Brady J. Garvin]
[This extension is released under the Creative Commons Attribution 3.0 Unported License (CC BY 3.0) so that it can qualify as a public Inform extension. See the LICENSE file included in the release for further details.]
Book "Extension Information"
[Nothing to mention here in the present version.]
Chapter "Use Options"
Use a resource hash table size of at least 23 translates as (- Constant GWW_RESOURCE_HASH_SIZE={N}; -).
To decide what number is the resource hash table size: (- GWW_RESOURCE_HASH_SIZE -).
Use a wrapped window state preallocation of at least 32 translates as (- Constant GWW_WINDOW_STATE_PREALLOC={N}; -).
Use a wrapped stream state preallocation of at least 64 translates as (- Constant GWW_STREAM_STATE_PREALLOC={N}; -).
To decide what number is the wrapped window state preallocation: (- GWW_WINDOW_STATE_PREALLOC -).
To decide what number is the wrapped stream state preallocation: (- GWW_STREAM_STATE_PREALLOC -).
Book "Runtime Checks"
Chapter "Messages" - unindexed
To fail at finding a window state for the window (W - a wrapped window):
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]I needed the state of the window [W converted to a number in hexadecimal], but I could not find it anywhere in my bookkeeping.[terminating the story]".
To fail at finding a stream state for the stream (S - a wrapped stream):
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]I needed the state of the stream [S converted to a number in hexadecimal], but I could not find it anywhere in my bookkeeping.[terminating the story]".
To fail at preserving the relationship invariants on window states:
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]I found an inconsistency in my bookkeeping where the parent entry under one window and a child entry under another plainly contradict each other. Either the data is corrupted or I've lost track of something.[terminating the story]".
To fail at giving a parent window three children:
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]While recovering Glk window information I found three window that share a parent. But Glk parent windows always have two children, so something in my bookkeeping has gone quite wrong.[terminating the story]".
To fail at opening a root window twice in a single-window environment:
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]The story asked me to open a two root windows. That could either be a bug in the story or fallout from the story opening a root window with the rock 1735882496 (ASCII 'gww\0') in a single-window environment and then trying to recover it. Either way, I'm not able to fulfill the request.[terminating the story]".
To fail at discovering multiple windows in a single-window environment:
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]My previous assessment, by trying to open multiple windows, was that the Glk layer below is running a single-window environment. But now I find the story referring to multiple, distinct windows, so I must be confused.[terminating the story]".
To fail at opening any windows:
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]I was not able to open any windows. Unfortunately, it's unlikely you cannot see this error message, but if you can, then that is evidence that something is doubly wrong.[terminating the story]".
To fail at filling in for the frame window when multiple windows are not supported and there is already a conflicting window:
say "[low-level runtime failure in]Glk Window Wrappers[with explanation]I found that the Glk layer below only supports a single window, so I needed that single window to fill in for the frame window. But there was already a single window allocated, and not one previously created for that purpose.[terminating the story]".
Book "Glk Structures and Opaque Objects"
Chapter "Wrapped Windows"
Section "The Wrapped Window Kind"
A wrapped window is a kind of value.
A wrapped window is an invalid wrapped window. [See the note in the book "Extension Information."]
The specification of a wrapped window is "Wrapped windows represent Glk window handles specifically for the extension Glk Window Wrappers. Most other code would want to interact with handles in some other way, for instance via Jon Ingold's extension Flexible Windows."
Section "Wrapped Window Constants"
To decide what wrapped window is a null wrapped window: (- 0 -).
Section "Wrapped Window Adjectives"
Definition: a wrapped window is null if it is a null wrapped window.
Chapter "Wrapped Streams"
Section "The Wrapped Stream Kind"
A wrapped stream is a kind of value.
A wrapped stream is an invalid wrapped stream. [See the note in the book "Extension Information."]
The specification of a wrapped stream is "Wrapped streams represent Glk stream handles specifically for the extension Glk Window Wrappers. Most other code would want to interact with handles in some other way."
Section "Wrapped Stream Constants"
To decide what wrapped stream is a null wrapped stream: (- 0 -).
Section "Wrapped Stream Adjectives"
Definition: a wrapped stream is null if it is a null wrapped stream.
Chapter "Event Types"
To decide what number is the null event type: (- evtype_None -).
To decide what number is the timer event type: (- evtype_Timer -).
To decide what number is the character input event type: (- evtype_CharInput -).
To decide what number is the line input event type: (- evtype_LineInput -).
To decide what number is the mouse input event type: (- evtype_MouseInput -).
To decide what number is the window arrangement event type: (- evtype_Arrange -).
To decide what number is the redraw event type: (- evtype_Redraw -).
To decide what number is the sound notification event type: (- evtype_SoundNotify -).
To decide what number is the hyperlink event type: (- evtype_Hyperlink -).
Chapter "Wrapped Events"
Section "The Wrapped Event Kind"
A wrapped event is a kind of value.
A wrapped event is an invalid wrapped event. [See the note in the book "Extension Information."]
The specification of a wrapped event is "Wrapped events represent Glk event notifications specifically for the extension Glk Wrapped Windows. Most other code would want to interact with the Glk library in some other way, for instance via Emily Short's extension Glulx Entry Points."
Section "Wrapped Event Constants"
To decide what wrapped event is an on-the-stack wrapped event: (- (-1) -).
Section "Wrapped Event Adjectives"
Definition: a wrapped event is on the stack if it is an on-the-stack wrapped event.
Definition: a wrapped event is internally-spawned if the event type of it is not the character input event type and the event type of it is not the line input event type and the event type of it is not the mouse input event type and the event type of it is not the hyperlink event type.
Section "The Wrapped Event Structure" - unindexed
[Layout:
4 bytes for the event type
4 bytes for the source window
4 bytes for the first associated value
4 bytes for the second associated value]
To decide what number is the size in memory of a wrapped event: (- 16 -).
Section "Wrapped Event Construction"
To decide what wrapped event is a new permanent wrapped event:
decide on a permanent memory allocation of the size in memory of a wrapped event bytes converted to a wrapped event.
To decide what wrapped event is a new wrapped event:
decide on a memory allocation of the size in memory of a wrapped event bytes converted to a wrapped event.
To delete (A - a wrapped event):
free the memory allocation at address A converted to a number.
Section "Copying Wrapped Events"
To copy (A - a wrapped event) to (B - a wrapped event):
copy the size in memory of a wrapped event bytes from address (A converted to a number) to address (B converted to a number).
To copy (A - a wrapped event) to the four stack results beginning with stack result number (I - a number) of the Glk invocation just delegated:
write the event type of A to stack result number I of the Glk invocation just delegated;
write (the source window of A converted to a number) to stack result number I plus one of the Glk invocation just delegated;
write the first associated value of A to stack result number I plus two of the Glk invocation just delegated;
write the second associated value of A to stack result number I plus three of the Glk invocation just delegated.
To copy the four stack results beginning with stack result number (I - a number) of the Glk invocation just delegated to (B - a wrapped event):
write the event type stack result number I of the Glk invocation just delegated to B;
write the source window (stack result number I plus one of the Glk invocation just delegated converted to a wrapped window) to B;
write the first associated value stack result number I plus two of the Glk invocation just delegated to B;
write the second associated value stack result number I plus three of the Glk invocation just delegated to B.
Section "Wrapped Event Accessors and Mutators"
To decide what number is the event type of (A - a wrapped event): (- llo_getInt({A}) -).
To write the event type (X - a number) to (A - a wrapped event): (- llo_setInt({A},{X}); -).
To decide what wrapped window is the source window of (A - a wrapped event): (- llo_getField({A},1) -).
To write the source window (X - a wrapped window) to (A - a wrapped event): (- llo_setField({A},1,{X}); -).
To decide what number is the first associated value of (A - a wrapped event): (- llo_getField({A},2) -).
To write the first associated value (X - a number) to (A - a wrapped event): (- llo_setField({A},2,{X}); -).
To decide what number is the second associated value of (A - a wrapped event): (- llo_getField({A},3) -).
To write the second associated value (X - a number) to (A - a wrapped event): (- llo_setField({A},3,{X}); -).
Book "State Data Structures"
Chapter "Wrapped Window States"
Section "The Wrapped Window State Kind" - unindexed
A wrapped window state is a kind of value.
A wrapped window state is an invalid wrapped window state. [See the note in the book "Extension Information."]
The specification of a wrapped window state is "Wrapped window states represent the relationships between story windows. The extension Glk Window Wrappers tracks these relationships to simplify its code."
Section "The Wrapped Window State Structure" - unindexed
[Layout:
4 bytes for the window
4 bytes for the parent
4 bytes for the first child
4 bytes for the second child
4 bytes for the last-seen character input request (the glk function selector used to make the request, zero for none)
4 bytes for the last-seen line input request (ditto)
4 bytes for the last-seen line buffer address
4 bytes for the last-seen line buffer length (in bytes, not characters)
4 bytes for the last-seen initial line buffer content address
4 bytes for the last-seen initial line buffer content length (in bytes, not characters)
4 bytes for the last-seen mouse input request (the glk function selector used to make the request, zero for none)
4 bytes for the last-seen hyperlink input request (ditto)
4 bytes for the occupancy count]
To decide what number is the size in memory of a wrapped window state: (- 52 -).
Section "Wrapped Window State Construction and Destruction" - unindexed
The wrapped window state object pool is an object pool that varies.
A GRIF setup rule (this is the allocate an object pool for wrapped window states rule):
now the wrapped window state object pool is a new permanent object pool with the wrapped window state preallocation objects of size the size in memory of a wrapped window state bytes.
To decide what wrapped window state is a new wrapped window state for (W - a wrapped window):
let the result be a memory allocation from the wrapped window state object pool converted to a wrapped window state;
zero the size in memory of a wrapped window state bytes at address result converted to a number;
write the window W to the result;
decide on the result.
To delete (A - a wrapped window state):
let the initial line buffer content address be the last-seen initial line buffer content address of A;
if the initial line buffer content address is not zero:
free the possibly zero-length memory allocation at address initial line buffer content address;
free the memory allocation at address (A converted to a number) to the wrapped window state object pool.
Section "Wrapped Window State Accessors and Mutators" - unindexed
To decide what wrapped window is the window of (A - a wrapped window state): (- llo_getInt({A}) -).
To write the window (X - a wrapped window) to (A - a wrapped window state): (- llo_setInt({A},{X}); -).
To decide what wrapped window is the parent of (A - a wrapped window state): (- llo_getField({A},1) -).
To write the parent (X - a wrapped window) to (A - a wrapped window state): (- llo_setField({A},1,{X}); -).
To decide what wrapped window is the first child of (A - a wrapped window state): (- llo_getField({A},2) -).
To write the first child (X - a wrapped window) to (A - a wrapped window state): (- llo_setField({A},2,{X}); -).
To decide what wrapped window is the second child of (A - a wrapped window state): (- llo_getField({A},3) -).
To write the second child (X - a wrapped window) to (A - a wrapped window state): (- llo_setField({A},3,{X}); -).
To decide what number is the last-seen character input request of (A - a wrapped window state): (- llo_getField({A},4) -).
To write the last-seen character input request (X - a number) to (A - a wrapped window state): (- llo_setField({A},4,{X}); -).
To decide what number is the last-seen line input request of (A - a wrapped window state): (- llo_getField({A},5) -).
To write the last-seen line input request (X - a number) to (A - a wrapped window state): (- llo_setField({A},5,{X}); -).
To decide what number is the last-seen line buffer address of (A - a wrapped window state): (- llo_getField({A},6) -).
To write the last-seen line buffer address (X - a number) to (A - a wrapped window state): (- llo_setField({A},6,{X}); -).
To decide what number is the last-seen line buffer length of (A - a wrapped window state): (- llo_getField({A},7) -).
To write the last-seen line buffer length (X - a number) to (A - a wrapped window state): (- llo_setField({A},7,{X}); -).
To decide what number is the last-seen initial line buffer content address of (A - a wrapped window state): (- llo_getField({A},8) -).
To write the last-seen initial line buffer content address (X - a number) to (A - a wrapped window state): (- llo_setField({A},8,{X}); -).
To decide what number is the last-seen initial line buffer content length of (A - a wrapped window state): (- llo_getField({A},9) -).
To write the last-seen initial line buffer content length (X - a number) to (A - a wrapped window state): (- llo_setField({A},9,{X}); -).
To decide what number is the last-seen mouse input request of (A - a wrapped window state): (- llo_getField({A},10) -).
To write the last-seen mouse input request (X - a number) to (A - a wrapped window state): (- llo_setField({A},10,{X}); -).
To decide what number is the last-seen hyperlink input request of (A - a wrapped window state): (- llo_getField({A},11) -).
To write the last-seen hyperlink input request (X - a number) to (A - a wrapped window state): (- llo_setField({A},11,{X}); -).
To decide whether (A - a wrapped window state) is occupied: (- llo_getField({A},12) -).
To occupy (A - a wrapped window state): (- llo_setField({A},12,llo_getField({A},12)+1); -).
To vacate (A - a wrapped window state): (- llo_setField({A},12,llo_getField({A},12)-1); -).
Chapter "Wrapped Stream States"
Section "The Wrapped Stream State Kind" - unindexed
A wrapped stream state is a kind of value.
A wrapped stream state is an invalid wrapped stream state. [See the note in the book "Extension Information."]
The specification of a wrapped stream state is "Wrapped stream states represent the stream information that the extension Glk Stream Wrappers must track to prevent formatting anomalies."
Section "The Wrapped Stream State Structure" - unindexed
[Layout:
4 bytes for the stream
4 bytes for the echo stream
4 bytes for the last-seen style
4 bytes for the occupancy count]
To decide what number is the size in memory of a wrapped stream state: (- 16 -).
Section "Wrapped Stream State Construction and Destruction" - unindexed
The wrapped stream state object pool is an object pool that varies.
A GRIF setup rule (this is the allocate an object pool for wrapped stream states rule):
now the wrapped stream state object pool is a new permanent object pool with the wrapped stream state preallocation objects of size the size in memory of a wrapped stream state bytes.
To decide what wrapped stream state is a new wrapped stream state for (S - a wrapped stream):
let the result be a memory allocation from the wrapped stream state object pool converted to a wrapped stream state;
zero the size in memory of a wrapped stream state bytes at address result converted to a number;
write the stream S to the result;
decide on the result.
To delete (A - a wrapped stream state):
free the memory allocation at address (A converted to a number) to the wrapped stream state object pool.
Section "Wrapped Stream State Accessors and Mutators" - unindexed
To decide what wrapped stream is the stream of (A - a wrapped stream state): (- llo_getInt({A}) -).
To write the stream (X - a wrapped stream) to (A - a wrapped stream state): (- llo_setInt({A},{X}); -).
To decide what wrapped stream is the echo stream of (A - a wrapped stream state): (- llo_getField({A},1) -).
To write the echo stream (X - a wrapped stream) to (A - a wrapped stream state): (- llo_setField({A},1,{X}); -).
To decide what number is the last-seen style of (A - a wrapped stream state): (- llo_getField({A},2) -).
To write the last-seen style (X - a number) to (A - a wrapped stream state): (- llo_setField({A},2,{X}); -).
To decide whether (A - a wrapped stream state) is occupied: (- llo_getField({A},3) -).
To occupy (A - a wrapped stream state): (- llo_setField({A},3,llo_getField({A},3)+1); -).
To vacate (A - a wrapped stream state): (- llo_setField({A},3,llo_getField({A},3)-1); -).
Book "Wrapping Framework"
Chapter "Event Routing Decisions"
An event routing decision is a kind of value.
The event routing decisions are routing the event normally and routing the event no further.
The specification of an event routing decision is "Wrapping layers use the event routing decisions returned by their foreign event handlers to decide whether ambiguously destined events should be sent to the wrapped event handler or not. At the time of writing only two kinds of events could be unclear about whether they were meant for the wrapping or the wrapped code: timer events and sound notification events."
Chapter "Wrapping Layers"
Section "The Wrapping Layer Kind"
A wrapping layer is a kind of value.
A wrapping layer is an invalid wrapping layer. [See the note in the book "Extension Information."]
The specification of a wrapping layer is "Wrapping layers represent the Glk interception layers used by the extension Glk Window Wrappers, as well as their associated data. Most other code would want to interact with Glk layers directly, via the extension Glk Interception."
Section "The Wrapping Layer Structure" - unindexed
[Layout:
4 bytes for the layer after this one
4 bytes for the window hash table
4 bytes for the stream hash table
4 bytes for the frame window
4 bytes for the deferred event linked list
4 bytes for the deferred event linked list tail
4 bytes for the foreign event handler
4 bytes for the multiple windows supported flag]
To decide what number is the size in memory of a wrapping layer: (- 32 -).
Section "Wrapping Layer Construction" - unindexed
To decide what wrapping layer is a new permanent wrapping layer followed by (L - a Glk layer) with foreign events handled by (H - a phrase wrapped event -> event routing decision) (this is constructing a permanent wrapping layer):
let the result be a permanent memory allocation of the size in memory of a wrapping layer bytes converted to a wrapping layer;
zero the size in memory of a wrapping layer bytes at address result converted to a number;
write L as the Glk layer after the result;
let the window hash table be a new hash table with the resource hash table size buckets;
write the window hash table the window hash table to the result;
let the stream hash table be a new hash table with the resource hash table size buckets;
write the stream hash table the stream hash table to the result;
write the foreign event handler H to the result;
decide on the result.
Section "Private Wrapping Layer Accessors and Mutators" - unindexed
To write (X - a Glk layer) as the Glk layer after (A - a wrapping layer): (- llo_setInt({A},{X}); -).
To decide what hash table is the window hash table of (A - a wrapping layer): (- llo_getField({A},1) -).
To write the window hash table (X - a hash table) to (A - a wrapping layer): (- llo_setField({A},1,{X}); -).
To decide what hash table is the stream hash table of (A - a wrapping layer): (- llo_getField({A},2) -).
To write the stream hash table (X - a hash table) to (A - a wrapping layer): (- llo_setField({A},2,{X}); -).
To decide what linked list is the deferred event linked list of (A - a wrapping layer): (- ({A}-->4) -).
To write the deferred event linked list (X - a linked list) to (A - a wrapping layer): (- llo_setField({A},4,{X}); -).
To decide what linked list tail is the deferred event linked list tail of (A - a wrapping layer): (- ({A}-->5) -).
To write the deferred event linked list tail (X - a linked list tail) to (A - a wrapping layer): (- llo_setField({A},5,{X}); -).
To decide what phrase wrapped event -> event routing decision is the foreign event handler of (A - a wrapping layer): (- llo_getField({A},6) -).
To write the foreign event handler (X - a phrase wrapped event -> event routing decision) to (A - a wrapping layer): (- llo_setField({A},6,{X}); -).
To reset the multiple windows supported flag in (A - a wrapping layer): (- llo_setField({A},7,0); -).
To set the multiple windows supported flag in (A - a wrapping layer): (- llo_setField({A},7,1); -).
To decide what wrapped window state is the window state for (W - a wrapped window) in (A - a wrapping layer):
decide on the first wrapped window state value matching the key W in the window hash table of A or an invalid wrapped window state if there are no matches.
To decide what wrapped stream state is the stream state for (S - a wrapped stream) in (A - a wrapping layer):
decide on the first wrapped stream state value matching the key S in the stream hash table of A or an invalid wrapped stream state if there are no matches.
To decide what wrapped window state is the legal window state for (W - a wrapped window) in (A - a wrapping layer) (this is finding a legal window state according to a wrapping layer):
let the result be the first wrapped window state value matching the key W in the window hash table of A or an invalid wrapped window state if there are no matches;
always check that the result is not an invalid wrapped window state or else fail at finding a window state for the window W;
decide on the result.
To decide what wrapped stream state is the legal stream state for (S - a wrapped stream) in (A - a wrapping layer) (this is finding a legal stream state according to a wrapping layer):
let the result be the first wrapped stream state value matching the key S in the stream hash table of A or an invalid wrapped stream state if there are no matches;
always check that the result is not an invalid wrapped stream state or else fail at finding a stream state for the stream S;
decide on the result.
To delete (S - a wrapped stream) from (A - a wrapping layer):
unless S is null:
let the stream state be the legal stream state for S in A;
remove the first occurrence of the key S from the stream hash table of A;
delete the stream state.
Section "Public Wrapping Layer Accessors and Mutators"
To decide what Glk layer is the Glk layer after (A - a wrapping layer): (- llo_getInt({A}) -).
To decide whether the multiple windows supported flag is set in (A - a wrapping layer): (- llo_getField({A},7) -).
To decide what wrapped window is the parent of (W - a wrapped window) according to (A - a wrapping layer):
let the window state be the window state for W in A;
if the window state is an invalid wrapped window state:
decide on a null wrapped window;
decide on the parent of the window state.
To decide what wrapped window is the first child of (W - a wrapped window) according to (A - a wrapping layer):
let the window state be the window state for W in A;
if the window state is an invalid wrapped window state:
decide on a null wrapped window;
decide on the first child of the window state.
To decide what wrapped window is the second child of (W - a wrapped window) according to (A - a wrapping layer):
let the window state be the window state for W in A;
if the window state is an invalid wrapped window state:
decide on a null wrapped window;
decide on the second child of the window state.
To decide what wrapped window is the frame window of (A - a wrapping layer): (- llo_getField({A},3) -).
To write the frame window (X - an wrapped window) to (A - a wrapping layer): (- llo_setField({A},3,{X}); -).
To delete (W - a wrapped window) from (A - a wrapping layer):
let the next layer be the Glk layer after A;
unless W is null:
let the window hash table be the window hash table of A;
let the window state be the legal window state for W in A;
remove the first occurrence of the key W from the window hash table;
delete the window state;
let the stream be the window stream of W according to the next layer;
delete the stream from A.
To enqueue (E - a wrapped event) as a deferred event for (A - a wrapping layer):
let the deferred event be a new wrapped event;
copy E to the deferred event;
enqueue the key the deferred event in the deferred event linked list of A through the deferred event linked list tail of A.
Chapter "Dispatch Utilities" - unindexed
To decide what number is the result of Glk function number (F - a number) according to (L - a Glk layer):
let the invocation copy be an invalid Glk invocation;
let the outcome copy be an invalid Glk outcome;
if the Glk layers are in the pre-call state:
now the invocation copy is a new copy of the current Glk invocation;
otherwise:
now the outcome copy is a new copy of the current Glk outcome;
prepare a spontaneous Glk invocation;
write the function selector F to the current Glk invocation;
write the argument count zero to the current Glk invocation;
delegate the current Glk invocation to L;
let the result be the result of the Glk invocation just delegated;
if the invocation copy is not an invalid Glk invocation:
prepare another Glk invocation from the invocation copy;
delete the invocation copy;
otherwise:
overwrite the current Glk outcome with the outcome copy;
delete the outcome copy;
decide on the result.
To decide what number is the result of Glk function number (F - a number) applied to (V - a value) according to (L - a Glk layer):
let the invocation copy be an invalid Glk invocation;
let the outcome copy be an invalid Glk outcome;
if the Glk layers are in the pre-call state:
now the invocation copy is a new copy of the current Glk invocation;
otherwise:
now the outcome copy is a new copy of the current Glk outcome;
prepare a spontaneous Glk invocation;
write the function selector F to the current Glk invocation;
write the argument count one to the current Glk invocation;
write V to argument number zero of the current Glk invocation;
delegate the current Glk invocation to L;
let the result be the result of the Glk invocation just delegated;
if the invocation copy is not an invalid Glk invocation:
prepare another Glk invocation from the invocation copy;
delete the invocation copy;
otherwise:
overwrite the current Glk outcome with the outcome copy;
delete the outcome copy;
decide on the result.
To decide what number is the result of Glk function number (F - a number) applied to (U - a value) and (V - a value) according to (L - a Glk layer):
let the invocation copy be an invalid Glk invocation;
let the outcome copy be an invalid Glk outcome;
if the Glk layers are in the pre-call state:
now the invocation copy is a new copy of the current Glk invocation;
otherwise:
now the outcome copy is a new copy of the current Glk outcome;
prepare a spontaneous Glk invocation;
write the function selector F to the current Glk invocation;
write the argument count two to the current Glk invocation;
write U to argument number zero of the current Glk invocation;
write V to argument number one of the current Glk invocation;
delegate the current Glk invocation to L;
let the result be the result of the Glk invocation just delegated;
if the invocation copy is not an invalid Glk invocation:
prepare another Glk invocation from the invocation copy;
delete the invocation copy;
otherwise:
overwrite the current Glk outcome with the outcome copy;
delete the outcome copy;
decide on the result.
Chapter "Window Management"
Section "Dispatch Utilities for Window Management" - unindexed
To decide what wrapped window is the root according to (L - a Glk layer):
let the result be the result of Glk function number 34 [glk_window_get_root] according to L;
decide on the result converted to a wrapped window.
To decide what wrapped window is the parent of (W - a wrapped window) according to (L - a Glk layer):
let the result be the result of Glk function number 41 [glk_window_get_parent] applied to W according to L;
decide on the result converted to a wrapped window.
To decide what wrapped stream is the window stream of (W - a wrapped window) according to (L - a Glk layer):
let the result be the result of Glk function number 44 [glk_window_get_stream] applied to W according to L;
decide on the result converted to a wrapped stream.
To decide what wrapped stream is the echo stream of the window (W - a wrapped window) according to (L - a Glk layer):
let the result be the result of Glk function number 46 [glk_window_get_echo_stream] applied to W according to L;
decide on the result converted to a wrapped stream.
To decide what number is the rock of the window (W - a wrapped window) according to (L - a Glk layer):
decide on the result of Glk function number 33 [glk_window_get_rock] applied to W according to L.
To close the window (W - a wrapped window) via (L - a Glk layer):
let the discarded value be the result of Glk function number 36 [glk_window_close] applied to W and zero according to L.
Section "Simulated Window Functions" - unindexed
To simulate glk_window_iterate to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least two arguments;
let the invocation copy be a new copy of the current Glk invocation;
delegate the current Glk invocation to the next layer;
repeat until a break:
let the result be the result of the Glk invocation just delegated;
if the result is zero or the window hash table contains the key the result:
break;
prepare another Glk invocation from the invocation copy;
write the result to argument number zero of the current Glk invocation;
delegate the current Glk invocation to the next layer;
delete the invocation copy.
To simulate glk_window_get_root to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
if the multiple windows supported flag is set in A:
let the frame window be the frame window of A;
if the frame window is null:
delegate the current Glk invocation to a do-nothing layer returning zero stack results;
otherwise:
write the function selector 48 [glk_window_get_sibling] to the current Glk invocation;
write the argument count one to the current Glk invocation;
write the frame window to argument number zero of the current Glk invocation;
delegate the current Glk invocation to the next layer;
otherwise:
delegate the current Glk invocation to the next layer;
let the result be the result of the Glk invocation just delegated;
unless the window hash table of A contains the key the result:
write the result zero to the Glk invocation just delegated.
To decide what number is the window-opening method for a window in a frame window: (- (winmethod_Above+winmethod_Proportional) -).
To decide what number is the window-opening size for a window in a frame window: (- 100 -).
To simulate glk_window_open to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
let the stream hash table be the stream hash table of A;
ensure that the current Glk invocation has at least five arguments;
let the sibling be argument number zero of the current Glk invocation converted to a wrapped window;
if the sibling is null:
if the multiple windows supported flag is set in A:
write the frame window of A to argument number zero of the current Glk invocation;
write the window-opening method for a window in a frame window to argument number one of the current Glk invocation;
write the window-opening size for a window in a frame window to argument number two of the current Glk invocation;
otherwise:
let the root be the root according to the next layer;
let the rock be the rock of the window the root according to the next layer;
always check that the rock is the rock for a window filling in for the frame window or else fail at opening a root window twice in a single-window environment;
close the window the root via the next layer;
delegate the current Glk invocation to the next layer;
let the window be the result of the Glk invocation just delegated converted to a wrapped window;
unless the window is null:
let the state be a new wrapped window state for the window;
insert the key the window and the value the state into the window hash table;
let the stream be the window stream of the window according to the next layer;
unless the stream is null:
let the stream state be a new wrapped stream state for the stream;
insert the key the stream and the value the stream state into the stream hash table;
let the sibling state be the window state for the sibling in A;
unless the sibling state is an invalid wrapped window state:
let the parent be the parent of the window according to the next layer;
let the parent state be a new wrapped window state for the parent;
insert the key the parent and the value the parent state into the window hash table;
let the grandparent be the parent of the sibling state;
let the grandparent state be the window state for the grandparent in A;
write the parent the parent to the state;
write the parent the parent to the sibling state;
write the parent the grandparent to the parent state;
write the first child the sibling to the parent state;
write the second child the window to the parent state;
unless the grandparent state is an invalid wrapped window state:
if the first child of the grandparent state is the sibling:
write the first child the parent to the grandparent state;
otherwise:
always check that the second child of the grandparent state is the sibling or else fail at preserving the relationship invariants on window states;
write the second child the parent to the grandparent state;
write the result the window to the Glk invocation just delegated.
To decide what number is the text buffer window type: (- wintype_TextBuffer -).
To simulate glk_window_close to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
let the stream hash table be the stream hash table of A;
ensure that the current Glk invocation has at least one argument;
let the moribund window be argument number zero of the current Glk invocation converted to a wrapped window;
let the parent be the parent of the moribund window according to A;
unless the parent is null:
let the sibling be the first child of the parent according to A;
if the sibling is the moribund window:
now the sibling is the second child of the parent according to A;
let the sibling state be the window state for the sibling in A;
let the grandparent be the parent of the parent according to A;
let the grandparent state be the window state for the grandparent in A;
unless the grandparent state is an invalid wrapped window state:
if the first child of the grandparent state is the parent:
write the first child the sibling to the grandparent state;
otherwise:
always check that the second child of the grandparent state is the parent or else fail at preserving the relationship invariants on window states;
write the second child the sibling to the grandparent state;
write the parent the grandparent to the sibling state;
delete the parent from A;
let the worklist be an empty linked list;
let the worklist tail be an empty linked list's tail;
let the detached stream list be an empty linked list;
enqueue the key the moribund window in the worklist through the worklist tail;
while the worklist is not empty:
let the current window be a wrapped window key dequeued from the worklist through the worklist tail;
let the child be the first child of the current window according to A;
unless the child is null:
enqueue the key the child in the worklist through the worklist tail;
now the child is the second child of the current window according to A;
unless the child is null:
enqueue the key the child in the worklist through the worklist tail;
let the stream be the window stream of the current window according to the next layer;
unless the stream is null:
push the key the stream onto the detached stream list;
delete the current window from A; [deletes the stream automatically]
repeat with the stream state running through the wrapped stream state values of the stream hash table:
let the echo stream be the echo stream of the stream state;
if the detached stream list contains the key the echo stream:
write the echo stream a null wrapped stream to the stream state;
delegate the current Glk invocation to the next layer;
unless the multiple windows supported flag is set in A:
always check that parent is null or else fail at discovering multiple windows in a single-window environment;
let the outcome copy be a new copy of the current Glk outcome;
prepare a spontaneous Glk invocation;
write the function selector 35 [glk_window_open] to the current Glk invocation;
write the argument count five to the current Glk invocation;
write zero to argument number zero of the current Glk invocation;
write zero to argument number one of the current Glk invocation;
write zero to argument number two of the current Glk invocation;
write the text buffer window type to argument number three of the current Glk invocation;
write the rock for a window filling in for the frame window to argument number four of the current Glk invocation;
delegate the current Glk invocation to the next layer;
overwrite the current Glk outcome with the outcome copy;
delete the outcome copy.
To simulate glk_window_get_relation to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
delegate the current Glk invocation to the next layer;
unless the window hash table contains the key the result of the Glk invocation just delegated:
write the result zero to the Glk invocation just delegated.
Chapter "Stream Management"
Section "Simulated Stream Functions" - unindexed
To simulate glk_stream_iterate to hide stream wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the stream hash table be the stream hash table of A;
ensure that the current Glk invocation has at least two arguments;
let the invocation copy be a new copy of the current Glk invocation;
delegate the current Glk invocation to the next layer;
repeat until a break:
let the result be the result of the Glk invocation just delegated;
if the result is zero or the stream hash table contains the key the result:
break;
prepare another Glk invocation from the invocation copy;
write the result to argument number zero of the current Glk invocation;
delegate the current Glk invocation to the next layer;
delete the invocation copy.
To simulate glk_stream_open to hide stream wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the stream hash table be the stream hash table of A;
delegate the current Glk invocation to the next layer;
let the result be the result of the Glk invocation just delegated converted to a wrapped stream;
unless the result is null:
let the stream state be a new wrapped stream state for the result;
insert the key the result and the value the stream state into the stream hash table.
To simulate glk_stream_close to hide stream wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
ensure that the current Glk invocation has at least one argument;
let the moribund stream be argument number zero of the current Glk invocation converted to a wrapped stream;
delete the moribund stream from A;
delegate the current Glk invocation to the next layer.
To simulate glk_window_set_echo_stream to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
let the stream hash table be the stream hash table of A;
ensure that the current Glk invocation has at least two arguments;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
let the window state be the legal window state for the window in A;
let the stream be the window stream of the window according to the next layer;
unless the stream is null:
let the stream state be the legal stream state for the stream in A;
let the echo stream be argument number one of the current Glk invocation converted to a wrapped stream;
write the echo stream the echo stream to the stream state;
delegate the current Glk invocation to the next layer.
To simulate glk_set_style to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
ensure that the current Glk invocation has at least one argument;
let the style be argument number zero of the current Glk invocation;
let the invocation copy be a new copy of the current Glk invocation;
write the function selector 72 [glk_stream_get_current] to the current Glk invocation;
write the argument count zero to the current Glk invocation;
delegate the current Glk invocation to the next layer;
let the stream be the result of the Glk invocation just delegated converted to a wrapped stream;
unless the stream is null:
let the stream state be the legal stream state for the stream in A;
write the last-seen style the style to the stream state;
prepare another Glk invocation from the invocation copy;
delegate the current Glk invocation to the next layer;
delete the invocation copy.
To simulate glk_set_style_stream to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the stream hash table be the stream hash table of A;
ensure that the current Glk invocation has at least two arguments;
let the stream be argument number zero of the current Glk invocation converted to a wrapped stream;
let the style be argument number one of the current Glk invocation;
unless the stream is null:
let the stream state be the legal stream state for the stream in A;
write the last-seen style the style to the stream state;
delegate the current Glk invocation to the next layer.
Chapter "Event Management"
Section "Simulated Event Functions" - unindexed
To simulate glk_select to hide window wrapping with (A - a wrapping layer), polling only:
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the target event be argument number zero of the current Glk invocation converted to a wrapped event;
if the deferred event linked list of A is empty:
let the invocation copy be a new copy of the current Glk invocation;
let responding on the stack be whether or not the target event is on the stack;
if responding on the stack is true:
now the target event is a new wrapped event;
repeat until a break:
delegate the current Glk invocation to the next layer;
if responding on the stack is true:
copy the four stack results beginning with stack result number zero of the Glk invocation just delegated to the target event;
let the source window be the source window of the target event;
let the source window state be the window state for the source window in A;
let the break flag be true;
let the applied flag be false;
if the event type of the target event is:
-- 1: [timer event]
if (the foreign event handler of A applied to the target event) is routing the event no further:
now the break flag is false;
now the applied flag is true;
-- 2: [character input]
if the source window state is an invalid wrapped window state:
now the break flag is false;
otherwise:
write the last-seen character input request zero to the source window state;
-- 3: [line input]
if the source window state is an invalid wrapped window state:
now the break flag is false;
otherwise:
let the initial line buffer content address be the last-seen initial line buffer content address of the source window state;
if the initial line buffer content address is not zero:
free the possibly zero-length memory allocation at address initial line buffer content address;
write the last-seen line input request zero to the source window state;
write the last-seen line buffer address zero to the source window state;
write the last-seen line buffer length zero to the source window state;
write the last-seen initial line buffer content address zero to the source window state;
write the last-seen initial line buffer content length zero to the source window state;
-- 4: [mouse input]
if the source window state is an invalid wrapped window state:
now the break flag is false;
otherwise:
write the last-seen mouse input request zero to the source window state;
-- 5: [window arrangement event]
write the source window a null wrapped window to the target event;
let the discarded value be the foreign event handler of A applied to the target event;
now the applied flag is true;
-- 6: [redraw event]
write the source window a null wrapped window to the target event;
let the discarded value be the foreign event handler of A applied to the target event;
now the applied flag is true;
-- 7: [sound notify event]
if (the foreign event handler of A applied to the target event) is routing the event no further:
now the break flag is false;
now the applied flag is true;
-- 8: [hyperlink input]
if the source window state is an invalid wrapped window state:
now the break flag is false;
otherwise:
write the last-seen hyperlink input request zero to the source window state;
if the break flag is true:
break;
if the applied flag is false:
let the discarded value be the foreign event handler of A applied to the target event;
prepare another Glk invocation from the invocation copy;
if responding on the stack is true:
delete the target event;
delete the invocation copy;
otherwise:
let the deferred event be an invalid wrapped event;
if polling only:
let the moribund linked list vertex be an invalid linked list vertex;
repeat with the linked list vertex running through the deferred event linked list of A:
if the wrapped event key of the linked list vertex is internally-spawned:
now the moribund linked list vertex is the linked list vertex;
if the moribund linked list vertex is an invalid linked list vertex:
now the deferred event is a new wrapped event;
write the event type the null event type to the deferred event;
otherwise:
now the deferred event is the wrapped event key of the moribund linked list vertex;
write the deferred event linked list the deferred event linked list of A after removing the moribund linked list vertex to A;
if the moribund linked list vertex is the deferred event linked list tail of A converted to a linked list vertex:
write the deferred event linked list tail the tail of the deferred event linked list of A to A;
otherwise:
now the deferred event is a wrapped event key dequeued from the deferred event linked list of A through the deferred event linked list tail of A;
if the target event is on the stack:
delegate the current Glk invocation to a do-nothing layer returning four stack results;
copy the deferred event to the four stack results beginning with stack result number zero of the Glk invocation just delegated;
otherwise:
delegate the current Glk invocation to a do-nothing layer returning zero stack results;
copy the deferred event to the target event;
delete the deferred event.
To simulate glk_request_char_event_any to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
write the last-seen character input request the function selector of the current Glk invocation to the window state;
delegate the current Glk invocation to the next layer.
To simulate glk_cancel_char_event to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
write the last-seen character input request zero to the window state;
delegate the current Glk invocation to the next layer.
To simulate glk_request_line_event_any to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least four arguments;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
let the initial line buffer content address be the last-seen initial line buffer content address of the window state;
if the initial line buffer content address is not zero:
free the possibly zero-length memory allocation at address initial line buffer content address;
let the buffer address be argument number one of the current Glk invocation;
let the length be argument number two of the current Glk invocation;
let the initial line buffer content length be argument number three of the current Glk invocation;
now the initial line buffer content address is a possibly zero-length memory allocation of the initial line buffer content length bytes;
copy the initial line buffer content length bytes from address the buffer address to address the initial line buffer content address;
write the last-seen line input request the function selector of the current Glk invocation to the window state;
write the last-seen line buffer address the buffer address to the window state;
write the last-seen line buffer length the length to the window state;
write the last-seen initial line buffer content address the initial line buffer content address to the window state;
write the last-seen initial line buffer content length the initial line buffer content length to the window state;
delegate the current Glk invocation to the next layer.
To simulate glk_cancel_line_event to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
let the initial line buffer content address be the last-seen initial line buffer content address of the window state;
if the initial line buffer content address is not zero:
free the possibly zero-length memory allocation at address initial line buffer content address;
write the last-seen line input request zero to the window state;
write the last-seen line buffer address zero to the window state;
write the last-seen line buffer length zero to the window state;
write the last-seen initial line buffer content address zero to the window state;
write the last-seen initial line buffer content length zero to the window state;
delegate the current Glk invocation to the next layer.
To simulate glk_request_mouse_event to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
write the last-seen mouse input request the function selector of the current Glk invocation to the window state;
delegate the current Glk invocation to the next layer.
To simulate glk_cancel_mouse_event to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
write the last-seen mouse input request zero to the window state;
delegate the current Glk invocation to the next layer.
To simulate glk_request_hyperlink_event to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
write the last-seen hyperlink input request the function selector of the current Glk invocation to the window state;
delegate the current Glk invocation to the next layer.
To simulate glk_cancel_hyperlink_event to hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
let the window hash table be the window hash table of A;
ensure that the current Glk invocation has at least one argument;
let the window be argument number zero of the current Glk invocation converted to a wrapped window;
unless the window is null:
let the window state be the legal window state for the window in A;
write the last-seen hyperlink input request zero to the window state;
delegate the current Glk invocation to the next layer.
Chapter "The Glk Layer"
To hide window wrapping with (A - a wrapping layer):
let the next layer be the Glk layer after A;
if the function selector of the current Glk invocation is:
-- 32: [glk_window_iterate]
simulate glk_window_iterate to hide window wrapping with A;
-- 34: [glk_window_get_root]
simulate glk_window_get_root to hide window wrapping with A;
-- 35: [glk_window_open]
simulate glk_window_open to hide window wrapping with A;
-- 36: [glk_window_close]
simulate glk_window_close to hide window wrapping with A;
-- 41: [glk_window_get_parent]
simulate glk_window_get_relation to hide window wrapping with A;
-- 45: [glk_window_set_echo_stream]
simulate glk_window_set_echo_stream to hide window wrapping with A;
-- 48: [glk_window_get_sibling]
simulate glk_window_get_relation to hide window wrapping with A;
-- 64: [glk_stream_iterate]
simulate glk_stream_iterate to hide stream wrapping with A;
-- 66: [glk_stream_open_file]
simulate glk_stream_open to hide stream wrapping with A;
-- 67: [glk_stream_open_memory]
simulate glk_stream_open to hide stream wrapping with A;
-- 68: [glk_stream_close]
simulate glk_stream_close to hide stream wrapping with A;
-- 134: [glk_set_style]
simulate glk_set_style to hide window wrapping with A;
-- 135: [glk_set_style_stream]
simulate glk_set_style_stream to hide window wrapping with A;
-- 192: [glk_select]
simulate glk_select to hide window wrapping with A;
-- 193: [glk_select_poll]
simulate glk_select to hide window wrapping with A, polling only;
-- 208: [glk_request_line_event]
simulate glk_request_line_event_any to hide window wrapping with A;
-- 209: [glk_cancel_line_event]
simulate glk_cancel_line_event to hide window wrapping with A;
-- 210: [glk_request_char_event]