## Process this file with automake to produce Makefile.in
## Created by Anjuta
-SUBDIRS = src po
+SUBDIRS = src po docs
chimaradocdir = ${prefix}/doc/chimara
chimaradoc_DATA = \
done
DISTCLEANFILES = intltool-extract intltool-merge intltool-update
+
+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
### GTK-DOC #########################################################
# Run before autotools
echo "Setting up Gtk-Doc"
-gtkdocize || exit 1
+gtkdocize --flavour no-tmpl || exit 1
### AUTOTOOLS #######################################################
# Runs autoconf, autoheader, aclocal, automake, autopoint, libtoolize
AC_CONFIG_FILES([
Makefile
src/Makefile
+docs/Makefile
+docs/reference/Makefile
+docs/reference/version.xml
po/Makefile.in
])
# Do it
--- /dev/null
+Makefile
+Makefile.in
+
--- /dev/null
+SUBDIRS=reference
--- /dev/null
+.libs
+Makefile
+Makefile.in
+html
+xml
+*.stamp
+version.xml
+chimara.args
+chimara.hierarchy
+chimara.interfaces
+chimara.signals
+chimara.prerequisites
+chimara-decl.txt
+chimara-decl-list.txt
+chimara-overrides.txt
+chimara-undeclared.txt
+chimara-undocumented.txt
+
--- /dev/null
+### Makefile.am for Gtk-Doc directory #########################################
+# Adapted from examples/Makefile.am in Gtk-Doc distribution
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE = chimara
+
+# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
+# DOC_MODULE_VERSION = 2
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+DOC_SOURCE_DIR = ../../src
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS =
+
+# Extra options to supply to gtkdoc-scan.
+# DO NOT use --rebuild-types, because it will think glk_window_get_type()
+# is a GObject type. That makes it segfault.
+SCAN_OPTIONS =
+
+# Extra options to supply to gtkdoc-mkdb.
+MKDB_OPTIONS = --sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+MKTMPL_OPTIONS =
+
+# Extra options to supply to gtkdoc-mkhtml
+MKHTML_OPTIONS =
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+FIXXREF_OPTIONS =
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+HFILE_GLOB = $(top_srcdir)/src/*.h
+CFILE_GLOB = $(top_srcdir)/src/*.c
+
+# Extra headers to include when scanning, which are not under DOC_SOURCE_DIR
+EXTRA_HFILES =
+
+# Header files to ignore when scanning. Use base file name, no paths
+IGNORE_HFILES = chimara-glk-private.h \
+ abort.h charset.h event.h input.h stream.h window.h \
+ callbacks.h error.h
+
+# Images to copy into HTML directory.
+HTML_IMAGES =
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+content_files = version.xml \
+ glk-front-matter.sgml \
+ glk-introduction.sgml \
+ glk-main-function.sgml \
+ glk-api-conventions.sgml \
+ glk-character-encoding.sgml \
+ glk-output.sgml \
+ glk-line-input.sgml \
+ glk-windows.sgml \
+ glk-window-arrangement.sgml \
+ glk-display-style.sgml \
+ glk-other-events.sgml
+
+# SGML files where gtk-doc abbreviations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+expand_content_files = \
+ glk-main-function.sgml \
+ glk-api-conventions.sgml \
+ glk-output.sgml \
+ glk-line-input.sgml \
+ glk-window-arrangement.sgml \
+ glk-display-style.sgml \
+ glk-other-events.sgml
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+GTKDOC_CFLAGS = -I$(top_srcdir) $(CHIMARA_CFLAGS)
+GTKDOC_LIBS = $(top_builddir)/src/libchimara.la
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+EXTRA_DIST += version.xml.in
+
+# Files not to distribute
+# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
+# for --rebuild-sections in $(SCAN_OPTIONS), e.g. $(DOC_MODULE)-sections.txt
+# DISTCLEANFILES +=
+
+# Comment this out if you want your docs-status tested during 'make check'
+# TESTS_ENVIRONMENT = cd $(srcsrc)
+# TESTS = $(GTKDOC_CHECK)
+
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Chimara Reference Manual</title>
+ <releaseinfo>
+ for Chimara &version;. The latest version of this documentation can be
+ found on-line at <ulink role="online-location"
+ url="http://[SERVER]/chimara/index.html">http://[SERVER]/chimara/</ulink>.
+ </releaseinfo>
+ </bookinfo>
+
+ <reference>
+ <title>Chimara API Reference</title>
+ <xi:include href="xml/chimara-glk.xml"/>
+ </reference>
+
+ <reference>
+ <title>Glk API Specification, version 0.7.0</title>
+ <xi:include href="glk-front-matter.sgml"/>
+
+ <!-- Chapter 0. Introduction -->
+ <xi:include href="glk-introduction.sgml"/>
+
+ <!-- Chapter 1. Overall Structure -->
+ <chapter>
+ <title>Overall Structure</title>
+ <!-- For Gtk-Doc post-processed SGML files, look in the xml directory-->
+ <xi:include href="xml/glk-main-function.sgml"/>
+ <xi:include href="xml/glk-exiting.xml"/>
+ <xi:include href="xml/glk-interrupt.xml"/>
+ <xi:include href="xml/glk-tick.xml"/>
+ <xi:include href="xml/glk-types.xml"/>
+ <xi:include href="xml/glk-opaque-objects.xml"/>
+ <xi:include href="xml/glk-gestalt.xml"/>
+ <xi:include href="xml/glk-api-conventions.sgml"/>
+ </chapter>
+
+ <!-- Chapter 2. Character Encoding -->
+ <chapter>
+ <title>Character Encoding</title>
+ <xi:include href="glk-character-encoding.sgml"/>
+ <xi:include href="xml/glk-output.sgml"/>
+ <xi:include href="xml/glk-line-input.sgml"/>
+ <xi:include href="xml/glk-character-input.xml"/>
+ <xi:include href="xml/glk-case.xml"/>
+ </chapter>
+
+ <!-- Chapter 3. Windows -->
+ <chapter>
+ <title>Windows</title>
+ <xi:include href="glk-windows.sgml"/>
+ <xi:include href="xml/glk-window-arrangement.sgml"/>
+ <xi:include href="xml/glk-window-opening.xml"/>
+ <xi:include href="xml/glk-window-constraints.xml"/>
+ <xi:include href="xml/glk-display-style.sgml"/>
+ <xi:include href="xml/glk-window-types.xml"/>
+ <xi:include href="xml/glk-echo-streams.xml"/>
+ <xi:include href="xml/glk-window-other.xml"/>
+ </chapter>
+
+ <!-- Chapter 4. Events -->
+ <chapter>
+ <title>Events</title>
+ <xi:include href="xml/glk-events.xml"/>
+ <xi:include href="xml/glk-character-input-events.xml"/>
+ <xi:include href="xml/glk-line-input-events.xml"/>
+ <!--<xi:include href="xml/glk-mouse-events.xml"/>
+ <xi:include href="xml/glk-timer-events.xml"/>
+ <xi:include href="xml/glk-arrangement-events.sgml"/>
+ <xi:include href="xml/glk-redraw-events.sgml"/>
+ <xi:include href="xml/glk-sound-notify-events.sgml"/>
+ <xi:include href="xml/glk-hyperlink-events.sgml"/>-->
+ <xi:include href="xml/glk-other-events.sgml"/>
+ </chapter>
+
+ <!-- Chapter 5. Streams -->
+ <chapter>
+ <title>Streams</title>
+ <xi:include href="xml/glk-streams.xml"/>
+ <xi:include href="xml/glk-print.xml"/>
+ <xi:include href="xml/glk-read.xml"/>
+ <xi:include href="xml/glk-closing-streams.xml"/>
+ <xi:include href="xml/glk-stream-positions.xml"/>
+ <!--<xi:include href="xml/glk-styles.xml"/>-->
+ <xi:include href="xml/glk-stream-types.xml"/>
+ <xi:include href="xml/glk-stream-other.xml"/>
+ </chapter>
+
+ <!-- Chapter 6. File References -->
+ <chapter>
+ <title>File References</title>
+ <xi:include href="xml/glk-fileref.xml"/>
+ <xi:include href="xml/glk-fileref-types.xml"/>
+ <xi:include href="xml/glk-fileref-other.xml"/>
+ </chapter>
+
+ <!-- Chapter 7. Graphics -->
+<!-- <chapter>
+ <title>Graphics</title>
+ <xi:include href="xml/glk-image-resources.xml"/>
+ <xi:include href="xml/glk-graphics-windows.xml"/>
+ <xi:include href="xml/glk-graphics-text.xml"/>
+ <xi:include href="xml/glk-graphics-testing.xml"/>
+ </chapter>
+-->
+ <!-- Chapter 8. Sound -->
+<!-- <chapter>
+ <title>Sound</title>
+ <xi:include href="xml/glk-sound-channels.xml"/>
+ <xi:include href="xml/glk-playing-sounds.xml"/>
+ <xi:include href="xml/glk-sound-other.xml"/>
+ <xi:include href="xml/glk-sound-testing.xml"/>
+ </chapter>
+-->
+ <!-- Chapter 9. Hyperlinks -->
+<!-- <chapter>
+ <title>Hyperlinks</title>
+ <xi:include href="xml/glk-creating-hyperlinks.xml"/>
+ <xi:include href="xml/glk-accepting-hyperlinks.xml"/>
+ <xi:include href="xml/glk-hyperlinks-testing.xml"/>
+ </chapter>
+-->
+ <!-- Chapter 10. Porting, Adapting and Other Messy Bits -->
+<!-- <chapter>
+ <title>Porting, Adapting, and Other Messy Bits</title>
+ </chapter>
+-->
+ <!-- Chapter 11. Appendices -->
+<!-- <appendix>
+ <title>The Dispatch Layer</title>
+ </appendix>
+
+ <appendix>
+ <title>The Blorb Layer</title>
+ </appendix>
+-->
+ </reference>
+</book>
--- /dev/null
+<SECTION>
+<FILE>chimara-glk</FILE>
+<TITLE>ChimaraGlk</TITLE>
+ChimaraGlk
+chimara_glk_new
+chimara_glk_set_interactive
+chimara_glk_get_interactive
+chimara_glk_set_protect
+chimara_glk_get_protect
+chimara_glk_run
+chimara_glk_stop
+chimara_glk_wait
+<SUBSECTION Standard>
+ChimaraGlkClass
+CHIMARA_GLK
+CHIMARA_IS_GLK
+CHIMARA_TYPE_GLK
+chimara_glk_get_type
+CHIMARA_GLK_CLASS
+CHIMARA_IS_GLK_CLASS
+CHIMARA_GLK_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>glk-exiting</FILE>
+<TITLE>Exiting Your Program</TITLE>
+glk_exit
+<SUBSECTION Private>
+glk_main
+</SECTION>
+
+<SECTION>
+<FILE>glk-interrupt</FILE>
+<TITLE>The Interrupt Handler</TITLE>
+glk_set_interrupt_handler
+</SECTION>
+
+<SECTION>
+<FILE>glk-tick</FILE>
+<TITLE>The Tick Thing</TITLE>
+glk_tick
+</SECTION>
+
+<SECTION>
+<FILE>glk-types</FILE>
+<TITLE>Basic Types</TITLE>
+glui32
+glsi32
+</SECTION>
+
+<SECTION>
+<FILE>glk-opaque-objects</FILE>
+<TITLE>Opaque Objects</TITLE>
+winid_t
+strid_t
+frefid_t
+schanid_t
+</SECTION>
+
+<SECTION>
+<FILE>glk-gestalt</FILE>
+<TITLE>The Gestalt System</TITLE>
+glk_gestalt_ext
+glk_gestalt
+<SUBSECTION The Version Number>
+gestalt_Version
+<SUBSECTION Testing for Unicode Capabilities>
+gestalt_Unicode
+GLK_MODULE_UNICODE
+<SUBSECTION Output>
+gestalt_CharOutput
+gestalt_CharOutput_CannotPrint
+gestalt_CharOutput_ApproxPrint
+gestalt_CharOutput_ExactPrint
+<SUBSECTION Line Input>
+gestalt_LineInput
+<SUBSECTION Character Input>
+gestalt_CharInput
+<SUBSECTION Constants>
+gestalt_MouseInput
+gestalt_Timer
+gestalt_Graphics
+gestalt_DrawImage
+gestalt_Sound
+gestalt_SoundVolume
+gestalt_SoundNotify
+gestalt_Hyperlinks
+gestalt_HyperlinkInput
+gestalt_SoundMusic
+gestalt_GraphicsTransparency
+</SECTION>
+
+<SECTION>
+<FILE>glk-character-input</FILE>
+<TITLE>Character Input</TITLE>
+keycode_Unknown
+keycode_Left
+keycode_Right
+keycode_Up
+keycode_Down
+keycode_Return
+keycode_Delete
+keycode_Escape
+keycode_Tab
+keycode_PageUp
+keycode_PageDown
+keycode_Home
+keycode_End
+keycode_Func1
+keycode_Func2
+keycode_Func3
+keycode_Func4
+keycode_Func5
+keycode_Func6
+keycode_Func7
+keycode_Func8
+keycode_Func9
+keycode_Func10
+keycode_Func11
+keycode_Func12
+keycode_MAXVAL
+</SECTION>
+
+<SECTION>
+<FILE>glk-case</FILE>
+<TITLE>Upper and Lower Case</TITLE>
+glk_char_to_lower
+glk_char_to_upper
+glk_buffer_to_lower_case_uni
+glk_buffer_to_upper_case_uni
+glk_buffer_to_title_case_uni
+</SECTION>
+
+<SECTION>
+<FILE>glk-window-opening</FILE>
+<TITLE>Window Opening, Closing, and Constraints</TITLE>
+glk_window_open
+winmethod_Left
+winmethod_Right
+winmethod_Above
+winmethod_Below
+winmethod_DirMask
+winmethod_Fixed
+winmethod_Proportional
+winmethod_DivisionMask
+glk_window_close
+</SECTION>
+
+<SECTION>
+<FILE>glk-window-constraints</FILE>
+<TITLE>Changing Window Constraints</TITLE>
+glk_window_get_size
+glk_window_set_arrangement
+glk_window_get_arrangement
+</SECTION>
+
+<SECTION>
+<FILE>glk-window-types</FILE>
+<TITLE>The Types of Windows</TITLE>
+wintype_Blank
+wintype_Pair
+wintype_TextBuffer
+wintype_TextGrid
+glk_window_move_cursor
+wintype_Graphics
+wintype_AllTypes
+</SECTION>
+
+<SECTION>
+<FILE>glk-echo-streams</FILE>
+<TITLE>Echo Streams</TITLE>
+glk_window_set_echo_stream
+glk_window_get_echo_stream
+</SECTION>
+
+<SECTION>
+<FILE>glk-window-other</FILE>
+<TITLE>Other Window Functions</TITLE>
+glk_window_iterate
+glk_window_get_rock
+glk_window_get_type
+glk_window_get_parent
+glk_window_get_sibling
+glk_window_get_root
+glk_window_clear
+glk_window_get_stream
+glk_set_window
+</SECTION>
+
+<SECTION>
+<FILE>glk-events</FILE>
+<TITLE>Events</TITLE>
+glk_select
+event_t
+glk_select_poll
+<SUBSECTION Constants>
+evtype_None
+evtype_Timer
+evtype_CharInput
+evtype_LineInput
+evtype_MouseInput
+evtype_Arrange
+evtype_Redraw
+evtype_SoundNotify
+evtype_Hyperlink
+</SECTION>
+
+<SECTION>
+<FILE>glk-character-input-events</FILE>
+<TITLE>Character Input Events</TITLE>
+glk_request_char_event
+glk_request_char_event_uni
+glk_cancel_char_event
+</SECTION>
+
+<SECTION>
+<FILE>glk-line-input-events</FILE>
+<TITLE>Line Input Events</TITLE>
+glk_request_line_event
+glk_request_line_event_uni
+glk_cancel_line_event
+</SECTION>
+
+<SECTION>
+<FILE>glk-mouse-events</FILE>
+<TITLE>Mouse Input Events</TITLE>
+glk_request_mouse_event
+glk_cancel_mouse_event
+</SECTION>
+
+<SECTION>
+<FILE>glk-timer-events</FILE>
+<TITLE>Timer Events</TITLE>
+glk_request_timer_events
+</SECTION>
+
+<SECTION>
+<FILE>glk-streams</FILE>
+<TITLE>Streams</TITLE>
+glk_stream_set_current
+glk_stream_get_current
+<SUBSECTION Constants>
+filemode_Write
+filemode_Read
+filemode_ReadWrite
+filemode_WriteAppend
+</SECTION>
+
+<SECTION>
+<FILE>glk-print</FILE>
+<TITLE>How to Print</TITLE>
+glk_put_char
+glk_put_string
+glk_put_buffer
+glk_put_char_stream
+glk_put_string_stream
+glk_put_buffer_stream
+glk_put_char_uni
+glk_put_string_uni
+glk_put_buffer_uni
+glk_put_char_stream_uni
+glk_put_string_stream_uni
+glk_put_buffer_stream_uni
+</SECTION>
+
+<SECTION>
+<FILE>glk-read</FILE>
+<TITLE>How to Read</TITLE>
+glk_get_char_stream
+glk_get_buffer_stream
+glk_get_line_stream
+glk_get_char_stream_uni
+glk_get_buffer_stream_uni
+glk_get_line_stream_uni
+</SECTION>
+
+<SECTION>
+<FILE>glk-closing-streams</FILE>
+<TITLE>Closing Streams</TITLE>
+glk_stream_close
+stream_result_t
+</SECTION>
+
+<SECTION>
+<FILE>glk-stream-positions</FILE>
+<TITLE>Stream Positions</TITLE>
+glk_stream_set_position
+glk_stream_get_position
+<SUBSECTION Constants>
+seekmode_Start
+seekmode_Current
+seekmode_End
+</SECTION>
+
+<SECTION>
+<FILE>glk-styles</FILE>
+<TITLE>Styles</TITLE>
+glk_set_style
+glk_set_style_stream
+<SUBSECTION Suggesting the Appearance of Styles>
+glk_stylehint_set
+glk_stylehint_clear
+<SUBSECTION Testing the Appearance of Styles>
+glk_style_distinguish
+glk_style_measure
+<SUBSECTION Constants>
+style_Normal
+style_Emphasized
+style_Preformatted
+style_Header
+style_Subheader
+style_Alert
+style_Note
+style_BlockQuote
+style_Input
+style_User1
+style_User2
+style_NUMSTYLES
+stylehint_Indentation
+stylehint_ParaIndentation
+stylehint_Justification
+stylehint_Size
+stylehint_Weight
+stylehint_Oblique
+stylehint_Proportional
+stylehint_TextColor
+stylehint_BackColor
+stylehint_ReverseColor
+stylehint_NUMHINTS
+stylehint_just_LeftFlush
+stylehint_just_LeftRight
+stylehint_just_Centered
+stylehint_just_RightFlush
+</SECTION>
+
+<SECTION>
+<FILE>glk-stream-types</FILE>
+<TITLE>The Types of Streams</TITLE>
+glk_stream_open_memory
+glk_stream_open_memory_uni
+glk_stream_open_file
+glk_stream_open_file_uni
+</SECTION>
+
+<SECTION>
+<FILE>glk-stream-other</FILE>
+<TITLE>Other Stream Functions</TITLE>
+glk_stream_iterate
+glk_stream_get_rock
+</SECTION>
+
+<SECTION>
+<FILE>glk-fileref</FILE>
+<TITLE>File References</TITLE>
+fileusage_Data
+fileusage_SavedGame
+fileusage_Transcript
+fileusage_InputRecord
+fileusage_TypeMask
+fileusage_TextMode
+fileusage_BinaryMode
+</SECTION>
+
+<SECTION>
+<FILE>glk-fileref-types</FILE>
+<TITLE>The Types of File References</TITLE>
+glk_fileref_create_temp
+glk_fileref_create_by_prompt
+glk_fileref_create_by_name
+glk_fileref_create_from_fileref
+</SECTION>
+
+<SECTION>
+<FILE>glk-fileref-other</FILE>
+<TITLE>Other File Reference Functions</TITLE>
+glk_fileref_destroy
+glk_fileref_iterate
+glk_fileref_get_rock
+glk_fileref_delete_file
+glk_fileref_does_file_exist
+</SECTION>
+
+<SECTION>
+<FILE>glk-image-resources</FILE>
+<TITLE>Image Resources</TITLE>
+glk_image_get_info
+glk_image_draw
+glk_image_draw_scaled
+</SECTION>
+
+<SECTION>
+<FILE>glk-graphics-windows</FILE>
+<TITLE>Graphics in Graphics Windows</TITLE>
+glk_window_set_background_color
+glk_window_fill_rect
+glk_window_erase_rect
+</SECTION>
+
+<SECTION>
+<FILE>glk-graphics-text</FILE>
+<TITLE>Graphics in Text Buffer Windows</TITLE>
+glk_window_flow_break
+<SUBSECTION Constants>
+imagealign_InlineUp
+imagealign_InlineDown
+imagealign_InlineCenter
+imagealign_MarginLeft
+imagealign_MarginRight
+</SECTION>
+
+<SECTION>
+<FILE>glk-graphics-testing</FILE>
+<TITLE>Testing for Graphics Capabilities</TITLE>
+GLK_MODULE_IMAGE
+</SECTION>
+
+<SECTION>
+<FILE>glk-sound-channels</FILE>
+<TITLE>Creating and Destroying Sound Channels</TITLE>
+glk_schannel_create
+glk_schannel_destroy
+</SECTION>
+
+<SECTION>
+<FILE>glk-playing-sounds</FILE>
+<TITLE>Playing Sounds</TITLE>
+glk_schannel_play
+glk_schannel_play_ext
+glk_schannel_stop
+glk_schannel_set_volume
+glk_sound_load_hint
+</SECTION>
+
+<SECTION>
+<FILE>glk-sound-other</FILE>
+<TITLE>Other Sound Channel Functions</TITLE>
+glk_schannel_iterate
+glk_schannel_get_rock
+</SECTION>
+
+<SECTION>
+<FILE>glk-sound-testing</FILE>
+<TITLE>Testing for Sound Capabilities</TITLE>
+GLK_MODULE_SOUND
+</SECTION>
+
+<SECTION>
+<FILE>glk-creating-hyperlinks</FILE>
+<TITLE>Creating Hyperlinks</TITLE>
+glk_set_hyperlink
+glk_set_hyperlink_stream
+</SECTION>
+
+<SECTION>
+<FILE>glk-accepting-hyperlinks</FILE>
+<TITLE>Accepting Hyperlink Events</TITLE>
+glk_request_hyperlink_event
+glk_cancel_hyperlink_event
+</SECTION>
+
+<SECTION>
+<FILE>glk-hyperlinks-testing</FILE>
+<TITLE>Testing for Hyperlink Capabilities</TITLE>
+GLK_MODULE_HYPERLINKS
+</SECTION>
+
--- /dev/null
+chimara_glk_get_type
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<refentry id="chimara-Other-API-Conventions">
+<refmeta>
+<refentrytitle>Other API Conventions</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Other API Conventions</refname>
+<refpurpose>General information about the Glk API</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+The <filename class="headerfile">glk.h</filename> header file is the same on all platforms, with the sole exception of the typedef of #glui32 and #glsi32. These will always be defined as 32-bit unsigned and signed integer types, which may be <quote><type>long</type></quote> or <quote><type>int</type></quote> or some other C definition.
+</para>
+<para>
+Note that all constants are #defines, and all functions are actual function declarations (as opposed to macros.)
+</para>
+<note><para>
+There are a few places where macros would be more efficient — glk_gestalt() and glk_gestalt_ext(), for example — but they are not likely to be CPU bottlenecks, and clarity seems more important.
+</para></note>
+<para>
+%FALSE is 0; %TRUE is 1. %NULL is also 0.
+</para>
+<para>
+As stated above, it is illegal to pass %NULL to a function which is expecting a valid object reference, unless the function definition says otherwise.
+</para>
+<para>
+Some functions have pointer arguments, acting as <quote>variable</quote> or <quote>reference</quote> arguments; the function's intent is to return some value in the space pointed to by the argument. Unless the function says otherwise, it is legal to pass a %NULL pointer to indicate that you do not care about that value.
+</para>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<refentry id="chimara-Character-Encoding">
+<refmeta>
+<refentrytitle>Character Encoding</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Character Encoding</refname>
+<refpurpose>Latin-1 and Unicode characters</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+Glk has two separate, but parallel, APIs for managing text input and output. The basic functions deal entirely in 8-bit characters; their arguments are arrays of bytes (octets). These functions all assume the Latin-1 character encoding. Equivalently, they may be said to use code points U+00..U+FF of <ulink url="http://unicode.org">Unicode</ulink>.
+</para>
+<para>
+Latin-1 is an 8-bit character encoding; it maps numeric codes in the range 0 to 255 into printed characters. The values from 32 to 126 are the standard printable ASCII characters (<code>' '</code> to <code>'~'</code>). Values 0 to 31 and 127 to 159 are reserved for control characters, and have no printed equivalent.
+</para>
+<note><para>
+Note that the basic Glk text API does not use UTF-8, or any other Unicode character form. Each character is represented by a single byte — even characters in the 128..255 range.
+</para></note>
+<para>
+The extended, or <quote>Unicode</quote>, Glk functions deal entirely in 32-bit words. They take arrays of words, not bytes, as arguments. They can therefore cope with any Unicode code point. The extended functions have names ending in <quote><code>_uni</code></quote>.
+</para>
+<note><para>
+Since these functions deal in arrays of 32-bit words, they can be said to use the UTF-32 character encoding form. (But <emphasis>not</emphasis> the UTF-32 character encoding <emphasis>scheme</emphasis> — that's a stream of bytes which must be interpreted in big-endian or little-endian mode. Glk Unicode functions operate on long integers, not bytes.) UTF-32 is also known as UCS-4, according to the Unicode spec (appendix C.2), modulo some semantic requirements which we will not deal with here. For practical purposes, we can ignore the whole encoding issue, and assume that we are dealing with sequences of numeric code points.
+</para></note>
+<note><para>
+Why not UTF-8? It is a reasonable bare-bones compression algorithm for Unicode character streams; but IF systems typically have their own compression models for text. Compositing the two ideas causes more problems than it solves. The other advantage of UTF-8 is that 7-bit ASCII is automatically valid UTF-8; but this is not compelling for IF systems, in which the compiler can be tasked with generating consistent textual data. And UTF-8 is a variable-width encoding. Nobody ever wept at the prospect of avoiding that kettle of eels.
+</para></note>
+<note>
+<para>
+What about bi-directional text? It's a good idea, and may show up in future versions of this document. It is not in this version because we want to get something simple implemented soon. For the moment, print out all text in reading order (not necessarily left-to-right) and hope for the best. Current suggestions include a <code>stylehint_Direction</code>, which the game can set to indicate that text in the given style should be laid out right-to-left. Top-to-bottom (or bottom-to-top) may be desirable too. The direction stylehints might only apply to full paragraphs (like justification stylehints); or they might apply to any text, thus requiring the library to lay out <quote>zig-zag</quote> blocks. The possibilities remain to be explored. Page layout is hard.
+</para>
+<para>
+Another possibility is to let the library determine the directionality of text from the character set. This is not impossible — MacOSX text widgets do it. It may be too difficult.
+</para>
+<para>
+In the meantime, it is worth noting that the Windows Glk library does not autodetect directionality, but the CheapGlk library running on MacOSX does. Therefore, there is no platform-independent way to handle right-to-left fonts at present.
+</para>
+</note>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<refentry id="chimara-A-Note-on-Display-Style">
+<refmeta>
+<refentrytitle>A Note on Display Style</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>A Note on Display Style</refname>
+<refpurpose>How windows may be displayed on different platforms</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+The way windows are displayed is, of course, entirely up to the Glk library; it depends on what is natural for the player's machine. The borders between windows may be black lines, 3-D bars, rows of <quote><computeroutput>#</computeroutput></quote> characters; there may even be no borders at all.
+</para>
+<note><para>
+This is an important possibility to keep in mind.
+</para></note>
+<para>
+There may be other decorations as well. A text buffer window will often have a scroll bar. The library (or player) may prefer wide margins around each text window. And so on.
+</para>
+<para>
+The library is reponsible for handling these decorations, margins, spaces, and borders. You should never worry about them. You are guaranteed that if you request a fixed size of two rows, your text grid window will have room for two rows of characters — if there is enough total space. Any margins or borders will be allowed for already. If there <emphasis>isn't</emphasis> enough total space (as in stages 4 and 5 of <link linkend="chimara-Figure-Squeezing-Window">this figure</link>), you lose, of course.
+</para>
+<para>
+How do you know when you're losing? You can call glk_window_get_size() to determine the window size you really got. Obviously, you should draw into your windows based on their real size, not the size you requested. If there's enough space, the requested size and the real size will be identical; but you should not rely on this. Call glk_window_get_size() and check.
+</para>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<referenceinfo>
+<title>Glk API Specification</title>
+<subtitle>API version 0.7.0</subtitle>
+<author>
+ <personname>
+ <firstname>Andrew</firstname>
+ <surname>Plotkin</surname>
+ </personname>
+ <email>erkyrath@eblong.com</email>
+</author>
+<copyright>
+ <year>1998–2004</year>
+ <holder>Andrew Plotkin</holder>
+</copyright>
+<legalnotice>
+You have permission to display, download, and print this document, provided that you do so for personal, non-commercial use only. You may not modify or distribute this document without the author's written permission.
+</legalnotice>
+<releaseinfo>
+The authors of the Chimara library have adapted this document to better fit the format of a GtkDoc reference manual. They have also added notes specific to Chimara's implementation of the Glk API. The original API specification and further Glk information can be found at: <ulink url="http://www.eblong.com/zarf/glk/">http://www.eblong.com/zarf/glk/</ulink>
+</releaseinfo>
+</referenceinfo>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<chapter id="chimara-Introduction"><title>Introduction</title>
+<sect1 id="chimara-What-Glk-Is"><title>What Glk Is</title>
+<para>
+Glk is an attempt to define a portable API (programming interface) for applications with text UIs (user interfaces.)
+</para>
+<para>
+Rather than go into a detailed explanation of what that means, let me give examples from the world of text adventures. TADS and Infocom's Z-machine have nearly identical interface capabilities; each allows a program to...
+<itemizedlist>
+ <listitem><para>print an indefinite stream of text into an output buffer, with some style control</para></listitem>
+ <listitem><para>input a line of text</para></listitem>
+ <listitem><para>display a few lines of text in a small separate window</para></listitem>
+ <listitem><para>store information in a file, or read it in</para></listitem>
+</itemizedlist>
+and so on. However, the implementation of these capabilities vary widely between platforms and operating systems. Furthermore, this variance is transparent to the program (the adventure game.) The game does not care whether output is displayed via a character terminal emulator or a GUI window; nor whether input uses Mac-style mouse editing or EMACS-style control key editing.
+</para>
+<para>
+On the third hand, the user is likely to care deeply about these interface decisions. This is why there are Mac-native interpreters on Macintoshes, pen-controlled interpreters on Newtons and PalmOS PDAs, and so on — and (ultimately) why there Macintoshes and Palms and X-windows platforms in the first place.
+</para>
+<para>
+On the <emphasis>fourth</emphasis> hand, TADS and Inform are not alone; there is historically a large number of text adventure systems. Most are obsolete or effectively dead; but it is inevitable that more will appear. Users want each living system ported to all the platforms in use. Users also prefer these ports to use the same interface, as much as possible.
+</para>
+<para>
+This all adds up to a pain in the ass.
+</para>
+<para>
+Glk tries to draw a line between the parts of the text adventure world which are identical on all IF systems, and different on different operating systems, from the parts which are unique to each IF system but identical in all OSs. The border between these two worlds is the Glk API.
+</para>
+<para>
+My hope is that a new IF system, or existing ones which are less-supported (Hugo, AGT, etc) can be written using Glk for all input and output function. The IF system would then be in <emphasis>truly</emphasis> portable C. On the other side of the line, there would be a Glk library for each operating system and interface (Macintosh, X-windows, curses-terminal, etc.) Porting the IF system to every platform would be trivial; compile the system, and link in the library.
+</para>
+<para>
+Glk can also serve as a nice interface for applications other than games — data manglers, quick hacks, or anything else which would normally lack niceties such as editable input, macros, scrolling, or whatever is native to your machine's interface idiom.
+</para>
+</sect1>
+<sect1 id="chimara-What-About-the-Virtual-Machine"><title>What About the Virtual Machine?</title>
+<para>
+You can think of Glk as an IF virtual machine, without the virtual machine part. The <quote>machine</quote> is just portable C code.
+</para>
+<para>
+An IF virtual machine has been designed specifically to go along with Glk. This VM, called Glulx, uses Glk as its interface; each Glk call corresponds to an input/output opcode of the VM.
+</para>
+<para>
+For more discussion of this approach, see <link linkend="chimara-Glk-and-the-Virtual-Machine">Glk and the Virtual Machine</link>. Glulx is documented at <ulink url="http://www.eblong.com/zarf/glulx/">http://www.eblong.com/zarf/glulx</ulink>.
+</para>
+<para>
+Of course, Glk can be used with other IF systems. The advantage of Glulx is that it provides the game author with direct and complete access to the Glk API. Other IF systems typically have an built-in abstract I/O API, which maps only partially onto Glk. For these systems, Glk tends to be a least-common-denominator interface: highly portable, but not necessarily featureful. (Even if Glk has a feature, it may not be available through the layers of abstraction.)
+</para>
+</sect1>
+<sect1 id="chimara-What-Does-Glk-Not-Do"><title>What Does Glk Not Do?</title>
+<para>
+Glk does not handle the things which should be handled by the program (or the IF system, or the virtual machine) which is linked to Glk. This means that Glk does not address
+<itemizedlist>
+ <listitem><para>parsing</para></listitem>
+ <listitem><para>game object storage</para></listitem>
+ <listitem><para>computation</para></listitem>
+ <listitem><para>text compression</para></listitem>
+</itemizedlist>
+</para>
+</sect1>
+<sect1 id="chimara-Conventions-of-This-Document"><title>Conventions of This Document</title>
+<para>
+This document defines the Glk API. I have tried to specify exactly what everything does, what is legal, what is illegal, and why.
+</para>
+<note><para>
+Sections labeled like this are notes. They do not define anything; they clarify or explain what has already been defined. If there seems to be a conflict, ignore the note and follow the definition.
+</para></note>
+<note><title>WORK</title>
+<para>
+Notes with the label <quote>WORK</quote> are things which I have not yet fully resolved. Your comments requested and welcome.
+</para></note>
+<note><title>Chimara</title>
+<para>
+Notes labeled <quote>Chimara</quote> are specific to Chimara's implementation of the Glk API and are not part of the original Glk API specification.
+</para></note>
+<para>
+This document is written for the point of view of the game programmer — the person who wants to use the Glk library to print text, input text, and so on. By saying what the Glk library does, of course, this document also defines the task of the Glk programmer — the person who wants to port the Glk library to a new platform or operating system. If the Glk library guarantees something, the game programmer can rely on it, and the Glk programmer is required to support it. Contrariwise, if the library does not guarantee something, the Glk programmer may handle it however he likes, and the game programmer must not rely on it. If something is illegal, the game programmer must not do it, and the Glk programmer is not required to worry about it.
+</para>
+<note><para>
+It is preferable, but not required, that the Glk library detect illegal requests and display error messages. The Glk library may simply crash when the game program does something illegal. This is why the game programmer must not do it. Right?
+</para></note>
+<note><title>Chimara</title>
+<para>
+Wherever possible, Chimara checks for anything defined as illegal, and prints a
+warning message to standard error. It tries to recover as gracefully as possible
+so that the program can continue.
+</para></note>
+<para>
+Hereafter, <quote>Glk</quote> or <quote>the library</quote> refers to the Glk library, and <quote>the program</quote> is the game program (or whatever) which is using the Glk library to print text, input text, or whatever. <quote>You</quote> are the person writing the program. <quote>The player</quote> is the person who will use the program/Glk library combination to actually play a game. Or whatever.
+</para>
+<para>
+The Glk API is declared in a C header file called <quote><filename class="headerfile">glk.h</filename></quote>. Please refer to that file when reading this one.
+</para>
+</sect1>
+<sect1 id="chimara-Credits"><title>Credits</title>
+<para>
+Glk has been a work of many years and many people. If I tried to list everyone who has offered comments and suggestions, I would immediately go blank, forget everyone's name, and become a mute hermit-like creature living in a train tunnel under Oakland. But I must thank those people who have written Glk libraries and linking systems: Matt Kimball, Ross Raszewski, David Kinder, John Elliott, Joe Mason, Stark Springs, and, er, anyone I missed. Look! A train!
+</para>
+<para>
+Evin Robertson wrote the original proposal for the Glk Unicode functions, which I imported nearly verbatim into this document. Thank you.
+</para>
+</sect1>
+</chapter>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<refentry id="chimara-Line-Input">
+<refmeta>
+<refentrytitle>Line Input</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Line Input</refname>
+<refpurpose>Reading lines of text</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+You can request that the player enter a line of text. See <link linkend="chimara-Line-Input-Events">Line Input Events</link>.
+</para>
+<para>
+This text will be placed in a buffer of your choice. There is no length field or null terminator in the buffer. (The length of the text is returned as part of the line-input event.)
+</para>
+<para>
+If you use the basic text API, the buffer will contain only printable Latin-1 characters (32 to 126, 160 to 255).
+</para>
+<para>
+A particular implementation of Glk may not be able to accept all Latin-1 printable characters as input. It is guaranteed to be able to accept the ASCII characters (32 to 126.)
+</para>
+<para>
+You can test for this by using the #gestalt_LineInput selector.
+</para>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<refentry id="chimara-Your-Programs-Main-Function">
+<refmeta>
+<refentrytitle>Your Program's Main Function</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Your Program's Main Function</refname>
+<refpurpose>How Glk starts your program</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+The top level of the program — the <function>main()</function> function in C, for example — belongs to Glk.
+</para>
+<note><para>
+This means that Glk isn't really a library. In a sense, you are writing a library, which is linked into Glk. This is bizarre to think about, so forget it.
+</para></note>
+<note><title>Chimara</title>
+<para>
+In Chimara, the arrangement is even more bizarre. Chimara <emphasis>is</emphasis> a library, and it runs your Glk program from within a GTK+ graphical application (the <quote>host program</quote>). Chimara treats your program as a plugin, or shared library, and it executes your program in its own thread, displaying windows and output in the GTK+ program.
+</para>
+<para>
+This makes absolutely no difference to you, the Glk <emphasis>programmer</emphasis>; if your program works correctly with a <quote>regular</quote> Glk library, it will also work properly with Chimara. The only difference is in compiling your Glk program.
+</para></note>
+<para>
+You define a function called glk_main(), which the library calls to begin running your program. glk_main() should run until your program is finished, and then return.
+</para>
+<para>
+Glk does all its user-interface work in a function called glk_select(). This function waits for an event — typically the player's input — and returns an structure representing that event. This means that your program must have an event loop. In the very simplest case, you could write
+</para>
+<informalexample>
+<programlisting>
+void glk_main()
+{
+ #event_t ev;
+ while (1) {
+ #glk_select(&ev);
+ switch (ev.type) {
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+}
+</programlisting>
+</informalexample>
+<para>
+This is a legal Glk-compatible program. As you might expect, it doesn't do anything. The player will see an empty window, which he can only stare at, or destroy in a platform-defined standard manner.
+</para>
+<note><para>
+<keycombo action="simul"><keycap function="command">Command</keycap><keycap>period</keycap></keycombo> on the Macintosh; a <guimenuitem>kill-window</guimenuitem> menu option in an X window manager; <keycombo action="simul"><keycap function="control">control</keycap><keycap>C</keycap></keycombo> in a curses terminal window.
+</para></note>
+<note><title>Chimara</title>
+<para>
+In Chimara, there is no standard way; the program will stop when the host program calls chimara_glk_stop(). The host program might have a <quote>Stop</quote> button which does this, for example, but it will also generally happen when the #ChimaraGlk widget is destroyed or when the host program ends.
+</para></note>
+<note><para>
+However, this program does not spin wildly and burn CPU time. The glk_select() function waits for an event it can return. Since it only returns events which you have requested, it will wait forever, and grant CPU time to other processes if that's meaningful on the player's machine.
+</para></note>
+<note><para>
+Actually, there are some events which are always reported. More may be defined in future versions of the Glk API. This is why the default response to an event is to do nothing. If you don't recognize the event, ignore it.
+</para></note>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<refentry id="chimara-Other-Events">
+<refmeta>
+<refentrytitle>Other Events</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Other Events</refname>
+<refpurpose>Events in future versions of Glk</refpurpose>
+</refnamediv>
+<refsect1>
+<para>
+There are currently no other event types defined by Glk. (The <quote>#evtype_None</quote> constant is a placeholder, and is never returned by glk_select().)
+</para>
+<para>
+It is possible that new event types will be defined in the future.
+</para>
+<note><para>For example, if video or animation capabilities are added to Glk, there would probably be some sort of completion event for them.
+</para></note>
+<note><para>
+This is also why you must put calls to glk_select() in loops. If you tried to read a character by simply writing
+<informalexample><programlisting>
+#glk_request_char_event(win);
+#glk_select(&ev);
+</programlisting></informalexample>
+you might not get a CharInput event back. You could get some not-yet-defined event which happened to occur before the player hit a key. Or, for that matter, a window arrangement event.
+</para></note>
+<note><para>
+It is not generally necessary to put a call to glk_select_poll() in a loop. You usually call glk_select_poll() to update the display or test if an event is available, not to wait for a particular event. However, if you are using sound notification events, and several sounds are playing, it might be important to make sure you knew about all sounds completed at any particular time. You would do this with
+<informalexample><programlisting>
+#glk_select_poll(&ev);
+while (ev.type != #evtype_None) {
+ /* handle event */
+ #glk_select_poll(&ev);
+}
+</programlisting></informalexample>
+</para>
+<para>
+Once glk_select_poll() returns #evtype_None, you should not call it again immediately. Do some work first. If you want to wait for an event, use glk_select(), not a loop of glk_select_poll().
+</para></note>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+]>
+<refentry id="chimara-Output">
+<refmeta>
+<refentrytitle>Output</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Output</refname>
+<refpurpose>Printing basics</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+When you are sending text to a window, or to a file open in text mode, you can print any of the printable Latin-1 characters: 32 to 126, 160 to 255. You can also print the newline character (linefeed, <keycombo action="simul"><keycap function="control">control</keycap><keycap>J</keycap></keycombo>, decimal 10, hex 0x0A.)
+</para>
+<para>
+It is <emphasis>not</emphasis> legal to print any other control characters (0 to 9, 11 to 31, 127 to 159). You may not print even common formatting characters such as tab (<keycombo action="simul"><keycap function="control">control</keycap><keycap>I</keycap></keycombo>), carriage return (<keycombo action="simul"><keycap function="control">control</keycap><keycap>M</keycap></keycombo>), or page break (<keycombo action="simul"><keycap function="control">control</keycap><keycap>L</keycap></keycombo>).
+</para>
+<note><para>
+As usual, the behavior of the library when you print an illegal character is undefined. It is preferable that the library display a numeric code, such as <quote><computeroutput>\177</computeroutput></quote> or <quote><computeroutput>0x7F</computeroutput></quote>, to warn the user that something illegal has occurred. The library may skip illegal characters entirely; but you should not rely on this.
+</para></note>
+<para>
+Printing Unicode characters above 255 is a more complicated matter — too complicated to be covered precisely by this specification. Refer to the Unicode specification, and good luck to you.
+</para>
+<note><para>
+Unicode combining characters are a particular nuisance. Printing a combining character may alter the appearance of the previous character printed. The library should be prepared to cope with this — even if the characters are printed by two separate glk_put_char_uni() calls.
+</para></note>
+<para>
+Note that when you are sending data to a file open in binary mode, you can print any byte value, without restriction. See <link linkend="chimara-File-Streams">File Streams</link>.
+</para>
+<para>
+A particular implementation of Glk may not be able to display all the printable characters. It is guaranteed to be able to display the ASCII characters (32 to 126, and the newline 10.) Other characters may be printed correctly, printed as multi-character combinations (such as <quote><computeroutput>ae</computeroutput></quote> for the <quote>æ</quote> ligature), or printed as some placeholder character (such as a bullet or question mark, or even an octal code.) You can test for this using #gestalt_CharOutput.
+</para>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<refentry id="chimara-Window-Arrangement">
+<refmeta>
+<refentrytitle>Window Arrangement</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Window Arrangement</refname>
+<refpurpose>The Way of Window Arrangement</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+The Way of Window Arrangement is fairly complicated. I'll try to explain it coherently.
+</para>
+<note><para>If you are reading this document to get an overview of Glk, by all means skip forward to <link linkend="chimara-The-Types-of-Windows">The Types of Windows</link>. Come back here later.
+</para></note>
+<para>
+Originally, there are no windows. You can create a window, which will take up the entire available screen area. You can then split this window in two. One of the halves is the original window; the other half is new, and can be of any type you want. You can control whether the new window is left, right, above, or below the original one. You can also control how the split occurs. It can be 50-50, or 70-30, or any other percentage split. Or, you can give a fixed width to the new window, and allow the old one to take up the rest of the available space. Or you can give a fixed width to the old window, and let the new one take up the rest of the space.
+</para>
+<para>
+Now you have two windows. In exactly the same way, you can split either of them — the original window, or the one you just created. Whichever one you split becomes two, which together take up the same space that the one did before.
+</para>
+<para>
+You can repeat this as often as you want. Every time you split a window, one new window is created. Therefore, the call that does this is called glk_window_open().
+</para>
+<note><para>
+It might have been less confusing to call it <quote>glk_split_window()</quote> — or it might have been more confusing. I picked one.
+</para></note>
+<para>
+It is important to remember that the order of splitting matters. If you split twice, you don't have a trio of windows; you have a pair with another pair on one side. Mathematically, the window structure is a binary tree.
+</para>
+<para>
+Example time. Say you do two splits, each a 50-50 percentage split. You start with the original window A, and split that into A and B; then you split B into B and C.
+<mediaobject><textobject><phrase>Screen shot 1</phrase></textobject></mediaobject>
+Or, you could split A into A and B, and then split A again into A and C.
+<mediaobject><textobject><phrase>Screen shot 2</phrase></textobject></mediaobject>
+I'm using the simplest possible splits in the examples above. Every split is 50-50, and the new window of the pair is always below the original one (the one that gets split.) You can get fancier than that. Here are three more ways to perform the first example; all of them have the same tree structure, but look different on the screen.
+<mediaobject><textobject><phrase>Screen shot 3</phrase></textobject></mediaobject>
+On the left, we turn the second split (B into B/C) upside down; we put the new window (C) above the old window (B).
+</para>
+<para>
+In the center, we mess with the percentages. The first split (A into A/B) is a 25-75 split, which makes B three times the size of A. The second (B into B/C) is a 33-66 split, which makes C twice the size of B. This looks rather like the second example above, but has a different internal structure.
+</para>
+<para>
+On the right, the second split (B into B/C) is vertical instead of horizontal, with the new window (C) on the left of the old one.
+</para>
+<para>
+The visible windows on the Glk screen are <quote>leaf nodes</quote> of the binary tree; they hang off the ends of the branches in the diagram. There are also the <quote>internal nodes</quote>, the ones at the forks, which are marked as <quote>O</quote>. These are the mysterious pair windows.
+</para>
+<para>
+You don't create pair windows directly; they are created as a consequence of window splits. Whenever you create a new window, a new pair window is also created automatically. In the following two-split process, you can see that when a window is split, it is replaced by a new pair window, and moves down to become one of that <quote>O</quote>'s two children.
+<mediaobject><textobject><phrase>Screen shot 4</phrase></textobject></mediaobject>
+</para>
+<para>
+You can't draw into a pair window. It's completely filled up with the two windows it contains. They're what you should be drawing into.
+</para>
+<para>
+Why have pair windows in the system at all? They're convenient for certain operations. For example, you can close any window at any time; but sometimes you want to close an entire nest of windows at once. In the third stage shown, if you close the lower pair window, it blows away all its descendents — both B and C — and leaves just a single window, A, which is what you started with.
+</para>
+<para>
+I'm using some math terminology already, so I'll explain it briefly. The <quote>root</quote> of the tree is the top (math trees, like family trees, grow upside down.) If there's only one window, it's the root; otherwise the root is the topmost <quote>O</quote>. Every pair window has exactly two <quote>children</quote>. Other kinds of windows are leaves on the tree, and have no children. A window's <quote>descendants</quote>, obviously, are its children and grandchildren and great-grandchildren and so on. The <quote>parent</quote> and <quote>ancestors</quote> of a window are exactly what you'd expect. So the root window is the ancestor of every other window.
+</para>
+<para>
+There are Glk functions to determine the root window, and to determine the parent of any given window. Note that every window's parent is a pair window. (Except for the root window, which has no parent.)
+</para>
+</refsect1>
+</refentry>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<refentry id="chimara-Windows">
+<refmeta>
+<refentrytitle>Windows</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>CHIMARA Library</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>Windows</refname>
+<refpurpose>Introduction to Glk windows</refpurpose>
+</refnamediv>
+<refsect1>
+<title>Description</title>
+<para>
+On most platforms, the program/library combination will appear to the player in a window — either a window which covers the entire screen, or one which shares screen space with other windows in a multi-programming environment. Obviously your program does not have worry about the details of this. The Glk screen space is a rectangle, which you can divide into panels for various purposes. It is these panels which I will refer to as <quote>windows</quote> hereafter.
+</para>
+<para>
+You refer to a window using an opaque C structure pointer. See <link linkend="chimara-Opaque-Objects">Opaque Objects</link>.
+</para>
+<para>
+A window has a type. Currently there are four window types:
+<variablelist>
+<varlistentry>
+ <term>Text buffer windows</term>
+ <listitem><para>
+ A stream of text.
+ </para>
+ <note><para>The <quote>story window</quote> of an Infocom game.
+ </para></note>
+ <para>
+ You can only print at the end of the stream, and input a line of text at the end of the stream.
+ </para></listitem>
+</varlistentry>
+<varlistentry>
+ <term>Text grid windows</term>
+ <listitem><para>
+ A grid of characters in a fixed-width font.
+ </para>
+ <note><para>The <quote>status window</quote> of an Infocom game.
+ </para></note>
+ <para>
+ You can print anywhere in the grid.
+ </para></listitem>
+</varlistentry>
+<varlistentry>
+ <term>Graphics windows</term>
+ <listitem><para>
+ A grid of colored pixels. Graphics windows do not support text input or output, but there are image commands to draw in them.
+ </para>
+ <note><para>This is an optional capability; not all Glk libraries support graphics. See <link linkend="chimara-Testing-for-Graphics-Capabilities">Testing for Graphics Capabilities</link>.
+ </para></note></listitem>
+</varlistentry>
+<varlistentry>
+ <term>Blank windows</term>
+ <listitem><para>A blank window. Blank windows support neither input nor output.
+ </para>
+ <note><para>They exist mostly to be an example of a <quote>generic</quote> window. You are unlikely to want to use them.
+ </para></note></listitem>
+</varlistentry>
+</variablelist>
+</para>
+<para>
+As Glk is an expanding system, more window types may be added in the future. Therefore, it is important to remember that not all window types will necessarily be available under all Glk libraries.
+</para>
+<para>
+There is one other special type of window, the pair window. Pair windows are created by Glk as part of the system of window arrangement. You cannot create them yourself. See <link linkend="wintype-Pair">Pair Windows</link>.
+</para>
+<para>
+Every window has a rock. This is a value you provide when the window is created; you can use it however you want. See <link linkend="chimara-Rocks">Rocks</link>.
+</para>
+<para>
+When Glk starts up, there are no windows.
+</para>
+<note><para>
+When I say there are no windows, I mean there are no Glk windows. In a multiprogramming environment, such as X or MacOS, there may be an application window visible; this is the screen space that will contain all the Glk windows that you create. But at first, this screen space is empty and unused.
+</para></note>
+<para>
+Without a window, you cannot do any kind of input or output; so the first thing you'll want to do is create one. See <link linkend="chimara-Window-Opening-Closing-and-Constraints">Window Opening, Closing, and Constraints</link>.
+</para>
+<para>
+You can create as many windows as you want, of any types. You control their arrangement and sizes through a fairly flexible system of calls. See <link linkend="chimara-Window-Arrangement">Window Arrangement</link>.
+</para>
+<para>
+You can close any windows you want. You can even close all the windows, which returns you to the original startup state.
+</para>
+<para>
+You can request input from any or all windows. Input can be mouse input (on platforms which support a mouse), single-character input, or input of an entire line of text. It is legal to request input from several windows at the same time. The library will have some interface mechanism for the player to control which window he is typing in.
+</para>
+</refsect1>
+</refentry>
--- /dev/null
+@PACKAGE_VERSION@
+++ /dev/null
-.libs
-.deps
-.*swp
-.nautilus-metafile.xml
-*.autosave
-*.gmo
-*.mo
-*.pot
-*~
-#*#
-*.bak
-*.o
-*.lo
-*.la
-cat-id-tbl.c
-stamp-cat-id
-messages
-missing
-POTFILES
-Makefile
-Makefile.in
-Makefile.in.in
-translations.xml
window.c window.h
libchimara_la_LIBADD = @CHIMARA_LIBS@
-libchimara_la_LDFLAGS = -no-undefined -export-symbols-regex "^chimara_glk_.*|^glk_.*"
+libchimara_la_LDFLAGS = -no-undefined -export-symbols-regex "^chimara_glk_|^glk_"
libchimara_includedir = $(includedir)/chimara/chimara
libchimara_include_HEADERS = chimara-glk.h
-PLUGIN_LDFLAGS = -module -shared -avoid-version -export-symbols-regex "glk_main"
+PLUGIN_LDFLAGS = -module -shared -avoid-version -export-symbols-regex "^glk_main$$"
pkglib_LTLIBRARIES = first.la model.la gridtest.la splittest.la
first_la_SOURCES = first.c
first_la_LDFLAGS = $(PLUGIN_LDFLAGS)
/**
* glk_set_interrupt_handler:
- * @func: A pointer to a function which takes no argument and returns no result.
+ * @func: A pointer to an interrupt handler function.
*
- * Specifies an interrupt handler function for cleaning up critical resources.
- * If Glk receives an interrupt, and you have set an interrupt handler, your
- * handler will be called, before the process is shut down.
+ * Sets @func to be the interrupt handler. @func should be a pointer to a
+ * function which takes no argument and returns no result. If Glk receives an
+ * interrupt, and you have set an interrupt handler, your handler will be
+ * called, before the process is shut down.
*
* Initially there is no interrupt handler. You can reset to not having any by
- * calling glk_set_interrupt_handler(%NULL).
+ * calling <code>#glk_set_interrupt_handler(%NULL)</code>.
*
* If you call glk_set_interrupt_handler() with a new handler function while an
* older one is set, the new one replaces the old one. Glk does not try to queue
* glk_char_to_lower:
* @ch: A Latin-1 character.
*
- * If @ch is an uppercase character in the Latin-1 character set, converts it
- * to lowercase. Otherwise, leaves it unchanged.
+ * You can convert Latin-1 characters between upper and lower case with two Glk
+ * utility functions, glk_char_to_lower() and glk_char_to_upper(). These have a
+ * few advantages over the standard ANSI <function>tolower()</function> and
+ * <function>toupper()</function> macros. They work for the entire Latin-1
+ * character set, including accented letters; they behave consistently on all
+ * platforms, since they're part of the Glk library; and they are safe for all
+ * characters. That is, if you call glk_char_to_lower() on a lower-case
+ * character, or a character which is not a letter, you'll get the argument
+ * back unchanged.
+ *
+ * The case-sensitive characters in Latin-1 are the ranges 0x41..0x5A,
+ * 0xC0..0xD6, 0xD8..0xDE (upper case) and the ranges 0x61..0x7A, 0xE0..0xF6,
+ * 0xF8..0xFE (lower case). These are arranged in parallel; so
+ * glk_char_to_lower() will add 0x20 to values in the upper-case ranges, and
+ * glk_char_to_upper() will subtract 0x20 from values in the lower-case ranges.
*
* Returns: A lowercase or non-letter Latin-1 character.
*/
* @ch: A Latin-1 character.
*
* If @ch is a lowercase character in the Latin-1 character set, converts it to
- * uppercase. Otherwise, leaves it unchanged.
+ * uppercase. Otherwise, leaves it unchanged. See glk_char_to_lower().
*
* Returns: An uppercase or non-letter Latin-1 character.
*/
* @len: Available length of @buf.
* @numchars: Number of characters in @buf.
*
- * Converts the first @numchars characters of @buf to their lowercase
- * equivalents, if there is such a thing. These functions provide two length
- * arguments because a string of Unicode characters may expand when its case
- * changes. The @len argument is the available length of the buffer; @numchars
- * is the number of characters in the buffer initially. (So @numchars must be
- * less than or equal to @len. The contents of the buffer after @numchars do
- * not affect the operation.)
+ * Unicode character conversion is trickier, and must be applied to character
+ * arrays, not single characters. These functions
+ * (glk_buffer_to_lower_case_uni(), glk_buffer_to_upper_case_uni(), and
+ * glk_buffer_to_title_case_uni()) provide two length arguments because a
+ * string of Unicode characters may expand when its case changes. The @len
+ * argument is the available length of the buffer; @numchars is the number of
+ * characters in the buffer initially. (So @numchars must be less than or equal
+ * to @len. The contents of the buffer after @numchars do not affect the
+ * operation.)
*
- * Returns: The number of characters after conversion. If this is greater than
- * @len, the characters in the array will be safely truncated at len, but the
- * true count will be returned. (The contents of the buffer after the returned
- * count are undefined.)
+ * The functions return the number of characters after conversion. If this is
+ * greater than @len, the characters in the array will be safely truncated at
+ * @len, but the true count will be returned. (The contents of the buffer after
+ * the returned count are undefined.)
+ *
+ * The <code>lower_case</code> and <code>upper_case</code> functions do what
+ * you'd expect: they convert every character in the buffer (the first @numchars
+ * of them) to its upper or lower-case equivalent, if there is such a thing.
+ *
+ * See the Unicode spec (chapter 3.13, chapter 4.2, etc) for the exact
+ * definitions of upper, lower, and title-case mapping.
+ *
+ * <note><para>
+ * Unicode has some strange case cases. For example, a combined character
+ * that looks like <quote>ss</quote> might properly be upper-cased into
+ * <emphasis>two</emphasis> characters <quote>S</quote>. Title-casing is even
+ * stranger; <quote>ss</quote> (at the beginning of a word) might be
+ * title-cased into a different combined character that looks like
+ * <quote>Ss</quote>. The glk_buffer_to_title_case_uni() function is actually
+ * title-casing the first character of the buffer. If it makes a difference.
+ * </para></note>
+ *
+ * Returns: The number of characters after conversion.
*/
glui32
glk_buffer_to_lower_case_uni(glui32 *buf, glui32 len, glui32 numchars)
* @lowerrest: %TRUE if the rest of @buf should be lowercased, %FALSE
* otherwise.
*
- * Converts the first character of @buf to uppercase, if there is such a thing.
- * See glk_buffer_to_lower_case_uni(). If @lowerrest is %TRUE, then the
- * remainder of @buf is lowercased.
+ * See glk_buffer_to_lower_case_uni(). The <code>title_case</code> function has
+ * an additional (boolean) flag. Its basic function is to change the first
+ * character of the buffer to upper-case, and leave the rest of the buffer
+ * unchanged. If @lowerrest is true, it changes all the non-first characters to
+ * lower-case (instead of leaving them alone.)
*
+ * <note><para>
+ * Earlier drafts of this spec had a separate function which title-cased the
+ * first character of every <emphasis>word</emphasis> in the buffer. I took
+ * this out after reading Unicode Standard Annex #29, which explains how
+ * to divide a string into words. If you want it, feel free to implement it.
+ * </para></note>
+ *
* Returns: The number of characters after conversion.
*/
glui32
G_END_DECLS
-#endif /* __CHIMARA_GLK_PRIVATE_H__ */
\ No newline at end of file
+#endif /* __CHIMARA_GLK_PRIVATE_H__ */
#define CHIMARA_GLK_MIN_WIDTH 0
#define CHIMARA_GLK_MIN_HEIGHT 0
+/**
+ * SECTION:chimara-glk
+ * @short_description: Widget which executes a Glk program
+ * @stability: Unstable
+ * @include: chimara/chimara-glk.h
+ *
+ * The ChimaraGlk widget opens and runs a Glk program. The program must be
+ * compiled as a plugin module, with a function <function>glk_main()</function>
+ * that the Glk library can hook into.
+ *
+ * On Linux systems, this is a file with a name like
+ * <filename>plugin.so</filename>. For portability, you can use libtool and
+ * automake:
+ * <informalexample><programlisting>
+ * pkglib_LTLIBRARIES = plugin.la
+ * plugin_la_SOURCES = plugin.c foo.c bar.c
+ * plugin_la_LDFLAGS = -module -shared -avoid-version -export-symbols-regex "^glk_main$$"
+ * </programlisting></informalexample>
+ * This will produce <filename>plugin.la</filename> which is a text file
+ * containing the correct plugin file to open (see the relevant section of the
+ * <ulink
+ * url="http://www.gnu.org/software/libtool/manual/html_node/Finding-the-dlname.html">
+ * Libtool manual</ulink>).
+ */
+
typedef void (* glk_main_t) (void);
enum {
/* Signals */
klass->stopped = chimara_glk_stopped;
klass->started = chimara_glk_started;
+ /**
+ * ChimaraGlk::stopped:
+ * @glk: The widget that received the signal
+ *
+ * The ::stopped signal is emitted when the a Glk program finishes
+ * executing in the widget, whether it ended normally, or was interrupted.
+ */
chimara_glk_signals[STOPPED] = g_signal_new("stopped",
G_OBJECT_CLASS_TYPE(klass), 0,
G_STRUCT_OFFSET(ChimaraGlkClass, stopped), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ /**
+ * ChimaraGlk::started:
+ * @glk: The widget that received the signal
+ *
+ * The ::started signal is emitted when a Glk program starts executing in
+ * the widget.
+ */
chimara_glk_signals[STARTED] = g_signal_new ("started",
G_OBJECT_CLASS_TYPE (klass), 0,
G_STRUCT_OFFSET(ChimaraGlkClass, started), NULL, NULL,
TRUE,
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_LAX_VALIDATION |
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
+ /**
+ * ChimaraGlk:interactive:
+ *
+ * Sets whether the widget is interactive. A Glk widget is normally
+ * interactive, but in non-interactive mode, keyboard and mouse input are
+ * ignored and the Glk program is controlled by chimara_glk_feed_text().
+ * "More" prompts when a lot of text is printed to a text buffer are also
+ * disabled. This is typically used when you wish to control an interpreter
+ * program by feeding it a predefined list of commands.
+ */
g_object_class_install_property(object_class, PROP_INTERACTIVE, pspec);
pspec = g_param_spec_boolean("protect", _("Protected"),
_("Whether the Glk program is barred from doing file operations"),
FALSE,
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_LAX_VALIDATION |
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
+ /**
+ * ChimaraGlk:protect:
+ *
+ * Sets whether the Glk program is allowed to do file operations. In protect
+ * mode, all file operations will fail.
+ */
g_object_class_install_property(object_class, PROP_PROTECT, pspec);
/* Private data */
* @glk: a #ChimaraGlk widget
* @interactive: whether the widget should expect user input
*
- * Sets the #ChimaraGlk:interactive property of @glk. A Glk widget is normally
- * interactive, but in non-interactive mode, keyboard and mouse input is ignored
- * and the Glk program is controlled by chimara_glk_feed_text(). "More" prompts
- * when a lot of text is printed to a text buffer are also disabled. This is
- * typically used when you wish to control an interpreter program by feeding it
- * a predefined list of commands.
+ * Sets the #ChimaraGlk:interactive property of @glk.
*/
void
chimara_glk_set_interactive(ChimaraGlk *glk, gboolean interactive)
* @glk: a #ChimaraGlk widget
*
* Returns whether @glk is interactive (expecting user input). See
- * chimara_glk_set_interactive().
+ * #ChimaraGlk:interactive.
*
* Return value: %TRUE if @glk is interactive.
*/
* @glk: a #ChimaraGlk widget
*
* Returns whether @glk is in protect mode (banned from doing file operations).
- * See chimara_glk_set_protect().
+ * See #ChimaraGlk:protect.
*
* Return value: %TRUE if @glk is in protect mode.
*/
/**
* chimara_glk_run:
* @glk: a #ChimaraGlk widget
- * @plugin: path to a plugin module compiled with glk.h
- * @error: location to store a #GError, or %NULL
+ * @plugin: path to a plugin module compiled with <filename
+ * class="header">glk.h</filename>
+ * @error: location to store a <link linkend="glib-GError">GError</link>, or
+ * %NULL
*
* Opens a Glk program compiled as a plugin and runs its glk_main() function in
* a separate thread. On failure, returns %FALSE and sets @error.
ChimaraGlkPrivate *priv = CHIMARA_GLK_PRIVATE(glk);
g_thread_join(priv->thread);
-}
\ No newline at end of file
+}
#define CHIMARA_GLK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
CHIMARA_TYPE_GLK, ChimaraGlkClass))
-typedef struct _ChimaraGlk ChimaraGlk;
-typedef struct _ChimaraGlkClass ChimaraGlkClass;
-
-struct _ChimaraGlk {
- GtkContainer parent_instance;
+/**
+ * ChimaraGlk:
+ *
+ * This structure contains no public members.
+ */
+typedef struct _ChimaraGlk {
+ GtkContainer parent_instance;
- /* Public members */
-};
+ /*< public >*/
+} ChimaraGlk;
-struct _ChimaraGlkClass {
- GtkContainerClass parent_class;
-
- /* Signals */
+typedef struct _ChimaraGlkClass {
+ GtkContainerClass parent_class;
+ /* Signals */
void(* stopped) (ChimaraGlk *self);
void(* started) (ChimaraGlk *self);
-};
+} ChimaraGlkClass;
GType chimara_glk_get_type(void) G_GNUC_CONST;
GtkWidget *chimara_glk_new(void);
G_END_DECLS
-#endif /* __CHIMARA_GLK_H__ */
\ No newline at end of file
+#endif /* __CHIMARA_GLK_H__ */
--- /dev/null
+/*
+ * doc.c - Contains the short and long descriptions of all the documentation
+ * sections in the Glk spec, as well as the GtkDoc comments for symbols
+ * defined only in glk.h.
+ */
+
+/**
+ * SECTION:glk-exiting
+ * @short_description: How to terminate a Glk program cleanly
+ * @include: glk.h
+ *
+ * A Glk program usually ends when the end of the glk_main() function is
+ * reached. You can also terminate it earlier.
+ */
+
+/**
+ * SECTION:glk-interrupt
+ * @short_description: Specifying an interrupt handler for cleaning up critical
+ * resources
+ * @include: glk.h
+ *
+ * Most platforms have some provision for interrupting a program —
+ * <keycombo action="simul"><keycap function="command">command</keycap>
+ * <keycap>period</keycap></keycombo> on the Macintosh, <keycombo
+ * action="simul"><keycap function="control">control</keycap><keycap>C</keycap>
+ * </keycombo> in Unix, possibly a window manager item, or other possibilities.
+ * This can happen at any time, including while execution is nested inside one
+ * of your own functions, or inside a Glk library function.
+ *
+ * If you need to clean up critical resources, you can specify an interrupt
+ * handler function.
+ */
+
+/**
+ * SECTION:glk-tick
+ * @short_description: Yielding time to the operating system
+ * @include: 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.
+ *
+ * Well, not really. But you should call glk_tick() every so often, just in
+ * case. It may be necessary to yield time to other applications in a
+ * cooperative-multitasking OS, or to check for player interrupts in an infinite
+ * loop.
+ */
+
+/**
+ * SECTION:glk-types
+ * @short_description: Basic types used in Glk
+ * @include: glk.h
+ *
+ * For simplicity, all the arguments used in Glk calls are of a very few types.
+ * <variablelist>
+ * <varlistentry>
+ * <term>32-bit unsigned integer</term>
+ * <listitem><para>Unsigned integers are used wherever possible, which is
+ * nearly everywhere. This type is called #glui32.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>32-bit signed integer</term>
+ * <listitem><para>This type is called #glsi32. Rarely used.</para>
+ * </listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>References to library objects</term>
+ * <listitem><para>These are pointers to opaque C structures; each library
+ * will use different structures, so you can not and should not try to
+ * manipulate their contents. See <link
+ * linkend="chimara-Opaque-Objects">Opaque Objects</link>.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Pointer to one of the above types</term>
+ * <listitem><para>Pointer to a structure which consists entirely of the
+ * above types.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term><type>unsigned char</type></term>
+ * <listitem><para>This is used only for Latin-1 text characters; see
+ * <link linkend="chimara-Character-Encoding">Character Encoding</link>.
+ * </para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Pointer to <type>char</type></term>
+ * <listitem><para>Sometimes this means a null-terminated string; sometimes
+ * an unterminated buffer, with length as a separate #glui32 argument. The
+ * documentation says which.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Pointer to <type>void</type></term>
+ * <listitem><para>When nothing else will do.</para></listitem>
+ * </varlistentry>
+ * </variablelist>
+ */
+
+/**
+ * SECTION:glk-opaque-objects
+ * @short_description: Complex objects in Glk
+ * @include: 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.
+ *
+ * Currently, these classes are:
+ * <variablelist>
+ * <varlistentry>
+ * <term>Windows</term>
+ * <listitem><para>Screen panels, used to input or output information.
+ * </para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Streams</term>
+ * <listitem><para>Data streams, to which you can input or output text.
+ * </para>
+ * <note><para>There are file streams and window streams, since you can
+ * output data to windows or files.</para></note>
+ * </listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>File references</term>
+ * <listitem><para>Pointers to files in permanent storage.</para>
+ * <note><para>In Unix a file reference is a pathname; on the Mac, an
+ * <type>FSSpec</type>. Actually there's a little more information included,
+ * such as file type and whether it is a text or binary file.</para></note>
+ * </listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Sound channels</term>
+ * <listitem><para>Audio output channels.</para>
+ * <note><para>Not all Glk libraries support sound.</para></note>
+ * </listitem>
+ * </varlistentry>
+ * </variablelist>
+ *
+ * <note><para>
+ * Note that there may be more object classes in future versions of the Glk API.
+ * </para></note>
+ *
+ * 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
+ * should always test for this possibility.
+ *
+ * %NULL is never the identifier of any object (window, stream, file reference,
+ * or sound channel). The value %NULL is often used to indicate <quote>no
+ * object</quote> or <quote>nothing</quote>, but it is not a valid reference. If
+ * a Glk function takes an object reference as an argument, it is illegal to
+ * pass in %NULL unless the function definition says otherwise.
+ *
+ * The <filename class="headerfile">glk.h</filename> file defines types
+ * #winid_t, #strid_t, #frefid_t, #schanid_t to store references. These are
+ * pointers to struct #glk_window_struct, #glk_stream_struct,
+ * #glk_fileref_struct, and #glk_schannel_struct respectively. It is, of course,
+ * illegal to pass one kind of pointer to a function which expects another.
+ *
+ * <note><para>
+ * 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>
+ * <refsect2 id="chimara-Rocks"><!-- Indeed it does. -->
+ * <title>Rocks</title>
+ * <para>
+ * Every one of these objects (window, stream, file reference, or sound channel)
+ * has a <quote>rock</quote> value. This is simply a 32-bit integer value which
+ * you provide, for your own purposes, when you create the object.
+ * </para>
+ * <note><para>The library — so to speak — stuffs this value under a
+ * rock for safe-keeping, and gives it back to you when you ask for it.
+ * </para></note>
+ * <note><para>If you don't know what to use the rocks for, provide 0 and forget
+ * about it.</para></note>
+ * </refsect2>
+ * <refsect2 id="chimara-Iterating-Through-Opaque-Objects">
+ * <title>Iteration Through Opaque Objects</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
+ * <informalexample><programlisting>
+ * <replaceable>CLASS</replaceable>id_t glk_<replaceable>CLASS</replaceable>_iterate(<replaceable>CLASS</replaceable>id_t <parameter>obj</parameter>, #glui32 *<parameter>rockptr</parameter>);
+ * </programlisting></informalexample>
+ * ...where <code><replaceable>CLASS</replaceable></code> represents one of the
+ * opaque object classes.
+ * </para>
+ * <note><para>
+ * So, at the current time, these are the functions glk_window_iterate(),
+ * glk_stream_iterate(), glk_fileref_iterate(), and glk_schannel_iterate().
+ * There may be more classes in future versions of the spec; they all behave
+ * the same.
+ * </para></note>
+ * <para>
+ * Calling <code>glk_<replaceable>CLASS</replaceable>_iterate(%NULL, r)</code>
+ * returns the first object; calling
+ * <code>glk_<replaceable>CLASS</replaceable>_iterate(obj, r)</code> returns
+ * the next object, until there aren't any more, at which time it returns %NULL.
+ * </para>
+ * <para>
+ * The @rockptr argument is a pointer to a location; whenever
+ * <code>glk_<replaceable>CLASS</replaceable>_iterate()</code> returns an
+ * object, the object's rock is stored in the location <code>(*@rockptr)</code>.
+ * If you don't want the rocks to be returned, you may set @rockptr to %NULL.
+ * </para>
+ * <para>
+ * You usually use this as follows:
+ * <informalexample><programlisting>
+ * obj = glk_<replaceable>CLASS</replaceable>_iterate(NULL, NULL);
+ * while (obj) {
+ * /* ...do something with obj... *<!-- -->/
+ * obj = glk_<replaceable>CLASS</replaceable>_iterate(obj, NULL);
+ * }
+ * </programlisting></informalexample>
+ * </para>
+ * <para>
+ * If you create or destroy objects inside this loop, obviously, the results are
+ * unpredictable. However it is always legal to call
+ * <code>glk_<replaceable>CLASS</replaceable>_iterate(obj, r)</code> as long as
+ * @obj is a valid object id, or %NULL.
+ * </para>
+ * <para>
+ * The order in which objects are returned is entirely arbitrary. The library
+ * may even rearrange the order every time you create or destroy an object of
+ * the given class. As long as you do not create or destroy any object, the rule
+ * is that <code>glk_<replaceable>CLASS</replaceable>_iterate(obj, r)</code> has
+ * a fixed result, and iterating through the results as above will list every
+ * object exactly once.
+ * </para>
+ * </refsect2>
+ */
+
+/**
+ * SECTION:glk-gestalt
+ * @short_description: Testing Glk's capabilities
+ * @include: 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
+ * impossible. New capabilities (graphics, sound, or so on) can be added without
+ * changing the basic specification. The system also allows for
+ * <quote>optional</quote> capabilities — those which not all Glk library
+ * implementations will support — and allows you to check for their
+ * presence without trying to infer them from a version number.
+ *
+ * The basic idea is that you can request information about the capabilities of
+ * the API, by calling the gestalt functions.
+ */
+
+/**
+ * SECTION:glk-character-input
+ * @short_description: Waiting for a single keystroke
+ * @include: glk.h
+ *
+ * You can request that the player hit a single key. See <link
+ * linkend="chimara-Character-Input-Events">Character Input Events</link>.
+ *
+ * If you use the basic text API, the character code which is returned can be
+ * any value from 0 to 255. The printable character codes have already been
+ * described. The remaining codes are typically control codes: <keycombo
+ * action="simul"><keycap function="control">control</keycap>
+ * <keycap>A</keycap></keycombo> to <keycombo action="simul"><keycap
+ * function="control">control</keycap><keycap>Z</keycap></keycombo> and a few
+ * others.
+ *
+ * There are also a number of special codes, representing special keyboard
+ * keys, which can be returned from a char-input event. These are represented
+ * as 32-bit integers, starting with 4294967295 (0xFFFFFFFF) and working down.
+ * The special key codes are defined in the <filename
+ * class="headerfile">glk.h</filename> file. They include one code for <keycap
+ * function="enter">return</keycap> or <keycap function="enter">enter</keycap>,
+ * one for <keycap function="delete">delete</keycap> or <keycap
+ * function="backspace">backspace</keycap>, twelve function keys, and one code
+ * for any key which has no Latin-1 or special code. The full list of key codes
+ * is included below.
+ *
+ * Various implementations of Glk will vary widely in which characters the
+ * player can enter. The most obvious limitation is that some characters are
+ * mapped to others. For example, most keyboards return a <keycombo
+ * action="simul"><keycap function="control">control</keycap><keycap>I</keycap>
+ * </keycombo> code when the <keycap function="tab">tab</keycap> key is
+ * pressed. The Glk library, if it can recognize this at all, will generate a
+ * <keysym>#keycode_Tab</keysym> event (value 0xFFFFFFF7) when this occurs.
+ * Therefore, for these keyboards, no keyboard key will generate a <keycombo
+ * action="simul"><keycap function="control">control</keycap><keycap>I</keycap>
+ * </keycombo> event (value 9.) The Glk library will probably map many of the
+ * control codes to the other special keycodes.
+ *
+ * <note><para>
+ * On the other hand, the library may be very clever and discriminate between
+ * <keycap>tab</keycap> and <keycombo action="simul"><keycap
+ * function="control">control</keycap><keycap>I</keycap></keycombo>. This is
+ * legal. The idea is, however, that if your program asks the player to
+ * <quote><computeroutput>press the <keycap function="tab">tab</keycap>
+ * key</computeroutput></quote>, you should check for a
+ * <keysym>#keycode_Tab</keysym> event as opposed to a <keycombo
+ * action="simul"><keycap function="control">control</keycap>
+ * <keycap>I</keycap></keycombo> event.
+ * </para></note>
+ *
+ * Some characters may not be enterable simply because they do not exist.
+ *
+ * <note><para>
+ * Not all keyboards have a <keycap function="home">home</keycap> or <keycap
+ * function="end">end</keycap> key. A pen-based platform may not recognize
+ * any control characters at all.
+ * </para></note>
+ *
+ * Some characters may not be enterable because they are reserved for the
+ * purposes of the interface. For example, the Mac Glk library reserves the
+ * <keycap function="tab">tab</keycap> key for switching between different Glk
+ * windows. Therefore, on the Mac, the library will never generate a
+ * <keysym>#keycode_Tab</keysym> event or a <keycombo action="simul">
+ * <keycap function="control">control</keycap><keycap>I</keycap></keycombo>
+ * event.
+ *
+ * <note><para>
+ * Note that the linefeed or <keycombo action="simul"><keycap
+ * function="control">control</keycap><keycap>J</keycap></keycombo>
+ * character, which is the only printable control character, is probably not
+ * typable. This is because, in most libraries, it will be converted to
+ * <keysym>#keycode_Return</keysym>. Again, you should check for
+ * <keysym>#keycode_Return</keysym> if your program asks the player to
+ * <quote><computeroutput>press the <keycap function="enter">return</keycap>
+ * key</computeroutput></quote>.
+ * </para></note>
+ *
+ * <note><para>
+ * The <keycap function="delete">delete</keycap> and <keycap
+ * function="backspace">backspace</keycap> keys are merged into a single
+ * keycode because they have such an astonishing history of being confused in
+ * the first place... this spec formally waives any desire to define the
+ * difference. Of course, a library is free to distinguish <keycap
+ * function="delete">delete</keycap> and <keycap
+ * function="backspace">backspace</keycap> during line input. This is when it
+ * matters most; conflating the two during character input should not be a
+ * large problem.
+ * </para></note>
+ *
+ * You can test for this by using the #gestalt_CharInput selector.
+ *
+ * <note><para>
+ * Glk porters take note: it is not a goal to be able to generate every
+ * single possible key event. If the library says that it can generate a
+ * particular keycode, then game programmers will assume that it is
+ * available, and ask players to use it. If a <keysym>#keycode_Home</keysym>
+ * event can only be generated by typing <keycombo action="seq"><keycap
+ * function="escape">escape</keycap><keycombo action="simul"><keycap
+ * function="control">control</keycap><keycap>A</keycap></keycombo>
+ * </keycombo>, and the player does not know this, the player will be lost
+ * when the game says <quote><computeroutput>Press the <keycap
+ * function="home">home</keycap> key to see the next
+ * hint.</computeroutput></quote> It is better for the library to say that it
+ * cannot generate a <keysym>#keycode_Home</keysym> event; that way the game
+ * can detect the situation and ask the user to type <keycap>H</keycap>
+ * instead.
+ * </para>
+ * <para>
+ * Of course, it is better not to rely on obscure keys in any case. The arrow
+ * keys and <keycap function="enter">return</keycap> are nearly certain to be
+ * available; the others are of gradually decreasing reliability, and you
+ * (the game programmer) should not depend on them. You must be certain to
+ * check for the ones you want to use, including the arrow keys and <keycap
+ * function="enter">return</keycap>, and be prepared to use different keys in
+ * your interface if #gestalt_CharInput says they are not available.
+ * </para></note>
+ */
+
+/**
+ * SECTION:glk-case
+ * @short_description: Changing the case of strings
+ * @include: 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
+ * vice versa, so the Latin-1 functions act on single characters. The Unicode
+ * functions act on whole strings, since the length of the string may change.
+ */
+
+/**
+ * SECTION:glk-window-opening
+ * @short_description: Creating new windows and closing them
+ * @include: 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: 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: 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: 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
+ * a window. Any text printed to the window is also echoed to this second
+ * stream, which is called the window's <quote>echo stream.</quote>
+ *
+ * Effectively, any call to glk_put_char() (or the other output commands) which
+ * is directed to the window's window stream, is replicated to the window's echo
+ * stream. This also goes for the style commands such as glk_set_style().
+ *
+ * Note that the echoing is one-way. You can still print text directly to the
+ * echo stream, and it will go wherever the stream is bound, but it does not
+ * back up and appear in the window.
+ *
+ * An echo stream can be of any type, even another window's window stream.
+ *
+ * <note><para>
+ * This would be somewhat silly, since it would mean that any text printed to
+ * the window would be duplicated in another window. More commonly, you would
+ * set a window's echo stream to be a file stream, in order to create a
+ * transcript file from that window.
+ * </para></note>
+ *
+ * A window can only have one echo stream. But a single stream can be the echo
+ * stream of any number of windows, sequentially or simultaneously.
+ *
+ * If a window is closed, its echo stream remains open; it is not automatically
+ * closed.
+ *
+ * <note><para>
+ * Do not confuse the window's window stream with its echo stream. The window
+ * stream is <quote>owned</quote> by the window, and dies with it. The echo
+ * stream is merely temporarily associated with the window.
+ * </para></note>
+ *
+ * If a stream is closed, and it is the echo stream of one or more windows,
+ * those windows are reset to not echo anymore. (So then calling
+ * glk_window_get_echo_stream() on them will return %NULL.)
+ */
+
+/**
+ * SECTION:glk-window-other
+ * @short_description: Miscellaneous functions for windows
+ * @include: glk.h
+ *
+ * This section contains functions for windows that don't fit anywhere else.
+ */
+
+/**
+ * SECTION:glk-events
+ * @short_description: Waiting for events
+ * @include: 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
+ * the glk_select() call, in the form of events. You should write at least one
+ * event loop to retrieve these events.
+ */
+
+/**
+ * SECTION:glk-character-input-events
+ * @short_description: Events representing a single keystroke
+ * @include: 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
+ * and Unicode input; see #gestalt_Unicode.
+ */
+
+/**
+ * SECTION:glk-line-input-events
+ * @short_description: Events representing a line of user input
+ * @include: 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
+ * and Unicode input; see #gestalt_Unicode.
+ */
+
+/**
+ * SECTION:glk-streams
+ * @short_description: Input and output abstractions
+ * @include: 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
+ * open file is represented by an output stream as well.
+ *
+ * There are also input streams; these are used for reading from files on disk.
+ * It is possible for a stream to be both an input and an output stream.
+ *
+ * <note><para>
+ * Player input is done through line and character input events, not streams.
+ * This is a small inelegance in theory. In practice, player input is slow and
+ * things can interrupt it, whereas file input is immediate. If a network
+ * extension to Glk were proposed, it would probably use events and not
+ * streams, since network communication is not immediate.
+ * </para></note>
+ *
+ * It is also possible to create a stream that reads or writes to a buffer in
+ * memory.
+ *
+ * Finally, there may be platform-specific types of streams, which are created
+ * before your program starts running.
+ *
+ * <note><para>
+ * For example, a program running under Unix may have access to standard input
+ * as a stream, even though there is no Glk call to explicitly open standard
+ * input. On the Mac, data in a Mac resource may be available through a
+ * resource-reading stream.
+ * </para></note>
+ *
+ * You do not need to worry about the origin of such streams; just read or write
+ * them as usual. For information about how platform-specific streams come to
+ * be, see <link linkend="chimara-Startup-Options">Startup Options</link>.
+ *
+ * A stream is opened with a particular file mode, see the
+ * <code>filemode_</code> constants below.
+ *
+ * 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
+ * will fail, in which case the creation function will return %NULL.
+ *
+ * Each stream remembers two character counts, the number of characters printed
+ * to and read from that stream. The write-count is exactly one per
+ * glk_put_char() call; it is figured before any platform-dependent character
+ * cookery.
+ *
+ * <note><para>
+ * For example, if a newline character is converted to
+ * linefeed-plus-carriage-return, the stream's count still only goes up by
+ * one; similarly if an accented character is displayed as two characters.
+ * </para></note>
+ *
+ * The read-count is exactly one per glk_get_char_stream() call, as long as the
+ * call returns an actual character (as opposed to an end-of-file token.)
+ *
+ * Glk has a notion of the <quote>current (output) stream</quote>. If you print
+ * text without specifying a stream, it goes to the current output stream. The
+ * current output stream may be %NULL, meaning that there isn't one. It is
+ * illegal to print text to stream %NULL, or to print to the current stream when
+ * there isn't one.
+ *
+ * If the stream which is the current stream is closed, the current stream
+ * becomes %NULL.
+ */
+
+/**
+ * SECTION:glk-print
+ * @short_description: Printing to streams
+ * @include: 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
+ * format for that stream.
+ */
+
+/**
+ * SECTION:glk-read
+ * @short_description: Reading from streams
+ * @include: 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
+ * them.
+ */
+
+/**
+ * SECTION:glk-closing-streams
+ * @short_description: Closing streams and retrieving their character counts
+ * @include: glk.h
+ *
+ * When you close a Glk stream, you have the opportunity to examine the
+ * character counts — the number of characters written to or read from the
+ * stream.
+ */
+
+/**
+ * SECTION:glk-stream-positions
+ * @short_description: Moving the read/write mark
+ * @include: glk.h
+ *
+ * You can set the position of the read/write mark in a stream.
+ *
+ * <note><para>
+ * Which makes one wonder why they're called <quote>streams</quote> in the
+ * first place. Oh well.
+ * </para></note>
+ */
+
+/**
+ * SECTION:glk-stream-types
+ * @short_description: Window, memory, and file streams
+ * @include: glk.h
+ *
+ * <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().
+ *
+ * A window stream cannot be closed with glk_stream_close(). It is closed
+ * automatically when you close its window with glk_window_close().
+ *
+ * Only printable characters (including newline) may be printed to a window
+ * stream. See <link linkend="chimara-Character-Encoding">Character
+ * Encoding</link>.
+ * </para>
+ * </refsect2>
+ * <refsect2 id="chimara-Memory-Streams"><title>Memory Streams</title>
+ * <para>
+ * You can open a stream which reads from or writes to a space in memory. See
+ * glk_stream_open_memory() and glk_stream_open_memory_uni(). When opening a
+ * memory stream, you specify a buffer to which the stream's output will be
+ * written, and its length @buflen.
+ *
+ * When outputting, if more than @buflen characters are written to the stream,
+ * all of them beyond the buffer length will be thrown away, so as not to
+ * overwrite the buffer. (The character count of the stream will still be
+ * maintained correctly. That is, it will count the number of characters written
+ * into the stream, not the number that fit into the buffer.)
+ *
+ * If the buffer is %NULL, or for that matter if @buflen is zero, then
+ * <emphasis>everything</emphasis> written to the stream is thrown away. This
+ * may be useful if you are interested in the character count.
+ *
+ * When inputting, if more than @buflen characters are read from the stream, the
+ * stream will start returning -1 (signalling end-of-file.) If the buffer is
+ * %NULL, the stream will always return end-of-file.
+ *
+ * The data is written to the buffer exactly as it was passed to the printing
+ * functions (glk_put_char(), etc.); input functions will read the data exactly
+ * as it exists in memory. No platform-dependent cookery will be done on it.
+ *
+ * <note><para>
+ * You can write a disk file in text mode, but a memory stream is effectively
+ * always in binary mode.
+ * </para></note>
+ *
+ * Whether reading or writing, the contents of the buffer are undefined until
+ * the stream is closed. The library may store the data there as it is written,
+ * or deposit it all in a lump when the stream is closed. It is illegal to
+ * change the contents of the buffer while the stream is open.
+ * </para>
+ * </refsect2>
+ * <refsect2 id="chimara-File-Streams"><title>File Streams</title>
+ * <para>
+ * You can open a stream which reads from or writes to a disk file. See
+ * glk_stream_open_file() and glk_stream_open_file_uni().
+ *
+ * The file may be written in text or binary mode; this is determined by the
+ * file reference you open the stream with. Similarly, platform-dependent
+ * attributes such as file type are determined by the file reference. See <link
+ * linkend="chimara-File-References">File References</link>.
+ * </para>
+ * </refsect2>
+ */
+
+/**
+ * SECTION:glk-stream-other
+ * @short_description: Miscellaneous functions for streams
+ * @include: 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: 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
+ * Objects</link>.
+ *
+ * A file reference contains platform-specific information about the name and
+ * location of the file, and possibly its type, if the platform has a notion of
+ * file type. It also includes a flag indication whether the file is a text file
+ * or binary file.
+ *
+ * <note><para>
+ * Note that this is different from the standard C I/O library, in which you
+ * specify text or binary mode when the file is opened.
+ * </para></note>
+ *
+ * A fileref does not have to refer to a file which actually exists. You can
+ * 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.
+ *
+ * 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
+ * to be read back by your program, or if the data must be stored exactly. Text
+ * mode is appropriate for #fileusage_Transcript; binary mode is appropriate for
+ * #fileusage_SavedGame and probably for #fileusage_InputRecord. #fileusage_Data
+ * files may be text or binary, depending on what you use them for.
+ */
+
+/**
+ * SECTION:glk-fileref-types
+ * @short_description: Four different ways to create a file reference
+ * @include: 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
+ * creation will fail and return %NULL.
+ */
+
+/**
+ * SECTION:glk-fileref-other
+ * @short_description: Miscellaneous functions for file references
+ * @include: glk.h
+ *
+ * This section includes functions for file references that don't fit anywhere
+ * else.
+ */
+
+/*---------------- TYPES AND CONSTANTS FROM GLK.H ----------------------------*/
+
+/**
+ * glui32:
+ *
+ * A 32-bit unsigned integer type, used wherever possible in Glk.
+ */
+
+/**
+ * glsi32:
+ *
+ * A 32-bit signed integer type, rarely used.
+ */
+
+/**
+ * GLK_MODULE_UNICODE:
+ *
+ * If this preprocessor symbol is defined, so are all the Unicode functions and
+ * constants (see #gestalt_Unicode). If not, not.
+ */
+
+/**
+ * winid_t:
+ *
+ * Opaque structure representing a Glk window. It has no user-accessible
+ * members.
+ */
+
+/**
+ * strid_t:
+ *
+ * Opaque structure representing an input or output stream. It has no
+ * user-accessible members.
+ */
+
+/**
+ * frefid_t:
+ *
+ * Opaque structure representing a file reference. It has no user-accessible
+ * members.
+ */
+
+/**
+ * gestalt_Version:
+ *
+ * For an example of the gestalt mechanism, consider the selector
+ * #gestalt_Version. If you do
+ * <informalexample><programlisting>
+ * #glui32 res;
+ * res = #glk_gestalt(#gestalt_Version, 0);
+ * </programlisting></informalexample>
+ * <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
+ * version number; the next 8 bits stores the minor version number; the low 8
+ * bits stores an even more minor version number, if any.
+ *
+ * <note><para>
+ * 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.
+ *
+ * <informalexample><programlisting>
+ * #glui32 res;
+ * res = #glk_gestalt_ext(#gestalt_Version, 0, NULL, 0);
+ * </programlisting></informalexample>
+ * 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.
+ */
+
+/**
+ * gestalt_CharInput:
+ *
+ * If you set <code>ch</code> to a character code, or a special code (from
+ * 0xFFFFFFFF down), and call
+ * <informalexample><programlisting>
+ * #glui32 res;
+ * res = #glk_gestalt(#gestalt_CharInput, ch);
+ * </programlisting></informalexample>
+ * 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
+ * linkend="chimara-Character-Input">Character Input</link>.
+ */
+
+/**
+ * gestalt_LineInput:
+ *
+ * If you set <code>ch</code> to a character code, and call
+ * <informalexample><programlisting>
+ * #glui32 res;
+ * res = #glk_gestalt(#gestalt_LineInput, ch);
+ * </programlisting></informalexample>
+ * 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
+ * a nonprintable Latin-1 character (0 to 31, 127 to 159), then this is
+ * guaranteed to return %FALSE. See <link linkend="chimara-Line-Input">Line
+ * Input</link>.
+ */
+
+/**
+ * gestalt_CharOutput:
+ *
+ * If you set <code>ch</code> to a character code (Latin-1 or higher), and call
+ * <informalexample><programlisting>
+ * #glui32 res, len;
+ * res = #glk_gestalt_ext(#gestalt_CharOutput, ch, &len, 1);
+ * </programlisting></informalexample>
+ * then <code>res</code> will be one of #gestalt_CharOutput_CannotPrint,
+ * #gestalt_CharOutput_ExactPrint, or #gestalt_CharOutput_ApproxPrint (see
+ * below.)
+ *
+ * In all cases, <code>len</code> (the #glui32 value pointed at by the third
+ * argument) will be the number of actual glyphs which will be used to represent
+ * the character. In the case of #gestalt_CharOutput_ExactPrint, this will
+ * always be 1; for #gestalt_CharOutput_CannotPrint, it may be 0 (nothing
+ * printed) or higher; for #gestalt_CharOutput_ApproxPrint, it may be 1 or
+ * higher. This information may be useful when printing text in a fixed-width
+ * font.
+ *
+ * <note><para>
+ * As described in <link linkend="chimara-Other-API-Conventions">Other API
+ * Conventions</link>, you may skip this information by passing %NULL as the
+ * third argument in glk_gestalt_ext(), or by calling glk_gestalt() instead.
+ * </para></note>
+ *
+ * This selector will always return #gestalt_CharOutput_CannotPrint if
+ * <code>ch</code> is an unprintable eight-bit character (0 to 9, 11 to 31, 127
+ * to 159.)
+ *
+ * <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 (þ), and then call
+ * <informalexample><programlisting>
+ * res = #glk_gestalt(#gestalt_CharOutput, ch);
+ * </programlisting></informalexample>
+ * 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
+ * should write
+ * <informalexample><programlisting>
+ * res = #glk_gestalt(#gestalt_CharOutput, (unsigned char)ch);
+ * </programlisting></informalexample>
+ * instead.
+ * </para></note>
+ * <note><para>
+ * Unicode includes the concept of non-spacing or combining characters, which
+ * do not represent glyphs; and double-width characters, whose glyphs take up
+ * two spaces in a fixed-width font. Future versions of this spec may
+ * recognize these concepts by returning a <code>len</code> of 0 or 2 when
+ * #gestalt_CharOutput_ExactPrint is used. For the moment, we are adhering to
+ * a policy of <quote>simple stuff first</quote>.
+ * </para></note>
+ */
+
+/**
+ * gestalt_CharOutput_CannotPrint:
+ *
+ * When the #gestalt_CharOutput selector returns this for a character, the
+ * character cannot be meaningfully printed. If you try, the player may see
+ * nothing, or may see a placeholder.
+ */
+
+/**
+ * gestalt_CharOutput_ApproxPrint:
+ *
+ * When the #gestalt_CharOutput selector returns this for a character, the
+ * library will print some approximation of the character. It will be more or
+ * less right, but it may not be precise, and it may not be distinguishable from
+ * other, similar characters. (Examples:
+ * <quote><computeroutput>ae</computeroutput></quote> for the one-character
+ * <quote>æ</quote> ligature,
+ * <quote><computeroutput>e</computeroutput></quote> for
+ * <quote>è</quote>, <quote><computeroutput>|</computeroutput></quote>
+ * for a broken vertical bar (¦).)
+ */
+
+/**
+ * gestalt_CharOutput_ExactPrint:
+ *
+ * When the #gestalt_CharOutput selector returns this for a character, the
+ * character will be printed exactly as defined.
+ */
+
+/**
+ * gestalt_Unicode:
+ *
+ * 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:
+ * <informalexample><programlisting>
+ * glui32 res;
+ * res = #glk_gestalt(#gestalt_Unicode, 0);
+ * </programlisting></informalexample>
+ *
+ * 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
+ * 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(),
+ * glk_put_buffer_uni(), glk_put_char_stream_uni(), glk_put_string_stream_uni(),
+ * glk_put_buffer_stream_uni(), glk_get_char_stream_uni(),
+ * glk_get_buffer_stream_uni(), glk_get_line_stream_uni(),
+ * glk_request_char_event_uni(), glk_request_line_event_uni(),
+ * glk_stream_open_file_uni(), glk_stream_open_memory_uni().
+ *
+ * If you are writing a C program, there is an additional complication. A
+ * library which does not support Unicode may not implement the Unicode
+ * functions at all. Even if you put gestalt tests around your Unicode 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 Unicode 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_UNICODE.
+ */
+
+/**
+ * evtype_None:
+ *
+ * No event. This is a placeholder, and glk_select() never returns it.
+ */
+
+/**
+ * evtype_Timer:
+ *
+ * An event that repeats at fixed intervals. See <link
+ * linkend="chimara-Timer-Events">Timer Events</link>.
+ */
+
+/**
+ * evtype_CharInput:
+ *
+ * A keystroke event in a window. See <link
+ * linkend="chimara-Character-Input-Events">Character Input Events</link>.
+ *
+ * If a window has a pending request for character input, and the player hits a
+ * key in that window, glk_select() will return an event whose type is
+ * #evtype_CharInput. Once this happens, the request is complete; it is no
+ * longer pending. You must call glk_request_char_event() or
+ * glk_request_char_event_uni() if you want another character from that window.
+ *
+ * In the event structure, @win tells what window the event came from. @val1
+ * tells what character was entered; this will be a character code, or a special
+ * keycode. (See <link linkend="chimara-Character-Input">Character
+ * Input</link>.) If you called glk_request_char_event(), @val1 will be in
+ * 0..255, or else a special keycode. In any case, @val2 will be 0.
+ */
+
+/**
+ * evtype_LineInput:
+ *
+ * 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
+ * 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>
+ *
+ * It is illegal to print anything to a window which has line input pending.
+ *
+ * <note><para>
+ * This is because the window may be displaying and editing the player's
+ * input, and printing anything would make life unnecessarily complicated for
+ * the library.
+ * </para></note>
+ */
+
+/**
+ * evtype_MouseInput:
+ *
+ * A mouse click in a window. See <link
+ * linkend="chimara-Mouse-Input-Events">Mouse Input Events</link>.
+ */
+
+/**
+ * evtype_Arrange:
+ *
+ * An event signalling that the sizes of some windows have changed.
+ *
+ * Some platforms allow the player to resize the Glk window during play. This
+ * will naturally change the sizes of your windows. If this occurs, then
+ * immediately after all the rearrangement, glk_select() will return an event
+ * whose type is #evtype_Arrange. You can use this notification to redisplay the
+ * contents of a graphics or text grid window whose size has changed.
+ *
+ * <note><para>
+ * The display of a text buffer window is entirely up to the library, so you
+ * don't need to worry about those.
+ * </para></note>
+ *
+ * In the event structure, @win will be %NULL if all windows are affected. If
+ * only some windows are affected, @win will refer to a window which contains
+ * all the affected windows. @val1 and @val2 will be 0.
+ *
+ * <note><para>
+ * You can always play it safe, ignore @win, and redraw every graphics and
+ * text grid window.
+ * </para></note>
+ *
+ * An arrangement event is guaranteed to occur whenever the player causes any
+ * window to change size, as measured by its own metric.
+ *
+ * <note><para>
+ * Size changes caused by you — for example, if you open, close, or
+ * resize a window — do not trigger arrangement events. You must be
+ * aware of the effects of your window management, and redraw the windows that
+ * you affect.
+ * </para></note>
+ *
+ * <note><para>
+ * It is possible that several different player actions can cause windows to
+ * change size. For example, if the player changes the screen resolution, an
+ * arrangement event might be triggered. This might also happen if the player
+ * changes his display font to a different size; the windows would then be
+ * different <quote>sizes</quote> in the metric of rows and columns, which is
+ * the important metric and the only one you have access to.
+ * </para></note>
+ *
+ * Arrangement events, like timer events, can be returned by glk_select_poll().
+ * But this will not occur on all platforms. You must be ready to receive an
+ * arrangement event when you call glk_select_poll(), but it is possible that it
+ * will not arrive until the next time you call glk_select().
+ *
+ * <note><para>
+ * This is because on some platforms, window resizing is handled as part of
+ * player input; on others, it can be triggered by an external process such as
+ * a window manager.
+ * </para></note>
+ */
+
+/**
+ * evtype_Redraw:
+ *
+ * An event signalling that graphics windows must be redrawn.
+ *
+ * On platforms that support graphics, it is possible that the contents of a
+ * graphics window will be lost, and have to be redrawn from scratch. If this
+ * occurs, then glk_select() will return an event whose type is #evtype_Redraw.
+ *
+ * In the event structure, @win will be %NULL if all windows are affected. If
+ * only some windows are affected, @win will refer to a window which contains
+ * all the affected windows. @val1 and @val2 will be 0.
+ *
+ * <note><para>
+ * You can always play it safe, ignore @win, and redraw every graphics window.
+ * </para></note>
+ *
+ * Affected windows are already cleared to their background color when you
+ * receive the redraw event.
+ *
+ * Redraw events can be returned by glk_select_poll(). But, like arrangement
+ * 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>.
+ */
+
+/**
+ * evtype_SoundNotify:
+ *
+ * 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:
+ *
+ * On platforms that support hyperlinks, you can request to receive an
+ * #evtype_Hyperlink event when the player selects a link. See <link
+ * linkend="chimara-Accepting-Hyperlink-Events">Accepting Hyperlink
+ * Events</link>.
+ */
+
+/**
+ * event_t:
+ * @type: the event type
+ * @win: the window that spawned the event, or %NULL
+ * @val1: information, the meaning of which depends on the type of event
+ * @val2: more information, the meaning of which depends on the type of event
+ *
+ * The event structure is self-explanatory. @type is the event type. The window
+ * that spawned the event, if relevant, is in @win. The remaining fields contain
+ * more information specific to the event.
+ *
+ * The event types are described below. Note that #evtype_None is zero, and the
+ * other values are positive. Negative event types (0x80000000 to 0xFFFFFFFF)
+ * are reserved for implementation-defined events.
+ */
+
+/**
+ * keycode_Unknown:
+ *
+ * Represents any key that has no Latin-1 or special code.
+ */
+
+/**
+ * keycode_Left:
+ *
+ * Represents the <keycap function="left">left arrow</keycap> key.
+ */
+
+/**
+ * keycode_Right:
+ *
+ * Represents the <keycap function="right">right arrow</keycap> key.
+ */
+
+/**
+ * keycode_Up:
+ *
+ * Represents the <keycap function="up">up arrow</keycap> key.
+ */
+
+/**
+ * keycode_Down:
+ *
+ * Represents the <keycap function="down">down arrow</keycap> key.
+ */
+
+/**
+ * keycode_Return:
+ *
+ * Represents the <keycap function="enter">return</keycap> or <keycap
+ * function="enter">enter</keycap> keys.
+ */
+
+/**
+ * keycode_Delete:
+ *
+ * Represents the <keycap function="delete">delete</keycap> or <keycap
+ * function="backspace">backspace</keycap> keys.
+ */
+
+/**
+ * keycode_Escape:
+ *
+ * Represents the <keycap function="escape">escape</keycap> key.
+ */
+
+/**
+ * keycode_Tab:
+ *
+ * Represents the <keycap function="tab">tab</keycap> key.
+ */
+
+/**
+ * keycode_PageUp:
+ *
+ * Represents the <keycap function="pageup">page up</keycap> key.
+ */
+
+/**
+ * keycode_PageDown:
+ *
+ * Represents the <keycap function="pagedown">page down</keycap> key.
+ */
+
+/**
+ * keycode_Home:
+ *
+ * Represents the <keycap function="home">home</keycap> key.
+ */
+
+/**
+ * keycode_End:
+ *
+ * Represents the <keycap function="end">end</keycap> key.
+ */
+
+/**
+ * keycode_Func1:
+ *
+ * Represents the <keycap>F1</keycap> key.
+ */
+
+/**
+ * keycode_Func2:
+ *
+ * Represents the <keycap>F2</keycap> key.
+ */
+
+/**
+ * keycode_Func3:
+ *
+ * Represents the <keycap>F3</keycap> key.
+ */
+
+/**
+ * keycode_Func4:
+ *
+ * Represents the <keycap>F4</keycap> key.
+ */
+
+/**
+ * keycode_Func5:
+ *
+ * Represents the <keycap>F5</keycap> key.
+ */
+
+/**
+ * keycode_Func6:
+ *
+ * Represents the <keycap>F6</keycap> key.
+ */
+
+/**
+ * keycode_Func7:
+ *
+ * Represents the <keycap>F7</keycap> key.
+ */
+
+/**
+ * keycode_Func8:
+ *
+ * Represents the <keycap>F8</keycap> key.
+ */
+
+/**
+ * keycode_Func9:
+ *
+ * Represents the <keycap>F9</keycap> key.
+ */
+
+/**
+ * keycode_Func10:
+ *
+ * Represents the <keycap>F10</keycap> key.
+ */
+
+/**
+ * keycode_Func11:
+ *
+ * Represents the <keycap>F11</keycap> key.
+ */
+
+/**
+ * keycode_Func12:
+ *
+ * Represents the <keycap>F12</keycap> key.
+ */
+
+/**
+ * keycode_MAXVAL:
+ *
+ * This value is equal to the number of special keycodes. The last keycode is
+ * The last keycode is always
+ * <informalequation>
+ * <alt>(0x100000000 - <keysym>keycode_MAXVAL</keysym>)</alt>
+ * <mathphrase>(0x100000000 - <keysym>keycode_MAXVAL</keysym>)</mathphrase>
+ * </informalequation>
+ * .
+ */
+
+/**
+ * stream_result_t:
+ * @readcount: Number of characters read from the stream.
+ * @writecount: Number of characters printed to the stream, including ones that
+ * were thrown away.
+ *
+ * If you are interested in the character counts of a stream (see <link
+ * linkend="chimara-Streams">Streams</link>), then you can pass a pointer to
+ * #stream_result_t as an argument of glk_stream_close() or glk_window_close().
+ * The structure will be filled with the stream's final character counts.
+ */
+
+/**
+ * wintype_AllTypes:
+ *
+ * A constant representing all window types, which may be used as the @wintype
+ * argument in glk_stylehint_set().
+ */
+
+/**
+ * wintype_Pair:
+ *
+ * A pair window is completely filled by the two windows it contains. It
+ * supports no input and no output, and it has no size.
+ *
+ * You cannot directly create a pair window; one is automatically created
+ * every time you split a window with glk_window_open(). Pair windows are
+ * always created with a rock value of 0.
+ *
+ * You can close a pair window with glk_window_close(); this also closes every
+ * window contained within the pair window.
+ *
+ * It is legal to split a pair window when you call glk_window_open().
+ */
+
+/**
+ * wintype_Blank:
+ *
+ * A blank window is always blank. It supports no input and no output. (You
+ * can call glk_window_get_stream() on it, as you can with any window, but
+ * printing to the resulting stream has no effect.) A blank window has no
+ * size; glk_window_get_size() will return (0,0), and it is illegal to set a
+ * window split with a fixed size in the measurement system of a blank window.
+ *
+ * <note><para>
+ * A blank window is not the same as there being no windows. When Glk starts
+ * up, there are no windows at all, not even a window of the blank type.
+ * </para></note>
+ */
+
+/**
+ * wintype_TextBuffer:
+ *
+ * A text buffer window contains a linear stream of text. It supports output;
+ * when you print to it, the new text is added to the end. There is no way for
+ * you to affect text which has already been printed. There are no guarantees
+ * about how much text the window keeps; old text may be stored forever, so
+ * that the user can scroll back to it, or it may be thrown away as soon as it
+ * scrolls out of the window.
+ *
+ * <note><para>
+ * Therefore, there may or may not be a player-controllable scroll bar or
+ * other scrolling widget.
+ * </para></note>
+ *
+ * The display of the text in a text buffer is up to the library. Lines will
+ * probably not be broken in the middles of words — but if they are, the
+ * library is not doing anything illegal, only ugly. Text selection and copying
+ * to a clipboard, if available, are handled however is best on the player's
+ * machine. Paragraphs (as defined by newline characters in the output) may be
+ * indented.
+ *
+ * <note><para>
+ * You should not, in general, fake this by printing spaces before each
+ * paragraph of prose text. Let the library and player preferences handle
+ * that. Special cases (like indented lists) are of course up to you.
+ * </para></note>
+ *
+ * When a text buffer is cleared (with glk_window_clear()), the library will do
+ * something appropriate; the details may vary. It may clear the window, with
+ * later text appearing at the top — or the bottom. It may simply print
+ * enough blank lines to scroll the current text out of the window. It may
+ * display a distinctive page-break symbol or divider.
+ *
+ * The size of a text buffer window is necessarily imprecise. Calling
+ * glk_window_get_size() will return the number of rows and columns that would
+ * be available <emphasis>if</emphasis> the window was filled with
+ * <quote>0</quote> (zero) characters in the <quote>normal</quote> font.
+ * However, the window may use a non-fixed-width font, so that number of
+ * characters in a line could vary. The window might even support
+ * variable-height text (say, if the player is using large text for emphasis);
+ * that would make the number of lines in the window vary as well.
+ *
+ * Similarly, when you set a fixed-size split in the measurement system of a
+ * text buffer, you are setting a window which can handle a fixed number of rows
+ * (or columns) of <quote>0</quote> characters. The number of rows (or
+ * characters) that will actually be displayed depends on font variances.
+ *
+ * A text buffer window supports both character and line input, but not mouse
+ * input.
+ *
+ * In character input, there will be some visible signal that the window is
+ * waiting for a keystroke. (Typically, a cursor at the end of the text.) When
+ * the player hits a key in that window, an event is generated, but the key is
+ * <emphasis>not</emphasis> printed in the window.
+ *
+ * In line input, again, there will be some visible signal. It is most common
+ * for the player to compose input in the window itself, at the end of the text.
+ * (This is how IF story input usually looks.) But it's not strictly required.
+ * An alternative approach is the way MUD clients usually work: there is a
+ * dedicated one-line input window, outside of Glk's window space, and the user
+ * composes input there.
+ *
+ * <note><para>
+ * If this approach is used, there will still be some way to handle input from
+ * two windows at once. It is the library's responsibility to make this
+ * available to the player. You only need request line input and wait for the
+ * 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.
+ *
+ * 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.
+ */
+
+/**
+ * wintype_TextGrid:
+ *
+ * A text grid contains a rectangular array of characters, in a fixed-width
+ * font. Its size is the number of columns and rows of the array.
+ *
+ * A text grid window supports output. It maintains knowledge of an output
+ * cursor position. When the window is opened, it is filled with blanks (space
+ * characters), and the output cursor starts in the top left corner —
+ * character (0,0). If the window is cleared with glk_window_clear(), the window
+ * is filled with blanks again, and the cursor returns to the top left corner.
+ *
+ * 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.
+ *
+ * <note><para>
+ * Note that printing fancy characters may cause the cursor to advance more
+ * than one position per character. (For example, the <quote>æ</quote>
+ * ligature may print as two characters.) See <link
+ * linkend="chimara-Output">Output</link>, for how to test this situation.
+ * </para></note>
+ *
+ * You can set the cursor position with glk_window_move_cursor().
+ *
+ * When a text grid 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 blanks.
+ *
+ * <note><para>
+ * You may wish to watch for #evtype_Arrange events, and clear-and-redraw your
+ * text grid windows when you see them change size.
+ * </para></note>
+ *
+ * Text grid window support character and line input, as well as mouse input (if
+ * a mouse is available.)
+ *
+ * Mouse input returns the position of the character that was touched, from
+ * (0,0) to
+ * <inlineequation>
+ * <alt>(width-1,height-1)</alt>
+ * <mathphrase>(width - 1, height - 1)</mathphrase>
+ * </inlineequation>
+ * .
+ *
+ * Character input is as described in the previous section.
+ *
+ * Line input is slightly different; it is guaranteed to take place in the
+ * window, at the output cursor position. The player can compose input only to
+ * the right edge of the window; therefore, the maximum input length is
+ * <inlineequation>
+ * <alt>(windowwidth - 1 - cursorposition)</alt>
+ * <mathphrase>(windowwidth - 1 - cursorposition)</mathphrase>
+ * </inlineequation>
+ * . If the maxlen argument of glk_request_line_event() is smaller than this,
+ * the library will not allow the input cursor to go more than maxlen characters
+ * past its start point.
+ *
+ * <note><para>
+ * This allows you to enter text in a fixed-width field, without the player
+ * being able to overwrite other parts of the window.
+ * </para></note>
+ *
+ * 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.
+ */
+
+/**
+ * wintype_Graphics:
+ *
+ * A graphics window contains a rectangular array of pixels. Its size is the
+ * number of columns and rows of the array.
+ *
+ * Each graphics window has a background color, which is initially white. You
+ * can change this; see <link
+ * 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
+ * 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.
+ *
+ * <note><para>
+ * You may wish to watch for #evtype_Arrange events, and clear-and-redraw your
+ * graphics windows when you see them change size.
+ * </para></note>
+ *
+ * In some libraries, you can receive a graphics-redraw event (#evtype_Redraw)
+ * at any time. This signifies that the window in question has been cleared to
+ * its background color, and must be redrawn. If you create any graphics
+ * windows, you <emphasis>must</emphasis> handle these events.
+ *
+ * <note><para>
+ * Redraw events can be triggered when a Glk window is uncovered or made
+ * visible by the platform's window manager. On the other hand, some Glk
+ * libraries handle these problem automatically — for example, with a
+ * backing store — and do not send you redraw events. On the third hand,
+ * the backing store may be discarded if memory is low, or for other reasons
+ * — perhaps the screen's color depth has changed. So redraw events are
+ * always a possibility, even in clever libraries. This is why you must be
+ * prepared to handle them.
+ *
+ * However, you will not receive a redraw event when you create a graphics
+ * window. It is assumed that you will do the initial drawing of your own
+ * accord. You also do not get redraw events when a graphics window is
+ * enlarged. If you ordered the enlargement, you already know about it; if the
+ * player is responsible, you receive a window-arrangement event, which covers
+ * the situation.
+ * </para></note>
+ *
+ * For a description of the drawing functions that apply to graphics windows,
+ * see <link linkend="chimara-Graphics-in-Graphics-Windows">Graphics in Graphics
+ * Windows</link>.
+ *
+ * Graphics windows support no text input or output.
+ *
+ * Not all libraries support graphics windows. You can test whether Glk graphics
+ * are available using the gestalt system. In a C program, you can also test
+ * whether the graphics functions are defined at compile-time. See <link
+ * linkend="chimara-Testing-for-Graphics-Capabilities">Testing for Graphics
+ * Capabilities</link>.
+ *
+ * <note><para>
+ * As with all windows, you should also test for %NULL when you create a
+ * graphics window.
+ * </para></note>
+ */
+
+/**
+ * winmethod_Left:
+ *
+ * When calling glk_window_open() with this @method, the new window will be
+ * to the left of the old one which was split.
+ */
+
+/**
+ * winmethod_Right:
+ *
+ * When calling glk_window_open() with this @method, the new window will be
+ * to the right of the old one which was split.
+ */
+
+/**
+ * winmethod_Above:
+ *
+ * When calling glk_window_open() with this @method, the new window will be
+ * above the old one which was split.
+ */
+
+/**
+ * winmethod_Below:
+ *
+ * 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 fixed size. (See glk_window_open()).
+ */
+
+/**
+ * winmethod_Proportional:
+ *
+ * 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:
+ *
+ * Bitwise AND this value with a window splitting method argument to find
+ * whether the new window has #winmethod_Fixed or #winmethod_Proportional.
+ */
+
+/**
+ * fileusage_Data:
+ *
+ * Any other kind of file (preferences, statistics, arbitrary data.)
+ */
+
+/**
+ * fileusage_SavedGame:
+ *
+ * A file which stores game state.
+ */
+
+/**
+ * fileusage_Transcript:
+ *
+ * A file which contains a stream of text from the game (often an echo stream
+ * from a window.)
+ */
+
+/**
+ * fileusage_InputRecord:
+ *
+ * A file which records player input.
+ */
+
+/**
+ * fileusage_TextMode:
+ *
+ * The file contents will be transformed to a platform-native text file as they
+ * are written out. Newlines may be converted to linefeeds or
+ * 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.
+ *
+ * <note><para>
+ * Line breaks will always be converted; other conversions are more
+ * questionable. If you write out a file in text mode, and then read it back
+ * in text mode, high-bit characters (128 to 255) may be transformed or lost.
+ * </para></note>
+ * <note><title>Chimara</title>
+ * <para>
+ * Text mode files in Chimara are in UTF-8, which is GTK+'s native file
+ * encoding.
+ * </para></note>
+ */
+
+/**
+ * fileusage_BinaryMode:
+ *
+ * The file contents will be stored exactly as they are written, and read back
+ * in the same way. The resulting file may not be viewable on platform-native
+ * text file viewers.
+ */
+
+/**
+ * fileusage_TypeMask:
+ *
+ * Bitwise AND this value with a file usage argument to find whether the file
+ * type is #fileusage_SavedGame, #fileusage_Transcript, #fileusage_InputRecord,
+ * or #fileusage_Data.
+ */
+
+/**
+ * filemode_Write:
+ *
+ * An output stream.
+ *
+ * <note><para>
+ * Corresponds to mode <code>"w"</code> in the stdio library, using fopen().
+ * </para></note>
+ */
+
+/**
+ * filemode_Read:
+ *
+ * An input stream.
+ *
+ * <note><para>
+ * Corresponds to mode <code>"r"</code> in the stdio library, using fopen().
+ * </para></note>
+ */
+
+/**
+ * filemode_ReadWrite:
+ *
+ * Both an input and an output stream.
+ *
+ * <note><para>
+ * Corresponds to mode <code>"r+"</code> in the stdio library, using fopen().
+ * </para></note>
+ */
+
+/**
+ * filemode_WriteAppend:
+ *
+ * An output stream, but the data will added to the end of whatever already
+ * existed in the destination, instead of replacing it.
+ *
+ * <note><para>
+ * Corresponds to mode <code>"a"</code> in the stdio library, using fopen().
+ * </para></note>
+ */
+
+/**
+ * seekmode_Start:
+ *
+ * In glk_stream_set_position(), signifies that @pos is counted in characters
+ * after the beginning of the file.
+ */
+
+/**
+ * seekmode_Current:
+ *
+ * In glk_stream_set_position(), signifies that @pos is counted in characters
+ * after the current position (moving backwards if @pos is negative.)
+ */
+
+/**
+ * seekmode_End:
+ *
+ * In glk_stream_set_position(), signifies that @pos is counted in characters
+ * after the end of the file. (@pos should always be zero or negative, so that
+ * this will move backwards to a position within the file.
+ */
+
/* If an abort event was generated, the thread should have exited by now */
g_assert(event->type != evtype_Abort);
}
+
/**
* glk_fileref_iterate:
- * @fref: A file reference, or #NULL.
- * @rockptr: Return location for the next window's rock, or #NULL.
+ * @fref: A file reference, or %NULL.
+ * @rockptr: Return location for the next fileref's rock, or %NULL.
*
- * Iterates over the list of file references; if @fref is #NULL, it returns the
- * first file reference, otherwise the next file reference after @fref. If
- * there are no more, it returns #NULL. The file reference's rock is stored in
- * @rockptr. If you don't want the rocks to be returned, you may set @rockptr
- * to #NULL.
+ * Iterates through all the existing filerefs. See <link
+ * linkend="chimara-Iterating-Through-Opaque-Objects">Iterating Through Opaque
+ * Objects</link>.
*
- * The order in which file references are returned is arbitrary. The order may
- * change every time you create or destroy a file reference, invalidating the
- * iteration.
- *
- * Returns: the next file reference, or #NULL if there are no more.
+ * Returns: the next file reference, or %NULL if there are no more.
*/
frefid_t
glk_fileref_iterate(frefid_t fref, glui32 *rockptr)
* glk_fileref_get_rock:
* @fref: A file reference.
*
- * Returns the file reference @fref's rock value.
+ * Retrieves the file reference @fref's rock value. See <link
+ * linkend="chimara-Rocks">Rocks</link>.
*
* Returns: A rock value.
*/
/**
* glk_fileref_create_temp:
- * @usage: Bitfield with one or more of the #fileusage_ constants.
+ * @usage: Bitfield with one or more of the <code>fileusage_</code> constants.
* @rock: The new fileref's rock value.
*
* Creates a reference to a temporary file. It is always a new file (one which
* does not yet exist). The file (once created) will be somewhere out of the
* player's way.
*
+ * <note><para>
+ * This is why no name is specified; the player will never need to know it.
+ * </para></note>
+ *
* A temporary file should never be used for long-term storage. It may be
* deleted automatically when the program exits, or at some later time, say
* when the machine is turned off or rebooted. You do not have to worry about
/**
* glk_fileref_create_by_prompt:
- * @usage: Bitfield with one or more of the #fileusage_ constants.
+ * @usage: Bitfield with one or more of the <code>fileusage_</code> constants.
* @fmode: File mode, contolling the dialog's behavior.
* @rock: The new fileref's rock value.
*
- * Creates a reference to a file by opening a file chooser dialog. If @fmode is
- * #filemode_Read, then the file must already exist and the user will be asked
- * to select from existing files. If @fmode is #filemode_Write, then the file
- * should not exist; if the user selects an existing file, he or she will be
- * warned that it will be replaced. If @fmode is #filemode_ReadWrite, then the
- * file may or may not exist; if it already exists, the user will be warned
- * that it will be modified. The @fmode argument should generally match the
- * @fmode which will be used to open the file.
+ * Creates a reference to a file by asking the player to locate it. The library
+ * may simply prompt the player to type a name, or may use a platform-native
+ * file navigation tool. (The prompt, if any, is inferred from the usage
+ * argument.)
+ *
+ * <note><title>Chimara</title>
+ * <para>
+ * Chimara uses a <link
+ * linkend="gtk-GtkFileChooserDialog">GtkFileChooserDialog</link>.
+ * </para></note>
+ *
+ * @fmode must be one of these values:
+ * <variablelist>
+ * <varlistentry>
+ * <term>#filemode_Read</term>
+ * <listitem><para>The file must already exist; and the player will be asked
+ * to select from existing files which match the usage.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>#filemode_Write</term>
+ * <listitem><para>The file should not exist; if the player selects an
+ * existing file, he will be warned that it will be replaced.
+ * </para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>#filemode_ReadWrite</term>
+ * <listitem><para>The file may or may not exist; if it already exists, the
+ * player will be warned that it will be modified.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>#filemode_WriteAppend</term>
+ * <listitem><para>Same behavior as #filemode_ReadWrite.</para></listitem>
+ * </varlistentry>
+ * </variablelist>
+ *
+ * The @fmode argument should generally match the @fmode which will be used to
+ * open the file.
+ *
+ * <note><para>
+ * It is possible that the prompt or file tool will have a
+ * <quote>cancel</quote> option. If the player chooses this,
+ * glk_fileref_create_by_prompt() will return %NULL. This is a major reason
+ * why you should make sure the return value is valid before you use it.
+ * </para></note>
*
* Returns: A new fileref, or #NULL if the fileref creation failed or the
* dialog was canceled.
/**
* glk_fileref_create_by_name:
- * @usage: Bitfield with one or more of the #fileusage_ constants.
+ * @usage: Bitfield with one or more of the <code>fileusage_</code> constants.
* @name: A filename.
* @rock: The new fileref's rock value.
*
* This creates a reference to a file with a specific name. The file will be
- * in the same directory as your program, and visible to the player.
+ * in a fixed location relevant to your program, and visible to the player.
+ *
+ * <note><para>
+ * This usually means <quote>in the same directory as your program.</quote>
+ * </para></note>
+ * <note><title>Chimara</title>
+ * <para>
+ * In Chimara, the file is created in the current working directory.
+ * </para></note>
*
- * Returns: A new fileref, or #NULL if the fileref creation failed.
+ * Since filenames are highly platform-specific, you should use
+ * glk_fileref_create_by_name() with care. It is legal to pass any string in the
+ * name argument. However, the library may have to mangle, transform, or
+ * truncate the string to make it a legal native filename.
+ *
+ * <note><para>
+ * For example, if you create two filerefs with the names <quote>File</quote>
+ * and <quote>FILE</quote>, they may wind up pointing to the same file; the
+ * platform may not support case distinctions in file names. Another example:
+ * on a platform where file type is specified by filename suffix, the library
+ * will add an appropriate suffix based on the usage; any suffix in the string
+ * will be overwritten or added to. For that matter, remember that the period
+ * is not a legal character in Acorn filenames...
+ * </para></note>
+ *
+ * The most conservative approach is to pass a string of no more than 8
+ * characters, consisting entirely of upper-case letters and numbers, starting
+ * with a letter. You can then be reasonably sure that the resulting filename
+ * will display all the characters you specify — in some form.
+ *
+ * Returns: A new fileref, or %NULL if the fileref creation failed.
*/
frefid_t
glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock)
/**
* glk_fileref_create_from_fileref:
- * @usage: Bitfield with one or more of the #fileusage_ constants.
+ * @usage: Bitfield with one or more of the <code>fileusage_</code> constants.
* @fref: Fileref to copy.
* @rock: The new fileref's rock value.
*
* This copies an existing file reference @fref, but changes the usage. (The
- * original @fref is not modified.)
+ * original fileref is not modified.)
+ *
+ * The use of this function can be tricky. If you change the type of the fileref
+ * (#fileusage_Data, #fileusage_SavedGame, etc), the new reference may or may
+ * not point to the same actual disk file.
*
- * If you write to a file in text mode and then read from it in binary mode,
- * the results are platform-dependent.
+ * <note><para>
+ * This generally depends on whether the platform uses suffixes to indicate
+ * file type.
+ * </para></note>
+ *
+ * If you do this, and open both file references for writing, the results are
+ * unpredictable. It is safest to change the type of a fileref only if it refers
+ * to a nonexistent file.
+ *
+ * If you change the mode of a fileref (#fileusage_TextMode,
+ * #fileusage_BinaryMode), but leave the rest of the type unchanged, the new
+ * fileref will definitely point to the same disk file as the old one.
+ *
+ * Obviously, if you write to a file in text mode and then read from it in
+ * binary mode, the results are platform-dependent.
*
- * Returns: A new fileref, or #NULL if the fileref creation failed.
+ * Returns: A new fileref, or %NULL if the fileref creation failed.
*/
frefid_t
glk_fileref_create_from_fileref(glui32 usage, frefid_t fref, glui32 rock)
* glk_fileref_destroy:
* @fref: Fileref to destroy.
*
- * Destroys a fileref which you have created. This does not affect the disk
- * file.
+ * Destroys a fileref which you have created. This does <emphasis>not</emphasis>
+ * affect the disk file; it just reclaims the resources allocated by the
+ * <code>glk_fileref_create...</code> function.
*
* It is legal to destroy a fileref after opening a file with it (while the
* file is still open.) The fileref is only used for the opening operation,
* glk_fileref_delete_file:
* @fref: A refrence to the file to delete.
*
- * Deletes the file referred to by @fref. Does not destroy @fref itself.
+ * Deletes the file referred to by @fref. It does not destroy @fref itself.
*/
void
glk_fileref_delete_file(frefid_t fref)
*
* Checks whether the file referred to by @fref exists.
*
- * Returns: #TRUE (1) if @fref refers to an existing file, #FALSE (0) if not.
+ * Returns: %TRUE (1) if @fref refers to an existing file, and %FALSE (0) if
+ * not.
*/
glui32
glk_fileref_does_file_exist(frefid_t fref)
#include <gtk/gtk.h>
#include "glk.h"
+/**
+ * glk_fileref_struct:
+ *
+ * This is an opaque structure (see <link linkend="chimara-Opaque-Structures">
+ * Opaque Structures</link> and should not be accessed directly.
+ */
struct glk_fileref_struct
{
+ /*< private >*/
glui32 rock;
/* Pointer to the list node in the global fileref list that contains this
fileref */
* Calls the gestalt system to request information about the capabilities of the
* API. The selector @sel tells which capability you are requesting information
* about; the other three arguments are additional information, which may or may
- * not be meaningful. The @arr and @arrlen arguments are always optional; you
- * may always pass %NULL and 0, if you do not want whatever information they
- * represent. glk_gestalt() is simply a shortcut for this; glk_gestalt(x, y) is
- * exactly the same as glk_gestalt_ext(x, y, NULL, 0).
+ * not be meaningful. The @arr and @arrlen arguments of glk_gestalt_ext() are
+ * always optional; you may always pass %NULL and 0, if you do not want whatever
+ * information they represent. glk_gestalt() is simply a shortcut for this;
+ * <code>#glk_gestalt(x, y)</code> is exactly the same as
+ * <code>#glk_gestalt_ext(x, y, %NULL, 0)</code>.
*
* The critical point is that if the Glk library has never heard of the selector
- * sel, it will return 0. It is always safe to call glk_gestalt(x, y) (or
- * glk_gestalt_ext(x, y, NULL, 0)). Even if you are using an old library, which
- * was compiled before the given capability was imagined, you can test for the
- * capability by calling glk_gestalt(); the library will correctly indicate that
- * it does not support it, by returning 0.
+ * @sel, it will return 0. It is <emphasis>always</emphasis> safe to call
+ * <code>#glk_gestalt(x, y)</code> (or <code>#glk_gestalt_ext(x, y, %NULL,
+ * 0)</code>). Even if you are using an old library, which was compiled before
+ * the given capability was imagined, you can test for the capability by calling
+ * glk_gestalt(); the library will correctly indicate that it does not support
+ * it, by returning 0.
*
- * <note><para>
- * It is also safe to call glk_gestalt_ext(x, y, z, zlen) for an unknown
- * selector x, where z is not %NULL, as long as z points at an array of at
- * least zlen elements. The selector will be careful not to write beyond that
- * point in the array, if it writes to the array at all.
- * </para></note>
+ * (It is also safe to call <code>#glk_gestalt_ext(x, y, z, zlen)</code> for an
+ * unknown selector <code>x</code>, where <code>z</code> is not %NULL, as long
+ * as <code>z</code> points at an array of at least <code>zlen</code> elements.
+ * The selector will be careful not to write beyond that point in the array, if
+ * it writes to the array at all.)
*
- * <note><para>
- * If a selector does not use the second argument, you should always pass 0; do
- * not assume that the second argument is simply ignored. This is because the
- * selector may be extended in the future. You will continue to get the current
- * behavior if you pass 0 as the second argument, but other values may produce
- * other behavior.
- * </para></note>
+ * (If a selector does not use the second argument, you should always pass 0; do
+ * not assume that the second argument is simply ignored. This is because the
+ * selector may be extended in the future. You will continue to get the current
+ * behavior if you pass 0 as the second argument, but other values may produce
+ * other behavior.)
*
* Returns: an integer, depending on what selector was called.
*/
/**
* glk_exit:
*
- * Shuts down the Glk program. This function does not return.
+ * If you want to shut down your program in the middle of your <function>
+ * glk_main()</function> function, you can call glk_exit().
+ *
+ * This function does not return.
*
* If you print some text to a window and then shut down your program, you can
- * assume that the player will be able to read it.
+ * assume that the player will be able to read it. Most likely the Glk library
+ * will give a <quote><computeroutput>Hit any key to
+ * exit</computeroutput></quote> prompt. (There are other possiblities, however.
+ * A terminal-window version of Glk might simply exit and leave the last screen
+ * state visible in the terminal window.)
*
* <note><para>
- * You should only shut down your program with glk_exit() or by returning from
- * your glk_main() function. If you call the ANSI <function>exit()</function>
- * function, bad things may happen. This Glk library is designed for multiple
- * sessions, for example, and you would be cutting off all the sessions instead
- * of just yours. You would also prevent final text from being visible to the
- * player.
+ * You should only shut down your program with glk_exit() or by returning from
+ * your <function>glk_main()</function> function. If you call the ANSI
+ * <function>exit()</function> function, bad things may happen. Some versions of
+ * the Glk library may be designed for multiple sessions, for example, and you
+ * would be cutting off all the sessions instead of just yours. You would
+ * probably also prevent final text from being visible to the player.
+ * </para></note>
+ * <note><title>Chimara</title>
+ * <para>
+ * If there are any windows open at the time glk_exit() is called, then Chimara
+ * will leave them open. This way, the final text remains visible. Note that bad
+ * things most definitely <emphasis>will</emphasis> happen if you use the ANSI
+ * <function>exit()</function>.
* </para></note>
*/
void
/**
* glk_tick:
*
- * 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.
- *
- * Well, not really. But you should call glk_tick() every so often, just in
- * case. It may be necessary to yield time to other applications in a
- * cooperative-multitasking OS, or to check for player interrupts in an infinite
- * loop.
- *
- * This call is fast; in fact, on average, it does nothing at all. So you can
- * call it often. (In a virtual machine interpreter, once per opcode is
- * appropriate. In a program with lots of computation, pick a comparable rate.)
+ * Carries out platform-dependent actions such as yielding time to the operating
+ * system and checking for interrupts. glk_tick() should be called every so
+ * often when there is a long interval between calls of glk_select() or
+ * glk_select_poll(). This call is fast; in fact, on average, it does nothing at
+ * all. So you can call it often.
+ *
+ * <note><para>
+ * In a virtual machine interpreter, once per opcode is appropriate. In a
+ * program with lots of computation, pick a comparable rate.
+ * </para></note>
*
* glk_tick() does not try to update the screen, or check for player input, or
* any other interface task. For that, you should call glk_select() or
- * glk_select_poll().
+ * glk_select_poll(). See <link linkend="chimara-Events">Events</link>.
*
- * Basically, you must ensure there's some fixed upper bound on the amount of
- * computation that can occur before a glk_tick() (or glk_select()) occurs. In a
- * VM interpreter, where the VM code might contain an infinite loop, this is
- * critical. In a C program, you can often eyeball it.
+ * <note>
+ * <para>Captious critics have pointed out that in the sample program
+ * <filename>model.c</filename>, I do not call glk_tick() at all. This is
+ * because <filename>model.c</filename> has no heavy loops. It does a bit of
+ * work for each command, and then cycles back to the top of the event loop.
+ * The glk_select() call, of course, blocks waiting for input, so it does all
+ * the yielding and interrupt-checking one could imagine.
+ * </para>
+ * <para>Basically, you must ensure there's some fixed upper bound on the
+ * amount of computation that can occur before a glk_tick() (or glk_select())
+ * occurs. In a VM interpreter, where the VM code might contain an infinite
+ * loop, this is critical. In a C program, you can often eyeball it.
+ * </para>
+ * <para>But the next version of <filename>model.c</filename> will have a
+ * glk_tick() in the ornate printing loop of <function>verb_yada()</function>.
+ * Just to make the point.
+ * </para>
+ * </note>
*/
void
glk_tick()
gtk_main_iteration();
gdk_threads_leave();
}
+
#include "charset.h"
#include "input.h"
-/** glk_request_char_event:
+/**
+ * glk_request_char_event:
* @win: A window to request char events from.
*
* Request input of a Latin-1 character or special key. A window cannot have
g_signal_handler_unblock( G_OBJECT(win->widget), win->keypress_handler );
}
-/** glk_request_char_event_uni:
+/**
+ * glk_request_char_event_uni:
* @win: A window to request char events from.
*
* Request input of a Unicode character or special key. See
end_line_input_request(win, text);
g_free(text);
}
+
* @str: A stream, or %NULL.
* @rockptr: Return location for the next window's rock, or %NULL.
*
- * Iterates over the list of streams; if @str is %NULL, it returns the first
- * stream, otherwise the next stream after @str. If there are no more, it
- * returns %NULL. The stream's rock is stored in @rockptr. If you don't want
- * the rocks to be returned, you may set @rockptr to %NULL.
- *
- * The order in which streams are returned is arbitrary. The order may change
- * every time you create or destroy a stream, invalidating the iteration.
+ * Iterates through all the existing streams. See <link
+ * linkend="chimara-Iterating-Through-Opaque-Objects">Iterating Through Opaque
+ * Objects</link>.
*
* Returns: the next stream, or %NULL if there are no more.
*/
* glk_stream_get_rock:
* @str: A stream.
*
- * Returns the stream @str's rock value.
+ * Retrieves the stream @str's rock value. See <link
+ * linkend="chimara-Rocks">Rocks</link>.
*
* Returns: A rock value.
*/
*
* Returns the current stream, or %NULL if there is none.
*
- * Returns: A stream.
+ * Returns: A stream, or %NULL.
*/
strid_t
glk_stream_get_current()
* @ch: A character in Latin-1 encoding.
*
* Prints one character to the current stream. As with all basic functions, the
- * character is assumed to be in the Latin-1 character encoding.
+ * character is assumed to be in the Latin-1 character encoding. See <link
+ * linkend="chimara-Character-Encoding">Character Encoding</link>.
*/
void
glk_put_char(unsigned char ch)
* @ch: A Unicode code point.
*
* Prints one character to the current stream. The character is assumed to be a
- * Unicode code point.
+ * Unicode code point. See <link linkend="chimara-Character-Encoding">Character
+ * Encoding</link>.
*/
void
glk_put_char_uni(glui32 ch)
* @s: A null-terminated string in Latin-1 encoding.
*
* Prints a null-terminated string to the current stream. It is exactly
- * equivalent to:
+ * equivalent to
* <informalexample><programlisting>
- * for (ptr = s; *ptr; ptr++)
- * glk_put_char(*ptr);
+ * for (ptr = @s; *ptr; ptr++)
+ * #glk_put_char(*ptr);
* </programlisting></informalexample>
* However, it may be more efficient.
*/
* Prints a block of characters to the current stream. It is exactly equivalent
* to:
* <informalexample><programlisting>
- * for (i = 0; i < len; i++)
- * glk_put_char(buf[i]);
+ * for (i = 0; i < @len; i++)
+ * #glk_put_char(@buf[i]);
* </programlisting></informalexample>
* However, it may be more efficient.
*/
* to the buffer where output will be read from or written to. @buflen is the
* length of the buffer.
*
- * When outputting, if more than @buflen characters are written to the stream,
- * all of them beyond the buffer length will be thrown away, so as not to
- * overwrite the buffer. (The character count of the stream will still be
- * maintained correctly. That is, it will count the number of characters written
- * into the stream, not the number that fit into the buffer.)
- *
- * If @buf is %NULL, or for that matter if @buflen is zero, then <emphasis>
- * everything</emphasis> written to the stream is thrown away. This may be
- * useful if you are interested in the character count.
- *
- * When inputting, if more than @buflen characters are read from the stream, the
- * stream will start returning -1 (signalling end-of-file.) If @buf is %NULL,
- * the stream will always return end-of-file.
- *
- * The data is written to the buffer exactly as it was passed to the printing
- * functions (glk_put_char(), etc.); input functions will read the data exactly
- * as it exists in memory. No platform-dependent cookery will be done on it.
- * (You can write a disk file in text mode, but a memory stream is effectively
- * always in binary mode.)
- *
* Unicode values (characters greater than 255) cannot be written to the buffer.
- * If you try, they will be stored as 0x3F ("?") characters.
+ * If you try, they will be stored as 0x3F (<code>"?"</code>) characters.
*
- * Whether reading or writing, the contents of the buffer are undefined until
- * the stream is closed. The library may store the data there as it is written,
- * or deposit it all in a lump when the stream is closed. It is illegal to
- * change the contents of the buffer while the stream is open.
+ * Returns: the new stream, or %NULL on error.
*/
strid_t
glk_stream_open_memory(char *buf, glui32 buflen, glui32 fmode, glui32 rock)
* of 32-bit words, instead of bytes. This allows you to write and read any
* Unicode character. The @buflen is the number of words, not the number of
* bytes.
+ *
+ * Returns: the new stream, or %NULL on error.
*/
strid_t
glk_stream_open_memory_uni(glui32 *buf, glui32 buflen, glui32 fmode, glui32 rock)
* already exists, it is truncated down to zero length (an empty file). If
* @fmode is #filemode_WriteAppend, the file mark is set to the end of the
* file.
- *
- * The file may be written in text or binary mode; this is determined by the
- * @fileref argument. Similarly, platform-dependent attributes such as file
- * type are determined by @fileref.
*
* When writing in binary mode, Unicode values (characters greater than 255)
- * cannot be written to the file. If you try, they will be stored as 0x3F ("?")
- * characters. In text mode, Unicode values are stored in UTF-8.
+ * cannot be written to the file. If you try, they will be stored as 0x3F
+ * (<code>"?"</code>) characters. In text mode, Unicode values may be stored
+ * exactly, approximated, or abbreviated, depending on what the platform's text
+ * files support.
*
* Returns: A new stream, or %NULL if the file operation failed.
*/
* characters are written and read as four-byte (big-endian) values. This
* allows you to write any Unicode character.
*
- * In text mode, the file is written and read in UTF-8.
+ * In text mode, the file is written and read in a platform-dependent way, which
+ * may or may not handle all Unicode characters. A text-mode file created with
+ * glk_stream_open_file_uni() may have the same format as a text-mode file
+ * created with glk_stream_open_file(); or it may use a more Unicode-friendly
+ * format.
*
* Returns: A new stream, or %NULL if the file operation failed.
*/
* If @str is the current output stream, the current output stream is set to
* %NULL.
*
- * You cannot close window streams; use glk_window_close() instead.
+ * You cannot close window streams; use glk_window_close() instead. See <link
+ * linkend="chimara-Window-Opening-Closing-and-Constraints">Window Opening,
+ * Closing, and Constraints</link>.
*/
void
glk_stream_close(strid_t str, stream_result_t *result)
STREAM_TYPE_FILE
};
+/**
+ * glk_stream_struct:
+ *
+ * This is an opaque structure (see <link linkend="chimara-Opaque-Structures">
+ * Opaque Structures</link> and should not be accessed directly.
+ */
struct glk_stream_struct
{
+ /*< private >*/
glui32 rock;
/* Pointer to the list node in the global stream list that contains this
stream */
* @str: An output stream.
* @ch: A character in Latin-1 encoding.
*
- * Prints one character @ch to the stream @str. It is illegal for @str to be
- * %NULL, or an input-only stream.
+ * The same as glk_put_char(), except that you specify a stream @str to print
+ * to, instead of using the current stream. It is illegal for @str to be %NULL,
+ * or an input-only stream.
*/
void
glk_put_char_stream(strid_t str, unsigned char ch)
* @str: An output stream.
* @ch: A Unicode code point.
*
- * Prints one character @ch to the stream @str. It is illegal for @str to be
+ * The same as glk_put_char_uni(), except that you specify a stream @str to
+ * print to, instead of using the current stream. It is illegal for @str to be
* %NULL, or an input-only stream.
*/
void
* @str: An output stream.
* @s: A null-terminated string in Latin-1 encoding.
*
- * Prints @s to the stream @str. It is illegal for @str to be %NULL, or an
- * input-only stream.
+ * The same as glk_put_string(), except that you specify a stream @str to print
+ * to, instead of using the current stream. It is illegal for @str to be %NULL,
+ * or an input-only stream.
*/
void
glk_put_string_stream(strid_t str, char *s)
* @str: An output stream.
* @s: A null-terminated array of Unicode code points.
*
- * Prints @s to the stream @str. It is illegal for @str to be %NULL, or an
- * input-only stream.
+ * The same as glk_put_string_uni(), except that you specify a stream @str to
+ * print to, instead of using the current stream. It is illegal for @str to be
+ * %NULL, or an input-only stream.
*/
void
glk_put_string_stream_uni(strid_t str, glui32 *s)
* @buf: An array of characters in Latin-1 encoding.
* @len: Length of @buf.
*
- * Prints @buf to the stream @str. It is illegal for @str to be %NULL, or an
- * input-only stream.
+ * The same as glk_put_buffer(), except that you specify a stream @str to print
+ * to, instead of using the current stream. It is illegal for @str to be %NULL,
+ * or an input-only stream.
*/
void
glk_put_buffer_stream(strid_t str, char *buf, glui32 len)
* @buf: An array of Unicode code points.
* @len: Length of @buf.
*
- * Prints @buf to the stream @str. It is illegal for @str to be %NULL, or an
- * input-only stream.
+ * The same as glk_put_buffer_uni(), except that you specify a stream @str to
+ * print to, instead of using the current stream. It is illegal for @str to be
+ * %NULL, or an input-only stream.
*/
void
glk_put_buffer_stream_uni(strid_t str, glui32 *buf, glui32 len)
* glk_get_char_stream:
* @str: An input stream.
*
- * Reads one character from the stream @str. (There is no notion of a ``current
- * input stream.'') It is illegal for @str to be %NULL, or an output-only
- * stream.
+ * Reads one character from the stream @str. (There is no notion of a
+ * <quote>current input stream.</quote>) It is illegal for @str to be %NULL, or
+ * an output-only stream.
*
* The result will be between 0 and 255. As with all basic text functions, Glk
- * assumes the Latin-1 encoding. If the end of the stream has been reached, the
- * result will be -1. Note that high-bit characters (128..255) are
- * <emphasis>not</emphasis> returned as negative numbers.
+ * assumes the Latin-1 encoding. See <link
+ * linkend="chimara-Character-Encoding">Character Encoding</link>. If the end
+ * of the stream has been reached, the result will be -1.
+ *
+ * <note><para>
+ * Note that high-bit characters (128..255) are <emphasis>not</emphasis>
+ * returned as negative numbers.
+ * </para></note>
*
- * If the stream contains Unicode data --- for example, if it was created with
- * glk_stream_open_file_uni() or glk_stream_open_memory_uni() --- then
- * characters beyond 255 will be returned as 0x3F ("?").
+ * If the stream contains Unicode data — for example, if it was created
+ * with glk_stream_open_file_uni() or glk_stream_open_memory_uni() — then
+ * characters beyond 255 will be returned as 0x3F (<code>"?"</code>).
+ *
+ * It is usually more efficient to read several characters at once with
+ * glk_get_buffer_stream() or glk_get_line_stream(), as opposed to calling
+ * glk_get_char_stream() several times.
*
* Returns: A character value between 0 and 255, or -1 on end of stream.
*/
* Reads one character from the stream @str. The result will be between 0 and
* 0x7FFFFFFF. If the end of the stream has been reached, the result will be -1.
*
- * Returns: A character value between 0 and 255, or -1 on end of stream.
+ * Returns: A value between 0 and 0x7FFFFFFF, or -1 on end of stream.
*/
glsi32
glk_get_char_stream_uni(strid_t str)
* @buf: A buffer with space for at least @len characters.
* @len: The number of characters to read, plus one.
*
- * Reads characters from @str, until either @len - 1 characters have been read
- * or a newline has been read. It then puts a terminal null ('\0') aracter on
+ * Reads characters from @str, until either
+ * <inlineequation>
+ * <alt>@len - 1</alt>
+ * <mathphrase>@len - 1</mathphrase>
+ * </inlineequation>
+ * characters have been read or a newline has been read. It then puts a
+ * terminal null (<code>'\0'</code>) aracter on
* the end. It returns the number of characters actually read, including the
* newline (if there is one) but not including the terminal null.
*
- * It is usually more efficient to read several characters at once with
- * glk_get_buffer_stream() or glk_get_line_stream(), as opposed to calling
- * glk_get_char_stream() several times.
- *
* Returns: The number of characters actually read.
*/
glui32
* @buf: A buffer with space for at least @len Unicode code points.
* @len: The number of characters to read, plus one.
*
- * Reads Unicode characters from @str, until either @len - 1 Unicode characters
- * have been read or a newline has been read. It then puts a terminal null (a
- * zero value) on the end.
+ * Reads Unicode characters from @str, until either
+ * <inlineequation>
+ * <alt>@len - 1</alt>
+ * <mathphrase>@len - 1</mathphrase>
+ * </inlineequation>
+ * Unicode characters have been read or a newline has been read. It then puts a
+ * terminal null (a zero value) on the end.
*
* Returns: The number of characters actually read, including the newline (if
* there is one) but not including the terminal null.
* a 32-bit word. So in a binary Unicode file, positions are multiples of four
* bytes.
*
+ * <note><para>
+ * If this bothers you, don't use binary Unicode files. I don't think they're
+ * good for much anyhow.
+ * </para></note>
+ *
* Returns: position of the read/write mark in @str.
*/
glui32
* @seekmode: One of #seekmode_Start, #seekmode_Current, or #seekmode_End.
*
* Sets the position of the read/write mark in @str. The position is controlled
- * by @pos, and the meaning of @pos is controlled by @seekmode:
- * <itemizedlist>
- * <listitem>#seekmode_Start: @pos characters after the beginning of the file.
- * </listitem>
- * <listitem>#seekmode_Current: @pos characters after the current position
- * (moving backwards if @pos is negative.)</listitem>
- * <listitem>#seekmode_End: @pos characters after the end of the file. (@pos
- * should always be zero or negative, so that this will move backwards to a
- * position within the file.</listitem>
- * </itemizedlist>
+ * by @pos, and the meaning of @pos is controlled by @seekmode. See the
+ * <code>seekmode_</code> constants below.
+ *
* It is illegal to specify a position before the beginning or after the end of
* the file.
*
- * In binary files, the mark position is exact --- it corresponds with the
+ * In binary files, the mark position is exact — it corresponds with the
* number of characters you have read or written. In text files, this mapping
* can vary, because of linefeed conventions or other character-set
- * approximations. glk_stream_set_position() and glk_stream_get_position()
- * measure positions in the platform's native encoding --- after character
- * cookery. Therefore, in a text stream, it is safest to use
- * glk_stream_set_position() only to move to the beginning or end of a file, or
- * to a position determined by glk_stream_get_position().
+ * approximations. See <link linkend="chimara-Streams">Streams</link>.
+ * glk_stream_set_position() and glk_stream_get_position() measure positions in
+ * the platform's native encoding — after character cookery. Therefore,
+ * in a text stream, it is safest to use glk_stream_set_position() only to move
+ * to the beginning or end of a file, or to a position determined by
+ * glk_stream_get_position().
*
* Again, in Latin-1 streams, characters are bytes. In Unicode streams,
* characters are 32-bit words, or four bytes each.
return;
}
}
-
+
#include "glk.h"
-/**
- * glk_set_style:
- * @val: A style.
- *
- * Changes the style of the current output stream. @val should be one of
- * #style_Normal, #style_Emphasized, #style_Preformatted, #style_Header,
- * #style_Subheader, #style_Alert, #style_Note, #style_BlockQuote, #style_Input,
- * #style_User1, or #style_User2. However, any value is actually legal; if the
- * library does not recognize the style value, it will treat it as
- * #style_Normal. (This policy allows for the future definition of styles
- * without breaking old Glk libraries.)
- */
void
-glk_set_style(glui32 val)
+glk_set_style(glui32 styl)
{
/* No nothing yet */
return;
* @win: A window, or %NULL.
* @rockptr: Return location for the next window's rock, or %NULL.
*
- * Iterates over the list of windows; if @win is %NULL, it returns the first
- * window, otherwise the next window after @win. If there are no more, it
- * returns #NULL. The window's rock is stored in @rockptr. If you don't want
- * the rocks to be returned, you may set @rockptr to %NULL.
+ * This function can be used to iterate through the list of all open windows
+ * (including pair windows.) See <link
+ * linkend="chimara-Iterating-Through-Opaque-Objects">Iterating Through Opaque
+ * Objects</link>.
*
- * The order in which windows are returned is arbitrary. The root window is
- * not necessarily first, nor is it necessarily last. The order may change
- * every time you create or destroy a window, invalidating the iteration.
+ * As that section describes, the order in which windows are returned is
+ * arbitrary. The root window is not necessarily first, nor is it necessarily
+ * last.
*
* Returns: the next window, or %NULL if there are no more.
*/
* @win: A window.
*
* Returns @win's rock value. Pair windows always have rock 0; all other windows
- * have the rock value you created them with.
+ * return whatever rock value you created them with.
*
* Returns: A rock value.
*/
* glk_window_get_parent:
* @win: A window.
*
- * Returns the window @win's parent window. If @win is the root window, this
- * returns %NULL, since the root window has no parent. Remember that the parent
- * of every window is a pair window; other window types are always childless.
+ * Returns the window which is the parent of @win. If @win is the root window,
+ * this returns %NULL, since the root window has no parent. Remember that the
+ * parent of every window is a pair window; other window types are always
+ * childless.
*
* Returns: A window, or %NULL.
*/
* glk_window_get_sibling:
* @win: A window.
*
- * Returns the other child of the window @win's parent. If @win is the
- * root window, this returns %NULL.
+ * Returns the other child of @win's parent. If @win is the root window, this
+ * returns %NULL.
*
* Returns: A window, or %NULL.
*/
* #wintype_TextBuffer, or #wintype_Graphics.
* @rock: The new window's rock value.
*
- * If there are no windows, create a new root window. @split must be 0, and
- * @method and @size are ignored. Otherwise, split window @split into two, with
- * position, size, and type specified by @method, @size, and @wintype. See the
- * Glk documentation for the window placement algorithm.
+ * Creates a new window. If there are no windows, the first three arguments are
+ * meaningless. @split <emphasis>must</emphasis> be 0, and @method and @size
+ * are ignored. @wintype is the type of window you're creating, and @rock is
+ * the rock (see <link linkend="chimara-Rocks">Rocks</link>).
+ *
+ * If any windows exist, new windows must be created by splitting existing
+ * ones. @split is the window you want to split; this <emphasis>must
+ * not</emphasis> be zero. @method is a mask of constants to specify the
+ * direction and the split method (see below). @size is the size of the split.
+ * @wintype is the type of window you're creating, and @rock is the rock.
+ *
+ * Remember that it is possible that the library will be unable to create a new
+ * window, in which case glk_window_open() will return %NULL.
+ *
+ * <note><para>
+ * It is acceptable to gracefully exit, if the window you are creating is an
+ * important one — such as your first window. But you should not try to
+ * perform any window operation on the id until you have tested to make sure
+ * it is non-zero.
+ * </para></note>
+ *
+ * The examples we've seen so far have the simplest kind of size control. (Yes,
+ * this is <quote>below</quote>.) Every pair is a percentage split, with
+ * <inlineequation>
+ * <alt>X</alt>
+ * <mathphrase>X</mathphrase>
+ * </inlineequation>
+ * percent going to one side, and
+ * <inlineequation>
+ * <alt>(100-X)</alt>
+ * <mathphrase>(100 - X)</mathphrase>
+ * </inlineequation>
+ * percent going to the other side. If the player resizes the window, the whole
+ * mess expands, contracts, or stretches in a uniform way.
+ *
+ * As I said above, you can also make fixed-size splits. This is a little more
+ * complicated, because you have to know how this fixed size is measured.
+ *
+ * Sizes are measured in a way which is different for each window type. For
+ * example, a text grid window is measured by the size of its fixed-width font.
+ * You can make a text grid window which is fixed at a height of four rows, or
+ * ten columns. A text buffer window is measured by the size of its font.
+ *
+ * <note><para>
+ * Remember that different windows may use different size fonts. Even two
+ * text grid windows may use fixed-size fonts of different sizes.
+ * </para></note>
+ *
+ * Graphics windows are measured in pixels, not characters. Blank windows
+ * aren't measured at all; there's no meaningful way to measure them, and
+ * therefore you can't create a blank window of a fixed size, only of a
+ * proportional (percentage) size.
+ *
+ * So to create a text buffer window which takes the top 40% of the original
+ * window's space, you would execute
+ * <informalexample><programlisting>
+ * newwin = #glk_window_open(win, #winmethod_Above | #winmethod_Proportional, 40, #wintype_TextBuffer, 0);
+ * </programlisting></informalexample>
+ *
+ * To create a text grid which is always five lines high, at the bottom of the
+ * original window, you would do
+ * <informalexample><programlisting>
+ * newwin = #glk_window_open(win, #winmethod_Below | #winmethod_Fixed, 5, #wintype_TextGrid, 0);
+ * </programlisting></informalexample>
+ *
+ * Note that the meaning of the @size argument depends on the @method argument.
+ * If the method is #winmethod_Fixed, it also depends on the @wintype argument.
+ * The new window is then called the <quote>key window</quote> of this split,
+ * because its window type determines how the split size is computed.
+ *
+ * <note><para>
+ * For #winmethod_Proportional splits, you can still call the new window the
+ * <quote>key window</quote>. But the key window is not important for
+ * proportional splits, because the size will always be computed as a simple
+ * ratio of the available space, not a fixed size of one child window.
+ * </para></note>
+ *
+ * This system is more or less peachy as long as all the constraints work out.
+ * What happens when there is a conflict? The rules are simple. Size control
+ * always flows down the tree, and the player is at the top. Let's bring out an
+ * example:
+ * <mediaobject><textobject><phrase>Screen shot 5</phrase></textobject>
+ * </mediaobject>
+ *
+ * First we split A into A and B, with a 50% proportional split. Then we split
+ * A into A and C, with C above, C being a text grid window, and C gets a fixed
+ * size of two rows (as measured in its own font size). A gets whatever remains
+ * of the 50% it had before.
+ *
+ * Now the player stretches the window vertically.
+ * <mediaobject><textobject><phrase>Screen shot 6</phrase></textobject>
+ * </mediaobject>
+ *
+ * The library figures: the topmost split, the original A/B split, is 50-50. So
+ * B gets half the screen space, and the pair window next to it (the lower
+ * <quote>O</quote>) gets the other half. Then it looks at the lower
+ * <quote>O</quote>. C gets two rows; A gets the rest. All done.
+ *
+ * Then the user maliciously starts squeezing the window down, in stages:
+ * <mediaobject id="chimara-Figure-Squeezing-Window"><textobject><phrase>
+ * Screen shot 7</phrase></textobject></mediaobject>
+ *
+ * The logic remains the same. B always gets half the space. At stage 3,
+ * there's no room left for A, so it winds up with zero height. Nothing
+ * displayed in A will be visible. At stage 4, there isn't even room in the
+ * upper 50% to give C its two rows; so it only gets one. Finally, C is
+ * squashed out of existence as well.
+ *
+ * When a window winds up undersized, it remembers what size it should be. In
+ * the example above, A remembers that it should be two rows; if the user
+ * expands the window to the original size, it would return to the original
+ * layout.
+ *
+ * The downward flow of control is a bit harsh. After all, in stage 4, there's
+ * room for C to have its two rows if only B would give up some of its 50%. But
+ * this does not happen.
+ *
+ * <note><para>
+ * This makes life much easier for the Glk library. To determine the
+ * configuration of a window, it only needs to look at the window's
+ * ancestors, never at its descendants. So window layout is a simple
+ * recursive algorithm, no backtracking.
+ * </para></note>
+ *
+ * What happens when you split a fixed-size window? The resulting pair window
+ * — that is, the two new parts together — retain the same size
+ * constraint as the original window that was split. The key window for the
+ * original split is still the key window for that split, even though it's now
+ * a grandchild instead of a child.
+ *
+ * The easy, and correct, way to think about this is that the size constraint
+ * is stored by a window's parent, not the window itself; and a constraint
+ * consists of a pointer to a key window plus a size value.
+ *
+ * <mediaobject><textobject><phrase>Screen shot 8</phrase></textobject>
+ * </mediaobject>
+ * After the first split, the new pair window (O1, which covers the whole
+ * screen) knows that its first child (A) is above the second, and gets 50% of
+ * its own area. (A is the key window for this split, but a proportional split
+ * doesn't care about key windows.)
+ *
+ * After the second split, all this remains true; O1 knows that its first child
+ * gets 50% of its space, and A is O1's key window. But now O1's first child is
+ * O2 instead of A. The newer pair window (O2) knows that its first child (C)
+ * is above the second, and gets a fixed size of two rows. (As measured in C's
+ * font, because C is O2's key window.)
+ *
+ * If we split C, now, the resulting pair will still be two C-font rows high
+ * — that is, tall enough for two lines of whatever font C displays. For
+ * the sake of example, we'll do this vertically.
+ * <mediaobject><textobject><phrase>Screen shot 9</phrase></textobject>
+ * </mediaobject>
+ *
+ * O3 now knows that its children have a 50-50 left-right split. O2 is still
+ * committed to giving its upper child, O3, two C-font rows. Again, this is
+ * because C is O2's key window.
+ *
+ * <note><para>
+ * This turns out to be a good idea, because it means that C, the text grid
+ * window, is still two rows high. If O3 had been a upper-lower split, things
+ * wouldn't work out so neatly. But the rules would still apply. If you don't
+ * like this, don't do it.
+ * </para></note>
*
* Returns: the new window, or %NULL on error.
*/
* the same thing.)
*
* The @result argument is filled with the output character count of the window
- * stream.
+ * stream. See <link linkend="chimara-Streams">Streams</link> and <link
+ * linkend="chimara-Closing-Streams">Closing Streams</link>.
+ *
+ * When you close a window (and it is not the root window), the other window
+ * in its pair takes over all the freed-up area. Let's close D, in the current
+ * example:
+ * <mediaobject><textobject><phrase>Screen shot 10</phrase></textobject>
+ * </mediaobject>
+ *
+ * Notice what has happened. D is gone. O3 is gone, and its 50-50 left-right
+ * split has gone with it. The other size constraints are unchanged; O2 is
+ * still committed to giving its upper child two rows, as measured in the font
+ * of O2's key window, which is C. Conveniently, O2's upper child is C, just as
+ * it was before we created D. In fact, now that D is gone, everything is back
+ * to the way it was before we created D.
+ *
+ * But what if we had closed C instead of D? We would have gotten this:
+ * <mediaobject><textobject><phrase>Screen shot 11</phrase></textobject>
+ * </mediaobject>
+ *
+ * Again, O3 is gone. But D has collapsed to zero height. This is because its
+ * height is controlled by O2, and O2's key window was C, and C is now gone. O2
+ * no longer has a key window at all, so it cannot compute a height for its
+ * upper child, so it defaults to zero.
+ *
+ * <note><para>
+ * This may seem to be an inconvenient choice. That is deliberate. You should
+ * not leave a pair window with no key, and the zero-height default reminds
+ * you not to. You can use glk_window_set_arrangement() to set a new split
+ * measurement and key window. See <link
+ * linkend="chimara-Changing-Window-Constraints">Changing Window
+ * Constraints</link>.
+ * </para></note>
*/
void
glk_window_close(winid_t win, stream_result_t *result)
* glk_window_clear:
* @win: A window.
*
- * Erases the window @win. The meaning of this depends on the window type.
- *
- * <itemizedlist>
- * <listitem><para>
- * Text buffer: This may do any number of things, such as delete all text in
- * the window, or print enough blank lines to scroll all text beyond
- * visibility, or insert a page-break marker which is treated specially by the
- * display part of the library.
- * </para></listitem>
+ * Erases @win. The meaning of this depends on the window type.
+ * <variablelist>
+ * <varlistentry>
+ * <term>Text buffer</term>
* <listitem><para>
- * Text grid: This will clear the window, filling all positions with blanks.
- * The window cursor is moved to the top left corner (position 0,0).
+ * This may do any number of things, such as delete all text in the window, or
+ * print enough blank lines to scroll all text beyond visibility, or insert a
+ * page-break marker which is treated specially by the display part of the
+ * library.
* </para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Text grid</term>
* <listitem><para>
- * Graphics: Clears the entire window to its current background color.
+ * This will clear the window, filling all positions with blanks. The window
+ * cursor is moved to the top left corner (position 0,0).
* </para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Graphics</term>
* <listitem><para>
- * Other window types: No effect.
+ * Clears the entire window to its current background color. See <link
+ * linkend="chimara-Graphics-Windows">Graphics Windows</link>.
* </para></listitem>
- * </itemizedlist>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>Other window types</term>
+ * <listitem><para>No effect.</para></listitem>
+ * </varlistentry>
+ * </variablelist>
*
* It is illegal to erase a window which has line input pending.
*/
* @win: A window.
*
* Sets the current stream to @win's window stream. It is exactly equivalent to
- * <informalexample><programlisting>
- * glk_stream_set_current(glk_window_get_stream(win))
- * </programlisting></informalexample>
+ * <code>#glk_stream_set_current(#glk_window_get_stream(@win))</code>.
*/
void
glk_set_window(winid_t win)
* glk_window_get_stream:
* @win: A window.
*
- * Returns the stream which is associated with @win. Every window has a stream
- * which can be printed to, but this may not be useful, depending on the window
- * type. (For example, printing to a blank window's stream has no effect.)
+ * Returns the stream which is associated with @win. (See <link
+ * linkend="chimara-Window-Streams">Window Streams</link>.) Every window has a
+ * stream which can be printed to, but this may not be useful, depending on the
+ * window type.
+ *
+ * <note><para>
+ * For example, printing to a blank window's stream has no effect.
+ * </para></note>
*
- * Returns: The window stream.
+ * Returns: A window stream.
*/
strid_t glk_window_get_stream(winid_t win)
{
* @win: A window.
* @str: A stream to attach to the window, or %NULL.
*
- * Attaches the stream @str to @win as a second stream. Any text printed to the
- * window is also echoed to this second stream, which is called the window's
- * "echo stream."
- *
- * Effectively, any call to glk_put_char() (or the other output commands) which
- * is directed to @win's window stream, is replicated to @win's echo stream.
- * This also goes for the style commands such as glk_set_style().
- *
- * Note that the echoing is one-way. You can still print text directly to the
- * echo stream, and it will go wherever the stream is bound, but it does not
- * back up and appear in the window.
- *
- * It is illegal to set a window's echo stream to be its own window stream,
- * which would create an infinite loop. It is similarly illegal to create a
- * longer loop (two or more windows echoing to each other.)
+ * Sets @win's echo stream to @str, which can be any valid output stream. You
+ * can reset a window to stop echoing by calling
+ * <code>#glk_window_set_echo_stream(@win, %NULL)</code>.
*
- * You can reset a window to stop echoing by setting @str to %NULL.
+ * It is illegal to set a window's echo stream to be its
+ * <emphasis>own</emphasis> window stream. That would create an infinite loop,
+ * and is nearly certain to crash the Glk library. It is similarly illegal to
+ * create a longer loop (two or more windows echoing to each other.)
*/
void
glk_window_set_echo_stream(winid_t win, strid_t str)
* glk_window_get_echo_stream:
* @win: A window.
*
- * Returns the echo stream of window @win. If the window has no echo stream (as
- * is initially the case) then this returns %NULL.
+ * Returns the echo stream of window @win. Initially, a window has no echo
+ * stream, so <code>#glk_window_get_echo_stream(@win)</code> will return %NULL.
*
* Returns: A stream, or %NULL.
*/
* @heightptr: Pointer to a location to store the window's height, or %NULL.
*
* Simply returns the actual size of the window, in its measurement system.
- * Either @widthptr or @heightptr can be %NULL, if you only want one
- * measurement. (Or, in fact, both, if you want to waste time.)
+ * As described in <link linkend="chimara-Other-API-Conventions">Other API
+ * Conventions</link>, either @widthptr or @heightptr can be %NULL, if you
+ * only want one measurement.
+ *
+ * <note><para>Or, in fact, both, if you want to waste time.</para></note>
*/
void
glk_window_get_size(winid_t win, glui32 *widthptr, glui32 *heightptr)
g_warning("glk_window_get_size: Unsupported window type");
}
}
-
+
/**
* glk_window_move_cursor:
* @win: A text grid window.
* beginning of the next line.
*
* If you move the cursor below the last line, or when the cursor reaches the
- * end of the last line, it goes "off the screen" and further output has no
- * effect. You must call glk_window_move_cursor() or glk_window_clear() to move
- * the cursor back into the visible region.
+ * end of the last line, it goes <quote>off the screen</quote> and further
+ * output has no effect. You must call glk_window_move_cursor() or
+ * glk_window_clear() to move the cursor back into the visible region.
*
* <note><para>
* Note that the arguments of glk_window_move_cursor() are <type>unsigned
* Also note that the output cursor is not necessarily visible. In particular,
* when you are requesting line or character input in a grid window, you cannot
* rely on the cursor position to prompt the player where input is indicated.
- * You should print some character prompt at that spot -- a ">" character, for
- * example.
+ * You should print some character prompt at that spot — a
+ * <quote>></quote> character, for example.
* </para></note>
*/
void
gdk_threads_leave();
}
+
INPUT_REQUEST_LINE_UNICODE
};
+/**
+ * glk_window_struct:
+ *
+ * This is an opaque structure (see <link linkend="chimara-Opaque-Structures">
+ * Opaque Structures</link> and should not be accessed directly.
+ */
struct glk_window_struct
{
+ /*< private >*/
glui32 rock;
/* Pointer to the node in the global tree that contains this window */
GNode *window_node;