Переглянути джерело

- made _wputch wrap lines as well as cols (wraps back to line 0, as we have not way to scroll...)

- implemented color_content, wborder, wblrtobot, wclrtoeol, wcolor_set and several small functions
- added rest of expected global variables
tags/v0.9.3
Dan Lynch 18 роки тому
джерело
коміт
d166dc57ab
1 змінених файлів з 220 додано та 61 видалено
  1. 220
    61
      src/core/curses.c

+ 220
- 61
src/core/curses.c Переглянути файл

@@ -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
 

Завантаження…
Відмінити
Зберегти