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