|
@@ -1,6 +1,7 @@
|
1
|
1
|
#include <curses.h>
|
2
|
2
|
#include <malloc.h>
|
3
|
3
|
#include <stddef.h>
|
|
4
|
+#include <vsprintf.h>
|
4
|
5
|
|
5
|
6
|
/** @file
|
6
|
7
|
*
|
|
@@ -11,26 +12,53 @@
|
11
|
12
|
#define WRAP 0
|
12
|
13
|
#define NOWRAP 1
|
13
|
14
|
|
|
15
|
+unsigned short _COLS;
|
|
16
|
+unsigned short _LINES;
|
|
17
|
+unsigned short _COLOURS;
|
|
18
|
+unsigned int *_COLOUR_PAIRS; /* basically this is an array, but as its
|
|
19
|
+ length is determined only when initscr
|
|
20
|
+ is run, I can only think to make it a
|
|
21
|
+ pointer and malloc the array into being
|
|
22
|
+ ... */
|
|
23
|
+
|
14
|
24
|
struct cursor_pos {
|
15
|
25
|
unsigned int y, x;
|
16
|
26
|
};
|
17
|
27
|
|
|
28
|
+WINDOW _stdscr = {
|
|
29
|
+ .attrs = A_DEFAULT,
|
|
30
|
+ .ori_y = 0,
|
|
31
|
+ .ori_x = 0,
|
|
32
|
+ .curs_y = 0,
|
|
33
|
+ .curs_x = 0,
|
|
34
|
+};
|
|
35
|
+
|
18
|
36
|
/*
|
19
|
|
- Primitives
|
20
|
|
-*/
|
|
37
|
+ * Primitives
|
|
38
|
+ */
|
21
|
39
|
|
22
|
40
|
/**
|
23
|
41
|
* Write a single character rendition to a window
|
24
|
42
|
*
|
25
|
43
|
* @v *win window in which to write
|
26
|
44
|
* @v ch character rendition to write
|
|
45
|
+ * @v wrap wrap "switch"
|
27
|
46
|
*/
|
28
|
47
|
static void _wputch ( WINDOW *win, chtype ch, int wrap ) {
|
|
48
|
+ /* make sure we set the screen cursor to the right position
|
|
49
|
+ first! */
|
|
50
|
+ win->scr->movetoyx( win->scr, win->ori_y + win->curs_y,
|
|
51
|
+ win->ori_x + win->curs_x );
|
29
|
52
|
win->scr->putc(win->scr, ch);
|
30
|
53
|
if ( ++(win->curs_x) > win->width ) {
|
31
|
54
|
if ( wrap == WRAP ) {
|
32
|
55
|
win->curs_x = 0;
|
33
|
|
- (win->curs_y)++;
|
|
56
|
+ /* specification says we should really scroll,
|
|
57
|
+ but we have no buffer to scroll with, so we
|
|
58
|
+ can only overwrite back at the beginning of
|
|
59
|
+ the window */
|
|
60
|
+ win->curs_y += ( ( win->curs_y - win->height ) == 0 ?
|
|
61
|
+ -(win->curs_y) : 1 );
|
34
|
62
|
} else {
|
35
|
63
|
(win->curs_x)--;
|
36
|
64
|
}
|
|
@@ -45,7 +73,7 @@ static void _wputch ( WINDOW *win, chtype ch, int wrap ) {
|
45
|
73
|
* @v wrap wrap "switch"
|
46
|
74
|
* @v n write at most n chtypes
|
47
|
75
|
*/
|
48
|
|
-static void _wputchstr ( WINDOW *win, chtype *chstr, int wrap, int n ) {
|
|
76
|
+static void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) {
|
49
|
77
|
for ( ; *chstr && n-- ; chstr++ ) {
|
50
|
78
|
_wputch(win,*chstr,wrap);
|
51
|
79
|
}
|
|
@@ -53,12 +81,13 @@ static void _wputchstr ( WINDOW *win, chtype *chstr, int wrap, int n ) {
|
53
|
81
|
|
54
|
82
|
/**
|
55
|
83
|
* Write a standard c-style string to a window
|
|
84
|
+ *
|
56
|
85
|
* @v *win window in which to write
|
57
|
86
|
* @v *str string
|
58
|
87
|
* @v wrap wrap "switch"
|
59
|
88
|
* @v n write at most n chars from *str
|
60
|
89
|
*/
|
61
|
|
-static void _wputstr ( WINDOW *win, char *str, int wrap, int n ) {
|
|
90
|
+static void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) {
|
62
|
91
|
for ( ; *str && n-- ; str++ ) {
|
63
|
92
|
_wputch( win, *str | win->attrs, wrap );
|
64
|
93
|
}
|
|
@@ -106,16 +135,6 @@ int wmove ( WINDOW *win, int y, int x ) {
|
106
|
135
|
}
|
107
|
136
|
|
108
|
137
|
|
109
|
|
-
|
110
|
|
-
|
111
|
|
-WINDOW _stdscr = {
|
112
|
|
- .attrs = A_DEFAULT,
|
113
|
|
- .ori_y = 0,
|
114
|
|
- .ori_x = 0,
|
115
|
|
- .curs_y = 0,
|
116
|
|
- .curs_x = 0,
|
117
|
|
-};
|
118
|
|
-
|
119
|
138
|
/**
|
120
|
139
|
* get terminal baud rate
|
121
|
140
|
*
|
|
@@ -131,11 +150,7 @@ int baudrate ( void ) {
|
131
|
150
|
* @ret rc return status code
|
132
|
151
|
*/
|
133
|
152
|
int beep ( void ) {
|
134
|
|
- /* ok, so I can't waste memory buffering the screen (or in
|
135
|
|
- this case, backing up the background colours of the screen
|
136
|
|
- elements), but maybe I can buffer the border and flash that
|
137
|
|
- - or maybe even just the top and bottom? Assuming I can't
|
138
|
|
- make the system speaker beep, of course... */
|
|
153
|
+ printf("\a");
|
139
|
154
|
return OK;
|
140
|
155
|
}
|
141
|
156
|
|
|
@@ -149,42 +164,57 @@ int beep ( void ) {
|
149
|
164
|
* @ret rc return status code
|
150
|
165
|
*/
|
151
|
166
|
int box ( WINDOW *win, chtype verch, chtype horch ) {
|
152
|
|
- return OK;
|
153
|
|
- err:
|
154
|
|
- return ERR;
|
|
167
|
+ int corner = '+' | win->attrs; /* default corner character */
|
|
168
|
+ return wborder( win, verch, verch, horch, horch,
|
|
169
|
+ corner, corner, corner, corner );
|
155
|
170
|
}
|
156
|
171
|
|
157
|
172
|
/**
|
158
|
|
- * Indicates whether the attached terminal is capable of having
|
159
|
|
- * colours redefined
|
|
173
|
+ * Indicates whether the underlying terminal device is capable of
|
|
174
|
+ * having colours redefined
|
160
|
175
|
*
|
161
|
|
- * @ret bool returns boolean dependent on colour changing caps of terminal
|
|
176
|
+ * @ret bool returns boolean
|
162
|
177
|
*/
|
163
|
178
|
bool can_change_colour ( void ) {
|
164
|
179
|
return (bool)TRUE;
|
165
|
|
- err:
|
166
|
|
- return (bool)FALSE;
|
167
|
180
|
}
|
168
|
181
|
|
169
|
182
|
/**
|
170
|
|
- * Identifies the intensity components of colour number "colour" and
|
171
|
|
- * stores the RGB intensity values in the respective addresses pointed
|
172
|
|
- * to by "red", "green" and "blue" respectively
|
173
|
|
- */
|
174
|
|
-int colour_content ( short colour, short *red, short *green, short *blue ) {
|
175
|
|
- return OK;
|
176
|
|
- err:
|
177
|
|
- return ERR;
|
178
|
|
-}
|
179
|
|
-
|
180
|
|
-/**
|
181
|
|
- * Window colour attribute control function
|
|
183
|
+ * Identify the RGB components of a given colour value
|
182
|
184
|
*
|
183
|
|
- * @v colour_pair_number colour pair integer
|
184
|
|
- * @v *opts pointer to options
|
185
|
|
- * @ret rc return status code
|
|
185
|
+ * @v colour colour value
|
|
186
|
+ * @v *red address to store red component
|
|
187
|
+ * @v *green address to store green component
|
|
188
|
+ * @v *blue address to store blue component
|
|
189
|
+ * @ret rc return status code
|
186
|
190
|
*/
|
187
|
|
-int colour_set ( short colour_pair_number, void *opts ) {
|
|
191
|
+int colour_content ( short colour, short *red, short *green, short *blue ) {
|
|
192
|
+ /* we do not have a particularly large range of colours (3
|
|
193
|
+ primary, 3 secondary and black), so let's just put in a
|
|
194
|
+ basic switch... */
|
|
195
|
+ switch(colour) {
|
|
196
|
+ case COLOUR_BLACK:
|
|
197
|
+ *red = 0; *green = 0; *blue = 0;
|
|
198
|
+ break;
|
|
199
|
+ case COLOUR_BLUE:
|
|
200
|
+ *red = 0; *green = 0; *blue = 1000;
|
|
201
|
+ break;
|
|
202
|
+ case COLOUR_GREEN:
|
|
203
|
+ *red = 0; *green = 1000; *blue = 0;
|
|
204
|
+ break;
|
|
205
|
+ case COLOUR_CYAN:
|
|
206
|
+ *red = 0; *green = 1000; *blue = 1000;
|
|
207
|
+ break;
|
|
208
|
+ case COLOUR_RED:
|
|
209
|
+ *red = 1000; *green = 0; *blue = 0;
|
|
210
|
+ break;
|
|
211
|
+ case COLOUR_MAGENTA:
|
|
212
|
+ *red = 1000; *green = 0; *blue = 1000;
|
|
213
|
+ break;
|
|
214
|
+ case COLOUR_YELLOW:
|
|
215
|
+ *red = 1000; *green = 1000; *blue = 0;
|
|
216
|
+ break;
|
|
217
|
+ }
|
188
|
218
|
return OK;
|
189
|
219
|
}
|
190
|
220
|
|
|
@@ -205,6 +235,16 @@ int delwin ( WINDOW *win ) {
|
205
|
235
|
return ERR;
|
206
|
236
|
}
|
207
|
237
|
|
|
238
|
+/**
|
|
239
|
+ * Get the background rendition attributes for a window
|
|
240
|
+ *
|
|
241
|
+ * @v *win subject window
|
|
242
|
+ * @ret ch chtype rendition representation
|
|
243
|
+ */
|
|
244
|
+inline chtype getbkgd ( WINDOW *win ) {
|
|
245
|
+ return win->attrs;
|
|
246
|
+}
|
|
247
|
+
|
208
|
248
|
/**
|
209
|
249
|
* Initialise console environment
|
210
|
250
|
*
|
|
@@ -246,9 +286,8 @@ WINDOW *newwin ( int nlines, int ncols, int begin_y, int begin_x ) {
|
246
|
286
|
* @ret rc return status code
|
247
|
287
|
*/
|
248
|
288
|
int waddch ( WINDOW *win, const chtype ch ) {
|
|
289
|
+ _wputch( win, ch, WRAP );
|
249
|
290
|
return OK;
|
250
|
|
- err:
|
251
|
|
- return ERR;
|
252
|
291
|
}
|
253
|
292
|
|
254
|
293
|
/**
|
|
@@ -277,20 +316,12 @@ int waddchnstr ( WINDOW *win, const chtype *chstr, int n ) {
|
277
|
316
|
* @ret rc return status code
|
278
|
317
|
*/
|
279
|
318
|
int waddnstr ( WINDOW *win, const char *str, int n ) {
|
280
|
|
- unsigned int ch, count = 0;
|
281
|
|
- char *strptr = str;
|
282
|
|
-
|
283
|
|
- while ( ( ( ch = *strptr ) != '\0' )
|
284
|
|
- && ( count++ < (unsigned)n ) ) {
|
285
|
|
- }
|
286
|
|
-
|
|
319
|
+ _wputstr( win, str, WRAP, n );
|
287
|
320
|
return OK;
|
288
|
|
- err:
|
289
|
|
- return ERR;
|
290
|
321
|
}
|
291
|
322
|
|
292
|
323
|
/**
|
293
|
|
- * Turn off attributes
|
|
324
|
+ * Turn off attributes in a window
|
294
|
325
|
*
|
295
|
326
|
* @v win subject window
|
296
|
327
|
* @v attrs attributes to enable
|
|
@@ -302,7 +333,7 @@ int wattroff ( WINDOW *win, int attrs ) {
|
302
|
333
|
}
|
303
|
334
|
|
304
|
335
|
/**
|
305
|
|
- * Turn on attributes
|
|
336
|
+ * Turn on attributes in a window
|
306
|
337
|
*
|
307
|
338
|
* @v win subject window
|
308
|
339
|
* @v attrs attributes to enable
|
|
@@ -314,14 +345,69 @@ int wattron ( WINDOW *win, int attrs ) {
|
314
|
345
|
}
|
315
|
346
|
|
316
|
347
|
/**
|
317
|
|
- * Set attributes
|
|
348
|
+ * Set attributes in a window
|
318
|
349
|
*
|
319
|
350
|
* @v win subject window
|
320
|
351
|
* @v attrs attributes to enable
|
321
|
352
|
* @ret rc return status code
|
322
|
353
|
*/
|
323
|
354
|
int wattrset ( WINDOW *win, int attrs ) {
|
324
|
|
- win->attrs = attrs;
|
|
355
|
+ win->attrs = ( attrs | ( win->attrs & A_COLOR ) );
|
|
356
|
+ return OK;
|
|
357
|
+}
|
|
358
|
+
|
|
359
|
+/**
|
|
360
|
+ * Get attributes and colour pair information
|
|
361
|
+ *
|
|
362
|
+ * @v *win window to obtain information from
|
|
363
|
+ * @v *attrs address in which to store attributes
|
|
364
|
+ * @v *pair address in which to store colour pair
|
|
365
|
+ * @v *opts undefined (for future implementation)
|
|
366
|
+ * @ret rc return status cude
|
|
367
|
+ */
|
|
368
|
+int wattr_get ( WINDOW *win, attr_t *attrs, short *pair, void *opts ) {
|
|
369
|
+ *attrs = win->attrs & A_ATTRIBUTES;
|
|
370
|
+ *pair = (short)(( win->attrs & A_COLOR ) >> CPAIR_SHIFT);
|
|
371
|
+ return OK;
|
|
372
|
+}
|
|
373
|
+
|
|
374
|
+/**
|
|
375
|
+ * Turn off attributes in a window
|
|
376
|
+ *
|
|
377
|
+ * @v *win subject window
|
|
378
|
+ * @v attrs attributes to toggle
|
|
379
|
+ * @v *opts undefined (for future implementation)
|
|
380
|
+ * @ret rc return status code
|
|
381
|
+ */
|
|
382
|
+int wattr_off ( WINDOW *win, attr_t attrs, void *opts ) {
|
|
383
|
+ wattroff( win, attrs );
|
|
384
|
+ return OK;
|
|
385
|
+}
|
|
386
|
+
|
|
387
|
+/**
|
|
388
|
+ * Turn on attributes in a window
|
|
389
|
+ *
|
|
390
|
+ * @v *win subject window
|
|
391
|
+ * @v attrs attributes to toggle
|
|
392
|
+ * @v *opts undefined (for future implementation)
|
|
393
|
+ * @ret rc return status code
|
|
394
|
+ */
|
|
395
|
+int wattr_on ( WINDOW *win, attr_t attrs, void *opts ) {
|
|
396
|
+ wattron( win, attrs );
|
|
397
|
+ return OK;
|
|
398
|
+}
|
|
399
|
+
|
|
400
|
+/**
|
|
401
|
+ * Set attributes and colour pair information in a window
|
|
402
|
+ *
|
|
403
|
+ * @v *win subject window
|
|
404
|
+ * @v attrs attributes to set
|
|
405
|
+ * @v cpair colour pair to set
|
|
406
|
+ * @v *opts undefined (for future implementation)
|
|
407
|
+ * @ret rc return status code
|
|
408
|
+ */
|
|
409
|
+int wattr_set ( WINDOW *win, attr_t attrs, short cpair, void *opts ) {
|
|
410
|
+ wattrset( win, attrs | ( ( (unsigned short)cpair ) << CPAIR_SHIFT ) );
|
325
|
411
|
return OK;
|
326
|
412
|
}
|
327
|
413
|
|
|
@@ -343,8 +429,81 @@ int wattrset ( WINDOW *win, int attrs ) {
|
343
|
429
|
int wborder ( WINDOW *win, chtype ls, chtype rs,
|
344
|
430
|
chtype ts, chtype bs, chtype tl,
|
345
|
431
|
chtype tr, chtype bl, chtype br ) {
|
|
432
|
+
|
|
433
|
+ wmove(win,0,0);
|
|
434
|
+
|
|
435
|
+ _wputch(win,tl,WRAP);
|
|
436
|
+ while ( win->width - win->curs_x ) {
|
|
437
|
+ _wputch(win,ts,WRAP);
|
|
438
|
+ }
|
|
439
|
+ _wputch(win,tr,WRAP);
|
|
440
|
+
|
|
441
|
+ while ( ( win->height - 1 ) - win->curs_y ) {
|
|
442
|
+ _wputch(win,ls,WRAP);
|
|
443
|
+ wmove(win,win->curs_y,win->width-1);
|
|
444
|
+ _wputch(win,rs,WRAP);
|
|
445
|
+ }
|
|
446
|
+
|
|
447
|
+ _wputch(win,bl,WRAP);
|
|
448
|
+ while ( win->width - win->curs_x ) {
|
|
449
|
+ _wputch(win,bs,WRAP);
|
|
450
|
+ }
|
|
451
|
+ _wputch(win,br,NOWRAP); /* do not wrap last char to leave
|
|
452
|
+ cursor in last position */
|
|
453
|
+
|
|
454
|
+ return OK;
|
|
455
|
+}
|
|
456
|
+
|
|
457
|
+/**
|
|
458
|
+ * Clear a window to the bottom
|
|
459
|
+ *
|
|
460
|
+ * @v *win subject window
|
|
461
|
+ * @ret rc return status code
|
|
462
|
+ */
|
|
463
|
+int wclrtobot ( WINDOW *win ) {
|
|
464
|
+ struct cursor_pos pos;
|
|
465
|
+
|
|
466
|
+ _store_curs_pos( win, &pos );
|
|
467
|
+ while ( win->curs_y + win->curs_x ) {
|
|
468
|
+ _wputch( win, (unsigned)' ', WRAP );
|
|
469
|
+ }
|
|
470
|
+ _restore_curs_pos( win, &pos );
|
|
471
|
+
|
|
472
|
+ return OK;
|
|
473
|
+}
|
|
474
|
+
|
|
475
|
+/**
|
|
476
|
+ * Clear a window to the end of the current line
|
|
477
|
+ *
|
|
478
|
+ * @v *win subject window
|
|
479
|
+ * @ret rc return status code
|
|
480
|
+ */
|
|
481
|
+int wclrtoeol ( WINDOW *win ) {
|
|
482
|
+ struct cursor_pos pos;
|
|
483
|
+
|
|
484
|
+ _store_curs_pos( win, &pos );
|
|
485
|
+ while ( ( win->curs_y - pos.y ) == 0 ) {
|
|
486
|
+ _wputch( win, (unsigned)' ', WRAP );
|
|
487
|
+ }
|
|
488
|
+ _restore_curs_pos( win, &pos );
|
|
489
|
+
|
|
490
|
+ return OK;
|
|
491
|
+}
|
|
492
|
+
|
|
493
|
+/**
|
|
494
|
+ * Set colour pair for a window
|
|
495
|
+ *
|
|
496
|
+ * @v *win subject window
|
|
497
|
+ * @v colour_pair_number colour pair integer
|
|
498
|
+ * @v *opts undefined (for future implementation)
|
|
499
|
+ * @ret rc return status code
|
|
500
|
+ */
|
|
501
|
+int wcolour_set ( WINDOW *win, short colour_pair_number, void *opts ) {
|
|
502
|
+ if ( ( unsigned short )colour_pair_number > COLORS )
|
|
503
|
+ return ERR;
|
|
504
|
+
|
|
505
|
+ win->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) |
|
|
506
|
+ ( win->attrs & A_ATTRIBUTES );
|
346
|
507
|
return OK;
|
347
|
|
- err:
|
348
|
|
- return ERR;
|
349
|
508
|
}
|
350
|
509
|
|