OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [mw/] [doc/] [original_mini-x.txt] - Blame information for rev 1767

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
                        MINI-X TUTORIAL
2
                        David I. Bell
3
                        19 May 91
4
 
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.
12
 
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
18
tutorial.
19
 
20
 
21
WINDOWS
22
 
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.
29
 
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.
37
 
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.
44
 
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
50
starts off unmapped.
51
 
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.
56
 
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.
65
 
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.
73
 
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.
80
 
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.
88
 
89
 
90
GRAPHICS CONTEXTS
91
 
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.
103
 
104
For example, instead of a function call like:
105
        drawline(window, x1, y1, x2, y2, color, width, style, operation);
106
 
107
you have instead
108
        drawline(window, gc, x1, y1, x2, y2),
109
 
110
where the graphics context contains within itself the parameters color, width,
111
style, and operation.
112
 
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.
120
 
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.
130
 
131
The parameters contained within a graphics context are currently the
132
following:
133
 
134
Drawing mode.
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
140
 
141
Text font.
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.
145
 
146
Foreground color.
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.
149
 
150
Background color.
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.
155
 
156
UseBackground flag.
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.
160
 
161
 
162
EVENTS
163
 
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.
170
 
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.
180
 
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.
188
 
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
196
never propagate.
197
 
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).
205
 
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.
216
 
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.
231
 
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.)
253
 
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.
260
 
261
 
262
GR_EVENT_TYPE_NONE      (GR_EVENT)
263
        This indicates that no event has occurred.
264
 
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.
270
 
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.
277
 
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.
281
 
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.
285
 
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.
289
 
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.
295
 
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.
301
 
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.
309
 
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.
314
 
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.
318
 
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.
322
 
323
 
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.
331
 
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.
339
 
340
 
341
MODIFIER AND MOUSE BUTTONS
342
 
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:
349
 
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
354
 
355
 
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
359
buttons are defined:
360
 
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
365
 
366
 
367
BITMAPS
368
 
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:
377
 
378
        GR_BITMAP_SIZE(width, height).
379
 
380
The symbol GR_MAX_BITMAP_SIZE is the number of bitmap words required for
381
the maximum sized cursor.
382
 
383
 
384
ERROR CODES
385
 
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.
393
 
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.
399
 
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
405
the program.
406
 
407
The following is a list of the possible errors:
408
 
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
422
 
423
 
424
SCREEN PROPERTIES
425
 
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.
435
 
436
 
437
typedef struct {
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 */
448
} GR_SCREEN_INFO;
449
 
450
 
451
INCLUDE FILE AND GRAPHICS LIBRARY
452
 
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 
457
 
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.
461
 
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
466
 
467
 
468
TYPEDEFS
469
 
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
473
shorts, or longs.
474
 
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)
498
 
499
 
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.
503
 
504
 
505
typedef struct {
506
        GR_COORD        x;              /* x coordinate */
507
        GR_COORD        y;              /* y coordinate */
508
} GR_POINT;
509
 
510
typedef struct {
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 */
515
} GR_LINE;
516
 
517
typedef struct {
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 */
522
} GR_ELLIPSE;
523
 
524
typedef struct {
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 */
529
} GR_RECT;
530
 
531
 
532
LIMITS
533
 
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.
536
 
537
The maximum size of a cursor definition is GR_MAX_CURSOR_SIZE, which is
538
16 pixels by 16 pixels.
539
 
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.
543
 
544
 
545
GRAPHICS CALLS
546
 
547
 
548
int
549
GrOpen()
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.
553
 
554
 
555
void
556
GrClose()
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.
562
 
563
 
564
GR_ERROR_FUNC
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.
576
 
577
 
578
void
579
GrGetScreenInfo(sip)
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.
583
 
584
 
585
void
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.
596
 
597
 
598
void
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.
607
 
608
 
609
void
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
620
sizes are in pixels.
621
 
622
 
623
void
624
GrGetNextEvent(ep)
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.
632
 
633
 
634
void
635
GrCheckNextEvent(ep)
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.
641
 
642
 
643
void
644
GrPeekEvent(ep)
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.
650
 
651
 
652
void
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.
659
 
660
 
661
GR_WINDOW_ID
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.
681
 
682
 
683
GR_WINDOW_ID
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.
697
 
698
 
699
void
700
GrDestroyWindow(wid)
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
705
not been read yet.
706
 
707
 
708
void
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.
717
 
718
 
719
GR_GC_ID
720
GrNewGC()
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.
725
 
726
 
727
GR_GC_ID
728
GrCopyGC(gc)
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.
734
 
735
 
736
void
737
GrDestroyGC(gc)
738
        GR_GC_ID        gc;             /* graphics context to destroy */
739
Destroy an existing graphics context.
740
 
741
 
742
void
743
GrMapWindow(wid)
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.
748
 
749
 
750
void
751
GrUnmapWindow(wid)
752
        GR_WINDOW_ID    wid;            /* window to be unmapped */
753
Unmap the window to make it and its children invisible on the screen.
754
 
755
 
756
void
757
GrRaiseWindow(wid)
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.
762
 
763
 
764
void
765
GrLowerWindow(wid)
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.
769
 
770
 
771
void
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.
777
 
778
 
779
void
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.
786
 
787
 
788
void
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.
795
 
796
 
797
void
798
GrSetFocus(wid)
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).
804
 
805
 
806
void
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.
811
 
812
 
813
void
814
GrSetCursor(wid, width, height, hotx, hoty, foreground, background,
815
        fgbitmap, bgbitmap)
816
 
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.
833
 
834
 
835
void
836
GrMoveCursor(x, y)
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.
843
 
844
 
845
void
846
GrFlush()
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.
850
 
851
 
852
void
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.
857
 
858
 
859
void
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.
864
 
865
 
866
void
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.
872
 
873
 
874
void
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
880
GR_MODE_SET.
881
 
882
 
883
void
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.
890
 
891
 
892
void
893
GrLine(id, gc, x1, y1, x2, y2)
894
        GR_DRAW_ID      id;
895
        GR_GC_ID        gc;
896
        GR_COORD        x1;
897
        GR_COORD        y1;
898
        GR_COORD        x2;
899
        GR_COORD        y2;
900
Draw a line in the specified drawable using the specified graphics context.
901
 
902
 
903
void
904
GrRect(id, gc, x, y, width, height)
905
        GR_DRAW_ID      id;
906
        GR_GC_ID        gc;
907
        GR_COORD        x;
908
        GR_COORD        y;
909
        GR_SIZE         width;
910
        GR_SIZE         height;
911
Draw the boundary of a rectangle in the specified drawable using the
912
specified graphics context.
913
 
914
 
915
void
916
GrFillRect(id, gc, x, y, width, height)
917
        GR_DRAW_ID      id;
918
        GR_GC_ID        gc;
919
        GR_COORD        x;
920
        GR_COORD        y;
921
        GR_SIZE         width;
922
        GR_SIZE         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
925
the GrRect function.
926
 
927
 
928
void
929
GrEllipse(id, gc, x, y, rx, ry)
930
        GR_DRAW_ID      id;
931
        GR_GC_ID        gc;
932
        GR_COORD        x;
933
        GR_COORD        y;
934
        GR_SIZE         rx;
935
        GR_SIZE         ry;
936
Draw the boundary of an ellipse in the specified drawable with
937
the specified graphics context.
938
 
939
 
940
void
941
GrFillEllipse(id, gc, x, y, rx, ry)
942
        GR_DRAW_ID      id;
943
        GR_GC_ID        gc;
944
        GR_COORD        x;
945
        GR_COORD        y;
946
        GR_SIZE         rx;
947
        GR_SIZE         ry;
948
Fill an ellipse in the specified drawable using the specified
949
graphics context.
950
 
951
 
952
void
953
GrBitmap(id, gc, x, y, width, height, bitmaptable)
954
        GR_DRAW_ID      id;
955
        GR_GC_ID        gc;
956
        GR_COORD        x;
957
        GR_COORD        y;
958
        GR_SIZE         width;
959
        GR_SIZE         height;
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.
969
 
970
 
971
void
972
GrArea8(id, gc, x, y, width, height, colortable)
973
        GR_DRAW_ID      id;
974
        GR_GC_ID        gc;
975
        GR_COORD        x;
976
        GR_COORD        y;
977
        GR_SIZE         width;
978
        GR_SIZE         height;
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.
986
 
987
 
988
void
989
GrReadArea8(id, x, y, width, height, colortable)
990
        GR_DRAW_ID      id;
991
        GR_COORD        x;
992
        GR_COORD        y;
993
        GR_SIZE         width;
994
        GR_SIZE         height;
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.
1001
 
1002
 
1003
void
1004
GrPoint(id, gc, x, y)
1005
        GR_DRAW_ID      id;
1006
        GR_GC_ID        gc;
1007
        GR_COORD        x;
1008
        GR_COORD        y;
1009
Draw a point in the specified drawable using the specified graphics context.
1010
 
1011
 
1012
void
1013
GrPoly(id, gc, count, pointtable)
1014
        GR_DRAW_ID      id;
1015
        GR_GC_ID        gc;
1016
        GR_COUNT        count;
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.
1023
 
1024
 
1025
void
1026
GrFillPoly(id, gc, count, pointtable)
1027
        GR_DRAW_ID      id;
1028
        GR_GC_ID        gc;
1029
        GR_COUNT        count;
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
1034
filled properly.
1035
 
1036
 
1037
void
1038
GrText(id, gc, x, y, str, count)
1039
        GR_DRAW_ID      id;
1040
        GR_GC_ID        gc;
1041
        GR_COORD        x;
1042
        GR_COORD        y;
1043
        GR_CHAR         *str;
1044
        GR_COUNT        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.
1048
 
1049
 
1050
EXAMPLE PROGRAM
1051
 
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.
1054
 
1055
 
1056
#include 
1057
#include 
1058
 
1059
#define MARGIN  50                      /* margin around window */
1060
 
1061
 
1062
main()
1063
{
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 */
1068
 
1069
        if (GrOpen() < 0) {
1070
                fprintf(stderr, "Cannot open graphics\n");
1071
                exit(1);
1072
        }
1073
 
1074
        GrGetScreenInfo(&si);
1075
 
1076
        wid = GrNewWindow(GR_ROOT_WINDOW_ID, MARGIN, MARGIN,
1077
                si.cols - MARGIN * 2, si.rows - MARGIN * 2,
1078
                1, si.black, si.white);
1079
 
1080
        GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_EXPOSURE);
1081
        GrMapWindow(wid);
1082
        gc = GrNewGC();
1083
 
1084
        while (1) {
1085
                GrGetNextEvent(&event);
1086
                switch (event.type) {
1087
                        case GR_EVENT_TYPE_BUTTON_DOWN:
1088
                                if (event.button.wid != wid)
1089
                                        break;
1090
                                GrClose();
1091
                                exit(0);
1092
 
1093
                        case GR_EVENT_TYPE_EXPOSURE:
1094
                                if (event.exposure.wid == wid)
1095
                                        GrText(wid, gc, 50, 50, "EXIT", 4);
1096
                                break;
1097
                }
1098
        }
1099
}
1100
 
1101
 
1102
For a more complete demonstration program, see the file "demo.c" in the
1103
/usr/src/graphics/clients directory.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.