5 This is a simple tutorial on using the mini-X graphics system. Much of this
6 is a lot easier to understand if you are familiar to X. I am not going to
7 try to explain every concept in detail here, nor how to put it all together
8 to make really fancy programs. Instead, I am only going to tell you just
9 enough to let you make some simple graphics programs which work. Experience
10 with simple test programs will enable you to build much fancier graphics
11 programs much easier than trying to decipher what I could tell you.
13 I am assuming that you basically know what a screen, pixels, colors,
14 keyboards, mice, buttons, and windows are. However, you probably don't
15 know exactly what the properties of windows in this system are. Also, you
16 might not know two other concepts which are important here, which are
17 graphics contexts and events. So these things will be explained in this
23 Windows are rectangular areas which can be drawn into. Windows have a
24 position, specified by the x and y coordinates of their upper left corners,
25 and also a size, specified by their width and height. Windows are arranged
26 in a tree structure, with the parent windows controlling the child windows.
27 The top of the tree is known as the root window. The root window is always
28 present, and represents the total screen area.
30 Each child window is clipped by its parent window. This means that a window
31 can be very large, but the only part of the window that can ever be seen is
32 the part which shows through its parent window. This applies recursively,
33 so that all of the parents of a window limit its visibility. The position
34 of a window is specified relative to its parent, and not absolutely. This
35 means that for example, when a window is moved, then all of its children will
36 move with it. The position of a window can be negative.
38 Windows which have the same parent can clip each other. That is, there is a
39 defined order among the children of a window as to which is more important.
40 If two sibling windows overlap, then the more important window will be visible
41 in preference to the less important window. The precedence of visibility
42 of siblings can be dynamically adjusted. Clipping can also occur on a window
43 by earlier siblings of any of the window's parents.
45 Windows can be mapped or unmapped. Unmapped windows are not visible, and
46 cause no events. They can be thought of as "in storage" or offscreen.
47 When a window is mapped, then it can become visible on the screen. Children
48 of an unmapped window are implicitly also unmapped. So a window is not
49 visible until it and all of its parents are mapped. A newly created window
52 Windows have a background color. A newly mapped window is filled with its
53 background color. Clearing the window later, or having obscured portions
54 of the window become visible again, will fill the region with the background.
55 The client program can then draw into the window to make it look correct.
57 Windows may have a border. A border is a set of rectangles adjacent to the
58 four sides of the window which is drawn in a specified color, with a
59 specified width. This makes pretty lines around the window, for example.
60 The border cannot be drawn in by the program. Borders are optional, so
61 that a window with a border width of zero has no border at all. Borders
62 are "around" the window, so that they do not affect the coordinates of the
63 window. Whether or not a window has borders, its position determines the
64 location of the upper left corner which can be drawn into.
66 Windows can have a cursor associated with them. The graphics server tracks
67 the location of the mouse, and maintains the position of a graphics cursor
68 on the screen. This cursor can automatically change its shape and colors as
69 it moves between different windows. The use of different cursors for different
70 windows can be used to provide a powerful clue to the user as to what will
71 happen if a mouse button is pressed in a window. Newly created windows
72 inherit the same cursor as their parent.
74 There are two types of windows, input-output and input-only windows.
75 Input-output windows are normal windows which are visible and can be drawn
76 into. Input-only windows are invisible, have no border, and cannot be
77 drawn into. Their purpose is to catch events, and to enable the cursor
78 to be changed in different regions of a visible window. The only children
79 of input-only windows are also input-only windows.
81 Windows are identified by integers called window ids. The root window has
82 a constant window id value of GR_ROOT_WINDOW_ID. The root window does not
83 need creating, and cannot be unmapped, moved, resized, or destroyed.
84 However, it can be drawn into and events can be delivered to it. New windows
85 can be created from existing windows. Their window ids are not constants,
86 but once created the window id remains until the window is destroyed. Window
87 ids are not reused as windows are created and destroyed.
92 When drawing objects such as lines, there are many parameters that can be
93 specified for the function call that affect the operation. Besides the
94 minimum information needed for the function such as the endpoint coordinates,
95 there are extra parameters that are less important and less variable.
96 Examples of these extra parameters are color, width (thin or thick), style
97 (dashed, dotted), and drawing operation (setting, XORing). Instead of
98 requiring the specifying of each of these extra parameters for every function
99 call, graphics contexts are used. Graphics contexts are just a collection
100 of specific combinations of these extra parameters. The many possible
101 extra parameters to each function are replaced by just one extra parameter,
102 which is the graphics context.
104 For example, instead of a function call like:
105 drawline(window, x1, y1, x2, y2, color, width, style, operation);
108 drawline(window, gc, x1, y1, x2, y2),
110 where the graphics context contains within itself the parameters color, width,
111 style, and operation.
113 Graphics contexts are stored in the graphics server, and are identified by
114 unique numbers in a way similar to window ids. Your program must allocate
115 graphic contexts, which then can be used in drawing functions. A newly
116 allocated graphics context is supplied with default parameters, such as a
117 foreground color of white, drawing operation of setting, and width of 0.
118 You can modify the parameters associated with the graphics context one by
119 one, by for example, setting the foreground color to black.
121 A single graphics context could be used for every drawing operation by
122 constantly setting the parameters associated with it to the values needed
123 for each drawing call. But this is inefficient. The reason that multiple
124 graphics contexts can be allocated is so that you can minimize the setting of
125 their parameters. By presetting the parameters of several graphics contexts
126 to commonly used values in your program, you can avoid changing them later.
127 For example, you can call one graphics context white_gc, and another graphics
128 context black_gc, and then use the correct graphics context in the drawing
129 functions to draw in either black or white.
131 The parameters contained within a graphics context are currently the
135 Specifies the operation performed when drawing each pixel. One of:
136 GR_MODE_SET draw pixels as given (default)
137 GR_MODE_XOR draw pixels using XOR
138 GR_MODE_OR draw pixels using OR
139 GR_MODE_AND draw pixels using AND
142 A small integer identifying the font for drawing text. The first few are
143 built-in to the device driver, others must be loaded by the graphics server.
144 The default font is 0.
147 The color that is used to draw almost all objects with, such as lines,
148 points, ellipses, text, bitmaps, and filled areas. Default is white.
151 The color used for some functions in addition to the foreground color.
152 For bitmaps and text, this is the color used for the zero bits. The
153 default background color is black. The drawing of this color can be
154 disabled by the next parameter.
157 This is a boolean value which indicates whether or not the background
158 color is actually to be drawn for bitmaps, text, and the GrArea8 function.
159 The default is GR_TRUE.
164 Events are the way in which the graphics system notifies your program
165 of asychronous changes in the state of the screen, mouse, or keyboard.
166 Whenever the state changes, your program is notified of this change and
167 can act on it. The word "event" is used both for the actual change
168 that took place, and also for the data that is returned to your program
169 which describes the change.
171 Events are generated for various different types of changes that may be useful
172 for your program to know. Events directly related to the hardware are the
173 keyboard and mouse events. Keyboard events are generated for each key which
174 is pressed (and released, if possible). The event contains the character
175 which caused the event. Mouse events are generated when a button on the
176 mouse is pressed or released, or when the mouse position moves. The event
177 contains the buttons which are pressed, and the current position of the mouse.
178 Other events are more subtle, and are based on non-physical changes, such
179 as having the mouse move into or out of specific windows.
181 Events are generally tied to individual windows. Your program can enable
182 or disable which kinds of events it wants for each window. Part of the data
183 associated with an event is the window associated with the event. For
184 example, if a key is pressed on the keyboard, the event for that key will
185 indicate which window that key is for. You program can then act differently
186 for different windows. Events which you have not indicated an interest in
187 are simply discarded.
189 The keyboard and mouse events can propagate upwards through the window tree
190 and be delivered to some parent window. This occurs if the window does
191 not select for the event, but one of the parent windows does. Part of the
192 information returned about these events is the window that accepted the event,
193 and also the original window which caused the event. Therefore, your program
194 can determine which child window an event was for without having to select
195 for the event for each child. Events other than keyboard and mouse events
198 The window that keyboard events are delivered to depends on the current
199 mouse position or on the "input focus". The input focus is a way of
200 specifying that keyboard events are to be delivered to a particular window,
201 no matter where the mouse is currently pointing. Your program can change
202 the input focus as desired. If the input focus is set to the root window,
203 then the keyboard events will be delivered to the window which contains
204 the mouse pointer (or one of its parents).
206 Events are returned to your program as a structure containing the information
207 about the event. This information is the event type, the window id which
208 the event is associated with, and other event-specific data. Events are
209 stored in a queue, and are delivered to your program one by one as requested.
210 The order of the events is preserved. Your program can either simply ask
211 for the next available event (waiting for one if none are yet available),
212 or it can check to see if an event is available without waiting. The
213 delivering of events only occurs when you request an event. So even though
214 events themselves are asychronous, the reading of them is synchronous.
215 There are no "interrupts" for events, you must explicitly ask for them.
217 The important thing about programming with events is that your program
218 should be written to run "upside-down". That is, you do not have a main
219 routine which checks that the mouse has been moved, or the keyboard has
220 been typed on, or which window the mouse is in. Instead, your main routine
221 just waits for an event, and then dispatches on its type and which window
222 it is for. Generally, you must keep some state information to remember
223 what is happening in your program. For example, if the user wants to click
224 the button in a window to indicate where some text should be inserted, then
225 your program cannot simply detect the mouse click, and then wait for the
226 text to be typed. Instead, when the mouse is clicked, it should just
227 remember the position of the mouse and set a flag to indicate that text
228 typing is allowed, When the keyboard event arrives, this saved information
229 then enables you to draw the text at the correct location. Your program
230 basically becomes one large state machine.
232 One obscure event is the exposure event. This is sent to your program when
233 a window requires redrawing. Due to lack of memory space, the graphics server
234 does not attempt to save the data from the parts of windows which are
235 covered by other windows. Therefore, when the obscured parts of the window
236 are uncovered, your program must be told to redraw those parts. The exposure
237 event contains a rectangular area which requires drawing (which may in fact
238 be larger than the area which was actually uncovered). Your program can
239 either just redraw that area, or if more convenient, redraw the whole window.
240 The area to be redrawn has already been cleared to the window's background
241 color. When a window is mapped, an exposure event is sent for the window.
242 Therefore, you should not explicitly draw into a window when it is first
243 created and mapped, but should instead just wait for the exposure event, and
244 then draw it. In this way, the code to draw the window only resides in one
245 place in your program, and you prevent redundant drawing of the window.
246 If you are drawing the complete window on all exposure events, then it
247 might be useful to use GrPeekEvent to examine the next event too. If it
248 is also an exposure event for the same window, then you can read it by using
249 GrGetNextEvent, and thereby prevent redundant redrawing. Of course, to
250 be able to redraw the window, you may need to save extra data in order to
251 regenerate the drawing commands. (Pixmaps are one way of doing this in
252 the future, but they are not currently implemented.)
254 The following is a description of the various types of events which are
255 available, and (in parenthesis) the typedef name for the structure that
256 returns the event. Each event has a type field, which can be used to
257 distinguish between the various events. For details on the other data
258 within the structures, refer to graphics.h. The typedef GR_EVENT is a
259 union which contains all of the possible event structures.
262 GR_EVENT_TYPE_NONE (GR_EVENT)
263 This indicates that no event has occurred.
265 GR_EVENT_TYPE_EXPOSURE (GR_EVENT_EXPOSURE)
266 This is generated when a window needs redrawing because it is either
267 newly mapped, or has been uncovered by another window. This returns
268 the window id, and the x, y, width, and height of the area within
269 the window which needs redrawing.
271 GR_EVENT_TYPE_BUTTON_DOWN (GR_EVENT_BUTTON)
272 This is generated when a button is pressed down on the mouse.
273 This returns the window id which generated the event, the window id
274 which actually contains the mouse, the current position of the mouse,
275 the buttons which are currently down on the mouse, the buttons
276 which were just pressed down, and the current modifier flags.
278 GR_EVENT_TYPE_BUTTON_UP (GR_EVENT_BUTTON)
279 This is generated when a button is released on the mouse. This
280 returns data similarly to button down.
282 GR_EVENT_TYPE_MOUSE_ENTER (GR_EVENT_GENERAL)
283 This is generated when the mouse enters a window. This returns the
284 window id which generated the event.
286 GR_EVENT_TYPE_MOUSE_EXIT (GR_EVENT_GENERAL)
287 This is generated when the mouse leaves a window. This returns
288 the window id which generated the event.
290 GR_EVENT_TYPE_MOUSE_MOTION (GR_EVENT_MOUSE)
291 Mouse motion is generated for every motion of the mouse, and is
292 used to track the entire history of the mouse. Mouse motion
293 generates many events and causes lots of overhead. This returns
294 data similarly to mouse enter.
296 GR_EVENT_TYPE_MOUSE_POSITION (GR_EVENT_MOUSE)
297 Mouse position ignores the history of the motion, and only reports the
298 latest position of the mouse by only queuing the latest such event for
299 any single client (good for rubber-banding). This returns data
300 similarly to mouse enter.
302 GR_EVENT_TYPE_KEY_DOWN (GR_EVENT_KEYSTROKE)
303 This indicates that a key has been pressed on the keyboard.
304 This returns the window id which generated the event, the window id
305 which actually contains the pointer (if the pointer is outside of
306 the event window, this will be the event window), the current position
307 of the mouse, the current buttons on the mouse which are down, the
308 current modifier flags, and the character which was typed.
310 GR_EVENT_TYPE_KEY_UP (GR_EVENT_KEYSTROKE)
311 This indicates that a key has been released on the keyboard. This
312 event is not necessarily available, and should not be depended on.
313 This returns data similarly to key down.
315 GR_EVENT_TYPE_FOCUS_IN (GR_EVENT_GENERAL)
316 This indicates that the input focus has just changed to this window.
317 This returns the window id which got focus.
319 GR_EVENT_TYPE_FOCUS_OUT (GR_EVENT_GENERAL)
320 This indicates that the input focus has just left this window.
321 This returns the window id which lost focus.
324 To select for events, you use GrSelectEvents, and specify the window which
325 wants to receive the events, and also specify a mask indicating the events
326 you wish to receive. The mask is the logical OR of individual bit values
327 representing the event types. The mask names are the same as the event
328 names, except that the "_TYPE_" string is replaced by "_MASK_". For
329 example, the mask associated with the event GR_EVENT_TYPE_FOCUS_IN is
330 GR_EVENT_MASK_FOCUS_IN.
332 If you select for both button down and button up events, then the mouse
333 will be implicitly "grabbed" when any button is pressed down in that window.
334 This means that the mouse position and button down and up events will be
335 delivered only to that window, and the cursor shape won't change, even if
336 the mouse leaves that window. The implicit grabbing ends after the last
337 button is released. While this grabbing occurs, the input focus is also
338 not changed as the mouse is moved.
341 MODIFIER AND MOUSE BUTTONS
343 Modifiers are the status of special keyboard shift-like keys. The state
344 of these keys can be read as up or down, and don't generate any characters
345 by themselves. These keys are for things like SHIFT, CTRL, and ALT.
346 They are returned as bit values OR'd together in various events. Not all
347 of these modifiers may be implemented. The GrGetScreenInfo function returns
348 the modifiers that are implemented. The following modifiers are defined:
350 GR_MODIFIER_SHIFT shift key is down
351 GR_MODIFIER_CTRL ctrl key is down
352 GR_MODIFIER_META meta (or ALT) key is down
353 GR_MODIFIER_ANY any of the modifiers is down
356 The mouse button state are returned as bit values OR'd together in various
357 events. Not all of these buttons may be implemented. The GrGetScreenInfo
358 function returns the buttons that are implemented. The following mouse
361 GR_BUTTON_1 button 1 is down (left)
362 GR_BUTTON_2 button 2 is down (middle)
363 GR_BUTTON_3 button 3 is down (right)
364 GR_BUTTON_ANY any of the buttons is down
369 Bitmaps are defined as an array of GR_BITMAP values, which are unsigned shorts.
370 Each word is 16 bits, which specify foreground and background values, with 1
371 being foreground and 0 being background. Higher order bits in the word
372 represent pixels to the left of the lower order bits. Bitmaps have a width
373 and a height, measured in pixels. The width does not need to be a multiple
374 of 16. In this case, remaining bits in the last word of a row are unused,
375 so that each row starts with a new bitmap word. The GR_BITMAP_SIZE macro can
376 be used to allocate the proper number of bitmap words for a bitmap, as in:
378 GR_BITMAP_SIZE(width, height).
380 The symbol GR_MAX_BITMAP_SIZE is the number of bitmap words required for
381 the maximum sized cursor.
386 Calls to the graphics libraries may produce errors. Most errors that
387 occur are due to specifying a window or graphics context which does not
388 exist, or attempting an operation which is illegal. Many things are allowed
389 even if pointless, such as drawing outside of the window boundaries, or
390 while a window is not mapped. The things which return errors are those
391 which definitely indicate a program bug, attempts to exceed the system
392 limits, or a fatal device error.
394 In order to be as efficient as possible, error codes are not returned by
395 individual function calls. Instead, if a function fails, an error event
396 is generated which will eventually be noticed by the program at a possibly
397 much later time. This allows many drawing requests to be sent at one time
398 without having to worry about the status of each one.
400 Error events are detected when the program checks for events, such as
401 by calling GrGetNextEvent. At this point, if an error had occurred, a
402 special error handler routine is called to notice the error. If the program
403 had not set up its own error handler, a default one is called which will
404 disconnect from the server, print out an indication of the error, and exit
407 The following is a list of the possible errors:
409 GR_ERROR_BAD_WINDOW_ID the specified window id is unknown
410 GR_ERROR_BAD_GC_ID the specified graphics context id is unknown
411 GR_ERROR_BAD_CURSOR_SIZE the specified cursor is too large
412 GR_ERROR_MALLOC_FAILED no more memory is available in the server
413 GR_ERROR_BAD_WINDOW_SIZE the specified window size is illegal
414 GR_ERROR_KEYBOARD_ERROR an error occurred reading from the keyboard
415 GR_ERROR_MOUSE_ERROR an error occurred reading from the mouse
416 GR_ERROR_INPUT_ONLY_WINDOW drawing was attempted in an input-only window
417 GR_ERROR_ILLEGAL_ON_ROOT_WINDOW an illegal operation was attempted on the root
418 GR_ERROR_TOO_MUCH_CLIPPING complexity of windows exceeded clipping limits
419 GR_ERROR_SCREEN_ERROR an error occurred talking to the screen driver
420 GR_ERROR_UNMAPPED_FOCUS_WINDOW attempted to set focus to an unmapped window
421 GR_ERROR_BAD_DRAWING_MODE illegal drawing mode specified for a GC
426 You do not have to hard code the size of the screen or the number of colors
427 available in your program. Instead, you can find this information out
428 dynamically after the connection is made to the graphics server, by using
429 the GrGetScreenInfo call. This returns the above information, and in addition
430 returns the color values for black and white, the aspect ratio of pixels,
431 the number of built-in fonts available, and the modifiers and buttons which
432 are available. The aspect ratio is useful for drawing objects which need
433 to be scaled correctly, such as circles. The aspect ratio is the quotient
434 of xdpcm and ydpcm, which are integer values.
438 GR_SIZE rows; /* number of rows on screen */
439 GR_SIZE cols; /* number of columns on screen */
440 GR_SIZE xdpcm; /* dots/centimeter in x direction */
441 GR_SIZE ydpcm; /* dots/centimeter in y direction */
442 GR_COLOR maxcolor; /* maximum legal color value */
443 GR_COLOR black; /* the color black */
444 GR_COLOR white; /* the color white */
445 GR_COUNT fonts; /* number of built-in fonts */
446 GR_BUTTON buttons; /* buttons which are implemented */
447 GR_MODIFIER modifiers; /* modifiers which are implemented */
451 INCLUDE FILE AND GRAPHICS LIBRARY
453 To use the graphics server, your program must include "graphics.h".
454 This should be put into /usr/include, so that your program simply has
455 the following line at the top:
456 #include <graphics.h>
458 Including this file gives you all of the definitions you need to use the
459 graphics library. These are the typedefs, function declarations, event
460 structures, and various constants.
462 When loading your program, you need to load the graphics server into the
463 program by using the -lgraph option in the cc command. For example, if
464 your program is called myprog, then you could build it using the following:
465 cc -o myprog myprog.c -lgraph
470 The following is a list of the typedefs in the include file, and a short
471 description of their purpose. Refer to their definitions in graphics.h
472 to find out what their actual C base type is. Most are shorts, unsigned
475 GR_COORD coordinate value (x, y locations, signed)
476 GR_SIZE size value (widths, heights, signed)
477 GR_COUNT number of items (signed)
478 GR_COLOR full color value (32 bit value for full generality)
479 GR_COLOR8 eight bit color value (8 bit value for efficient storage)
480 GR_BITMAP bitmap unit (single words of 16 bits for bitmaps)
481 GR_MODE drawing mode (setting, xoring, anding, oring)
482 GR_CHAR text character (normal chars)
483 GR_ID resource ids (window, graphics context, pixmap)
484 GR_DRAW_ID drawable id (window, pixmap)
485 GR_WINDOW_ID window id (identifies individual window)
486 GR_PIXMAP_ID pixmap id (identifies individual pixmaps, not yet used)
487 GR_GC_ID graphics context id (identifies indiviual graphics contexts)
488 GR_FONT font number (identifies individual fonts, first few built-in)
489 GR_BOOL boolean value (GR_TRUE or GR_FALSE)
490 GR_FUNC function codes (not for clients to use)
491 GR_ERROR error value (reasons for graphics calls to fail)
492 GR_EVENT_TYPE event types (identifies the type of event)
493 GR_BUTTON button flags (which mouse buttons are depressed)
494 GR_MODIFIER modifier flags (CTRL, SHIFT, etc)
495 GR_EVENT_MASK event masks (mask values corresponding to event types)
496 GR_FUNC_NAME function name (for error reporting)
497 GR_ERROR_FUNC error function (for defining error handlers)
500 The following typedefs may be useful to your program. None of the library
501 functions (currently) accept any of these structures as arguments, except
502 for the GrPoly and GrFillPoly routines, which use GR_POINT.
506 GR_COORD x; /* x coordinate */
507 GR_COORD y; /* y coordinate */
511 GR_COORD x1; /* x coordinate of first point */
512 GR_COORD y1; /* y coordinate of first point */
513 GR_COORD x2; /* x coordinate of second point */
514 GR_COORD y2; /* y coordinate of second point */
518 GR_COORD x; /* x coordinate of center */
519 GR_COORD y; /* y coordinate of center */
520 GR_SIZE rx; /* radius in x direction */
521 GR_SIZE ry; /* radius in y direction */
525 GR_COORD x; /* x coordinate of top left corner */
526 GR_COORD y; /* y coordinate of top left corner */
527 GR_SIZE width; /* width of rectangle */
528 GR_SIZE height; /* height of rectangle */
534 The coordinate system is limited to integers in the range GR_COORD_MIN
535 to GR_COORD_MAX. This is -32768 to 32767, and fits in a short.
537 The maximum size of a cursor definition is GR_MAX_CURSOR_SIZE, which is
538 16 pixels by 16 pixels.
540 The complexity of overlapping windows is limited to GR_MAX_CLIPRECTS regions,
541 which is 200. Each window which overlaps another requires another 1 to 4
542 regions depending on its position and size.
550 Open a connection to the graphics server. This must be the first graphics
551 function used by your program. Currently, this sets the screen into
552 graphics mode. Returns zero if successful, -1 on failure.
557 Close the connection to the graphics server, first flushing any graphics
558 calls that have been buffered. Currently, this sets the screen back into
559 text mode. This (currently) should be called before your program exits,
560 otherwise the screen will be left in graphics mode. If this occurs, you
561 can run the 'tm' program to reset the terminal to text mode.
565 GrSetErrorHandler(func)
566 GR_ERROR_FUNC func; /* function to handle errors */
567 Set an error handling routine, which will be called on any errors from
568 the server (when events are asked for by the client). If zero is given,
569 then a default routine will be used which will describe the error and exit.
570 Returns the previous error handler (0 if none). When an error occurs,
571 the error handling function is called with the following parameters:
572 GR_ERROR, GR_FUNC_NAME, and GR_ID. These are the error code, the name
573 of the function which failed, and a resource id (0 if not meaningful).
574 The error routine can return if desired, but without corrective action
575 new errors will probably occur soon.
580 GR_SCREEN_INFO *sip; /* location to return info into */
581 Return useful information about the screen. This information returned
582 has been documented above.
586 GrGetFontInfo(font, fip)
587 GR_FONT font; /* font number */
588 GR_FONT_INFO *fip; /* address of font info */
589 Return useful information about the specified font number. This information
590 is the font number, the height of the font, the maximum width of any
591 character in the font, the height of the baseline, a flag indicating whether
592 or not the font is fixed-width, and a table of the individual widths of each
593 character in the font. If the font is unknown, the returned font number is
594 set to zero and the remainder of the information is undefined. Refer to
595 graphics.h for a definition of the fields of GR_FONT_INFO.
599 GrGetGCInfo(gc, gcip)
600 GR_GC_ID gc; /* graphics context */
601 GR_GC_INFO *gcip; /* address of graphics context info */
602 Return useful information about the specified graphics context. This
603 information is the graphics context id, the current font, the foreground
604 and background colors, and so on. If the graphics context is unknown,
605 the returned id is 0, and the other information is undefined. Refer to
606 graphics.h for a definition of the fields of GR_GC_INFO.
610 GrGetGCTextSize(gc, cp, len, retwidth, retheight, retbase)
611 GR_GC_ID gc; /* graphics context containing font */
612 GR_CHAR *cp; /* address of text string */
613 GR_SIZE len; /* length of text string */
614 GR_SIZE *retwidth; /* returned width of string */
615 GR_SIZE *retheight; /* returned height of string */
616 GR_SIZE *retbase; /* returned height of baseline */
617 Return the size of a text string for the font in a graphics context.
618 This is the width of the string, the height of the string, and the height
619 above the bottom of the font of the baseline for the font. The returned
625 GR_EVENT *ep; /* address where event is returned */
626 Return the next event from the event queue, waiting for it if necessary.
627 If a graphics error had occurred, the error handler will be called at this
628 point. This routine first flushes any buffered graphics commands. The
629 GR_EVENT is a union of all the possible events. The type field of the union
630 indicates which of the possible events took place, and then the correct
631 element of the union can be used to access that particular event type's data.
636 GR_EVENT *ep; /* address where event is returned */
637 Return the next event from the event queue if one is ready.
638 If one is not ready, then the event type GR_EVENT_TYPE_NONE is returned.
639 Therefore, this routine never blocks. This routine first flushes any
640 buffered graphics commands.
645 GR_EVENT *ep; /* address where event is returned */
646 Return the next event from the event queue if one is ready, without removing
647 it from the queue. If one is not ready, then the type GR_EVENT_TYPE_NONE
648 is returned. This routine never blocks. This routine first flushes any
649 buffered graphics commands.
653 GrSelectEvents(wid, eventmask)
654 GR_WINDOW_ID wid; /* window id */
655 GR_EVENT_MASK eventmask; /* mask of events wanted */
656 Select events for a window for this client. The events are a bitmask
657 specifying the events desired for this window. This totally replaces
658 any previously selected event mask for the window.
662 GrNewWindow(parent, x, y, width, height, bordersize, background, bordercolor)
663 GR_WINDOW_ID parent; /* parent id */
664 GR_COORD x; /* x position relative to parent */
665 GR_COORD y; /* y position relative to parent */
666 GR_SIZE width; /* width */
667 GR_SIZE height; /* height */
668 GR_SIZE bordersize; /* size of border */
669 GR_COLOR background; /* background color */
670 GR_COLOR bordercolor; /* border color */
671 Allocate a new input-output window which is a child of the specified window.
672 A new top-level window is made by specifying a parent of GR_ROOT_WINDOW_ID.
673 The x and y position is the upper left corner of the window, relative to
674 the parent's upper left corner. These corners are only for the drawable
675 area of the windows, so that the border does not affect the position. An
676 input-output window cannot be made as a child of an input-only window. The
677 new window starts off unmapped, and must be mapped before it can be seen.
678 The new window inherits the cursor of the parent window, and initially is
679 set to select no events. This routine returns the window id of the window
680 which can be used in other calls.
684 GrNewInputWindow(parent, x, y, width, height)
685 GR_WINDOW_ID parent; /* parent id */
686 GR_COORD x; /* x position relative to parent */
687 GR_COORD y; /* y position relative to parent */
688 GR_SIZE width; /* width */
689 GR_SIZE height; /* height */
690 Allocate a new input-only window which is a child of the specified window.
691 An input-only window is invisible, and cannot be drawn into. It's only
692 purposes are that it can select events, and can have it's own cursor. The
693 new window starts off unmapped, and must be mapped before it is effective.
694 The new window inherits the cursor of the parent window, and initially is
695 set to select no events. This routine returns the window id of the window
696 which can be used in other calls.
701 GR_WINDOW_ID wid; /* window to destroy */
702 This unmaps and then destroys the specified window, and all of its children.
703 The root window cannot be destroyed. After destroying a window, you must be
704 careful about handling events which refer to the dead window, but which have
709 GrGetWindowInfo(wid, wip)
710 GR_WINDOW_ID wid; /* window id to find out about */
711 GR_WINDOW_INFO *wip; /* location to return info into */
712 Return useful information about the specified window. Refer to the
713 graphics.h include file for the definition of GR_WINDOW_INFO to see
714 what data is returned. If the window id is not valid, an error is NOT
715 generated. Instead, the wid value in the returned structure is set to
716 zero, and the other fields are not defined.
721 Allocate a new graphics context with default parameters. These defaults are:
722 background of black, foreground of white, font as font 0, and drawing mode
723 as setting. This routine returns the id for the graphics context which can
724 be used in other calls.
729 GR_GC_ID gc; /* graphics context to copy */
730 Allocate a new graphics context which is a copy of another one. The new
731 graphics context has the same parameter values as the old one, but is then
732 independent. This routine returns the id for the graphics context which
733 can be used in other calls.
738 GR_GC_ID gc; /* graphics context to destroy */
739 Destroy an existing graphics context.
744 GR_WINDOW_ID wid; /* window to be mapped */
745 Map the window to make it (and possibly its children) visible on the screen.
746 This paints the border and background of the window, and creates an
747 exposure event to tell the client to draw into it.
752 GR_WINDOW_ID wid; /* window to be unmapped */
753 Unmap the window to make it and its children invisible on the screen.
758 GR_WINDOW_ID wid; /* window to be raised */
759 Raise the window to the highest level among its siblings. This means that
760 this window will be visible in preference to those siblings. Siblings are
761 windows which have the same parent as this window.
766 GR_WINDOW_ID wid; /* window to be lowered */
767 Lower the window to the lowest level among its siblings. This means that
768 this window will be covered by any siblings which overlap it.
772 GrMoveWindow(wid, x, y)
773 GR_WINDOW_ID wid; /* window to be lowered */
774 GR_COORD x; /* new relative x position */
775 GR_COORD y; /* new relative y position */
776 Move the window to the specified position relative to its parent.
780 GrResizeWindow(wid, width, height)
781 GR_WINDOW_ID wid; /* window to be lowered */
782 GR_SIZE width; /* new width of window */
783 GR_SIZE height; /* new height of window */
784 Resize the window to be the specified size. Resizing of a window can
785 generate exposure events.
789 GrClearWindow(wid, exposeflag)
790 GR_WINDOW_ID wid; /* window id */
791 GR_BOOL exposeflag; /* nonzero to cause an exposure */
792 Clear the specified window by setting it to its background color.
793 If the exposeflag is nonzero, then this also creates an exposure
794 event for the window.
799 GR_WINDOW_ID wid; /* window id */
800 Set the focus to a particular window. This makes keyboard events only
801 visible to that window or children of it, depending on the pointer location.
802 Setting the focus window to the root window makes the input focus track
803 the pointer (which is the default).
807 GrSetBorderColor(wid, color)
808 GR_WINDOW_ID wid; /* window id */
809 GR_COLOR color; /* color for border */
810 Set the border of a window to the specified color.
814 GrSetCursor(wid, width, height, hotx, hoty, foreground, background,
817 GR_WINDOW_ID wid; /* window id to set cursor for */
818 GR_SIZE width; /* width of cursor */
819 GR_SIZE height; /* height of cursor */
820 GR_COORD hotx; /* relative x position of hot spot */
821 GR_COORD hoty; /* relative y position of hot spot */
822 GR_COLOR foreground; /* foreground color of cursor */
823 GR_COLOR background; /* background color of cursor */
824 GR_BITMAP *fgbitmap; /* foreground bitmap */
825 GR_BITMAP *bgbitmap; /* background bitmap */
826 Specify a new cursor for a window. This cursor will only be used within
827 that window, and by default for its new children. The cursor is defined
828 by giving its width and height, its foreground and background colors, its
829 foreground and background bitmaps, and its "hot spot" position. If a pixel
830 is specified for both the foreground and background bitmaps, then the
831 foreground has precedence. The hot spot is an offset from the upper left
832 corner of the bitmap, and is the location in the cursor which is important.
837 GR_COORD x; /* new x position of cursor */
838 GR_COORD y; /* new y position of cursor */
839 Move the cursor to the specified absolute screen coordinates.
840 The coordinates are that of the defined hot spot of the cursor.
841 The cursor's appearance is changed to that defined for the window
842 in which the cursor is moved to.
847 Flush the graphics buffer so that all previous requests will be executed.
848 This is only needed if you do not check events quickly and want to see the
849 results on the screen soon, since checking for events does an automatic flush.
853 GrSetGCForeground(gc, foreground)
854 GR_GC_ID gc; /* graphics context id */
855 GR_COLOR foreground; /* foreground color */
856 Set the foreground color in a graphics context. The default is white.
860 GrSetGCBackground(gc, background)
861 GR_GC_ID gc; /* graphics context id */
862 GR_COLOR background; /* background color */
863 Set the background color in a graphics context. The default is black.
867 GrSetGCUseBackground(gc, flag)
868 GR_GC_ID gc; /* graphics context id */
869 GR_BOOL flag; /* TRUE if background is drawn */
870 Set whether or not the background color is drawn in bitmaps and text.
871 This affects GrBitmap, GrArea8, and GrText. The default is GR_TRUE.
875 GrSetGCMode(gc, mode)
876 GR_GC_ID gc; /* graphics context id */
877 GR_MODE mode; /* drawing mode */
878 Set the drawing mode in a graphics context. The drawing mode is one of
879 GR_MODE_SET, GR_MODE_XOR, GR_MODE_AND, or GR_MODE_OR. The default is
884 GrSetGCFont(gc, font)
885 GR_GC_ID gc; /* graphics context id */
886 GR_FONT font; /* text font */
887 Set the font used for text drawing in a graphics context.
888 The font is a number identifying one of several fonts.
889 Font number 0 is always available, and is the default font.
893 GrLine(id, gc, x1, y1, x2, y2)
900 Draw a line in the specified drawable using the specified graphics context.
904 GrRect(id, gc, x, y, width, height)
911 Draw the boundary of a rectangle in the specified drawable using the
912 specified graphics context.
916 GrFillRect(id, gc, x, y, width, height)
923 Fill a rectangle in the specified drawable using the specified graphics
924 context. The boundary of this rectangle is identical to that drawn by
929 GrEllipse(id, gc, x, y, rx, ry)
936 Draw the boundary of an ellipse in the specified drawable with
937 the specified graphics context.
941 GrFillEllipse(id, gc, x, y, rx, ry)
948 Fill an ellipse in the specified drawable using the specified
953 GrBitmap(id, gc, x, y, width, height, bitmaptable)
960 GR_BITMAP *bitmaptable;
961 Draw a rectangular area in the specified drawable using the specified
962 graphics context, as determined by the specified bit map. This differs
963 from rectangle drawing in that the rectangle is drawn using the foreground
964 color and possibly the background color as determined by the bit map.
965 Bits which are 1 are the foreground, and bits which are 0 are the background.
966 Each row of bits is aligned to the next bitmap word boundary (so there can
967 be padding at the end of each row). The background bit values are only
968 written if the usebackground flag is set in the GC.
972 GrArea8(id, gc, x, y, width, height, colortable)
979 GR_COLOR8 *colortable;
980 Draw a rectangular area in the specified drawable using the specified
981 graphics context. This differs from rectangle drawing in that the
982 color values for each pixel in the rectangle are specified. The color
983 values are estricted to 8 bit values. The color table is indexed row by
984 row from left to right. Table values whose color matches the background
985 color are only written if the usebackground flag is set in the GC.
989 GrReadArea8(id, x, y, width, height, colortable)
995 GR_COLOR8 *colortable;
996 Read the color values from the specified rectangular area of the specified
997 drawable into a supplied buffer. If the drawable is a window which is
998 obscured by other windows, then the returned values will include the values
999 from the covering windows. Regions outside of the screen boundaries, or
1000 from unmapped windows will return black.
1004 GrPoint(id, gc, x, y)
1009 Draw a point in the specified drawable using the specified graphics context.
1013 GrPoly(id, gc, count, pointtable)
1017 GR_POINT *pointtable;
1018 Draw a polygon in the specified drawable using the specified graphics
1019 context. The polygon is only complete if the first point is repeated at
1020 the end. Note: currently if the polygon crosses itself, and the drawing
1021 mode is set to XOR, then the individual line segments will affect each
1022 other. The endpoints of the lines are correct, however.
1026 GrFillPoly(id, gc, count, pointtable)
1030 GR_POINT *pointtable;
1031 Draw a filled polygon in the specified drawable using the specified
1032 graphics context. The last point may be a duplicate of the first point,
1033 but this is not required. Note: currently only convex polygons are
1038 GrText(id, gc, x, y, str, count)
1045 Draw a text string at the specified location in the specified drawable
1046 using the specified graphics context. The background of the characters
1047 are only drawn if the usebackground flag in the GC is set.
1052 The following simple program opens the graphics, creates a window, prints
1053 some text in it, waits for the mouse to be clicked in the window, then exits.
1057 #include <graphics.h>
1059 #define MARGIN 50 /* margin around window */
1064 GR_WINDOW_ID wid; /* window id */
1065 GR_GC_ID gc; /* graphics context id */
1066 GR_EVENT event; /* current event */
1067 GR_SCREEN_INFO si; /* screen information */
1070 fprintf(stderr, "Cannot open graphics\n");
1074 GrGetScreenInfo(&si);
1076 wid = GrNewWindow(GR_ROOT_WINDOW_ID, MARGIN, MARGIN,
1077 si.cols - MARGIN * 2, si.rows - MARGIN * 2,
1078 1, si.black, si.white);
1080 GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_EXPOSURE);
1085 GrGetNextEvent(&event);
1086 switch (event.type) {
1087 case GR_EVENT_TYPE_BUTTON_DOWN:
1088 if (event.button.wid != wid)
1093 case GR_EVENT_TYPE_EXPOSURE:
1094 if (event.exposure.wid == wid)
1095 GrText(wid, gc, 50, 50, "EXIT", 4);
1102 For a more complete demonstration program, see the file "demo.c" in the
1103 /usr/src/graphics/clients directory.