Update to Blorb protocol 1.5
[projects/chimara/chimara.git] / libchimara / doc.c
index cb20d6e8f15ca3f83e8a479b8324c5d0e4ad49cc..c45859f7b5cb7e8535ed8aa3807158cc0d7bdad1 100644 (file)
@@ -7,7 +7,6 @@
 /**
  * SECTION:glk-exiting
  * @short_description: How to terminate a Glk program cleanly
- * @include: libchimara/glk.h
  *
  * A Glk program usually ends when the end of the glk_main() function is 
  * reached. You can also terminate it earlier.
@@ -17,7 +16,6 @@
  * SECTION:glk-interrupt
  * @short_description: Specifying an interrupt handler for cleaning up critical
  * resources
- * @include: libchimara/glk.h
  *
  * Most platforms have some provision for interrupting a program —
  * <keycombo action="simul"><keycap function="command">command</keycap>
@@ -34,7 +32,6 @@
 /**
  * SECTION:glk-tick
  * @short_description: Yielding time to the operating system
- * @include: libchimara/glk.h
  *
  * Many platforms have some annoying thing that has to be done every so often,
  * or the gnurrs come from the voodvork out and eat your computer.
@@ -48,7 +45,6 @@
 /**
  * SECTION:glk-types
  * @short_description: Basic types used in Glk
- * @include: libchimara/glk.h
  *
  * For simplicity, all the arguments used in Glk calls are of a very few types.
  * <variablelist>
@@ -96,7 +92,6 @@
 /**
  * SECTION:glk-opaque-objects
  * @short_description: Complex objects in Glk
- * @include: libchimara/glk.h
  *
  * Glk keeps track of a few classes of special objects. These are opaque to your
  * program; you always refer to them using pointers to opaque C structures.
  * 
  * When you create one of these objects, it is always possible that the creation
  * will fail (due to lack of memory, or some other OS error.) When this happens,
- * the allocation function will return %NULL (0) instead of a valid pointer. You
+ * the allocation function will return %NULL instead of a valid pointer. You
  * should always test for this possibility.
  * 
  * %NULL is never the identifier of any object (window, stream, file reference,
  * This is how you deal with opaque objects from a C program. If you are using
  * Glk through a virtual machine, matters will probably be different. Opaque
  * objects may be represented as integers, or as VM objects of some sort.
- * </para></note>
+ * </para></note></para>
+ * <para>
  * <refsect2 id="chimara-Rocks"><!-- Indeed it does. -->
  * <title>Rocks</title>
  * <para>
  * For each class of opaque objects, there is an iterate function, which you can
  * use to obtain a list of all existing objects of that class. It takes the form
  * |[
- * <replaceable>CLASS</replaceable>id_t glk_<replaceable>CLASS</replaceable>_iterate(<replaceable>CLASS</replaceable>id_t <parameter>obj</parameter>, #glui32 *<parameter>rockptr</parameter>);
+ * CLASSid_t glk_CLASS_iterate(CLASSid_t obj, glui32 *rockptr);
  * ]|
  * ...where <code><replaceable>CLASS</replaceable></code> represents one of the
  * opaque object classes. 
  * <para>
  * You usually use this as follows:
  * |[
- * obj = glk_<replaceable>CLASS</replaceable>_iterate(NULL, NULL);
+ * obj = glk_CLASS_iterate(NULL, NULL);
  * while (obj) {
  *    /* ...do something with obj... *<!-- -->/
- *    obj = glk_<replaceable>CLASS</replaceable>_iterate(obj, NULL);
+ *    obj = glk_CLASS_iterate(obj, NULL);
  * }
  * ]|
  * </para>
 /**
  * SECTION:glk-gestalt
  * @short_description: Testing Glk's capabilities
- * @include: libchimara/glk.h
  *
  * The <quote>gestalt</quote> mechanism (cheerfully stolen from the Mac OS) is a
  * system by which the Glk API can be upgraded without making your life
 /**
  * SECTION:glk-character-input
  * @short_description: Waiting for a single keystroke
- * @include: libchimara/glk.h
  *
  * You can request that the player hit a single key. See <link 
  * linkend="chimara-Character-Input-Events">Character Input Events</link>.
 /**
  * SECTION:glk-case
  * @short_description: Changing the case of strings
- * @include: libchimara/glk.h
  *
  * Glk has functions to manipulate the case of both Latin-1 and Unicode strings.
  * One Latin-1 lowercase character corresponds to one uppercase character, and
  * functions act on whole strings, since the length of the string may change.
  */
 
+/**
+ * SECTION:glk-normalize
+ * @short_description: Combining characters
+ *
+ * Comparing Unicode strings is difficult, because there can be several ways to
+ * represent a piece of text as a Unicode string. For example, the one-character
+ * string <quote>&egrave;</quote> (an accented <quote>e</quote>) will be
+ * displayed the same as the two-character string containing <quote>e</quote>
+ * followed by Unicode character 0x0300 (COMBINING GRAVE ACCENT). These strings
+ * should be considered equal.
+ *
+ * Therefore, a Glk program that accepts line input should convert its text to a
+ * normalized form before parsing it. These functions offer those conversions.
+ * The algorithms are defined by the Unicode spec (chapter 3.7) and <ulink
+ * url="http://www.unicode.org/reports/tr15/">Unicode Standard Annex
+ * &num;15</ulink>.
+ */
+
 /**
  * SECTION:glk-window-opening
  * @short_description: Creating new windows and closing them
- * @include: libchimara/glk.h
  *
  * You can open a new window using glk_window_open() and close it again using
  * glk_window_close().
 /**
  * SECTION:glk-window-constraints
  * @short_description: Manipulating the size of a window
- * @include: libchimara/glk.h
  *
  * There are library functions to change and to measure the size of a window.
  */
 /**
  * SECTION:glk-window-types
  * @short_description: Blank, pair, text grid, text buffer, and graphics windows
- * @include: libchimara/glk.h
  * 
  * A technical description of all the window types, and exactly how they behave.
  */
 /**
  * SECTION:glk-echo-streams
  * @short_description: Creating a copy of a window's output
- * @include: libchimara/glk.h
  *
  * Every window has an associated window stream; you print to the window by
  * printing to this stream. However, it is possible to attach a second stream to
 /**
  * SECTION:glk-window-other
  * @short_description: Miscellaneous functions for windows
- * @include: libchimara/glk.h
  *
  * This section contains functions for windows that don't fit anywhere else.
  */
 /**
  * SECTION:glk-events
  * @short_description: Waiting for events
- * @include: libchimara/glk.h
  *
  * As described in <link linkend="chimara-Your-Programs-Main-Function">Your
  * Program's Main Function</link>, all player input is handed to your program by
 /**
  * SECTION:glk-character-input-events
  * @short_description: Events representing a single keystroke
- * @include: libchimara/glk.h
  *
  * You can request character input from text buffer and text grid windows. See 
  * %evtype_CharInput. There are separate functions for requesting Latin-1 input
 /**
  * SECTION:glk-line-input-events
  * @short_description: Events representing a line of user input
- * @include: libchimara/glk.h
  *
  * You can request line input from text buffer and text grid windows. See
  * %evtype_LineInput. There are separate functions for requesting Latin-1 input
 /**
  * SECTION:glk-mouse-events
  * @short_description: Events representing a mouse click
- * @include: libchimara/glk.h
  *
  * On some platforms, Glk can recognize when the mouse (or other pointer) is 
  * used to select a spot in a window. You can request mouse input only in text 
 /**
  * SECTION:glk-timer-events
  * @short_description: Events sent at fixed intervals
- * @include: libchimara/glk.h
  *
  * You can request that an event be sent at fixed intervals, regardless of what
  * the player does. Unlike input events, timer events can be tested for with
 /**
  * SECTION:glk-streams
  * @short_description: Input and output abstractions
- * @include: libchimara/glk.h
  *
  * All character output in Glk is done through streams. Every window has an
  * output stream associated with it. You can also write to files on disk; every
  * A stream is opened with a particular file mode, see the 
  * <code>filemode_</code> constants below.
  *
+ * <note><para>
+ *   In the stdio library, using fopen(), %filemode_Write would be mode
+ *   <code>"w"</code>; %filemode_Read would be mode <code>"r"</code>;
+ *   %filemode_ReadWrite would be mode <code>"r+"</code>. Confusingly,
+ *   %filemode_WriteAppend cannot be mode <code>"a"</code>, because the stdio
+ *   spec says that when you open a file with mode <code>"a"</code>, then
+ *   fseek() doesn't work. So we have to use mode <code>"r+"</code> for
+ *   appending. Then we run into the <emphasis>other</emphasis> stdio problem,
+ *   which is that <code>"r+"</code> never creates a new file. So
+ *   %filemode_WriteAppend has to <emphasis>first</emphasis> open the file with
+ *   <code>"a"</code>, close it, reopen with <code>"r+"</code>, and then
+ *   fseek() to the end of the file. For %filemode_ReadWrite, the process is
+ *   the same, except without the fseek() &mdash; we begin at the beginning of
+ *   the file.
+ * </para></note>
+ * <note><para>
+ *   We must also obey an obscure geas of ANSI C <code>"r+"</code> files: you
+ *   can't switch from reading to writing without doing an fseek() in between.
+ *   Switching from writing to reading has the same restriction, except that an
+ *   fflush() also works.
+ * </para></note>
+ *
  * For information on opening streams, see the discussion of each specific type
  * of stream in <link linkend="chimara-The-Types-of-Streams">The Types of
  * Streams</link>. Remember that it is always possible that opening a stream
 /**
  * SECTION:glk-print
  * @short_description: Printing to streams
- * @include: libchimara/glk.h
  *
  * You can print Latin-1 and Unicode characters, null-terminated strings, or
  * buffers to any stream. The characters will be converted into the appropriate
 /**
  * SECTION:glk-read
  * @short_description: Reading from streams
- * @include: libchimara/glk.h
  *
  * You can read Latin-1 or Unicode characters, buffers, or whole lines from any
  * stream. The characters will be converted into the form in which you request
 /**
  * SECTION:glk-closing-streams
  * @short_description: Closing streams and retrieving their character counts
- * @include: libchimara/glk.h
  *
  * When you close a Glk stream, you have the opportunity to examine the
  * character counts &mdash; the number of characters written to or read from the
 /**
  * SECTION:glk-stream-positions
  * @short_description: Moving the read/write mark
- * @include: libchimara/glk.h
  *
  * You can set the position of the read/write mark in a stream.
  *
 /**
  * SECTION:glk-styles
  * @short_description: Changing the appearance of printed text
- * @include: libchimara/glk.h
  *
  * You can send style-changing commands to an output stream. After a style
  * change, new text which is printed to that stream will be given the new style,
 /**
  * SECTION:glk-stylehints
  * @short_description: Setting style hints
- * @include: libchimara/glk.h
  *
  * There are no guarantees of how styles will look, but you can make 
  * suggestions.
 /**
  * SECTION:glk-style-measure
  * @short_description: Finding out how the library displays your style hints
- * @include: libchimara/glk.h
  *
  * You can suggest the appearance of a window's style before the window is
  * created; after the window is created, you can test the style's actual
 
 /**
  * SECTION:glk-stream-types
- * @short_description: Window, memory, and file streams
- * @include: libchimara/glk.h
+ * @short_description: Window, memory, file, and resource streams
  *
  * <refsect2 id="chimara-Window-Streams"><title>Window Streams</title>
  * <para>
  * Every window has an output stream associated with it. This is created
  * automatically, with %filemode_Write, when you open the window. You get it
- * with glk_window_get_stream().
+ * with glk_window_get_stream(). Window streams always have rock value 0.
  * 
  * A window stream cannot be closed with glk_stream_close(). It is closed
  * automatically when you close its window with glk_window_close().
  * linkend="chimara-File-References">File References</link>.
  * </para>
  * </refsect2>
+ * <refsect2 id="chimara-Resource-Streams"><title>Resource Streams</title>
+ * <para>
+ * You can open a stream which reads from (but not writes to) a resource file.
+ *
+ * <note><para>
+ *   Typically this is embedded in a Blorb file, as Blorb is the official
+ *   resource-storage format of Glk. A Blorb file can contain images and sounds,
+ *   but it can also contain raw data files, which are accessed by
+ *   glk_stream_open_resource() and glk_stream_open_resource_uni(). A data file
+ *   is identified by number, not by a filename. The Blorb usage field will be
+ *   <code>'Data'</code>. The chunk type will be %giblorb_ID_TEXT for text
+ *   resources, %giblorb_ID_BINA for binary resources.
+ * </para></note>
+ *
+ * <note><para>
+ *   If the running program is not associated with a Blorb file, the library may
+ *   look for data files as actual files instead. These would be named
+ *   <filename>DATA1</filename>, <filename>DATA2</filename>, etc, with a suffix
+ *   distinguishing text and binary files. See <quote>Other Resource
+ *   Arrangements</quote> in the Blorb spec: <ulink
+ *   url="http://eblong.com/zarf/blorb/"></ulink>
+ * </para></note>
+ * </para>
+ * </refsect2>
  */
  
 /**
  * SECTION:glk-stream-other
  * @short_description: Miscellaneous functions for streams
- * @include: libchimara/glk.h
  *
  * This section includes functions for streams that don't fit anywhere else.
  */
 /**
  * SECTION:glk-fileref
  * @short_description: A platform-independent way to refer to disk files
- * @include: libchimara/glk.h
  *
  * You deal with disk files using file references. Each fileref is an opaque C
  * structure pointer; see <link linkend="chimara-Opaque-Objects">Opaque 
  * create a fileref for a nonexistent file, and then open it in write mode to
  * create a new file.
  * 
- * You always provide a usage argument when you create a fileref. The usage is a
- * mask of constants (see below) to indicate the file type and the mode (text or
- * binary.) These values are used when you create a new file, and also to filter
- * file lists when the player is selecting a file to load. 
+ * You always provide a usage argument when you create a fileref. The usage
+ * indicates the file type and the mode (text or binary.) It must be the
+ * logical-or of a file-type constant and a mode constant. These values are used
+ * when you create a new file, and also to filter file lists when the player is
+ * selecting a file to load.
  * 
  * In general, you should use text mode if the player expects to read the file
  * with a platform-native text editor; you should use binary mode if the file is
 /**
  * SECTION:glk-fileref-types
  * @short_description: Four different ways to create a file reference
- * @include: libchimara/glk.h
  *
  * There are four different functions for creating a fileref, depending on how
  * you wish to specify it. Remember that it is always possible that a fileref
 /**
  * SECTION:glk-fileref-other
  * @short_description: Miscellaneous functions for file references
- * @include: libchimara/glk.h
  *
  * This section includes functions for file references that don't fit anywhere
  * else.
 /**
  * SECTION:glk-image-resources
  * @short_description: Graphics in Glk
- * @include: libchimara/glk.h
  *
  * In accordance with this modern age, Glk provides for a modicum of graphical
  * flair. It does not attempt to be a complete graphical toolkit. Those already
 /**
  * SECTION:glk-graphics-windows
  * @short_description: Drawing graphics in graphics windows
- * @include: libchimara/glk.h
  *
  * A graphics window is a rectangular canvas of pixels, upon which you can draw
  * images. The contents are entirely under your control. You can draw as many
 /**
  * SECTION:glk-graphics-text
  * @short_description: Drawing graphics inside or beside text
- * @include: libchimara/glk.h
  *
  * A text buffer is a linear text stream. You can draw images in-line with this
  * text. If you are familiar with HTML, you already understand this model. You
  * If you call glk_image_draw() or glk_image_draw_scaled() in a text buffer
  * window, @val1 gives the image alignment. The @val2 argument is currently
  * unused, and should always be zero.
+ *
+ * The two <quote>margin</quote> alignments require some care. To allow proper 
+ * positioning, images using %imagealign_MarginLeft and %imagealign_MarginRight 
+ * must be placed at the beginning of a line. That is, you may only call 
+ * glk_image_draw() (with these two alignments) in a window, if you have just 
+ * printed a newline to the window's stream, or if the window is entirely empty.
+ * If you margin-align an image in a line where text has already appeared, no 
+ * image will appear at all.
+ * 
+ * Inline-aligned images count as <quote>text</quote> for the purpose of this 
+ * rule.
+ * 
+ * You may have images in both margins at the same time.
+ * 
+ * It is also legal to have more than one image in the same margin (left or 
+ * right.) However, this is not recommended. It is difficult to predict how text
+ * will wrap in that situation, and libraries may err on the side of 
+ * conservatism. 
  */
 
 /**
  * SECTION:glk-graphics-testing
  * @short_description: Checking whether the library supports graphics
- * @include: libchimara/glk.h
  *
  * Before calling Glk graphics functions, you should use the gestalt selector
  * %gestalt_Graphics. To test for additional capabilities, you can also use the
  * %gestalt_DrawImage and %gestalt_GraphicsTransparency selectors.
  */
+
+/**
+ * SECTION:glk-sound-channels
+ * @short_description: Creating new sound channels and closing them
+ *
+ * Sounds in Glk are played through sound channels. Sound channels are another
+ * type of opaque object, like windows, streams, and file references.
+ */
+
+/**
+ * SECTION:glk-playing-sounds
+ * @short_description: Producing noise
+ *
+ * These functions play the actual sounds through the sound channels.
+ */
+
+/**
+ * SECTION:glk-sound-other
+ * @short_description: Miscellaneous functions for sound channels
+ *
+ * This section includes functions for sound channels that don't fit anywhere
+ * else.
+ */
+
+/**
+ * SECTION:glk-sound-testing
+ * @short_description: Checking whether the library supports sound
+ *
+ * Before calling Glk sound functions, you should use the %gestalt_Sound2
+ * selector.
+ *
+ * Earlier versions of the Glk spec defined separate selectors for various
+ * optional capabilities. This has proven to be an unnecessarily confusing
+ * strategy, and is no longer used. The %gestalt_Sound, %gestalt_SoundMusic,
+ * %gestalt_SoundVolume, and %gestalt_SoundNotify selectors still exist, but you
+ * should not need to test them; the %gestalt_Sound2 selector covers all of
+ * them.
+ */
+
 /**
  * SECTION:glk-creating-hyperlinks
  * @short_description: Printing text as a hyperlink
- * @include: libchimara/glk.h
  *
  * Some games may wish to mark up text in their windows with hyperlinks, which
  * can be selected by the player &mdash; most likely by mouse click. Glk allows
 /**
  * SECTION:glk-accepting-hyperlinks
  * @short_description: Generating and catching hyperlink navigation events
- * @include: libchimara/glk.h
+ *
+ * When you request a hyperlink event in a window, you will receive a hyperlink
+ * event when the player clicks on a hyperlink.
  */
 
 /**
  * SECTION:glk-hyperlinks-testing
  * @short_description: Checking whether the library supports hyperlinks
- * @include: libchimara/glk.h
  *
  * Before calling Glk hyperlink functions, you should use the gestalt selectors
  * %gestalt_Hyperlinks and %gestalt_HyperlinkInput.
  */
+
+/**
+ * SECTION:glk-clock
+ * @short_description: Getting the current time from the system clock
+ *
+ * You can get the current time, either as a Unix timestamp (seconds since 1970)
+ * or as a broken-out structure of time elements (year, month, day, hour,
+ * minute, second).
+ *
+ * The system clock is not guaranteed to line up with timer events (see <link 
+ * linkend="chimara-Timer-Events">Timer Events</link>). Timer events may be
+ * delivered late according to the system clock.
+ */
+
+/**
+ * SECTION:glk-clock-conversions
+ * @short_description: Converting from timestamps to date structures and back
+ *
+ * This section describes functions for converting timestamps to more
+ * human-readable date structures and back.
+ */
+
+/**
+ * SECTION:glk-clock-testing
+ * @short_description: Checking whether the library supports the clock functions
+ *
+ * Before calling Glk date and time functions, you should use the
+ * %gestalt_DateTime selector.
+ */
  
 /**
  * SECTION:dispatch-interrogating
  * @short_description: Finding out what functions the Glk library exports
- * @include: libchimara/glk.h, libchimara/gi_dispa.h
  *
  * These are the ancilliary functions that let you enumerate.
  */
 /**
  * SECTION:dispatch-dispatching
  * @short_description: Dispatching the call to the Glk library
- * @include: libchimara/glk.h, libchimara/gi_dispa.h
+ *
+ * The function gidispatch_call() invokes a function from the Glk library.
  */
  
 /**
  * SECTION:dispatch-prototypes
  * @short_description: Querying Glk function prototypes
- * @include: libchimara/glk.h, libchimara/gi_dispa.h
  *
  * There are many possible ways to set up a #gluniversal_t array, and it's
  * illegal to call gidispatch_call() with an array which doesn't match the
 /**
  * SECTION:dispatch-library-functions
  * @short_description: Platform-dependent dispatch layer functions
- * @include: libchimara/glk.h, libchimara/gi_dispa.h
  *
  * Ideally, the three layers &mdash; program, dispatch layer, Glk library
  * &mdash; would be completely modular; each would refer only to the layers
 /** 
  * SECTION:blorb-program
  * @short_description: How to use the Blorb layer in your program
- * @include: libchimara/glk.h, libchimara/gi_blorb.h
  *
  * If you wish your program to load its resources from a Blorb file, you need to
  * find and open that file in your startup code. (See <link 
 /**
  * SECTION:blorb-layer
  * @short_description: The platform-independent functions in the Blorb layer
- * @include: libchimara/glk.h, libchimara/gi_blorb.h
  *
  * These are the functions which are implemented in 
  * <filename>gi_blorb.c</filename>. They will be compiled into the library, but
 /** 
  * SECTION:blorb-errors
  * @short_description: Error codes returned by the Blorb layer functions
- * @include: libchimara/glk.h, libchimara/gi_blorb.h
  *
  * All Blorb layer functions, including giblorb_set_resource_map(), return the
  * following error codes.
 /**
  * SECTION:glkext-startup
  * @short_description: Parsing startup options
- * @include: libchimara/glk.h, libchimara/glkstart.h
  *
  * This section describes an extension to Glk for parsing command-line startup
  * options. It was written by Andrew Plotkin for the Glk libraries CheapGlk and
  * GlkTerm. 
  *
  * When you compile a Glk program, you may define a function called 
- * glkunix_startup_code(), and an array <code>glkunix_arguments[]</code>. These
- * set up various Unix-specific options used by the Glk library. There is a
- * sample <quote><filename>glkstart.c</filename></quote> file included in this 
- * package; you should modify it to your needs.
+ * <function>glkunix_startup_code&lpar;&rpar;</function>, and an array 
+ * <code>glkunix_arguments[]</code>. These set up various Unix-specific options
+ * used by the Glk library. There is a sample 
+ * <quote><filename>glkstart.c</filename></quote> file included in this package;
+ * you should modify it to your needs.
  * 
- * |[ extern #glkunix_argumentlist_t glkunix_arguments[]; ]|
+ * |[ extern glkunix_argumentlist_t glkunix_arguments[]; ]|
  *  
  * The <code>glkunix_arguments[]</code> array is a list of command-line 
  * arguments that your program can accept. The library will sort these out of 
 /**
  * SECTION:glkext-unix
  * @short_description: Unix-specific functions
- * @include: libchimara/glk.h, libchimara/glkstart.h
  *
  * This section describes an extension to Glk for various Unix functions. It was
  * written by Andrew Plotkin for the Glk libraries CheapGlk and GlkTerm.
  * generally be limited to finding and opening data files. There are a few Unix
  * Glk library functions which are convenient for this purpose.
  */
+
+/**
+ * SECTION:glkext-garglk
+ * @short_description: Gargoyle extensions to Glk
+ *
+ * This section describes various extensions to Glk that were written for the
+ * popular interpreter <ulink 
+ * url="http://www.ccxvii.net/gargoyle/">Gargoyle</ulink> by Tor Andersson (now 
+ * maintained by Ben Cressey).
+ *
+ * These functions mostly serve to close the gap between Glk's input/output
+ * capabilities and what some interpreters expect. For example, 
+ * garglk_set_zcolors() displays the colors defined in the Z-machine standard,
+ * and garglk_set_story_name() can be used to give the host program a hint
+ * about what to display in the title bar of its window.
+ */ 
  
 /*---------------- TYPES AND CONSTANTS FROM GLK.H ----------------------------*/
 
 /**
  * GLK_MODULE_UNICODE:
  *
- * If this preprocessor symbol is defined, so are all the Unicode functions and
+ * If this preprocessor symbol is defined, so are the core Unicode functions and
  * constants (see %gestalt_Unicode). If not, not.
  */
 
  *   sufficient.
  * </para></note>
  */
+
+/**
+ * GLK_MODULE_SOUND2:
+ *
+ * If you are writing a C program, there is an additional complication. A 
+ * library which does not support sound may not implement the sound functions at
+ * all. Even if you put gestalt tests around your sound calls, you may get 
+ * link-time errors. If the <filename class="headerfile">glk.h</filename> file 
+ * is so old that it does not declare the sound functions and constants, you may
+ * even get compile-time errors.
+ * 
+ * To avoid this, you can perform a preprocessor test for the existence of
+ * %GLK_MODULE_SOUND2. If this is defined, so are all the functions and constants
+ * described in this section. If not, not.
+ */
+
+/**
+ * GLK_MODULE_SOUND:
+ *
+ * You can perform a preprocessor test for the existence of %GLK_MODULE_SOUND.
+ * If this is defined, so are all the functions and constants described in this
+ * section. If not, not.
+ */
  
 /**
  * GLK_MODULE_HYPERLINKS:
  * functions and constants described in this section. If not, not.
  */
 
+/**
+ * GLK_MODULE_UNICODE_NORM:
+ *
+ * If this preprocessor symbol is defined, so are the Unicode normalization
+ * functions (see %gestalt_UnicodeNorm). If not, not.
+ */
+
+/**
+ * GLK_MODULE_DATETIME:
+ *
+ * If you are writing a C program, you can perform a preprocessor test for the
+ * existence of %GLK_MODULE_DATETIME. If this is defined, so are all the
+ * functions and data types described in this section.
+ */
+
+/**
+ * GLK_MODULE_LINE_ECHO:
+ *
+ * If this preprocessor symbol is defined, so is glk_set_echo_line_event(). If
+ * not, not.
+ */
+
+/**
+ * GLK_MODULE_LINE_TERMINATORS:
+ *
+ * If this preprocessor symbol is defined, so is
+ * glk_set_terminators_line_event(). If not, not.
+ */
+
 /**
  * winid_t:
  *
  * members.
  */
 
+/**
+ * schanid_t:
+ * 
+ * Opaque structure representing a sound channel. It has no user-accessible
+ * members.
+ */
+  
 /**
  * gestalt_Version:
  *
  * For an example of the gestalt mechanism, consider the selector
  * %gestalt_Version. If you do
  * |[
- * #glui32 res;
- * res = #glk_gestalt(#gestalt_Version, 0);
+ * glui32 res;
+ * res = glk_gestalt(gestalt_Version, 0);
  * ]|
  * <code>res</code> will be set to a 32-bit number which encodes the version of
  * the Glk spec which the library implements. The upper 16 bits stores the major
  *   So the version number 78.2.11 would be encoded as 0x004E020B.
  * </para></note>
  *
- * The current Glk specification version is 0.7.0, so this selector will return
- * 0x00000700.
+ * The current Glk specification version is 0.7.4, so this selector will return
+ * 0x00000704.
  *
  * |[
- * #glui32 res;
- * res = #glk_gestalt_ext(#gestalt_Version, 0, NULL, 0);
+ * glui32 res;
+ * res = glk_gestalt_ext(gestalt_Version, 0, NULL, 0);
  * ]|
  * does exactly the same thing. Note that, in either case, the second argument 
  * is not used; so you should always pass 0 to avoid future surprises.
  * If you set <code>ch</code> to a character code, or a special code (from
  * 0xFFFFFFFF down), and call
  * |[
- * #glui32 res;
- * res = #glk_gestalt(#gestalt_CharInput, ch);
+ * glui32 res;
+ * res = glk_gestalt(gestalt_CharInput, ch);
  * ]|
  * then <code>res</code> will be %TRUE (1) if that character can be typed by
  * the player in character input, and %FALSE (0) if not. See <link
  *
  * If you set <code>ch</code> to a character code, and call
  * |[
- * #glui32 res;
- * res = #glk_gestalt(#gestalt_LineInput, ch);
+ * glui32 res;
+ * res = glk_gestalt(gestalt_LineInput, ch);
  * ]|
  * then <code>res</code> will be %TRUE (1) if that character can be typed by the
  * player in line input, and %FALSE (0) if not. Note that if <code>ch</code> is 
  *
  * If you set <code>ch</code> to a character code (Latin-1 or higher), and call
  * |[
- * #glui32 res, len;
- * res = #glk_gestalt_ext(#gestalt_CharOutput, ch, &amp;len, 1);
+ * glui32 res, len;
+ * res = glk_gestalt_ext(gestalt_CharOutput, ch, &amp;len, 1);
  * ]|
  * then <code>res</code> will be one of %gestalt_CharOutput_CannotPrint,
  * %gestalt_CharOutput_ExactPrint, or %gestalt_CharOutput_ApproxPrint (see 
  *
  * <note><para>
  *   Make sure you do not get confused by signed byte values. If you set a
- *   <quote><type>char</type></quote> variable <code>ch</code> to 0xFE, the 
- *   small-thorn character (&thorn;), and then call
- *   |[ res = #glk_gestalt(#gestalt_CharOutput, ch); ]|
+ *   <quote><type>signed char</type></quote> variable <code>ch</code> to 0xFE,
+ *   the small-thorn character (&thorn;), it will wind up as -2. (The same is
+ *   true of a <quote><type>char</type></quote> variable, if your compiler
+ *   treats <quote><type>char</type></quote> as signed!) If you then call
+ *   |[ res = glk_gestalt(gestalt_CharOutput, ch); ]|
  *   then (by the definition of C/C++) <code>ch</code> will be sign-extended to
- *   0xFFFFFFFE, which is not a legitimate character, even in Unicode. You 
+ *   0xFFFFFFFE, which is not a legitimate character, even in Unicode. You
  *   should write
- *   |[ res = #glk_gestalt(#gestalt_CharOutput, (unsigned char)ch); ]|
+ *   |[ res = glk_gestalt(gestalt_CharOutput, (unsigned char)ch); ]|
  *   instead.
  * </para></note>
  * <note><para>
  * gestalt_Timer:
  *
  * You can test whether the library supports timer events:
- * |[ res = #glk_gestalt(#gestalt_Timer, 0); ]|
- * This returns 1 if timer events are supported, and 0 if they are not.
+ * |[ res = glk_gestalt(gestalt_Timer, 0); ]|
+ * This returns %TRUE (1) if timer events are supported, and %FALSE (0) if they 
+ * are not.
  */
 
 /**
  * Before calling Glk graphics functions, you should use the following gestalt
  * selector:
  * |[
- *     glui32 res;
- *     res = glk_gestalt(gestalt_Graphics, 0);
+ * glui32 res;
+ * res = glk_gestalt(gestalt_Graphics, 0);
  * ]|
  * This returns 1 if the overall suite of graphics functions is available. This
  * includes glk_image_draw(), glk_image_draw_scaled(), glk_image_get_info(),
  * gestalt_DrawImage:
  * 
  * This selector returns 1 if images can be drawn in windows of the given type. 
- * If it returns 0, glk_image_draw() will fail and return %FALSE. You should 
+ * If it returns 0, glk_image_draw() will fail and return %FALSE (0). You should 
  * test %wintype_Graphics and %wintype_TextBuffer separately, since libraries 
  * may implement both, neither, or only one.  
  */
+
+/**
+ * gestalt_Sound2:
+ *
+ * You can test whether the library supports sound:
+ * |[
+ * glui32 res;
+ * res = glk_gestalt(gestalt_Sound2, 0);
+ * ]|
+ * This returns 1 if the overall suite of sound functions is available. This
+ * includes all the functions defined in <link
+ * linkend="chimara-glk-spec-sound">this chapter</link>. It also includes the
+ * capabilities described below under %gestalt_SoundMusic, %gestalt_SoundVolume,
+ * and %gestalt_SoundNotify.
+ */
+
+/**
+ * gestalt_Sound:
+ *
+ * |[
+ * glui32 res;
+ * res = glk_gestalt(gestalt_Sound, 0);
+ * ]|
+ * This returns 1 if the overall suite of sound functions is available. This 
+ * includes glk_schannel_create(), glk_schannel_destroy(), 
+ * glk_schannel_iterate(), glk_schannel_get_rock(), glk_schannel_play(),
+ * glk_schannel_play_ext(), glk_schannel_stop(), glk_schannel_set_volume(), and
+ * glk_sound_load_hint().
+ *
+ * If this selector returns 0, you should not try to call these functions. They 
+ * may have no effect, or they may cause a run-time error.
+ *
+ * This selector is guaranteed to return 1 if %gestalt_Sound2 does.
+ */
+
+/**
+ * gestalt_SoundVolume:
+ *
+ * You can test whether the library supports setting the volume of sound 
+ * channels: 
+ * |[ res = glk_gestalt(gestalt_SoundVolume, 0); ]|
+ * This selector returns 1 if the glk_schannel_set_volume() function works. If 
+ * it returns zero, glk_schannel_set_volume() has no effect.
+ *
+ * This selector is guaranteed to return 1 if %gestalt_Sound2 does.
+ */
+
+/**
+ * gestalt_SoundNotify:
+ *
+ * You can test whether the library supports sound notification events:
+ * |[ res = glk_gestalt(gestalt_SoundNotify, 0); ]| 
+ * This selector returns 1 if the library supports sound notification events. If
+ * it returns zero, you will never get such events.
+ *
+ * This selector is guaranteed to return 1 if %gestalt_Sound2 does.
+ */
+
 /**
  * gestalt_Hyperlinks:
  *
  * You can test whether the library supports hyperlinks:
  * |[ 
- * #glui32 res;
- * res = #glk_gestalt(#gestalt_Hyperlinks, 0); 
+ * glui32 res;
+ * res = glk_gestalt(gestalt_Hyperlinks, 0); 
  * ]|
  * This returns 1 if the overall suite of hyperlinks functions is available.
  * This includes glk_set_hyperlink(), glk_set_hyperlink_stream(),
  *
  * You can test whether hyperlinks are supported with the 
  * %gestalt_HyperlinkInput selector:
- * |[ res = #glk_gestalt(#gestalt_HyperlinkInput, windowtype); ]|
+ * |[ res = glk_gestalt(gestalt_HyperlinkInput, windowtype); ]|
  * This will return %TRUE (1) if windows of the given type support hyperlinks.
  * If this returns %FALSE (0), it is still legal to call glk_set_hyperlink() and
  * glk_request_hyperlink_event(), but they will have no effect, and you will
  * never get hyperlink events.
  */
 
+/** 
+ * gestalt_SoundMusic:
+ *
+ * You can test whether music resources are supported:
+ * |[ res = glk_gestalt(gestalt_SoundMusic, 0); ]|
+ * This returns 1 if the library is capable of playing music sound resources. If 
+ * it returns 0, only sampled sounds can be played.
+ * <note><para>
+ *   <quote>Music sound resources</quote> means MOD songs &mdash; the only music
+ *   format that Blorb currently supports. The presence of this selector is, of 
+ *   course, an ugly hack. It is a concession to the current state of the Glk 
+ *   libraries, some of which can handle AIFF but not MOD sounds.
+ * </para></note>
+ *
+ * This selector is guaranteed to return 1 if %gestalt_Sound2 does.
+ */ 
+  
 /**
  * gestalt_GraphicsTransparency:
  *
  *
  * The basic text functions will be available in every Glk library. The Unicode
  * functions may or may not be available. Before calling them, you should use
- * the following gestalt selector:
+ * the %gestalt_Unicode and %gestalt_UnicodeNorm gestalt selectors.
+ *
  * |[
  * glui32 res;
- * res = #glk_gestalt(#gestalt_Unicode, 0);
+ * res = glk_gestalt(gestalt_Unicode, 0);
  * ]|
- * 
- * This returns 1 if the Unicode functions are available. If it returns 0, you
- * should not try to call them. They may print nothing, print gibberish, or
+ * This returns 1 if the core Unicode functions are available. If it returns 0,
+ * you should not try to call them. They may print nothing, print gibberish, or
  * cause a run-time error. The Unicode functions include
  * glk_buffer_to_lower_case_uni(), glk_buffer_to_upper_case_uni(),  
  * glk_buffer_to_title_case_uni(), glk_put_char_uni(), glk_put_string_uni(),
  * errors.
  * 
  * To avoid this, you can perform a preprocessor test for the existence of
- * #GLK_MODULE_UNICODE. 
+ * %GLK_MODULE_UNICODE.
  */
+
+/**
+ * gestalt_UnicodeNorm:
+ *
+ * |[
+ * glui32 res;
+ * res = glk_gestalt(gestalt_UnicodeNorm, 0);
+ * ]|
+ * This code returns 1 if the Unicode normalization functions are available. If
+ * it returns 0, you should not try to call them. The Unicode normalization
+ * functions include glk_buffer_canon_decompose_uni() and
+ * glk_buffer_canon_normalize_uni().
+ *
+ * The equivalent preprocessor test for these functions is
+ * %GLK_MODULE_UNICODE_NORM.
+ */
+
+/**
+ * gestalt_LineInputEcho:
+ *
+ * |[
+ * res = glk_gestalt(gestalt_LineInputEcho, 0);
+ * ]|
+ *
+ * This returns 1 if glk_set_echo_line_event() is supported, and 0 if it is not.
+ * <note><para>
+ *   Remember that if it is not supported, the behavior is always the default,
+ *   which is line echoing <emphasis>enabled</emphasis>.
+ * </para></note>
+ */
+
+/**
+ * gestalt_LineTerminators:
+ *
+ * |[
+ * res = glk_gestalt(gestalt_LineTerminators, 0);
+ * ]|
+ *
+ * This returns 1 if glk_set_terminators_line_event() is supported, and 0 if it
+ * is not.
+ */
+
+/**
+ * gestalt_LineTerminatorKey:
+ *
+ * |[
+ * res = glk_gestalt(gestalt_LineTerminatorKey, ch);
+ * ]|
+ *
+ * This returns 1 if the keycode @ch can be passed to
+ * glk_set_terminators_line_event(). If it returns 0, that keycode will be
+ * ignored as a line terminator. Printable characters and %keycode_Return will
+ * always return 0.
+ */
+
+/**
+ * gestalt_DateTime:
+ *
+ * |[
+ * res = glk_gestalt(gestalt_DateTime, 0);
+ * ]|
+ *
+ * This returns 1 if the overall suite of system clock functions, as described
+ * in <link linkend="chimara-The-System-Clock">this chapter</link>, is
+ * available.
+ *
+ * If this selector returns 0, you should not try to call these functions. They
+ * may have no effect, or they may cause a run-time error.
+ *
+ * <note><para>
+ *   Glk timer events are covered by a different selector. See %gestalt_Timer.
+ * </para></note>
+ */
+
+/**
+ * gestalt_ResourceStream:
+ *
+ * |[
+ * res = glk_gestalt(gestalt_ResourceStream, 0);
+ * ]|
+ *
+ * This returns 1 if the glk_stream_open_resource() and
+ * glk_stream_open_resource_uni() functions are available. If it returns 0, you
+ * should not call them.
+ */
+
 /**
  * evtype_None:
  *
  * A full line of input completed in a window. See <link 
  * linkend="chimara-Line-Input-Events">Line Input Events</link>.
  *
- * If a window has a pending request for line input, and the player hits
- * <keycap>enter</keycap> in that window (or whatever action is appropriate to
- * enter his input), glk_select() will return an event whose type is
- * %evtype_LineInput. Once this happens, the request is complete; it is no 
- * longer pending. You must call glk_request_line_event() if you want another 
+ * If a window has a pending request for line input, the player can generally
+ * hit the <keycap>enter</keycap> key (in that window) to complete line input.
+ * The details will depend on the platform's native user interface.
+ *
+ * When line input is completed, glk_select() will return an event whose type is
+ * %evtype_LineInput. Once this happens, the request is complete; it is no
+ * longer pending. You must call glk_request_line_event() if you want another
  * line of text from that window.
- * 
- * In the event structure, @win tells what window the event came from. @val1 
- * tells how many characters were entered. @val2 will be 0. The characters
- * themselves are stored in the buffer specified in the original
- * glk_request_line_event() or glk_request_line_event_uni() call. 
  *
- * <note><para>There is no null terminator stored in the buffer.</para></note>
+ * In the event structure, @win tells what window the event came from. @val1
+ * tells how many characters were entered. @val2 will be 0 unless input was
+ * ended by a special terminator key, in which case @val2 will be the keycode
+ * (one of the values passed to glk_set_terminators_line_event()).
+ *
+ * The characters themselves are stored in the buffer specified in the original
+ * glk_request_line_event() or glk_request_line_event_uni() call.
+ *
+ * <note><para>
+ *   There is no null terminator or newline stored in the buffer.
+ * </para></note>
  * 
  * It is illegal to print anything to a window which has line input pending. 
  *
  * events, this is platform-dependent. See %evtype_Arrange.
  *
  * For more about redraw events and how they affect graphics windows, see <link
- * linkend="chimara-Graphics-Windows">Graphics Windows</link>.
+ * linkend="wintype-Graphics">Graphics Windows</link>.
  */
 
 /**
  * evtype_SoundNotify:
  *
+ * The completion of a sound being played in a sound channel.
+ *
  * On platforms that support sound, you can request to receive an 
  * %evtype_SoundNotify event when a sound finishes playing. See <link
  * linkend="chimara-Playing-Sounds">Playing Sounds</link>.
  
 /**
  * evtype_Hyperlink:
+ *
+ * The selection of a hyperlink in a window.
  * 
  * On platforms that support hyperlinks, you can request to receive an
  * %evtype_Hyperlink event when the player selects a link. See <link
  * Events</link>.
  */
 
+/**
+ * evtype_VolumeNotify:
+ *
+ * The completion of a gradual volume change in a sound channel.
+ *
+ * On platforms that support sound, you can request to receive an
+ * %evtype_VolumeNotify event when a gradual volume change completes. See <link
+ * linkend="chimara-Playing-Sounds">Playing Sounds</link>.
+ */
+
 /**
  * event_t:
  * @type: the event type
  * Represents the <keycap>F12</keycap> key.
  */
 
-/**
- * keycode_MAXVAL:
- *
- * This value is equal to the number of special keycodes. The last keycode is
- * always 
- * <inlineequation>
- *   <alt>(0x100000000 - <keysym>keycode_MAXVAL</keysym>)</alt>
- *   <mathphrase>(0x100000000 - <keysym>keycode_MAXVAL</keysym>)</mathphrase>
- * </inlineequation>
- * .
- */
-
 /**
  * style_Normal: 
  *
  *
  * Another style available for your use. 
  */
-/**
- * style_NUMSTYLES:
- * 
- * The number of styles defined in this library.
- */
 
 /**
  * stream_result_t:
  *   result.
  * </para></note>
  * 
- * When the player finishes his line of input, the library will display the
- * input text at the end of the buffer text (if it wasn't there already.) It
- * will be followed by a newline, so that the next text you print will start a
- * new line (paragraph) after the input.
+ * By default, when the player finishes his line of input, the library will
+ * display the input text at the end of the buffer text (if it wasn't there
+ * already.) It will be followed by a newline, so that the next text you print
+ * will start a new line (paragraph) after the input.
  * 
  * If you call glk_cancel_line_event(), the same thing happens; whatever text
  * the user was composing is visible at the end of the buffer text, followed by
  * a newline.
+ *
+ * However, this default behavior can be changed with the
+ * glk_set_echo_line_event() call. If the default echoing is disabled, the
+ * library will <emphasis>not</emphasis> display the input text (plus newline)
+ * after input is either completed or cancelled. The buffer will end with
+ * whatever prompt you displayed before requesting input. If you want the
+ * traditional input behavior, it is then your responsibility to print the text,
+ * using the Input text style, followed by a newline (in the original style).
  */
  
 /**
  * 
  * When you print, the characters of the output are laid into the array in
  * order, left to right and top to bottom. When the cursor reaches the end of a
- * line, it goes to the beginning of the next line. The library makes no attempt
- * to wrap lines at word breaks.
+ * line, or if a newline (0x0A) is printed, the cursor goes to the beginning of
+ * the next line. The library makes <emphasis>no</emphasis> attempt to wrap
+ * lines at word breaks. If the cursor reaches the end of the last line, further
+ * printing has no effect on the window until the cursor is moved.
  * 
  * <note><para>
  *   Note that printing fancy characters may cause the cursor to advance more
  * When the player finishes his line of input, it will remain visible in the
  * window, and the output cursor will be positioned at the beginning of the 
  * <emphasis>next</emphasis> row. Again, if you glk_cancel_line_event(), the
- * same thing happens.
+ * same thing happens. The glk_set_echo_line_event() call has no effect in grid
+ * windows.
  */
  
 /**
  * linkend="chimara-Graphics-in-Graphics-Windows">Graphics in Graphics 
  * Windows</link>.
  * 
- * When a text grid window is resized smaller, the bottom or right area is
+ * When a graphics window is resized smaller, the bottom or right area is
  * thrown away, but the remaining area stays unchanged. When it is resized
  * larger, the new bottom or right area is filled with the background color.
  * 
  * When calling glk_window_open() with this @method, the new window will be 
  * below the old one which was split.
  */
-
-/**
- * winmethod_DirMask:
- *
- * Bitwise AND this value with a window splitting method argument to find
- * whether the split is %winmethod_Left, %winmethod_Right, %winmethod_Above, or
- * %winmethod_Below.
- */
  
 /**
  * winmethod_Fixed:
  * When calling glk_window_open() with this @method, the new window will be 
  * a given proportion of the old window's size. (See glk_window_open()).
  */
+
 /**
- * winmethod_DivisionMask:
+ * winmethod_Border:
  *
- * Bitwise AND this value with a window splitting method argument to find
- * whether the new window has %winmethod_Fixed or %winmethod_Proportional.
+ * When calling glk_window_open() with this @method, it specifies that there
+ * should be a visible window border between the new window and its sibling.
+ * (This is a hint to the library.)
+ *
+ * <note><title>Chimara</title><para>
+ *   There will only be a visible border if the #ChimaraGlk:spacing property
+ *   is nonzero. Setting #ChimaraGlk:spacing to zero disables all borders on Glk
+ *   windows.
+ * </para></note>
  */
+
+/**
+ * winmethod_NoBorder:
+ *
+ * When calling glk_window_open() with this @method, it specifies that there
+ * should not be a visible window border between the new window and its sibling.
+ * (This is a hint to the library; you might specify NoBorder between two
+ * graphics windows that should form a single image.)
+ */
+
 /** 
  * fileusage_Data: 
  *
  * linefeed-plus-carriage-return combinations; Latin-1 characters may be
  * converted to native character codes. When reading a file in text mode, native
  * line breaks will be converted back to newline (0x0A) characters, and native
- * character codes may be converted to Latin-1. 
+ * character codes may be converted to Latin-1 or UTF-8
  *
  * <note><para>
  *   Line breaks will always be converted; other conversions are more
  * existed in the destination, instead of replacing it. 
  *
  * <note><para>
- *   Corresponds to mode <code>"a"</code> in the stdio library, using fopen().
+ *   Confusingly, %filemode_WriteAppend cannot be mode <code>"a"</code>, because
+ *   the stdio spec says that when you open a file with mode <code>"a"</code>,
+ *   then fseek() doesn't work. So we have to use mode <code>"r+"</code> for
+ *   appending. Then we run into the <emphasis>other</emphasis> stdio problem,
+ *   which is that <code>"r+"</code> never creates a new file. So
+ *   %filemode_WriteAppend has to <emphasis>first</emphasis> open the file with
+ *   <code>"a"</code>, close it, reopen with <code>"r+"</code>, and then fseek()
+ *   to the end of the file. For %filemode_ReadWrite, the process is the same,
+ *   except without the fseek() &mdash; we begin at the beginning of the file.
  * </para></note>
  */
  
  *  others may support both, or neither.
  * </para></note>
  */
-
-/**
- * stylehint_NUMHINTS:
- *
- * The number of style hints defined in this library.
- */ 
  
 /**
  * stylehint_just_LeftFlush:
  * and baseline of the line of text. If the image is taller than the line of
  * text, it will stick up and down equally.
  */
+
+/**
+ * imagealign_MarginLeft:
+ * 
+ * The image appears in the left margin. Subsequent text will be displayed to
+ * the right of the image, and will flow around it &mdash; that is, it will be
+ * left-indented for as many lines as it takes to pass the image.
+ *
+ * <warning><para>Margin images are not implemented yet.</para></warning>
+ */
+
+/**
+ * imagealign_MarginRight:
+ *
+ * The image appears in the right margin, and subsequent text will flow around
+ * it on the left.
+ *
+ * <warning><para>Margin images are not implemented yet.</para></warning>
+ */
+
+/**
+ * glkdate_t:
+ * @year: The full (four-digit) year
+ * @month: The month number, ranging from 1-12, 1 is January
+ * @day: The day of the month, ranging from 1-31
+ * @weekday: The day of the week, ranging from 0-6, 0 is Sunday
+ * @hour: The hour of the day, ranging from 0-23
+ * @minute: The minute of the hour, ranging from 0-59
+ * @second: The second of the minute, ranging from 0-59; may be 60 during a leap
+ * second
+ * @microsec: The fraction of the second in microseconds, ranging from 0-999999
+ *
+ * This structure represents a human-readable date in a specific timezone.
+ */
+
+/**
+ * glktimeval_t:
+ * @high_sec: The most significant 32 bits of the timestamp in seconds.
+ * @low_sec: The least significant 32 bits of the timestamp in seconds.
+ * @microsec: The fraction of the timestamp, in microseconds, ranging from
+ * 0-999999.
+ *
+ * This structure represents the Unix timestamp, i.e. the number of seconds
+ * since January 1, 1970.
+ */
  
 /*---------- TYPES, FUNCTIONS AND CONSTANTS FROM GI_DISPA.H ------------------*/
 
  *
  * Returns: Number of opaque object classes used by the library.
  */
+
+/**
+ * gidispatch_get_class:
+ * @index: Unique integer index of the class.
+ *
+ * Returns a structure describing an opaque class that the library exports.
+ * @index can range from 0 to <inlineequation><mathphrase>N -
+ * 1</mathphrase><alt>N - 1</alt></inlineequation>, where N is the value
+ * returned by gidispatch_count_classes().
+ *
+ * Returns: A #gidispatch_intconst_t structure describing the class.
+ */
+
 /**
  * gidispatch_count_intconst:
  *
  * This structure simply contains a string and a value. The string is a
  * symbolic name of the value, and can be re-exported to anyone interested in
  * using Glk constants.
+ *
+ * <note><para>
+ *   In the current <filename>gi_dispa.c</filename> library, these structures
+ *   are static and immutable, and will never be deallocated. However, it is
+ *   safer to assume that the structure may be reused in future
+ *   gidispatch_get_intconst() calls.
+ * </para></note>
  */
  
 /**
  * 1</alt></inlineequation>, where N is the value returned by 
  * gidispatch_count_functions().
  *
+ * <note><para>
+ *   Again, it is safest to assume that the structure is only valid until the
+ *   next gidispatch_get_function() or gidispatch_get_function_by_id() call.
+ * </para></note>
+ *
  * Returns: A #gidispatch_function_t structure describing the function.
  */
  
  * Returns a structure describing the Glk function with selector @id. If there 
  * is no such function in the library, this returns %NULL.
  *
+ * <note><para>
+ *   Again, it is safest to assume that the structure is only valid until the
+ *   next gidispatch_get_function() or gidispatch_get_function_by_id() call.
+ * </para></note>
+ *
  * Returns: a #gidispatch_function_t structure, or %NULL.
  */
  
  * the list of arguments, and @numargs is the length of the list.
  * 
  * The arguments are all stored as #gluniversal_t objects. 
- * </para><refsect3 id="chimara-Basic-Types"><title>Basic Types</title><para>
+ * </para><refsect3 id="chimara-Basic-Dispatch-Types"><title>Basic Dispatch
+ * Types</title><para>
  * Numeric arguments are passed in the obvious way &mdash; one argument per
  * #gluniversal_t, with the @uint or @sint field set to the numeric value.
  * Characters and strings are also passed in this way &mdash; #char<!---->s in
  * <code>#glui32*</code>, <code>#winid_t*</code>, and so on &mdash; takes
  * <emphasis>one or two</emphasis> #gluniversal_t objects. The first is a flag
  * indicating whether the reference argument is %NULL or not. The @ptrflag field
- * of this #gluniversal_t should be %FALSE if the reference is %NULL, and %TRUE
- * otherwise. If %FALSE, that is the end of the argument; you should not use a
- * #gluniversal_t to explicitly store the %NULL reference. If the flag is %TRUE,
- * you must then put a #gluniversal_t storing the base type of the reference.
+ * of this #gluniversal_t should be %FALSE (0) if the reference is %NULL, and
+ * %TRUE (1) otherwise. If %FALSE, that is the end of the argument; you should
+ * not use a #gluniversal_t to explicitly store the %NULL reference. If the flag
+ * is %TRUE, you must then put a #gluniversal_t storing the base type of the
+ * reference.
  *
  * For example, consider a hypothetical function, with selector 
  * <code>0xABCD</code>:
  * |[ 
- * void glk_glomp(#glui32 num, #winid_t win, #glui32 *numref, #strid_t *strref);
+ * void glk_glomp(glui32 num, winid_t win, glui32 *numref, strid_t *strref);
  * ]|
  * ...and the calls:
  * |[
- * #glui32 value;
- * #winid_t mainwin;
- * #strid_t gamefile;
+ * glui32 value;
+ * winid_t mainwin;
+ * strid_t gamefile;
  * glk_glomp(5, mainwin, &value, &gamefile);
  * ]|
  *
  * To perform this through gidispatch_call(), you would do the following:
  * |[
- * #gluniversal_t arglist[6];
+ * gluniversal_t arglist[6];
  * arglist[0].uint = 5;
  * arglist[1].opaqueref = mainwin;
  * arglist[2].ptrflag = TRUE;
  * arglist[3].uint = value;
  * arglist[4].ptrflag = TRUE;
  * arglist[5].opaqueref = gamefile;
- * #gidispatch_call(0xABCD, 6, arglist);
+ * gidispatch_call(0xABCD, 6, arglist);
  * value = arglist[3].uint;
  * gamefile = arglist[5].opaqueref;
  * ]|
  * 
  * Note that you copy the value of the reference arguments into and out of
- * @arglist. Of course, it may be that glk_glomp() only uses these as pass-out
+ * @arglist. Of course, it may be that 
+ * <function>glk_glomp&lpar;&rpar;</function> only uses these as pass-out
  * references or pass-in references; if so, you could skip copying in or out.
  *
  * For further examples:
  * |[
  * glk_glomp(7, mainwin, NULL, NULL);
  * ...or...
- * #gluniversal_t arglist[4];
+ * gluniversal_t arglist[4];
  * arglist[0].uint = 7;
  * arglist[1].opaqueref = mainwin;
  * arglist[2].ptrflag = FALSE;
  * arglist[3].ptrflag = FALSE;
- * #gidispatch_call(0xABCD, 4, arglist);
+ * gidispatch_call(0xABCD, 4, arglist);
  * ]|
  *
  * |[
  * glk_glomp(13, NULL, NULL, &gamefile);
  * ...or...
- * #gluniversal_t arglist[5];
+ * gluniversal_t arglist[5];
  * arglist[0].uint = 13;
  * arglist[1].opaqueref = NULL;
  * arglist[2].ptrflag = FALSE;
  * arglist[3].ptrflag = TRUE;
  * arglist[4].opaqueref = gamefile;
- * #gidispatch_call(0xABCD, 5, arglist);
+ * gidispatch_call(0xABCD, 5, arglist);
  * gamefile = arglist[4].opaqueref;
  * ]|
  *
  * |[
  * glk_glomp(17, NULL, &value, NULL);
  * ...or...
- * #gluniversal_t arglist[5];
+ * gluniversal_t arglist[5];
  * arglist[0].uint = 17;
  * arglist[1].opaqueref = NULL;
  * arglist[2].ptrflag = TRUE;
  * arglist[3].uint = value;
  * arglist[4].ptrflag = FALSE;
- * #gidispatch_call(0xABCD, 5, arglist);
+ * gidispatch_call(0xABCD, 5, arglist);
  * value = arglist[3].uint;
  * ]|
  * 
  * 
  * For example, the function glk_select() can be invoked as follows:
  * |[
- * #event_t ev;
- * #gluniversal_t arglist[5];
+ * event_t ev;
+ * gluniversal_t arglist[5];
  * arglist[0].ptrflag = TRUE;
- * #gidispatch_call(0x00C0, 5, arglist);
+ * gidispatch_call(0x00C0, 5, arglist);
  * ev.type = arglist[1].uint;
  * ev.win = arglist[2].opaqueref;
  * ev.val1 = arglist[3].uint;
  * 
  * For example, the function glk_put_buffer() can be invoked as follows:
  * |[
- * #char buf[64];
- * #glui32 len = 64;
- * #glk_put_buffer(buf, len);
+ * char buf[64];
+ * glui32 len = 64;
+ * glk_put_buffer(buf, len);
  * ...or...
- * #gluniversal_t arglist[3];
+ * gluniversal_t arglist[3];
  * arglist[0].ptrflag = TRUE;
  * arglist[1].array = buf;
  * arglist[2].uint = len;
- * #gidispatch_call(0x0084, 3, arglist);
+ * gidispatch_call(0x0084, 3, arglist);
  * ]|
  * 
  * Since you are passing a C char array to gidispatch_call(), the contents will
  * 
  * For example, the function glk_window_get_rock() can be invoked as follows:
  * |[
- * #glui32 rock;
- * #winid_t win;
- * rock = #glk_window_get_rock(win);
+ * glui32 rock;
+ * winid_t win;
+ * rock = glk_window_get_rock(win);
  * ...or...
- * #gluniversal_t arglist[3];
+ * gluniversal_t arglist[3];
  * arglist[0].opaqueref = win;
  * arglist[1].ptrflag = TRUE;
- * #gidispatch_call(0x0021, 3, arglist);
+ * gidispatch_call(0x0021, 3, arglist);
  * rock = arglist[2].uint;
  * ]|
  * </para></refsect3><para>
  * @uch: Stores an #unsigned #char.
  * @sch: Stores a #signed #char.
  * @ch: Stores a #char with the default signedness.
- * @charstr: Stores a %NULL-terminated string.
+ * @charstr: Stores a null-terminated string.
+ * @unicharstr: Stores a zero-terminated string of #glui32 values representing
+ * Unicode characters.
  * @array: Stores a pointer to an array, and should be followed by another 
  * #gluniversal_t with the array length stored in the @uint member.
  * @ptrflag: If %FALSE, represents an opaque reference or array that is %NULL,
  * This returns a string which encodes the proper argument list for the given
  * function. If there is no such function in the library, this returns %NULL.
  * 
- * The prototype string for the glk_glomp() function described above would be:
- * <code>"4IuQa&amp;Iu&amp;Qb:"</code>. The <code>"4"</code> is the number of
- * arguments (including the return value, if there is one, which in this case
- * there isn't.) <code>"Iu"</code> denotes an unsigned integer;
- * <code>"Qa"</code> is an opaque object of class 0 (window).
+ * The prototype string for the <function>glk_glomp&lpar;&rpar;</function> 
+ * function described above would be: <code>"4IuQa&amp;Iu&amp;Qb:"</code>. The 
+ * <code>"4"</code> is the number of arguments (including the return value, if 
+ * there is one, which in this case there isn't.) <code>"Iu"</code> denotes an 
+ * unsigned integer; <code>"Qa"</code> is an opaque object of class 0 (window).
  * <code>"&amp;Iu"</code> is a <emphasis>reference</emphasis> to an unsigned
  * integer, and <code>"&amp;Qb"</code> is a reference to a stream. The colon at
  * the end terminates the argument list; the return value would follow it, if
  * 
  * Note that the initial number (<code>"4"</code> in this case) is the number of
  * logical arguments, not the number of #gluniversal_t objects which will be
- * passed to gidispatch_call(). The glk_glomp() call uses anywhere from four to
- * six #gluniversal_t objects, as demonstrated above.
+ * passed to gidispatch_call(). The <function>glk_glomp&lpar;&rpar;</function> 
+ * call uses anywhere from four to six #gluniversal_t objects, as demonstrated 
+ * above.
  * 
  * The basic type codes:
  * <variablelist>
  *   </para></note></listitem>
  * </varlistentry>
  * </variablelist>
- * Any type code can be prefixed with one or more of the following characters
- * (order does not matter):
+ * Any type code can be prefixed with one or more of the following characters:
  * <variablelist>
  * <varlistentry>
  *   <term><code>&amp;</code></term>
  * </varlistentry>
  * </variablelist>
  *
+ * The order of these characters and prefixes is not completely arbitrary. Here
+ * is a formal grammar for the prototype strings.
+ *
+ * <note><para>Thanks to Neil Cerutti for working this out.</para></note>
+ *
+ * <productionset>
+ * <production id="prototype">
+ *   <lhs>prototype</lhs>
+ *   <rhs>ArgCount [ <nonterminal def="&num;arg_list">arg_list</nonterminal> ]
+ *     ':' [ <nonterminal def="&num;arg">arg</nonterminal> ] EOL</rhs>
+ * </production>
+ * <production id="arg_list">
+ *   <lhs>arg_list</lhs>
+ *   <rhs><nonterminal def="&num;arg">arg</nonterminal> { <nonterminal
+ *     def="&num;arg">arg</nonterminal> }</rhs>
+ * </production>
+ * <production id="arg">
+ *   <lhs>arg</lhs>
+ *   <rhs>TypeName | <nonterminal def="&num;ref_type">ref_type</nonterminal>
+ *   </rhs>
+ * </production>
+ * <production id="ref_type">
+ *   <lhs>ref_type</lhs>
+ *   <rhs>RefType [ '+' ] <nonterminal
+ *     def="&num;target_type">target_type</nonterminal></rhs>
+ * </production>
+ * <production id="target_type">
+ *   <lhs>target_type</lhs>
+ *   <rhs>TypeName | <nonterminal def="&num;array">array</nonterminal> |
+ *     <nonterminal def="&num;struct">struct</nonterminal></rhs>
+ * </production>
+ * <production id="array">
+ *   <lhs>array</lhs>
+ *   <rhs>'&num;' [ '!' ] TypeName</rhs>
+ * </production>
+ * <production id="struct">
+ *   <lhs>struct</lhs>
+ *   <rhs>'[' ArgCount [ <nonterminal def="&num;arg_list">arg_list</nonterminal>
+ *     ] ']'</rhs>
+ * </production>
+ * </productionset>
+ * <constraintdef id="TypeName">
+ *   <para>TypeName is <code>I[us]<!---->|C[nus]<!---->|S|U|F|Q[a-z]</code>
+ *   </para>
+ * </constraintdef>
+ * <constraintdef id="ArgCount">
+ *   <para>ArgCount is <code>\d+</code></para>
+ * </constraintdef>
+ * <constraintdef id="RefType">
+ *   <para>RefType is <code>&amp;|&lt;|&gt;</code></para>
+ * </constraintdef>
+ * <constraintdef id="EOL">
+ *   <para>EOL is end of input</para>
+ * </constraintdef>
+ *
  * Returns: A string which encodes the prototype of the specified Glk function.
  */
 
  */
 
 /**
- * giblorb_method_DontLoad:
+ * giblorb_method_FilePos:
  *
  * Pass this to giblorb_load_chunk_by_type(), giblorb_load_chunk_by_number(), or
  * giblorb_load_resource() to get the position in the Blorb file at which the
  * Resource usage constant representing an image file.
  */
 
+/**
+ * giblorb_ID_Data:
+ *
+ * Resource usage constant representing a data file.
+ */
+
 /**
  * giblorb_ID_Copyright:
  *
  * Resource usage constant representing any textual annotation that the user or 
  * writing program sees fit to include.
  */ 
+
+/**
+ * giblorb_ID_TEXT:
+ *
+ * Resource usage constant representing a text data file.
+ */
+
+/**
+ * giblorb_ID_BINA:
+ *
+ * Resource usage constant representing a binary data file.
+ */
+
 /**
  * giblorb_map_t:
  *
  
 /**
  * giblorb_result_t:
+ * @chunknum: The chunk number (for use in giblorb_unload_chunk(), etc.)
+ * @length: The length of the data
+ * @chunktype: The type of the chunk.
  *
  * Holds information about a chunk loaded from a Blorb file, and the method of
- * accessing the chunk data. See giblorb_load_chunk_by_type() and
+ * accessing the chunk data. @data is a union of @ptr, a pointer to the data (if
+ * you used %giblorb_method_Memory) and @startpos, the position in the file (if
+ * you used %giblorb_method_FilePos). See giblorb_load_chunk_by_type() and
  * giblorb_load_chunk_by_number(). 
  */
  
 
 /**
  * glkunix_argumentlist_t:
- * 
- * In each entry, name is the option as it would appear on the command line
- * (including the leading dash, if any.) The desc is a description of the
- * argument; this is used when the library is printing a list of options. And
- * argtype is one of the following constants:
+ * @name: the option as it would appear on the command line (including the 
+ * leading dash, if any.) 
+ * @desc: a description of the argument; this is used when the library is 
+ * printing a list of options.
+ * @argtype: one of the <code>glkunix_arg_</code> constants.
  * 
  * <variablelist>
  * <varlistentry>
  * If you don't care about command-line arguments, you must still define an
  * empty arguments list, as follows:
  * |[
- * #glkunix_argumentlist_t glkunix_arguments[] = {
- *  { NULL, #glkunix_arg_End, NULL }
+ * glkunix_argumentlist_t glkunix_arguments[] = {
+ *     { NULL, glkunix_arg_End, NULL }
  * };
  * ]|
  * 
  * Here is a more complete sample list:
  * |[
- * #glkunix_argumentlist_t glkunix_arguments[] = {
- *  { "", #glkunix_arg_ValueFollows, "filename: The game file to load." },
- *  { "-hum", #glkunix_arg_ValueFollows, "-hum NUM: Hum some NUM." },
- *  { "-bom", #glkunix_arg_ValueCanFollow, "-bom [ NUM ]: Do a bom (on
- *   the NUM, if given)." },
- *  { "-goo", #glkunix_arg_NoValue, "-goo: Find goo." },
- *  { "-wob", #glkunix_arg_NumberValue, "-wob NUM: Wob NUM times." },
- *  { NULL, #glkunix_arg_End, NULL }
+ * glkunix_argumentlist_t glkunix_arguments[] = {
+ *     { "", glkunix_arg_ValueFollows, "filename: The game file to load." },
+ *     { "-hum", glkunix_arg_ValueFollows, "-hum NUM: Hum some NUM." },
+ *     { "-bom", glkunix_arg_ValueCanFollow, "-bom [ NUM ]: Do a bom (on
+ *       the NUM, if given)." },
+ *     { "-goo", glkunix_arg_NoValue, "-goo: Find goo." },
+ *     { "-wob", glkunix_arg_NumberValue, "-wob NUM: Wob NUM times." },
+ *     { NULL, glkunix_arg_End, NULL }
  * };
  * ]|
  * This would match the arguments <quote><code>thingfile -goo -wob8 -bom -hum 
  * After the library parses the command line, it does various occult rituals of
  * initialization, and then calls glkunix_startup_code().
  *
- * |[ int glkunix_startup_code(#glkunix_startup_t *data); ]|
+ * |[ int glkunix_startup_code(glkunix_startup_t *data); ]|
  *
  * This should return %TRUE if everything initializes properly. If it returns
  * %FALSE, the library will shut down without ever calling your glk_main() 
 
 /**
  * glkunix_startup_t: 
+ * @argc: The number of arguments in @argv.
+ * @argv: Strings representing command line arguments.
  * 
  * The fields are a standard Unix <code>(argc, argv)</code> list, which contain
  * the arguments you requested from the command line. In deference to custom,