Opaque Objects

Opaque Objects — Complex objects in Glk

Types and Values

typedef winid_t
typedef strid_t
typedef frefid_t
typedef schanid_t

Includes

#include <libchimara/glk.h>

Description

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:

Windows

Screen panels, used to input or output information.

Streams

Data streams, to which you can input or output text.

There are file streams and window streams, since you can output data to windows or files.

File references

Pointers to files in permanent storage.

In Unix a file reference is a pathname; on the Mac, an FSSpec. Actually there's a little more information included, such as file type and whether it is a text or binary file.

Sound channels

Audio output channels.

Not all Glk libraries support sound.

Note that there may be more object classes in future versions of the Glk API.

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 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 “no object” or “nothing”, 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 glk.h 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.

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.

Rocks

Every one of these objects (window, stream, file reference, or sound channel) has a “rock” value. This is simply a 32-bit integer value which you provide, for your own purposes, when you create the object.

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.

If you don't know what to use the rocks for, provide 0 and forget about it.


Iteration Through Opaque Objects

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

1
CLASSid_t glk_CLASS_iterate(CLASSid_t obj, glui32 *rockptr);

...where <replaceable>CLASS</replaceable> represents one of the opaque object classes.

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.

Calling glk_<replaceable>CLASS</replaceable>_iterate(NULL, r) returns the first object; calling glk_<replaceable>CLASS</replaceable>_iterate(obj, r) returns the next object, until there aren't any more, at which time it returns NULL.

The rockptr argument is a pointer to a location; whenever glk_<replaceable>CLASS</replaceable>_iterate() returns an object, the object's rock is stored in the location (*@rockptr). If you don't want the rocks to be returned, you may set rockptr to NULL.

You usually use this as follows:

1
2
3
4
5
obj = glk_CLASS_iterate(NULL, NULL);
while (obj) {
   // ...do something with obj...
   obj = glk_CLASS_iterate(obj, NULL);
}

If you create or destroy objects inside this loop, obviously, the results are unpredictable. However it is always legal to call glk_<replaceable>CLASS</replaceable>_iterate(obj, r) as long as obj is a valid object id, or NULL.

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 glk_<replaceable>CLASS</replaceable>_iterate(obj, r) has a fixed result, and iterating through the results as above will list every object exactly once.

Functions

Types and Values

winid_t

typedef struct glk_window_struct  *winid_t;

Opaque structure representing a Glk window. It has no user-accessible members.


strid_t

typedef struct glk_stream_struct  *strid_t;

Opaque structure representing an input or output stream. It has no user-accessible members.


frefid_t

typedef struct glk_fileref_struct *frefid_t;

Opaque structure representing a file reference. It has no user-accessible members.


schanid_t

typedef struct glk_schannel_struct *schanid_t;

Opaque structure representing a sound channel. It has no user-accessible members.