-
Notifications
You must be signed in to change notification settings - Fork 2
/
windowlib.c
224 lines (172 loc) · 4.38 KB
/
windowlib.c
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
/*
* Library of window routines.
*
* Robert W. Baldwin, December 1984.
*/
#include <stdio.h>
#include "window.h"
#include "specs.h"
/* The external topktab must be filled in by the application.
* It specifies the keystroke behavior that is the same in
* all windows. For example, the refresh function can be handled here.
* It should be terminated by a keychar == 0, not -1, so the
* active window will get a chance to handle the key.
*/
extern keyer topktab[];
/* This external must be a routine that gets and returns
* a keystroke (integer) without taking any arguments.
*/
extern key u_getkey();
/* This is the main loop that runs the window system.
* It returns if the cursor is not in any of the windows in wtab.
*/
void wl_driver(wtab)
gwindow *wtab[]; /* Ptr to null terminated list of windows. */
{
gwindow **pw, *w;
int lrow, lcol; /* Cursor location relative to window. */
key k;
while (TRUE) {
for (pw = wtab ; TRUE ; pw++) {
w = *pw;
if (w == NULL) return;
if (wl_hascur(w)) break;
}
lrow = rowcursor() - w->worg_row + 1;
lcol = colcursor() - w->worg_col + 1;
(*(w->wfirst))(w, lrow, lcol);
while (wl_hascur(w)) {
k = u_getkey();
if (!ddokey(w, k, topktab)) {
(*(w->wkey))(w, k);
}
}
(*(w->wlast))(w);
}
}
/* Refresh all windows.
* Do not move the cursor.
*/
void wl_refresh(wtab)
gwindow *wtab[]; /* Ptr to null terminated list of windows. */
{
gwindow **pw, *w;
int row, col; /* Initial global cursor location. */
row = rowcursor();
col = colcursor();
for (pw = wtab ; TRUE ; pw++) {
w = *pw;
if (w == NULL) break;
wl_draw(w);
}
setcursor(row, col);
}
/* Restore the cursor the the position saved in the window structure.
* Can also be used to set the cursor by first setting the cursor coords
* in the window data structure.
*/
int wl_rcursor(w)
gwindow *w; /* Pointer to basic window data. */
{
int grow,gcol; /* Global cursor locations. */
grow = w->wcur_row + w->worg_row - 1;
gcol = w->wcur_col + w->worg_col - 1;
setcursor(grow,gcol);
if (!wl_hascur(w)) disperr("wl_rcursor arguments out-of-bounds.");
return 0;
}
/* Set the cursor to the given coordinates within a window.
* That is, set it relative to the window's origin.
* It displays an error if the cursor leaves the window.
*/
int wl_setcur(w, row, col)
gwindow *w; /* Pointer to basic window data. */
int row, col; /* Local coordinates. */
{
int grow,gcol; /* Global cursor locations. */
w->wcur_row = row;
w->wcur_col = col;
grow = w->worg_row + row - 1;
gcol = w->worg_col + col - 1;
setcursor(grow,gcol);
if (!wl_hascur(w)) disperr("wl_setcur arguments out-of-bounds.");
return 0;
}
/* No-op window routine.
*/
int wl_noop(void)
{
return 0;
}
/* Return TRUE if the cursor is in the given window.
*/
int wl_hascur(w)
gwindow *w;
{
int grow, gcol; /* Global cursor location. */
int lrow, lcol; /* Cursor location relative to window. */
grow = rowcursor();
gcol = colcursor();
lrow = grow - w->worg_row + 1;
lcol = gcol - w->worg_col + 1;
if (lrow < 1 || w->wheight < lrow) return(FALSE);
if (lcol < 1 || w->wwidth < lcol) return(FALSE);
return(TRUE);
}
/* Generic draw routine.
*/
void wl_draw(w)
gwindow *w;
{
(*(w->wredraw))(w);
}
/* Redraw routine that can be used with any twindow.
* Leaves cursor on the last display line.
*/
int wl_twdraw(w)
twindow *w;
{
displine **lines, *line;
for (lines = w->dlines ; (line = *lines) != NULL ; lines++) {
(*(line->wredraw))(line);
}
return 0;
}
/* Erase the window by putting spaces of all of it.
* Leave the cursor at the window's origin.
*/
void wl_erase(w)
gwindow *w;
{
int grow, gcol; /* Global row and column locations. */
int i;
grow = w->worg_row;
gcol = w->worg_col;
for (i = 0 ; i < w->wheight ; i++) {
setcursor(grow+i, gcol);
plnspaces(w->wwidth);
}
wl_setcur(w, 1, 1);
}
/* Outline a window without changing its inside.
* Leave cursor at the origin.
*/
int wl_outline(w)
gwindow *w;
{
int grow, gcol; /* Global row and column locations. */
grow = w->worg_row;
gcol = w->worg_col;
setcursor(grow, gcol);
plnchars(w->wwidth, '-');
setcursor(grow+w->wheight-1, gcol);
plnchars(w->wwidth, '-');
setcursor(grow, gcol);
vertnchars(w->wheight, '|');
setcursor(grow, gcol+w->wwidth-1);
vertnchars(w->wheight, '|');
grow = w->worg_row + w->wcur_row - 1;
gcol = w->worg_col + w->wcur_col - 1;
setcursor(grow, gcol);
return 0;
}