4b3b19c0a3e5af913fdd06b75dea46c78062c0d9
[rodin/chimara.git] / src / gestalt.c
1 #include "glk.h"
2
3 /* Version of the Glk specification implemented by this library */
4 #define MAJOR_VERSION 0
5 #define MINOR_VERSION 7
6 #define SUB_VERSION   0
7
8 /**
9  * glk_gestalt:
10  * @sel: A selector, representing which capability to request information 
11  * about.
12  * @val: Extra information, depending on the value of @sel.
13  *
14  * Calls the gestalt system to request information about selector @sel, without
15  * passing an array to store extra information in (see glk_gestalt_ext()).
16  *
17  * Returns: an integer, depending on what selector was called.
18  */
19 glui32
20 glk_gestalt(glui32 sel, glui32 val)
21 {
22         return glk_gestalt_ext(sel, val, NULL, 0);
23 }
24
25 /**
26  * glk_gestalt_ext:
27  * @sel: A selector, representing which capability to request information
28  * about.
29  * @val: Extra information, depending on the value of @sel.
30  * @arr: Location of an array to store extra information in, or %NULL.
31  * @arrlen: Length of @arr, or 0 if @arr is %NULL.
32  *
33  * Calls the gestalt system to request information about the capabilities of the
34  * API. The selector @sel tells which capability you are requesting information
35  * about; the other three arguments are additional information, which may or may
36  * not be meaningful. The @arr and @arrlen arguments of glk_gestalt_ext() are
37  * always optional; you may always pass %NULL and 0, if you do not want whatever
38  * information they represent. glk_gestalt() is simply a shortcut for this;
39  * <code>#glk_gestalt(x, y)</code> is exactly the same as 
40  * <code>#glk_gestalt_ext(x, y, %NULL, 0)</code>.
41  *
42  * The critical point is that if the Glk library has never heard of the selector
43  * @sel, it will return 0. It is <emphasis>always</emphasis> safe to call 
44  * <code>#glk_gestalt(x, y)</code> (or <code>#glk_gestalt_ext(x, y, %NULL, 
45  * 0)</code>). Even if you are using an old library, which was compiled before
46  * the given capability was imagined, you can test for the capability by calling
47  * glk_gestalt(); the library will correctly indicate that it does not support
48  * it, by returning 0.
49  *
50  * (It is also safe to call <code>#glk_gestalt_ext(x, y, z, zlen)</code> for an
51  * unknown selector <code>x</code>, where <code>z</code> is not %NULL, as long
52  * as <code>z</code> points at an array of at least <code>zlen</code> elements.
53  * The selector will be careful not to write beyond that point in the array, if
54  * it writes to the array at all.)
55  *
56  * (If a selector does not use the second argument, you should always pass 0; do
57  * not assume that the second argument is simply ignored. This is because the
58  * selector may be extended in the future. You will continue to get the current
59  * behavior if you pass 0 as the second argument, but other values may produce
60  * other behavior.)
61  *
62  * Returns: an integer, depending on what selector was called.
63  */
64 glui32
65 glk_gestalt_ext(glui32 sel, glui32 val, glui32 *arr, glui32 arrlen)
66 {
67         switch(sel)
68         {
69                 /* Version number */
70                 case gestalt_Version:
71                         return (MAJOR_VERSION << 16) + (MINOR_VERSION << 8) + SUB_VERSION;
72                 
73                 /* Which characters can the player type in line input? */
74                 case gestalt_LineInput:
75                         /* Does not accept control chars */
76                         if( val < 32 || (val >= 127 && val <= 159) )
77                                 return 0;
78                         return 1;
79                         
80                 /* Which characters can the player type in char input? */
81                 case gestalt_CharInput:
82                         /* Does not accept control chars or unknown */
83                         if( val < 32 || (val >= 127 && val <= 159) || val == keycode_Unknown )
84                                 return 0;
85                         return 1;
86                 
87                 /* Which characters can we print? */    
88                 case gestalt_CharOutput:
89                         /* All characters are printed as one character, in any case */
90                         if(arr && arrlen > 0)
91                                 *arr = 1;
92                         /* Cannot print control chars except \n, or chars > 255 */
93                         if( (val < 32 && val != 10) || (val >= 127 && val <= 159) || (val > 255) )
94                                 return gestalt_CharOutput_CannotPrint;
95                         /* Can print all other Latin-1 characters */
96                         return gestalt_CharOutput_ExactPrint;
97                 
98                 /* Unicode capabilities present */
99                 case gestalt_Unicode:
100                         return 1;
101                         
102                 /* Unsupported capabilities */
103                 case gestalt_MouseInput:
104                 case gestalt_Timer:
105                 case gestalt_Graphics:
106                 case gestalt_DrawImage:
107                 case gestalt_Sound:
108                 case gestalt_SoundVolume:
109                 case gestalt_SoundNotify:
110                 case gestalt_Hyperlinks:
111                 case gestalt_HyperlinkInput:
112                 case gestalt_SoundMusic:
113                 case gestalt_GraphicsTransparency:
114                 /* Selector not supported */    
115                 default:
116                         return 0;
117         }
118 }
119