ChimaraGlk

ChimaraGlk — Widget which executes a Glk program

Stability Level

Unstable, unless otherwise indicated

Functions

Properties

gboolean interactive Read / Write / Construct
char * program-info Read
char * program-name Read
gboolean protect Read / Write / Construct
gboolean running Read
guint spacing Read / Write / Construct
char * story-name Read

Signals

Types and Values

Object Hierarchy

    GObject
    ╰── GInitiallyUnowned
        ╰── GtkWidget
            ╰── GtkContainer
                ╰── ChimaraGlk
                    ╰── ChimaraIF

Implemented Interfaces

ChimaraGlk implements AtkImplementorIface and GtkBuildable.

Includes

#include <libchimara/chimara-glk.h>

Description

The ChimaraGlk widget opens and runs a Glk program. The program must be compiled as a plugin module, with a function glk_main() that the Glk library can hook into.

On Linux systems, this is a file with a name like plugin.so. For portability, you can use libtool and automake:

1
2
3
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$$"

This will produce plugin.la which is a text file containing the correct plugin file to open (see the relevant section of the Libtool manual).

The following sample program shows how to initialize and construct a simple GTK window that runs a Glk program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <glib.h>
#include <gtk/gtk.h>
#include <libchimara/chimara-glk.h>

int
main(int argc, char *argv[])
{
    GtkWidget *window, *glk;
    GError *error = NULL;
    gchar *plugin_argv[] = { "plugin.so", "-option" };

    gtk_init(&argc, &argv);

    // Construct the window and its contents. We quit the GTK main loop
    // when the window's close button is clicked.
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
    glk = chimara_glk_new();
    gtk_container_add(GTK_CONTAINER(window), glk);
    gtk_widget_show_all(window);

    // Add a reference to the ChimaraGlk widget, since we want it to
    // persist after the window's delete-event -- otherwise it will be destroyed
    // with the window.
    g_object_ref(glk);

    // Start the Glk program in a separate thread
    if(!chimara_glk_run(CHIMARA_GLK(glk), "./plugin.so", 2, plugin_argv, &error))
        g_error("Error starting Glk library: %s\n", error->message);

    gtk_main();

    // After the GTK main loop exits, signal the Glk program to shut down if
    // it is still running, and wait for it to exit.
    chimara_glk_stop(CHIMARA_GLK(glk));
    chimara_glk_wait(CHIMARA_GLK(glk));
    g_object_unref(glk);

    return 0;
}

Functions

chimara_error_quark ()

GQuark
chimara_error_quark (void);

The error domain for errors from Chimara widgets.

Returns

The string “chimara-error-quark” as a GQuark.


ChimaraResourceLoadFunc ()

gchar *
(*ChimaraResourceLoadFunc) (ChimaraResourceType usage,
                            guint32 resnum,
                            gpointer user_data);

The type of function passed to chimara_glk_set_resource_load_callback(). It takes a ChimaraResourceType constant, usage , to indicate what sort of resource to look for; resnum is the resource number to look for, and user_data is the user data provided along with the callback. The function must return an allocated string containing the filename where the resource can be found.

Parameters

usage

A ChimaraResourceType constant.

 

resnum

The resource number to look for.

 

user_data

A pointer to provide to the callback.

 

chimara_glk_new ()

GtkWidget *
chimara_glk_new (void);

Creates and initializes a new ChimaraGlk widget.

Returns

a ChimaraGlk widget, with a floating reference.


chimara_glk_set_interactive ()

void
chimara_glk_set_interactive (ChimaraGlk *self,
                             gboolean interactive);

Sets the “interactive” property of self .

Parameters

self

a ChimaraGlk widget

 

interactive

whether the widget should expect user input

 

chimara_glk_get_interactive ()

gboolean
chimara_glk_get_interactive (ChimaraGlk *self);

Returns whether self is interactive (expecting user input). See “interactive”.

Parameters

self

a ChimaraGlk widget

 

Returns

TRUE if self is interactive.


chimara_glk_set_protect ()

void
chimara_glk_set_protect (ChimaraGlk *self,
                         gboolean protect);

Sets the “protect” property of self . In protect mode, the Glk program is not allowed to do file operations.

Parameters

self

a ChimaraGlk widget

 

protect

whether the widget should allow the Glk program to do file operations

 

chimara_glk_get_protect ()

gboolean
chimara_glk_get_protect (ChimaraGlk *self);

Returns whether self is in protect mode (banned from doing file operations). See “protect”.

Parameters

self

a ChimaraGlk widget

 

Returns

TRUE if self is in protect mode.


chimara_glk_set_spacing ()

void
chimara_glk_set_spacing (ChimaraGlk *self,
                         guint spacing);

Sets the “spacing” property of self , which is the border width in pixels between Glk windows.

Parameters

self

a ChimaraGlk widget

 

spacing

the number of pixels to put between Glk windows

 

chimara_glk_get_spacing ()

guint
chimara_glk_get_spacing (ChimaraGlk *self);

Gets the value set by chimara_glk_set_spacing().

Parameters

self

a ChimaraGlk widget

 

Returns

pixels of spacing between Glk windows


chimara_glk_set_css_to_default ()

void
chimara_glk_set_css_to_default (ChimaraGlk *glk);

Resets the styles for text buffer and text grid windows to their defaults.

This function is not implemented yet.

Parameters

glk

a ChimaraGlk widget

 

chimara_glk_set_css_from_file ()

gboolean
chimara_glk_set_css_from_file (ChimaraGlk *glk,
                               const gchar *filename,
                               GError **error);

Sets the styles for text buffer and text grid windows according to the CSS file filename . Note that the styles are set cumulatively on top of whatever the styles are at the time this function is called; to reset the styles to their defaults, use chimara_glk_set_css_to_default().

Parameters

glk

a ChimaraGlk widget

 

filename

path to a CSS file, or NULL

 

error

location to store a GError, or NULL

 

Returns

TRUE on success, FALSE if an error occurred, in which case error will be set.


chimara_glk_set_css_from_string ()

void
chimara_glk_set_css_from_string (ChimaraGlk *glk,
                                 const gchar *css);

Sets the styles for text buffer and text grid windows according to the CSS code css . Note that the styles are set cumulatively on top of whatever the styles are at the time this function is called; to reset the styles to their defaults, use chimara_glk_set_css_to_default().

Parameters

glk

a ChimaraGlk widget

 

css

a string containing CSS code

 

chimara_glk_run ()

gboolean
chimara_glk_run (ChimaraGlk *self,
                 const gchar *plugin,
                 int argc,
                 char *argv[],
                 GError **error);

Opens a Glk program compiled as a plugin. Sorts out its command line arguments from glkunix_arguments, calls its startup function glkunix_startup_code(), and then calls its main function glk_main() in a separate thread. On failure, returns FALSE and sets error .

The plugin must at least export a glk_main() function; glkunix_arguments and glkunix_startup_code() are optional.

Parameters

self

a ChimaraGlk widget

 

plugin

path to a plugin module compiled with glk.h

 

argc

Number of command line arguments in argv

 

argv

Array of command line arguments to pass to the plugin

 

error

location to store a GError, or NULL

 

Returns

TRUE if the Glk program was started successfully.


chimara_glk_run_file ()

gboolean
chimara_glk_run_file (ChimaraGlk *self,
                      GFile *plugin_file,
                      int argc,
                      char *argv[],
                      GError **error);

Opens a Glk program compiled as a plugin, from a GFile. See chimara_glk_run() for details.

Parameters

self

a ChimaraGlk widget

 

plugin_file

a GFile pointing to a plugin module compiled with glk.h

 

argc

Number of command line arguments in argv

 

argv

Array of command line arguments to pass to the plugin

 

error

location to store a GError, or NULL

 

Returns

TRUE if the Glk program was started successfully.


chimara_glk_stop ()

void
chimara_glk_stop (ChimaraGlk *self);

Signals the Glk program running in self to abort. Note that if the program is caught in an infinite loop in which glk_tick() is not called, this may not work.

This function does nothing if no Glk program is running.

Parameters

self

a ChimaraGlk widget

 

chimara_glk_wait ()

void
chimara_glk_wait (ChimaraGlk *self);

Holds up the main thread and waits for the Glk program running in self to finish.

This function does nothing if no Glk program is running.

Parameters

self

a ChimaraGlk widget

 

chimara_glk_unload_plugin ()

void
chimara_glk_unload_plugin (ChimaraGlk *self);

The plugin containing the Glk program is unloaded as late as possible before loading a new plugin, in order to prevent crashes while printing stack backtraces during debugging. Sometimes this behavior is not desirable. This function forces self to unload the plugin running in it.

This function does nothing if there is no plugin loaded.

Parameters

self

a ChimaraGlk widget

 

chimara_glk_get_running ()

gboolean
chimara_glk_get_running (ChimaraGlk *self);

Use this function to tell whether a program is currently running in the widget.

Parameters

self

a ChimaraGlk widget

 

Returns

TRUE if self is executing a Glk program, FALSE otherwise.


chimara_glk_feed_char_input ()

void
chimara_glk_feed_char_input (ChimaraGlk *self,
                             uint32_t keyval);

Pretend that a key was pressed in the Glk program as a response to a character input request. You can call this function even when no window has requested character input, in which case the key will be saved for the following window that requests character input. This has the disadvantage that if more than one window has requested character input, it is arbitrary which one gets the key press.

Parameters

self

a ChimaraGlk widget

 

keyval

a key symbol as defined in gdk/gdkkeysyms.h

 

chimara_glk_feed_line_input ()

void
chimara_glk_feed_line_input (ChimaraGlk *self,
                             const char *text);

Pretend that text was typed in the Glk program as a response to a line input request. text does not need to end with a newline. You can call this function even when no window has requested line input, in which case the text will be saved for the following window that requests line input. This has the disadvantage that if more than one window has requested line input, it is arbitrary which one gets the text.

Parameters

self

a ChimaraGlk widget

 

text

text to pass to the next line input request

 

chimara_glk_is_char_input_pending ()

gboolean
chimara_glk_is_char_input_pending (ChimaraGlk *self);

Use this function to tell if character input forced by chimara_glk_feed_char_input() has been passed to an input request or not.

Parameters

self

a ChimaraGlk widget

 

Returns

TRUE if forced character input is pending, FALSE otherwise.


chimara_glk_is_line_input_pending ()

gboolean
chimara_glk_is_line_input_pending (ChimaraGlk *self);

Use this function to tell if line input forced by chimara_glk_feed_line_input() has been passed to an input request or not.

Parameters

self

a ChimaraGlk widget

 

Returns

TRUE if forced line input is pending, FALSE otherwise.


chimara_glk_get_tag ()

GtkTextTag *
chimara_glk_get_tag (ChimaraGlk *self,
                     ChimaraGlkWindowType window,
                     const char *name);

Use this function to get a GtkTextTag so style properties can be changed. See also chimara_glk_set_css_from_string().

The layout of the text in Chimara is controlled by two sets of tags: one set describing the style in text buffers and one for text grids. See also the Glk specification for the difference between the two. The main narrative of a game is usually rendered in text buffers, whereas text grids are mostly used for status bars and in game menus.

The following tag names are supported:

  • normal

  • emphasized

  • preformatted

  • header

  • subheader

  • alert

  • note

  • block-quote

  • input

  • user1

  • user2

  • hyperlink

  • pager

Parameters

self

a ChimaraGlk widget

 

window

The type of window to retrieve the tag for

 

name

The name of the tag to retrieve

 

Returns

The GtkTextTag corresponding to name in the styles of window .

[transfer none]


chimara_glk_get_tag_names ()

const char * const *
chimara_glk_get_tag_names (ChimaraGlk *glk,
                           unsigned *num_tags);

Retrieves the possible tag names to use in chimara_glk_get_tag().

Parameters

glk

a ChimaraGlk widget

 

num_tags

Return location for the number of tag names retrieved.

 

Returns

Array of strings containing the tag names. This array is owned by Chimara, do not free it.

[transfer none][array length=num_tags][element-type utf8]


chimara_glk_set_resource_load_callback ()

void
chimara_glk_set_resource_load_callback
                               (ChimaraGlk *self,
                                ChimaraResourceLoadFunc func,
                                void *user_data,
                                GDestroyNotify destroy_user_data);

Sometimes it is preferable to load image and sound resources from somewhere else than a Blorb file, for example while developing a game. Section 14 of the Blorb specification allows for this possibility. This function sets func to be called when the Glk program requests loading an image or sound without a Blorb resource map having been loaded, optionally passing user_data as an extra parameter.

Note that func is only called if no Blorb resource map has been set; having a resource map in place overrides this function.

If you pass non-NULL for destroy_user_data , then self takes ownership of user_data . When it is not needed anymore, it will be freed by calling destroy_user_data on it. If you wish to retain ownership of user_data , pass NULL for destroy_user_data .

To deactivate the callback, call this function with func set to NULL.

Parameters

self

a ChimaraGlk widget

 

func

a function to call for loading resources, or NULL

 

user_data

user data to pass to func , or NULL

 

destroy_user_data

a function to call for freeing user_data , or NULL

 

Types and Values

ChimaraGlk

typedef struct _ChimaraGlk ChimaraGlk;

This structure contains no public members.


enum ChimaraError

Error codes returned by ChimaraGlk widgets and subclasses.

Members

CHIMARA_LOAD_MODULE_ERROR

There was an error opening the plugin containing the Glk program. The error message from g_module_error() is appended to the GError message.

 

CHIMARA_NO_GLK_MAIN

The plugin containing the Glk program did not export a glk_main() function.

 

CHIMARA_PLUGIN_NOT_FOUND

An appropriate interpreter plugin for the autodetected game file type could not be found.

 

CHIMARA_PLUGIN_ALREADY_RUNNING

A plugin was opened while there was already another plugin running in the widget.

 

CHIMARA_ERROR

#define CHIMARA_ERROR chimara_error_quark()

The domain of errors raised by Chimara widgets.


enum ChimaraResourceType

The type of resource that the Glk program is requesting, passed to a ChimaraResourceLoadFunc.

Members

CHIMARA_RESOURCE_SOUND

A sound file.

 

CHIMARA_RESOURCE_IMAGE

An image file.

 

enum ChimaraGlkWindowType

Specifies the type of windows for which to retrieve the style tag with chimara_glk_get_tag().

Members

CHIMARA_GLK_TEXT_BUFFER

The styles for text buffer windows.

 

CHIMARA_GLK_TEXT_GRID

The styles for text grid windows.

 

Property Details

The “interactive” property

  “interactive”              gboolean

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_char_input() and chimara_glk_feed_line_input(). “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.

Owner: ChimaraGlk

Flags: Read / Write / Construct

Default value: TRUE


The “program-info” property

  “program-info”             char *

Information about the currently running Glk program. You cannot set this property yourself. The plugin can change it by calling garglk_set_program_info(). See also “program-name”.

Owner: ChimaraGlk

Flags: Read

Default value: NULL


The “program-name” property

  “program-name”             char *

The name of the currently running Glk program. You cannot set this property yourself. It is set to the filename of the plugin when you call chimara_glk_run(), but the plugin can change it by calling garglk_set_program_name(). To find out when this information changes, for example to put the program name in the title bar of a window, connect to the ::notify::program-name signal.

Owner: ChimaraGlk

Flags: Read

Default value: NULL


The “protect” property

  “protect”                  gboolean

Sets whether the Glk program is allowed to do file operations. In protect mode, all file operations will fail.

Owner: ChimaraGlk

Flags: Read / Write / Construct

Default value: FALSE


The “running” property

  “running”                  gboolean

Whether this Glk widget is currently running a game or not.

Owner: ChimaraGlk

Flags: Read

Default value: FALSE


The “spacing” property

  “spacing”                  guint

The amount of space between the Glk windows. This space forms a visible border between windows; however, if you open a window using the winmethod_NoBorder flag, there will be no spacing between it and its sibling window, no matter what the value of this property is.

Owner: ChimaraGlk

Flags: Read / Write / Construct

Default value: 0


The “story-name” property

  “story-name”               char *

The name of the story currently running in the Glk interpreter. You cannot set this property yourself. It is set to the story filename when you call chimara_if_run_game(), but the plugin can change it by calling garglk_set_story_name().

Strictly speaking, this should be a property of ChimaraIF, but it is legal for any Glk program to call garglk_set_story_name(), even if it is not an interpreter and does not load story files.

Owner: ChimaraGlk

Flags: Read

Default value: NULL

Signal Details

The “char-input” signal

void
user_function (ChimaraGlk *self,
               guint       window_rock,
               char       *window_id_string,
               guint       keysym,
               gpointer    user_data)

Emitted when a Glk window receives character input. The window_rock can be used to identify the window. However, rock values in Glk are allowed to be identical for different windows, so Chimara also provides a string value with which the window can be uniquely identified.

Parameters

self

The widget that received the signal

 

window_rock

The rock value of the window that received character input (see Rocks)

 

window_id_string

A string value uniquely identifying the window that received character input

 

keysym

The key that was typed, in the form of a key symbol from gdk/gdkkeysyms.h

 

user_data

user data set when the signal handler was connected.

 

The “iliad-screen-update” signal

void
user_function (ChimaraGlk *self,
               gboolean    typing,
               gpointer    user_data)

Iliad specific signal which is emitted whenever the screen needs to be updated. Since iliad screen updates are very slow, updating should only be done when necessary.

Parameters

self

The widget that received the signal

 

typing

Whether to perform a typing or full screen update

 

user_data

user data set when the signal handler was connected.

 

The “line-input” signal

void
user_function (ChimaraGlk *self,
               guint       window_rock,
               char       *window_id_string,
               char       *text,
               gpointer    user_data)

Emitted when a Glk window receives line input. The window_rock can be used to identify the window. However, rock values in Glk are allowed to be identical for different windows, so Chimara also provides a string value with which the window can be uniquely identified.

Parameters

self

The widget that received the signal

 

window_rock

The rock value of the window that received line input (see Rocks)

 

window_id_string

A string value uniquely identifying the window that received the input

 

text

The text that was typed

 

user_data

user data set when the signal handler was connected.

 

The “started” signal

void
user_function (ChimaraGlk *glk,
               gpointer    user_data)

Emitted when a Glk program starts executing in the widget.

Parameters

glk

The widget that received the signal

 

user_data

user data set when the signal handler was connected.

 

Flags: Run First


The “stopped” signal

void
user_function (ChimaraGlk *glk,
               gpointer    user_data)

Emitted when the a Glk program finishes executing in the widget, whether it ended normally, or was interrupted.

Parameters

glk

The widget that received the signal

 

user_data

user data set when the signal handler was connected.

 

Flags: Run First


The “text-buffer-output” signal

void
user_function (ChimaraGlk *self,
               guint       window_rock,
               char       *window_id_string,
               char       *text,
               gpointer    user_data)

Emitted when text is printed to a text buffer window. The window_rock can be used to identify the window. However, rock values in Glk are allowed to be identical for different windows, so Chimara also provides a string value with which the window can be uniquely identified.

Parameters

self

The widget that received the signal

 

window_rock

The rock value of the window that was printed to (see Rocks)

 

window_id_string

A string value uniquely identifying the window that was printed to

 

text

The text that was printed

 

user_data

user data set when the signal handler was connected.

 

The “waiting” signal

void
user_function (ChimaraGlk *glk,
               gpointer    user_data)

Emitted when glk_select() is called by the Glk program and the event queue is empty, which means that the widget is waiting for input.

Parameters

glk

The widget that received the signal

 

user_data

user data set when the signal handler was connected.