Generic Canvas documentation notes

This document contains important information that should be documented in the developer manual.

Requirements
The Generic Canvas (GC) is meant to be a universal means to visualize a hierarchy of all kind of data structures and objects. In the first version this data will be a tree of GRT (Generic Runtime) entries that reflect the structure of a database. Hence the data to visualize consists mainly of tables, columns, indexes and the like. Each of these types gets a visible image (a figure) that helps to identify and manipulate the particular object.

A figure reacts in various ways to mouse input events. So it can be shown as "hot" or selected. It can be expanded and collapsed as a whole or parts of it. It can be dragged around and can be connected to other figures. It has the ability to adjust itself to its content. Its actual layout can be defined using an external description and can dynamically be changed. We have worked out a generic way to define layout information for each different object (Table, View, SP etc.) from our GRT system. An XML format was derived from the SVG 1.1 specification to define figures and expanded it for additional things we need. Note: the SVG specification served only as base and is not fully implemented in GC.

The whole implementation must be as platform-independent as possible. There are a few issues, which are discussed in an own paragraph below.
Rendering engine
For platform independence most of GC is written in C++. For image rendering OpenGL is used, which is available on many platforms for free, including Windows, Linux and Mac OS X. The use of OpenGL frees us from working out the ground work and helps us to start at a higher level. Currently only two dimensions are used with an orthogonal projection to maintain the metaphor of a canvas. OpenGL allows texturing objects and to define lights and view points (cameras). Additionally, it is hardware accelerated by almost all graphic boards available today to provide the system with an extremely fast and full featured rendering result even for very complex scenes with thousands of objects. A description of the OpenGL 1.1 APIs can be read in the OpenGL Red Book.
Basic structure
On top of the rendering engine a layer is drawn that manages a list of rendering commands, which can be defined by the application. All of these commands form a figure that can be manipulated as a whole. Each figure can have an unlimited number of sub figures that get transformed collectively by whatever transformation is given for the parent figure. The structure can recursively be continued forming so a tree for the entire scene.
Figure management
GC will create a scene structure on request of a higher level that gets everything that is needed to define the scene. This includes figures, textures, lights and cameras (lights and cameras are not yet used). GC supports PNG (portable network graphic) image files for texturing. Since it is easy to convert other image formats to PNG there is no support for any other image format.

In order to define figures dynamically GC supports a simple scripting language, which is discussed in the next paragraph.

Figures are named and must have a unique name throughout the whole scene. Figures can be accessed by name and their name can be used in the figure script to address it for inclusion. The same holds true for textures, except that they cannot be used standalone. Textures are kept by the canvas and accessed via their name by the figures.

For simplicity GC holds a set of predefined figures for basic geometric shapes like boxes, circles and the like. These can be used in the figures to build more complex objects.

Figure layouts
Figures consist of a hierarchy of elements, each of which can have an associated style and certain properties that determine the visible appearance. If a figure element has a style then it is rendered using that style before any of its child elements are drawn.

Styles
Styles are made of simple primitives. The format used to describe styles is a simplified derivation of the SVG specification. Line, polyline, polygon, rectangle, circle and ellipse elements are supported. In addition support is built-in for optional text and texturing.

Each figure element can have a caption (text) associated with it. The figure layouter will make sure that this text fits the element by resizing it if necessary, if no explicit size is given. Otherwise the text is shortened and marked with an ellipsis to indicate this fact.

Layout information is stored in one or more xml files and can be loaded dynamically. Non-referenced entries are ignored while non-existing entries result in an error while parsing.

Only the id and svg elements are required in the layout file. The rest is optional. Per layout definition only one svg tag is used. Any other is silently ignored. However you can have zero, one or more primitives in that svg element to compose a certain style.

The id attribute of the layout definition gives the name of the GRT type that is to be visualized by the instructions given in the definition. The id is a unique identifier and must not be used more than once. The svg element describes the shape. For more information on SVG, see the W3C pages about the format at http://www.w3.org/TR/SVG11/.

The Scalable Vector Graphics format is used to describe the figure. That is the reason why the separate namespace is used for that part of the file. Each of the SVG drawing elements understands certain style attributes. The recognized attributes are: 

•	stroke-width - The width of the line, relative to the user specified width. 
•	stroke - The color of the border. 
•	stroke-opacity – A value in the range [0..1] describing the opacity of the border.
•	fill - The fill colour. 
•	fill-opacity – A value in the range [0..1] describing the opacity of the interior.

So to draw a rectangle with a hairline stroke, the following would do the trick:
  <svg:rect stroke ="rgb(100, 255, 255)" stroke-opacity=”0.4” fill=”indianred” x="0" y="0" width="1" height="1"/>

Following elements are recognized: 
  <svg:line x1="..." y1="..." x2="..." y2="..."/>

This element is a line. 
  <svg:polyline points="...."/>

This is a polyline. That is, a number of connected line segments. The points attribute holds the coordinates of the end points for the line segments. The coordinates are separated by white space or commas.

  <svg:polygon points="...."/>

This is a polygon, which means a polyline but with automatically closed figure (end and start point are implicitely connected) that can have a fill color. The points argument has the same format as the polyline. 
  <svg:rect x="..." y="..." width="..." height="..."/>

This is a rectangle with position (x, y) and dimension (width, height). 
  <svg:circle cx="..." cy="..." r="..."/>

This is a circle with centre (cx, cy) and radius r. For ellipses use a simple scale transformation on the particular circle figure. The svg:ellipses element is not supported as separate entity. 
  <svg:text x="..." y="..." font-family=".." ...>A text</text>

This is a text element at positin (x, y). Only a subset of the entire SVG text definition is supported (see http://www.w3.org/TR/SVG11/text.html for a detailed description). In particular you cannot use subelements (e.g. tspan) nor is it possible to use any of attributes for layout (e.g. bidi), glyph orientation (e.g. glyph-orientation-vertical), text rendering order or alignment properties. Supported font attributes are font-family, font-style, font-weight and font-size. A part of the text decoration values can be used too (attribute "text-decoration"). These are none, underline and line-through. At the moment no other properties can be used for text output.

Figure elements
Figure elements are the building blocks of figures. Each figure has at least one figure element, which serves as parent the entire element hierarchy. A figure element can have any number of child elements and each of the children can be set to exist only once, one or more, or zero or more times. In order to simplify layouts specifications with a child element that can appear more than once are considered as list of that child element type. In this case you should not use yet another child element. You can always draw in another element to group child elements together. If an element has no style associated with it then it is entirely described by its child elements.

A figure layout definition is determined by the <layout-definition> tag. This tag must only have one child element, which then can be used to define the entire hierarchy. This looks like:

  <layout-definition layout-class="full" type="db.Table">
    <element attribute="value" …>
    </element>
  </layout-definition>

The following tables list the recognized attributes for definitions, elements and caption.

Tag <layout-definition>:

Attribute	Description	Possible values	Comment	
layout-class	An arbitrary string describing a “sub layout” for a layout. It can be used to select a certain layout definition that belongs to a particular type. A type can have more than one definition to allow different views of it.	any string	not required, no default, if not given then the class is not considered when searching for a definition	
type	An identifier (name) for the definition. Since it can appear more than once the standard xml attribute “id” could not be used.	any string	required, no default	

Tag <element>:

Attribute	Description	Possible values	Comment	
id	A document wide unique identifier for the element.	any string	not required	
key	A special path like identifier used by the external modules (like the GC-to-GRT bridge) to build a figure from external data. Usually the key corresponds to a property in the external data.	any string	not required	
layout	Identifies how child elements are laid out (e.g. a row).	row
column	not required, default is column	
resize	Direction into which the element can be resized (explicitly and automatically).	none
horizontal
vertical
both	not required, default is none	
template	An identifier specifying which style is to be used for that element. This must correspond to an id in the style definitions.	any string	not required, no default	
max-height	The maximum height the element can have. The element cannot be resized beyond this height.	a numerical value (float)	not required, default is -1, which means no constraint	
min-height	The minimum size for the element. The element cannot be resized smaller than this value.	a numerical value (float)	not required	
max-width	Like max-height but for the width.	see above	see above	
min-width	Like min-height but for the width.	see above	see above	
occurrence	Determines how often an element may appear within its parent’s child list.	+ (one or more)
* (zero or more)	not required, if missing occurrence is once	

Captions
An element can have a caption, which is optional. Only one caption can be given. If more than one caption is given then only the latest one is kept. The general syntax is:

<element attribute="value" …>
  <caption attribute="value" …>
</element>

These are the allowed attributes for the <caption> tag:

Attribute	Description	Possible values	Comment	
font-family	The name of an installed font to be used for the caption. Keep in mind that fonts might not be available on all platforms or even all machines on one platform.	any string	not required, default is Arial (also for fonts that could not be found)	
font-size	A number specifying the caption’s size in pixel.	any positive number	not required,
default is 20px	
font-weight	A number or a special string giving the “boldness” of the caption.	normal
bold
bolder
lighter
100, 200, 300, 400, 500, 600, 700, 800, 900
inherit	not required, default is 400	
font-style	A string indicating the style of the font.	normal
italic
oblique	not required, default is normal,
on Windows and MacOS X italic and oblique are identical	
default	The initial content of the caption. Can be changed at runtime.	any string	not required,
no default	
key	The same as the key attribute in the element tag.	any string	not required,
no default	
x	A horizontal offset for the caption relative to its container.	a numerical value (float)	not required
default is 0	
y	A vertical offset for the caption relative to its container.	a numerical value (float)	not required,
default is 0	
horizontal-alignment	Automatic horizontal position with regard to the caption’s container. The alignment is computed before offsets are applied. For the alignment to take effect it is necessary to have enough room, i.e. the parent element must be wider than the caption text is.	left,
center,
centered,
middle,
right
	not required, default is left,
centered and middle are synonyms for center	
vertical-alignment	Same as the horizontal alignment but for vertical spacing.	top,
center,
centered,
middle,
bottom
	not required, default is left,
centered and middle are synonyms for center	
fill	A color specification for the text.	see below for color descriptions	not required, there is no default, instead the parent’s color is used if this one is not given	
wrap	Indicates that the text should be wrapped if the horizontal space is not sufficient. This flag should be true if the caption contains embedded new lines.	true,
false	not required, default is false, if false then text output is on one line (and shortened if necessary)	
max-height, max-width, min-height, min-width	These attributes have the same meaning as in the element definition.			
Actions
Each element can have zero or more actions associated. An action is a process the canvas should start if the action’s trigger is executed on the owning element. Such processes can be changing the expand state of the element, start dragging of a figure and others. A trigger is a mouse action, i.e. mouse button down, mouse button up and double-click. Supported mouse buttons are left, middle, right, x-button 1 and x-button 2 (these are usually the thumb buttons used to navigate forward and backward). Additionally a modifier can be given to restrict an action to certain special keys. As modifier any combination of the Control, Shift and Alt key is allowed. On Mac OSX the Apple key (command key) is used for Alt. The option key (used on Mac OSX) is also supported.
The general syntax of an action is:

<element attribute="value" …>
  <action function="value">
    <trigger value="value" event="value" modifier="value" />
<action function="value">
    <trigger value="value" event="value" modifier="value" />
    <trigger value="value" event="value" modifier="value" />
    …
  …
</element>

These are the allowed attributes for the <action> tag:

Attribute	Description	Possible values	Comment	
function	A function like identifier with optional parameters that gives the process to start. The actual meaning of the parameters depends on the process and is listed elsewhere.	a string of the form:
identifier(param1, param2…) if parameters are required or :
identifier() for parameter-less calls.	required, parameters depend on the process	

The trigger tag is optional as well and there can be as many triggers as combinations of its parameters are possible. If no trigger is given then the action is always triggered, for each mouse event (that is, once for each mouse down, up and click, eventually double click).

These are the allowed attributes for the <trigger> tag:

Attribute	Description	Possible values	Comment	
controller	An identifier specifying the mouse button to use.	ignore,
left,
middle,
right,
xbutton1,
xbutton2	not required, default is ignore	
event	An identifier specifying the actual mouse event of the button.	ignore,
down,
up,
double-click	not required, default is ignore	
modifiers	A comma separated list of identifiers that must be pressed while the trigger is executed to make the action actually happen.	ignore,
none,
control,
shift,
alt	not required, default is ignore, any combination of these values is allowed, except for none and ignore, which must stand alone if used at all	

If the value “ignore” is given than it is as if the attribute was not specified at all and causes any value to match.
Platform dependant entries
In order to allow more flexibility an attribute was added that can be used to specify a certain platform an entry can be used on. This attribute is allowed for all elements, captions, actions and triggers and has the form:
<element platform="macosx,windows,linux" attribute="value" …>
  <action platform="windows,linux" function="value">
    <trigger platform="windows" value="value" event="value" modifier="value" />
<action platform="macosx" function="value">
    <trigger controller="value" event="value" modifier="value" />
    <trigger controller="value" event="value" modifier="value" />
    …
  …
</element>

The platform value is optional or can be empty, which is interpreted as “valid on all platforms”. If it is not empty then it must be a comma separated list of the 3 values “windows”, “linux” and “macosx”. Order does not matter but each enumerant must appear only once and no spaces are allowed around them. If only one enumerant is given then no comma is necessary.
Colors
Color specifications are support for styles as well as figure elements. GC follows in general the color definitions set be the SVG standard. However there are some significant differences. Gradient servers and URLs in common are not allowed in color specifications. Instead the svg:polygon definition has been enhanced to allow specifying individual colors for each vertex/point. This is more flexible than a simple linear gradient. However radial gradients cannot be used. The following color specifications are recognized:
-	Web style colors (hexadecimal values): #rgb and #rrggbb
-	Function style with either absolute values in the range [0...255] or percent values in the range [0..100%] per component
- 3 components absolute, e.g. rgb(100, 200, 255) 
- 3 components relative, e.g. rgb(20%, 100%, 0%)
-	Color names, recognized are a list of predefined colors as well as colors defined by the system, e.g. highlight, frame, scrollbar etc. See the tables below for allowed color names.
-	The reserved word “none”, which is the same as would the color had not been given at all.

aliceblue	240, 248, 255	
antiquewhite	250, 235, 215	
aqua 	0, 255, 255	
aquamarine 	127, 255, 212	
azure 	240, 255, 255	
beige 	245, 245, 220	
bisque	255, 228, 196	
black	0,   0,   0	
blanchedalmond	255, 235, 205	
blue	0,   0, 255	
blueviolet	138,  43, 226	
brown	165,  42,  42	
burlywood	222, 184, 135	
cadetblue	95, 158, 160	
chartreuse	127, 255,   0	
chocolate	210, 105,  30	
coral	255, 127,  80	
cornflowerblue	100, 149, 237	
cornsilk	255, 248, 220	
crimson	220,  20,  60	
cyan	0, 255, 255	
darkblue	0,   0, 139	
darkcyan	0, 139, 139	
darkgoldenrod	184, 134,  11	
darkgray	169, 169, 169	
darkgreen	0, 100,   0	
darkgrey	169, 169, 169	
darkkhaki	189, 183, 107	
darkmagenta	139,   0, 139	
darkolivegreen	85, 107,  47	
darkorange	255, 140,   0	
darkorchid	153,  50, 204	
darkred	139,   0,   0	
darksalmon	233, 150, 122	
darkseagreen	143, 188, 143	
darkslateblue	72,  61, 139	
darkslategray	47,  79,  79	
darkslategrey	47,  79,  79	
darkturquoise	0, 206, 209	
darkviolet	148,   0, 211	
deeppink	255,  20, 147	
deepskyblue	0, 191, 255	
dimgray	105, 105, 105	
dimgrey	105, 105, 105	
dodgerblue	 30, 144, 255	
firebrick	178,  34,  34	
floralwhite	255, 250, 240	
forestgreen	34, 139,  34	
fuchsia	255,   0, 255	
gainsboro	220, 220, 220	
ghostwhite	248, 248, 255	
gold	255, 215,   0	
goldenrod	218, 165,  32	
gray	128, 128, 128	
grey	128, 128, 128	
green	0, 128,   0	
greenyellow	173, 255,  47	
honeydew	240, 255, 240	
hotpink	255, 105, 180	
indianred	205,  92,  92	
indigo	 75,   0, 130	
ivory	255, 255, 240	
khaki	240, 230, 140	
lavender	230, 230, 250	
lavenderblush	255, 240, 245	
lawngreen	124, 252,   0	
lemonchiffon	255, 250, 205	
lightblue	173, 216, 230	
lightcoral	240, 128, 128	
lightcyan	224, 255, 255	
lightgoldenrodyellow	250, 250, 210	
lightgray	211, 211, 211	
lightgreen	144, 238, 144	
lightgrey	211, 211, 211	
lightpink	255, 182, 193	
lightsalmon	255, 160, 122	
lightseagreen	32, 178, 170	
lightskyblue	135, 206, 250	
lightslategray	119, 136, 153	
lightslategrey	119, 136, 153	
lightsteelblue	176, 196, 222	
lightyellow	255, 255, 224	
lime	0, 255,   0	
limegreen	50, 205,  50	
linen	250, 240, 230	
magenta	255,   0, 255	
maroon	128,   0,   0	
mediumaquamarine	102, 205, 170	
mediumblue	  0,   0, 205	
mediumorchid	186,  85, 211	
mediumpurple	147, 112, 219	
mediumseagreen	 60, 179, 113	
mediumslateblue	123, 104, 238	
mediumspringgreen	  0, 250, 154	
mediumturquoise	 72, 209, 204	
mediumvioletred	199,  21, 133	
midnightblue	 25,  25, 112	
mintcream	245, 255, 250	
mistyrose	255, 228, 225	
moccasin	255, 228, 181	
navajowhite	255, 222, 173	
navy	0,   0, 128	
oldlace	253, 245, 230	
olive	128, 128,   0	
olivedrab	107, 142,  35	
orange	255, 165,   0	
orangered	255,  69  , 0	
orchid	218, 112, 214	
palegoldenrod	238, 232, 170	
palegreen	152, 251, 152	
paleturquoise	175, 238, 238	
palevioletred	219, 112, 147	
papayawhip	255, 239, 213	
peachpuff	255, 218, 185	
peru	205, 133,  63	
pink	255, 192, 203	
plum	221, 160, 221	
powderblue	176, 224, 230	
purple	128,   0, 128	
red	255,   0,   0	
rosybrown	188, 143, 143	
royalblue	65, 105, 225	
saddlebrown	139,  69,  19	
salmon	250, 128, 114	
sandybrown	244, 164,  96	
seagreen	46, 139,  87	
seashell	255, 245, 238	
sienna	160,  82,  45	
silver	192, 192, 192	
skyblue	135, 206, 235	
slateblue	106,  90, 205	
slategray	112, 128, 144	
slategrey	112, 128, 144	
snow	255, 250, 250	
springgreen	0, 255, 127	
steelblue	70, 130, 180	
tan	210, 180, 140	
teal	0, 128, 128	
thistle	216, 191, 216	
tomato	255,  99,  71	
turquoise	 64, 224, 208	
violet	238, 130, 238	
wheat	245, 222, 179	
white	255, 255, 255	
whitesmoke	245, 245, 245	
yellow	255, 255,   0	
yellowgreen	154, 205,  50	

ActiveBorder	Active window border. 	
ActiveCaption	Active window caption. 	
AppWorkspace	Background color of multiple document interface. 	
Background	Desktop background. 	
ButtonFace	Face color for three-dimensional display elements. 	
ButtonHighlight	Dark shadow for three-dimensional display elements (for edges facing away from the light source). 	
ButtonShadow	Shadow color for three-dimensional display elements. 	
ButtonText	Text on push buttons. 	
CaptionText	Text in caption, size box and scroll arrow box	
GrayText	Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color. 	
Highlight	Item(s) selected in a control. 	
HighlightText	Text of item(s) selected in a control. 	
Hotlight	Hot tracked item.	
InactiveBorder	Inactive window border. 	
InactiveCaption	Inactive window caption. 	
InactiveCaptionText	Color of text in an inactive caption. 	
InfoBackground	Background color for tooltip controls. 	
InfoText	Text color for tooltip controls. 	
Menu	Menu background. 	
MenuText	Text in menus. 	
Scrollbar	Scroll bar gray area. 	
ThreeDDarkShadow	Dark shadow for three-dimensional display elements. 	
ThreeDFace	Face color for three-dimensional display elements. 	
ThreeDHighlight	Highlight color for three-dimensional display elements. 	
ThreeDLightShadow	Light color for three-dimensional display elements (for edges facing the light source). 	
ThreeDShadow	Dark shadow for three-dimensional display elements. 	
Window	Window background. 	
WindowFrame	Window frame. 	
WindowText	Text in windows	
Textures 
A non-layout element, which is allowed in the layout XML file, is <texture>. This element allows the definition of a texture and associating it with a name. Using this name the texture can be applied to any figure. The texture element can appear at any place as direct child element of <gc-layout>. However a texture must be defined before it can be used in a figure element. The following table lists all recognized attributes.

Attribute	Description	
id	The unique identification of this texture.	
location	The path and file name of the image file to use for this texture.	
wrap-mode-horizontal	Describes whether a texture should be repeated if texture coordinates reach beyond the [0..1] range. Valid values are: 
-	clamp: texture is clamped with interpolation of the texture border
-	clamp-to-border: like clamp, but the border is considered
-	clamp-to-edge: like clamp, but no interpolation at the border of the figure is done
-	repeat: texture is repeated (tiled)
Note: clamp-to-border and clamp-to-edge are only available with OpenGL 1.2. They do not harm on older version though.	
wrap-mode-vertical	Same as the horizontal variant.	
min-filter	Describes the minification filter used when the actual display requires the texture to be scaled down. Allowed values are:
-	nearest
-	linear
-	nearest-mipmap-nearest
-	linear-mipmap-nearest
-	nearest-mipmap-linear
-	linear-mipmap-linear
See OpenGL handbook for a description of these filter modes.	
mag-filter	Describes the magnification filter used when the actual display requires the texture to be scaled up. Allowed values are:
-	nearest
-	linear.
See OpenGL handbook for a description of these filter modes.	
dimensions	Can be 1 or 2, for one or two-dimensional texture images.	
mode	The mode how the texture image is applied. Allowed values are:
-	decal
-	modulate
-	blend
-	replace
See OpenGL handbook for a description of these modes.	

Generic Canvas implements texture LOD (level of details). This means one can specify several image files with different resolutions for one texture. Depending on the zoom state and the size of the textured object the canvas picks the most appropriate texture image improving so the overall quality because automatic scaling of textures, which often results in quality decrease is reduced.

The syntax for the <texture> element is:

<texture param=”value” … /> for textures without LOD. The image file given in the location parameter is that used all the time. For specifying level-of-detail images use:

<texture param=”value”>
  <texture-lod lod=”lod-level” location=”path-to-file”/>
</texture>

The lod parameter can be any positive integer inclusive 0. However if there is a file given in the location parameter of the <texture> element then this is implicitly used for level 0. The order of the level specification does not matter. There can even be more than one file for one level, in which case the latter overrides the former, however the higher the level the smaller the images must be. Keep in mind also that texture images always should be a power of 2 in size (e.g. 32 x32, 64 x 1024 etc.).

It is not necessary to specify an image for every level, however for quality it would be better. A sample definition looks so:

  <!-- Grid texture with LOD -->
  <texture id="grid" location="../images/textures/grid_0.png" dimensions="2" mode="modulate"
    min-filter="nearest-mipmap-linear" mag-filter="linear"
    wrap-mode-horizontal="repeat" wrap-mode-vertical="repeat">
    <!-- LOD 0 is given in the texture parameter list. All others go here. -->
    <texture-lod lod="1" location="../images/textures/grid_1.png" />
    <texture-lod lod="2" location="../images/textures/grid_2.png" />
    <texture-lod lod="3" location="../images/textures/grid_3.png" />
    <texture-lod lod="4" location="../images/textures/grid_4.png" />
    <texture-lod lod="5" location="../images/textures/grid_5.png" />
    <texture-lod lod="6" location="../images/textures/grid_6.png" />
    <texture-lod lod="7" location="../images/textures/grid_7.png" />
    <texture-lod lod="8" location="../images/textures/grid_8.png" />
</texture>

The smallest image (grid_8.png) is just one pixel in size. The next higher level has 2 x 2, then 4 x 4, 8 x 8 up to 256 x 256.
Platform dependant parts
For certain activities a platform dependant part is necessary, which must be separately implemented on each supported platform. This part includes:

•	Rendering context management (creation, destruction, associating with an output device like a window, widget, printer etc.) 
•	Trigger to actually draw the scene. 
•	Input handling for keyboard and mouse. This includes retrieving hit test information from GC and initiating feedback to the user. 
•	Start up and shut down of the OpenGL subsystem if necessary. 
•	Creation of a visual control to be used in the particular target application that is native to the used platform and that communicates with the GC library. 
The OpenGL Red Book contains a list of functions for each supported platforms that might be used to set up a rendering context with the local window manager system. Appendix C contains descriptions for the X Window System, Apple Macintosh, IBM OS/2 Warp and Windows.