1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
|
.TH GRAPHICS 3
.SH NAME
Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror, initdisplay, closedisplay, getdefont, getwindow, gengetwindow, flushimage, bufimage, lockdisplay, unlockdisplay, cursorswitch, cursorset, openfont, buildfont, freefont, Pfmt, Rfmt, strtochan, chantostr, chantodepth \- interactive graphics
.SH SYNOPSIS
.nf
.PP
.ft L
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
.ft P
.PP
.ta \w'\fLFont* 'u
.B
int initdraw(void (*errfun)(Display*, char*), char *font,
.B
char *label)
.PP
.B
int geninitdraw(char *devdir, void(*errfun)(Display*, char*),
.PP
.B
char *font, char *label, char *mousedir, char *windir,
.B
int ref)
.PP
.B
int newwindow(char *str)
.PP
.B
void drawerror(Display *d, char *msg)
.PP
.B
Display* initdisplay(char *devdir, char *win, void(*errfun)(Display*, char*))
.PP
.B
void closedisplay(Display *d)
.PP
.B
Font* getdefont(Display *d)
.PP
.B
int flushimage(Display *d, int vis)
.PP
.B
int bufimage(Display *d, int n)
.PP
.B
int lockdisplay(Display *d)
.PP
.B
int unlockdisplay(Display *d)
.PP
.B
int getwindow(Display *d, int ref)
.PP
.B
int gengetwindow(Display *d, char *winname,
.br
.B
Image **ip, Screen **sp, int ref)
.PP
.B
void cursorswitch(Cursor *curs)
.PP
.B
void cursorset(Point p)
.PP
.B
Font* openfont(Display *d, char *name)
.PP
.B
Font* buildfont(Display *d, char *desc, char *name)
.PP
.B
void freefont(Font *f)
.PP
.B
int Pfmt(Fmt*)
.PP
.B
int Rfmt(Fmt*)
.PP
.B
ulong strtochan(char *s)
.PP
.B
char* chantostr(char *s, ulong chan)
.PP
.B
int chantodepth(ulong chan)
.PP
.B
extern Display *display
.PP
.B
extern Image *screen
.PP
.B
extern Screen *_screen
.PP
.B
extern Font *font
.fi
.SH DESCRIPTION
A
.B Display
structure represents a connection to the graphics device,
.IR draw (3),
holding all graphics resources associated with the connection,
including in particular raster image data in use by the client program.
The structure is defined (in part) as:
.IP
.EX
.ta 6n +10n
typedef
struct Display
{
...
void (*error)(Display*, char*);
...
Image *black;
Image *white;
Image *opaque;
Image *transparent;
Image *image;
Font *defaultfont;
Subfont *defaultsubfont;
...
};
.EE
.PP
A
.B Point
is a location in an Image
(see below and
.IR draw (3)),
such as the display, and is defined as:
.IP
.EX
.ta 6n
typedef
struct Point {
int x;
int y;
} Point;
.EE
.PP
The coordinate system has
.I x
increasing to the right and
.I y
increasing down.
.PP
A
.B Rectangle
is a rectangular area in an image.
.IP
.EX
.ta 6n
typedef
struct Rectangle {
Point min; /* upper left */
Point max; /* lower right */
} Rectangle;
.EE
.PP
By definition,
.BR min.x ≤ max.x
and
.BR min.y ≤ max.y .
By convention, the right (maximum
.IR x )
and bottom (maximum
.IR y )
edges are
excluded from the represented rectangle, so abutting rectangles have no
points in common.
Thus,
.B max
contains the coordinates of the first point beyond the rectangle.
.PP
The
.B Image
data structure is defined in
.IR draw (3).
.PP
A
.B Font
is a set of character images, indexed by runes (see
.IR utf (6)).
The images are organized into
.BR Subfonts ,
each containing the images for a small, contiguous set of runes.
The detailed format of these data structures,
which are described in detail in
.IR cachechars (3),
is immaterial for most applications.
.B Font
and
.B Subfont
structures contain two interrelated fields:
.LR ascent ,
the distance from the top of the highest character
(actually the top of the image holding all the characters)
to the baseline,
and
.LR height ,
the distance from the top of the highest character to the bottom of
the lowest character (and hence, the interline spacing).
See
.IR cachechars (3)
for more details.
.PP
.I Buildfont
parses the font description in the buffer
.BR desc ,
returning a
.B Font*
pointer that can be used by
.B string
(see
.IR draw (3))
to draw characters from the font.
.I Openfont
does the same, but reads the description
from the named file.
.I Freefont
frees a font.
The convention for naming font files is:
.IP
.B /lib/font/bit/\fIname\fP/\fIrange\fP.\fIsize\fP.font
.PD
.PP
where
.I size
is approximately the height in pixels of the lower case letters
(without ascenders or descenders).
.I Range
gives some indication of which characters will be available: for example
.BR ascii ,
.BR latin1 ,
.BR euro ,
or
.BR unicode .
.B Euro
includes most European languages, punctuation marks, the International Phonetic
Alphabet, etc., but no Oriental languages.
.B Unicode
includes every character for which appropriate-sized images exist on the system.
.PP
A
.I Cursor
is defined:
.IP
.EX
.ta 6n +\w'Point 'u
typedef struct
Cursor {
Point offset;
uchar clr[2*16];
uchar set[2*16];
} Cursor;
.EE
.PP
The arrays are arranged in rows, two bytes per row, left to
right in big-endian order to give 16 rows
of 16 bits each.
A cursor is displayed on the screen by adding
.B offset
to the current mouse position, using
.B clr
as a mask to draw white at the pixels where
.B clr
is one, and then drawing black at the pixels where
.B set
is one.
.PP
The routine
.I initdraw
connects to the display; it returns \-1 if it fails and sets the error string.
.I Initdraw
sets up the global variables
.B display
(the
.B Display
structure representing the connection),
.B screen
(an
.B Image
representing the display memory itself or, if
.IR rio (1)
is running, the client's window),
and
.B font
(the default font for text).
The arguments to
.I initdraw
include a
.IR label ,
which is written to
.B /dev/label
if non-nil
so that it can be used to identify the window when hidden (see
.IR rio (1)).
The font is created by reading the named
.I font
file. If
.B font
is null,
.I initdraw
reads the file named in the environment variable
.BR $font ;
if
.B $font
is not set, it imports the default (usually minimal)
font from the operating system.
The global
.I font
will be set to point to the resulting
.B Font
structure.
The
.I errfun
argument is a
.I graphics error function
to call in the event of a fatal error in the library; it must never return.
Its arguments are the
display pointer and an error string.
If
.I errfun
is nil, the library provides a default, called
.IR drawerror .
Another effect of
.I initdraw
is that it installs
.IR print (3)
formats
.I Pfmt
and
.I Rfmt
as
.L %P
and
.L %R
for printing
.B Points
and
.BR Rectangles .
.PP
The
.I geninitdraw
function provides a less automated way to establish a connection, for programs
that wish to connect to multiple displays.
.I Devdir
is the name of the directory containing the device files for the display
(if nil, default
.BR /dev );
.IR errfun ,
.IR font ,
and
.I label
are as in
.IR initdraw ;
.I mousedir
and
.I windir
are the directories holding the
.B mouse
and
.B winname
files; and
.I ref
specifies the refresh function to be used to create the window, if running under
.IR rio (1)
(see
.IR window (3)).
.PP
The function
.I newwindow
may be called before
.I initdraw
or
.IR geninitdraw
to cause the program to occupy a newly created window rather than take over the one in
which it is running when it starts.
The
.I str
argument, if non-null, is concatenated to the string \f5\&"new\ "\fP
that is used to create the window (see
.IR rio (4)).
For example,
.B newwindow("-hide -dy 100")
will cause the program to run in a newly created, hidden window
100 pixels high.
.PP
.I Initdisplay
is part of
.IR geninitdraw ;
it sets up the display structures but does not allocate any fonts or call
.IR getwindow .
The arguments are similar to those of
.IR initdraw ;
.I win
names the directory, default
.BR /dev ,
in which the files associated with the window reside.
.I Closedisplay
disconnects the display and frees the associated data structures.
.I Getdefont
builds a
.B Font
structure from in-core data describing a default font.
None of these routines is needed by most programs, since
.I initdraw
calls them as needed.
.PP
The data structures associated with the display must be protected in a multi-process program,
because they assume only one process will be using them at a time.
Multi-process programs should set
.B display->locking
to
.BR 1 ,
to notify the library to use a locking protocol for its own accesses,
and call
.I lockdisplay
and
.I unlockdisplay
around any calls to the graphics library that will cause messages to be sent to the display device.
.I Initdraw
and
.I geninitdraw
initialize the display to the locked state.
.PP
.I Getwindow
returns a pointer to the window associated with the application; it is called
automatically by
.I initdraw
to establish the
.B screen
pointer but must be called after each resizing of the window to restore
the library's connection to the window.
If
.B rio
is not running, it returns
.BR display->image ;
otherwise it negotiates with
.B rio
by looking in
.B /dev/winname
to find the name of the window and opening it using
.B namedimage
(see
.IR allocimage (3)).
The resulting window will be created using the refresh method
.I ref
(see
.IR window (3));
this should almost always be
.B Refnone
because
.B rio
provides backing store for the window.
.PP
.I Getwindow
overwrites the global variables
.BR screen ,
a pointer to the
.B Image
defining the window (or the overall display, if no window system is running); and
.BR _screen ,
a pointer to the
.B Screen
representing the root of the window's hierarchy. (See
.IR window (3).
The overloading of the
.B screen
word is an unfortunate historical accident.)
.I Getwindow
arranges that
.B screen
point to the portion of the window inside the border;
sophisticated clients may use
.B _screen
to make further subwindows.
Programs desiring multiple independent windows
may use the mechanisms of
.IR rio (4)
to create more windows (usually by a fresh mount of the window sytem
in a directory other than
.BR /dev ),
then use
.I gengetwindow
to connect to them.
.IR Gengetwindow 's
extra arguments are the full path of the window's
.B winname
file and pointers to be overwritten with the values of the `global'
.B Image
and
.B Screen
variables for the new window.
.PP
The mouse cursor is always displayed.
The initial cursor is an arrow.
.I Cursorswitch
causes the argument cursor to be displayed instead.
A zero argument causes a switch back to the arrow cursor.
.I Cursorset
moves the mouse cursor to position
.IR p ,
provided (if in a window) that the requesting program is
executing in the current window and the mouse is within
the window boundaries; otherwise
.I cursorset
is a no-op.
.PP
The graphics functions described in
.IR draw (3),
.IR allocimage (3),
.IR cachechars (3),
and
.IR subfont (3)
are implemented by writing commands to files under
.B /dev/draw
(see
.IR draw (3));
the writes are buffered, so the functions may not take effect immediately.
.I Flushimage
flushes the buffer, doing all pending graphics operations.
If
.I vis
is non-zero, any changes are also copied from the `soft screen' (if any) in the
driver to the visible frame buffer.
The various allocation routines in the library flush automatically, as does the event
package (see
.IR event (3));
most programs do not need to call
.IR flushimage .
It returns \-1 on error.
.PP
.I Bufimage
is used to allocate space for
.I n
bytes in the display buffer.
It is used by all the graphics routines to send messages to the display.
.PP
The functions
.I strtochan
and
.I chantostr
convert between the channel descriptor strings
used by
.IR image (6)
and the internal
.B ulong
representation
used by the graphics protocol
(see
.IR draw (3)'s
.B b
message).
.B Chantostr
writes at most nine bytes into the buffer pointed at by
.I s
and returns
.I s
on success,
0
on failure.
.B Chantodepth
returns the number of bits per pixel used by the
format specified by
.IR chan .
Both
.B chantodepth
and
.B strtochan
return 0 when presented
with bad input.
.SH EXAMPLES
To reconnect to the window after a resize event,
.IP
.EX
if(getwindow(display, Refnone) < 0)
sysfatal("resize failed: %r");
.EE
.PP
To create and set up a new
.IR rio (1)
window,
.IP
.EX
Image *screen2;
Screen *_screen2;
srvwsys = getenv("wsys");
if(srvwsys == nil)
sysfatal("can't find $wsys: %r");
rfork(RFNAMEG); /* keep mount of rio private */
fd = open(srvwsys, ORDWR);
if(fd < 0)
sysfatal("can't open $wsys: %r");
/* mount creates window; see \f2rio\fP(4) */
if(mount(fd, -1, "/tmp", MREPL, "new -dx 300-dy 200") < 0)
sysfatal("can't mount new window: %r");
if(gengetwindow(display, "/tmp/winname",
&screen2, &_screen2, Refnone) < 0)
sysfatal("resize failed: %r");
/* now open /tmp/cons, /tmp/mouse */
\&...
.EE
.SH FILES
.BR /lib/font/bit " directory of fonts
.SH SOURCE
.B /usr/local/plan9/src/libdraw
.SH "SEE ALSO"
.IR rio (1),
.IR addpt (3),
.IR allocimage (3),
.IR cachechars (3),
.IR subfont (3),
.IR draw (3),
.IR event (3),
.IR frame (3),
.IR print (3),
.IR window (3),
.IR draw (3),
.IR rio (4),
.IR image (6),
.IR font (6)
.SH DIAGNOSTICS
An error function may call
.IR errstr (3)
for further diagnostics.
.SH BUGS
The names
.B clr
and
.B set
in the
.B Cursor
structure are reminders of an archaic color map
and might be more appropriately called
.B white
and
.BR black .
|