1 #include <stdio.h>
2 #include <X11/Xlib.h>
3 #include <X11/Xutil.h>
4
5 #include "ztypes.h"
6 #include "xio.h"
7
8 #define BLANKATTR (-1)
9 #define SPACEWIDTH (spacewidth[FIXED_FONT])
10
11 typedef struct sline_t {
12 int dirtybeg, dirtyend; /* [) protocol; -1,-1 for non-dirty */
13 int isclear; /* TRUE if text is all blank */
14 char *text; /* pointer to array of stat_wid chars */
15 int *attr; /* pointer to array of stat_wid ints */
16 } sline;
17
18 /*static int stat_xpos, stat_ypos;*/ /* in pixels */
19 static int stat_realwid, stat_realhgt; /* in pixels */
20 static int stat_wid, stat_hgt; /* in chars */
21 static sline *linelist; /* array of stat_hgt slines */
22
23 static int linesused; /* z-machine's idea of the status line size */
24 static int maxlinesused; /* lines currently visible -- reset only by hitting return. */
25 static int curlines; /* actual window size */
26
27 static int cursorx, cursory;
28 static int cursorattr;
29
30 static int dotactive; /* is there an insertion mark? */
31 static int dotdrawn; /* is the insertion mark currently drawn? */
32 static int dotdrawnx, dotdrawny;
33 static XPoint polydot[3];
34
35 #ifdef __STDC__
36 static void resizewindow(int lines);
37 static void clearlines(int beg, int end);
38 static void flipdot();
39 #else
40 static void resizewindow();
41 static void clearlines();
42 static void flipdot();
43 #endif
44
45 #ifdef __STDC__
xstat_init(int cols,int rows,int xpos,int ypos)46 void xstat_init(int cols, int rows, int xpos, int ypos)
47 #else
48 void xstat_init(cols, rows, xpos, ypos)
49 int cols;
50 int rows;
51 int xpos;
52 int ypos;
53 #endif
54 {
55 int ix;
56
57 stat_wid = cols;
58 stat_hgt = rows;
59
60 /*stat_xpos = xpos;
61 stat_ypos = ypos;*/
62 stat_realwid = cols * SPACEWIDTH;
63 stat_realhgt = rows * lineheight;
64
65 polydot[0].x = 0;
66 polydot[0].y = 0;
67 polydot[1].x = 4;
68 polydot[1].y = 5;
69 polydot[2].x = -8;
70 polydot[2].y = 0;
71
72 dotactive = FALSE;
73 dotdrawn = FALSE;
74 dotdrawnx = 0;
75 dotdrawny = 0;
76
77 linelist = (sline *)malloc(sizeof(sline) * stat_hgt);
78
79 for (ix=0; ix<stat_hgt; ix++) {
80 linelist[ix].text = (char *)malloc(sizeof(char) * stat_wid);
81 linelist[ix].attr = (int *)malloc(sizeof(int) * stat_wid);
82 linelist[ix].isclear = FALSE;
83 }
84
85 linesused = 0;
86 maxlinesused = 0;
87 curlines = rows;
88
89 cursorx = 0;
90 cursory = 0;
91 cursorattr = FIXED_FONT;
92
93 #ifndef TESTING
94 /* export to ZIP code */
95 screen_cols = cols;
96 screen_rows = rows;
97 #endif
98
99 xstat_clear_window();
100 }
101
102 #ifdef __STDC__
xstat_newgeometry(int newx,int newy,int newwid,int newhgt)103 void xstat_newgeometry(int newx, int newy, int newwid, int newhgt)
104 #else
105 void xstat_newgeometry(newx, newy, newwid, newhgt)
106 int newx;
107 int newy;
108 int newwid;
109 int newhgt;
110 #endif
111 {
112 stat_realwid = newwid;
113 stat_realhgt = newhgt;
114 }
115
116 #ifdef __STDC__
xstat_redraw()117 void xstat_redraw()
118 #else
119 void xstat_redraw()
120 #endif
121 {
122 int ix;
123 sline *curline;
124
125 for (ix=0; ix<stat_hgt; ix++) {
126 curline = (&linelist[ix]);
127 if (!curline->isclear) {
128 curline->dirtybeg = 0;
129 curline->dirtyend = stat_wid;
130 }
131 }
132
133 dotdrawn = FALSE;
134 xstat_layout();
135 }
136
137 #ifdef __STDC__
xstat_insert(int ch)138 void xstat_insert(int ch)
139 #else
140 void xstat_insert(ch)
141 int ch;
142 #endif
143 {
144 sline *curline;
145
146 if (cursory<0 || cursory>=stat_hgt || cursorx<0 || cursorx>=stat_wid)
147 return;
148
149 if (cursory+1 > linesused) {
150 xstat_set_window_size(cursory+1);
151 }
152
153 curline = (&linelist[cursory]);
154 if (curline->text[cursorx] != (char)ch || curline->attr[cursorx] != cursorattr) {
155 curline->text[cursorx] = (char)ch;
156 curline->attr[cursorx] = cursorattr;
157 curline->isclear = FALSE;
158 if (curline->dirtybeg == (-1) || cursorx < curline->dirtybeg)
159 curline->dirtybeg = cursorx;
160 if (curline->dirtyend == (-1) || cursorx+1 > curline->dirtyend)
161 curline->dirtyend = cursorx+1;
162 }
163
164 cursorx++;
165 if (cursorx == stat_wid) {
166 cursorx = 0;
167 cursory++;
168 }
169 }
170
171 #ifdef __STDC__
xstat_newline()172 void xstat_newline()
173 #else
174 void xstat_newline()
175 #endif
176 {
177 cursorx = 0;
178 cursory++;
179 }
180
181 #ifdef __STDC__
xstat_getpos(int * row,int * col)182 void xstat_getpos(int *row, int *col)
183 #else
184 void xstat_getpos(row, col)
185 int *row;
186 int *col;
187 #endif
188 {
189 *col = cursorx+1;
190 *row = cursory+1;
191 }
192
193 #ifdef __STDC__
xstat_setpos(int row,int col)194 void xstat_setpos(int row, int col)
195 #else
196 void xstat_setpos(row, col)
197 int row;
198 int col;
199 #endif
200 {
201 cursorx = col-1;
202 cursory = row-1;
203 }
204
205 #ifdef __STDC__
xstat_setattr(int attr)206 void xstat_setattr(int attr)
207 #else
208 void xstat_setattr(attr)
209 int attr;
210 #endif
211 {
212 cursorattr = attr | FIXED_FONT;
213 }
214
215 #ifdef __STDC__
xstat_set_window_size(int lines)216 void xstat_set_window_size(int lines)
217 #else
218 void xstat_set_window_size(lines)
219 int lines;
220 #endif
221 {
222 linesused = lines;
223 if (lines > maxlinesused)
224 maxlinesused = lines;
225 }
226
227 #ifdef __STDC__
xstat_set_dot_active(int visible)228 void xstat_set_dot_active(int visible)
229 #else
230 void xstat_set_dot_active(visible)
231 int visible;
232 #endif
233 {
234 if (visible) {
235 /* turn it on */
236 if (dotactive)
237 return;
238 dotactive = TRUE;
239 }
240 else {
241 /* turn it off */
242 if (!dotactive)
243 return;
244 dotactive = FALSE;
245 }
246 }
247
248 /* clear to blankness */
249 #ifdef __STDC__
xstat_clear_window()250 void xstat_clear_window()
251 #else
252 void xstat_clear_window()
253 #endif
254 {
255 clearlines(0, stat_hgt);
256
257 linesused = 0;
258 maxlinesused = linesused; /* because anything below the status window has been cleared */
259 }
260
261 #ifdef __STDC__
clearlines(int beg,int end)262 static void clearlines(int beg, int end)
263 #else
264 static void clearlines(beg, end)
265 int beg;
266 int end;
267 #endif
268 {
269 int ix;
270 int jx;
271 char *cx;
272 int *ax;
273
274 for (ix=beg; ix<end; ix++) {
275 if (!linelist[ix].isclear) {
276 linelist[ix].isclear = TRUE;
277 linelist[ix].dirtybeg = 0;
278 linelist[ix].dirtyend = stat_wid;
279 for (cx=linelist[ix].text, jx=stat_wid; jx; cx++, jx--)
280 *cx = ' ';
281 for (ax=linelist[ix].attr, jx=stat_wid; jx; ax++, jx--)
282 *ax = BLANKATTR;
283 }
284 }
285 }
286
287 /* redraw the dirty stuff */
288 #ifdef __STDC__
xstat_layout()289 void xstat_layout()
290 #else
291 void xstat_layout()
292 #endif
293 {
294 int ix;
295 int beg, end, pos, px;
296 int attr;
297 int newsize;
298 sline *curline;
299
300 if (dotdrawn) {
301 flipdot();
302 dotdrawn = FALSE;
303 }
304
305 newsize = maxlinesused;
306 if (prefs.autoclear && newsize != curlines) {
307 clearlines(newsize, stat_hgt);
308 }
309
310 for (ix=0; ix<stat_hgt; ix++) {
311 curline = (&linelist[ix]);
312 if (curline->dirtybeg == (-1))
313 continue;
314 beg = curline->dirtybeg;
315 end = curline->dirtyend;
316 pos = beg;
317 while (pos < end) {
318 attr = curline->attr[pos];
319 for (px=pos; px<end && curline->attr[px]==attr; px++);
320 if (attr==BLANKATTR) {
321 XClearArea(xiodpy, xioswin, pos*SPACEWIDTH, ix*lineheight, (px-pos)*SPACEWIDTH, lineheight, FALSE);
322 }
323 else if (attr & REVERSE) {
324 XFillRectangle(xiodpy, xioswin, gcsfont[attr], pos*SPACEWIDTH, ix*lineheight, (px-pos)*SPACEWIDTH, lineheight);
325 XDrawString(xiodpy, xioswin, gcsnegfont[attr], pos*SPACEWIDTH, ix*lineheight+lineheightoff, curline->text+pos, (px-pos));
326 }
327 else {
328 XClearArea(xiodpy, xioswin, pos*SPACEWIDTH, ix*lineheight, (px-pos)*SPACEWIDTH, lineheight, FALSE);
329 XDrawString(xiodpy, xioswin, gcsfont[attr], pos*SPACEWIDTH, ix*lineheight+lineheightoff, curline->text+pos, (px-pos));
330 }
331 pos = px;
332 }
333 curline->dirtybeg = (-1);
334 curline->dirtyend = (-1);
335 }
336
337 if (dotactive) {
338 dotdrawnx = cursorx * SPACEWIDTH;
339 dotdrawny = cursory * lineheight + lineheightoff;
340 flipdot();
341 dotdrawn = TRUE;
342 }
343
344 if (prefs.autoresize && newsize != curlines) {
345 resizewindow(newsize);
346 }
347 }
348
349 /* reset the window size to linesused (if max==FALSE) or temporarily to stat_hgt (if max==TRUE) */
350 #ifdef __STDC__
xstat_reset_window_size(int op)351 void xstat_reset_window_size(int op)
352 #else
353 void xstat_reset_window_size(op)
354 int op;
355 #endif
356 {
357 int newsize;
358
359 if (op==op_Clear) {
360 clearlines(linesused, stat_hgt);
361 xstat_layout();
362 return;
363 }
364 else if (op==op_Zoom)
365 newsize = stat_hgt;
366 else if (op==op_Shrink)
367 newsize = linesused;
368 else {
369 return;
370 }
371
372 if (prefs.autoclear && newsize != curlines) {
373 clearlines(newsize, stat_hgt);
374 }
375 if (prefs.autoresize && newsize != curlines) {
376 resizewindow(newsize);
377 }
378 maxlinesused = newsize;
379 }
380
381 #ifdef __STDC__
resizewindow(int lines)382 static void resizewindow(int lines)
383 #else
384 static void resizewindow(lines)
385 int lines;
386 #endif
387 {
388 XSizeHints szhints;
389 int xp, yp;
390 int newheight;
391 Window child;
392
393 curlines = lines;
394 newheight = curlines*lineheight;
395 if (newheight==0)
396 newheight++;
397
398 if (!prefs.resizeupward) {
399 szhints.flags = USSize;
400 szhints.width = stat_wid*SPACEWIDTH;
401 szhints.height = newheight;
402 XResizeWindow(xiodpy, xioswin, szhints.width, szhints.height);
403 XSetNormalHints(xiodpy, xioswin, &szhints);
404 }
405 else {
406 XTranslateCoordinates(xiodpy, xioswin, RootWindow(xiodpy, xioscn), 0, 0, &xp, &yp, &child);
407 yp -= (newheight - stat_realhgt);
408
409 szhints.flags = PMinSize|PResizeInc|USPosition|USSize;
410 szhints.width = stat_wid*SPACEWIDTH;
411 szhints.height = newheight;
412 szhints.x = xp;
413 szhints.y = yp;
414 szhints.width_inc = spacewidth[FIXED_FONT];
415 szhints.height_inc = lineheight;
416 szhints.min_width = 1 * szhints.width_inc;
417 szhints.min_height = 1 * szhints.height_inc;
418 XMoveResizeWindow(xiodpy, xioswin, xp, yp, szhints.width, szhints.height);
419 XSetNormalHints(xiodpy, xioswin, &szhints);
420 }
421 }
422
423 #ifdef __STDC__
flipdot()424 static void flipdot()
425 #else
426 static void flipdot()
427 #endif
428 {
429 polydot[0].x = dotdrawnx;
430 polydot[0].y = dotdrawny;
431 XFillPolygon(xiodpy, xioswin, gcsflip, polydot, 3, Convex, CoordModePrevious);
432 }
433