13 #include "../../gfx.h"
15 #if GFX_USE_GWIN && GWIN_NEED_CONSOLE
19 #include "gwin_class.h"
21 #define GWIN_CONSOLE_USE_CLEAR_LINES GFXON
22 #define GWIN_CONSOLE_USE_FILLED_CHARS GFXOFF
23 #define GWIN_CONSOLE_BUFFER_SCROLLING GFXON
26 #define GCONSOLE_FLG_NOSTORE (GWIN_FIRST_CONTROL_FLAG<<0)
27 #define GCONSOLE_FLG_OVERRUN (GWIN_FIRST_CONTROL_FLAG<<1)
30 #define ESC_REDBIT 0x01
31 #define ESC_GREENBIT 0x02
32 #define ESC_BLUEBIT 0x04
33 #define ESC_USECOLOR 0x08
34 #define ESC_UNDERLINE 0x10
41 #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
42 #define Stream2GWindow(ip) ((GHandle)(((char *)(ip)) - (size_t)(&(((GConsoleObject *)0)->stream))))
44 #if CH_KERNEL_MAJOR == 2
45 static size_t GWinStreamWrite(
void *ip,
const gU8 *bp,
size_t n) {
gwinPutCharArray(Stream2GWindow(ip), (
const char *)bp, n);
return RDY_OK; }
46 static size_t GWinStreamRead(
void *ip, gU8 *bp,
size_t n) { (void)ip; (void)bp; (void)n;
return 0; }
47 static msg_t GWinStreamPut(
void *ip, gU8 b) {
gwinPutChar(Stream2GWindow(ip), (
char)b);
return RDY_OK; }
48 static msg_t GWinStreamGet(
void *ip) {(void)ip;
return RDY_OK; }
49 static msg_t GWinStreamPutTimed(
void *ip, gU8 b, systime_t time) { (void)time;
gwinPutChar(Stream2GWindow(ip), (
char)b);
return RDY_OK; }
50 static msg_t GWinStreamGetTimed(
void *ip, systime_t timeout) { (void)ip; (void)timeout;
return RDY_OK; }
51 static size_t GWinStreamWriteTimed(
void *ip,
const gU8 *bp,
size_t n, systime_t time) { (void)time;
gwinPutCharArray(Stream2GWindow(ip), (
const char *)bp, n);
return RDY_OK; }
52 static size_t GWinStreamReadTimed(
void *ip, gU8 *bp,
size_t n, systime_t time) { (void)ip; (void)bp; (void)n; (void)time;
return 0; }
53 #elif CH_KERNEL_MAJOR == 3
54 static size_t GWinStreamWrite(
void *ip,
const gU8 *bp,
size_t n) {
gwinPutCharArray(Stream2GWindow(ip), (
const char *)bp, n);
return MSG_OK; }
55 static size_t GWinStreamRead(
void *ip, gU8 *bp,
size_t n) { (void)ip; (void)bp; (void)n;
return 0; }
56 static msg_t GWinStreamPut(
void *ip, gU8 b) {
gwinPutChar(Stream2GWindow(ip), (
char)b);
return MSG_OK; }
57 static msg_t GWinStreamGet(
void *ip) {(void)ip;
return MSG_OK; }
58 static msg_t GWinStreamPutTimed(
void *ip, gU8 b, systime_t time) { (void)time;
gwinPutChar(Stream2GWindow(ip), (
char)b);
return MSG_OK; }
59 static msg_t GWinStreamGetTimed(
void *ip, systime_t timeout) { (void)ip; (void)timeout;
return MSG_OK; }
60 static size_t GWinStreamWriteTimed(
void *ip,
const gU8 *bp,
size_t n, systime_t time) { (void)time;
gwinPutCharArray(Stream2GWindow(ip), (
const char *)bp, n);
return MSG_OK; }
61 static size_t GWinStreamReadTimed(
void *ip, gU8 *bp,
size_t n, systime_t time) { (void)ip; (void)bp; (void)n; (void)time;
return 0; }
64 struct GConsoleWindowVMT_t {
65 _base_asynchronous_channel_methods
68 static const struct GConsoleWindowVMT_t GWindowConsoleVMT = {
80 #if GWIN_CONSOLE_ESCSEQ
82 static gBool ESCtoAttr(
char c, gU8 *pattr) {
87 case '0':
case '1':
case '2':
case '3':
88 case '4':
case '5':
case '6':
case '7':
89 attr &= ~(ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT);
90 attr |= (c -
'0') | ESC_USECOLOR;
93 attr &= ~(ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT|ESC_USECOLOR);
96 attr |= ESC_UNDERLINE;
99 attr &= ~ESC_UNDERLINE;
110 if (attr == pattr[0])
116 static gColor ESCPrintColor(GConsoleObject *gcw) {
117 switch(gcw->currattr & (ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT|ESC_USECOLOR)) {
120 case (ESC_USECOLOR|ESC_REDBIT):
122 case (ESC_USECOLOR|ESC_GREENBIT):
124 case (ESC_USECOLOR|ESC_REDBIT|ESC_GREENBIT):
126 case (ESC_USECOLOR|ESC_BLUEBIT):
128 case (ESC_USECOLOR|ESC_REDBIT|ESC_BLUEBIT):
130 case (ESC_USECOLOR|ESC_GREENBIT|ESC_BLUEBIT):
132 case (ESC_USECOLOR|ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT):
139 #define ESCPrintColor(gcw) ((gcw)->g.color)
142 #if GWIN_CONSOLE_USE_HISTORY
144 #define gcw ((GConsoleObject *)gh)
158 static void scrollBuffer(GConsoleObject *gcw) {
163 if (!gcw->buffer || (gcw->g.flags & GCONSOLE_FLG_NOSTORE))
167 if ((gcw->g.flags & GCONSOLE_FLG_OVERRUN)) {
168 gcw->g.flags &= ~GCONSOLE_FLG_OVERRUN;
173 ep = gcw->buffer+gcw->bufpos;
174 for(p = gcw->buffer; p < ep && *p !=
'\n'; p++) {
175 #if GWIN_CONSOLE_ESCSEQ
177 ESCtoAttr(p[1], &gcw->startattr);
188 dp = ++p - gcw->buffer;
191 memcpy(gcw->buffer, p, gcw->bufpos);
195 #define gcw ((GConsoleObject *)gh)
204 while (gcw->cy > gh->
height) {
210 gh->
flags |= GCONSOLE_FLG_NOSTORE;
212 #if !GWIN_CONSOLE_USE_CLEAR_LINES
222 #if GWIN_CONSOLE_ESCSEQ
223 gcw->currattr = gcw->startattr;
229 #if GWIN_CONSOLE_USE_CLEAR_LINES
243 gh->
flags &= ~GCONSOLE_FLG_NOSTORE;
251 static void putCharInBuffer(GConsoleObject *gcw,
char c) {
253 if (!gcw->buffer || (gcw->g.flags & GCONSOLE_FLG_NOSTORE))
257 if (gcw->bufpos >= gcw->bufsize) {
273 ep = gcw->buffer+gcw->bufpos;
274 for(p = gcw->buffer; p < ep && *p !=
'\n'; p++) {
275 #if GWIN_CONSOLE_ESCSEQ
277 ESCtoAttr(p[1], &gcw->startattr);
285 gcw->g.flags |= GCONSOLE_FLG_OVERRUN;
288 dp = ++p - gcw->buffer;
291 memcpy(gcw->buffer, p, gcw->bufpos);
295 gcw->buffer[gcw->bufpos++] = c;
301 static void clearBuffer(GConsoleObject *gcw) {
304 if (!gcw->buffer || (gcw->g.flags & GCONSOLE_FLG_NOSTORE))
311 #define putCharInBuffer(gcw, c)
312 #define scrollBuffer(gcw)
313 #define clearBuffer(gcw)
317 #define gcw ((GConsoleObject *)gh)
321 #if GWIN_CONSOLE_ESCSEQ
322 gcw->startattr = gcw->currattr;
327 static const gwinVMT consoleVMT = {
329 sizeof(GConsoleObject),
341 if (!(gc = (GConsoleObject *)_gwindowCreate(g, &gc->g, pInit, &consoleVMT, 0)))
344 #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
345 gc->stream.
vmt = &GWindowConsoleVMT;
348 #if GWIN_CONSOLE_USE_HISTORY
350 #if GWIN_CONSOLE_HISTORY_ATCREATE
351 gwinConsoleSetBuffer(&gc->g, gTrue);
358 #if GWIN_CONSOLE_ESCSEQ
359 gc->startattr = gc->currattr = 0;
364 _gwinFlushRedraws(REDRAW_WAIT);
369 #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
370 BaseSequentialStream *gwinConsoleGetStream(
GHandle gh) {
371 if (gh->
vmt != &consoleVMT)
374 return (BaseSequentialStream *)&(((GConsoleObject *)(gh))->stream);
378 #if GWIN_CONSOLE_USE_HISTORY
379 gBool gwinConsoleSetBuffer(
GHandle gh, gBool onoff) {
380 #define gcw ((GConsoleObject *)gh)
382 if (gh->
vmt != &consoleVMT)
399 #if GWIN_CONSOLE_HISTORY_AVERAGING
410 if (!(gcw->buffer =
gfxAlloc(gcw->bufsize)))
414 gh->
flags &= ~GCONSOLE_FLG_OVERRUN;
431 #define DrawStart(gh) ((gh->flags & GCONSOLE_FLG_NOSTORE) || _gwinDrawStart(gh))
432 #define DrawEnd(gh) { if (!(gh->flags & GCONSOLE_FLG_NOSTORE)) _gwinDrawEnd(gh); }
435 #define gcw ((GConsoleObject *)gh)
438 if (gh->
vmt != &consoleVMT || !gh->font)
443 #if GWIN_CONSOLE_ESCSEQ
456 switch (gcw->escstate) {
459 if (ESCtoAttr(c, &gcw->currattr)) {
460 if (gcw->cx == 0 && gcw->cy == 0)
461 gcw->startattr = gcw->currattr;
463 putCharInBuffer(gcw, 27);
464 putCharInBuffer(gcw, c);
477 gcw->startattr = gcw->currattr;
498 #if GWIN_CONSOLE_USE_CLEAR_LINES
499 if (gcw->cx == 0 && gcw->cy+fy < gh->height && DrawStart(gh)) {
507 putCharInBuffer(gcw,
'\n');
515 #if GWIN_CONSOLE_ESCSEQ
527 #if GWIN_CONSOLE_ESCSEQ
528 if ((gcw->currattr & ESC_BOLD))
533 if (gcw->cx + width >= gh->
width) {
536 putCharInBuffer(gcw,
'\n');
540 if (gcw->cy + fy > gh->
height) {
541 #if GWIN_CONSOLE_USE_HISTORY && GWIN_CONSOLE_BUFFER_SCROLLING
544 if (gh->
flags & GCONSOLE_FLG_NOSTORE)
555 #if GDISP_NEED_SCROLL
578 #if GWIN_CONSOLE_ESCSEQ
579 gcw->startattr = gcw->currattr;
586 putCharInBuffer(gcw, c);
592 #if GWIN_CONSOLE_USE_CLEAR_LINES
597 #if GWIN_CONSOLE_USE_FILLED_CHARS
603 #if GWIN_CONSOLE_ESCSEQ
605 if ((gcw->currattr & ESC_UNDERLINE))
610 if ((gcw->currattr & ESC_BOLD))
635 #define MAX_FILLER 11
636 #define FLOAT_PRECISION 100000
638 static char *consltoa_wd(
char *p,
long num,
unsigned radix,
long divisor) {
642 if (!divisor) divisor = num;
646 i = (int)(num % radix);
652 }
while ((divisor /= radix) != 0);
654 i = (int)(p + MAX_FILLER - q);
662 #if GWIN_CONSOLE_USE_FLOAT
663 static char *ftoa(
char *p,
double num) {
665 unsigned long precision = FLOAT_PRECISION;
668 p = consltoa_wd(p, l, 10, 0);
670 l = (num - l) * precision;
671 return consltoa_wd(p, l, 10, precision / 10);
677 char *p, *s, c, filler;
678 int i, precision, width;
679 gBool is_long, left_align;
681 #if GWIN_CONSOLE_USE_FLOAT
683 char tmpbuf[2*MAX_FILLER + 1];
685 char tmpbuf[MAX_FILLER + 1];
688 if (gh->
vmt != &consoleVMT || !gh->font)
719 if (c >=
'0' && c <=
'9')
725 width = width * 10 + c;
731 if (c >=
'0' && c <=
'9')
737 precision = precision * 10 + c;
741 if (c ==
'l' || c ==
'L') {
747 is_long = (c >=
'A') && (c <=
'Z');
753 *p++ = va_arg(ap,
int);
757 if ((s = va_arg(ap,
char *)) == 0)
761 for (p = s; *p && (--precision >= 0); p++);
766 l = va_arg(ap,
long);
773 p = consltoa_wd(p, l, 10, 0);
775 #if GWIN_CONSOLE_USE_FLOAT
777 f = (float) va_arg(ap,
double);
788 goto unsigned_common;
792 goto unsigned_common;
798 l = va_arg(ap,
long);
801 p = consltoa_wd(p, l, c, 0);
809 if ((width -= i) < 0)
814 if (*s ==
'-' && filler ==
'0') {
820 }
while (++width != 0);
COLOR_TYPE gColor
The color type definition.
GHandle gwinGConsoleCreate(GDisplay *g, GConsoleObject *gc, const GWindowInit *pInit)
Create a console window.
void gwinPutCharArray(GHandle gh, const char *str, gMemSize n)
Put the character array at the cursor position in the window. It will wrap lines as required.
void gwinPutString(GHandle gh, const char *str)
Put a string at the cursor position in the window. It will wrap lines as required.
void gwinPrintf(GHandle gh, const char *fmt,...)
Print a formatted string at the cursor position in the window. It will wrap lines as required.
void gwinPutChar(GHandle gh, char c)
Put a character at the cursor position in the window.
void gdispGVerticalScroll(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, int lines, gColor bgcolor)
Scroll vertically a section of the screen.
gCoord gdispGetCharWidth(char c, gFont font)
Get the pixel width of a character.
void gdispGFillChar(GDisplay *g, gCoord x, gCoord y, gU16 c, gFont font, gColor color, gColor bgcolor)
Draw a text character with a filled background.
gCoord gdispGetFontMetric(gFont font, gFontmetric metric)
Get a metric of a font.
void gdispGFillArea(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, gColor color)
Fill an area with a color.
void gdispGDrawChar(GDisplay *g, gCoord x, gCoord y, gU16 c, gFont font, gColor color)
Draw a text character.
void gdispGDrawLine(GDisplay *g, gCoord x0, gCoord y0, gCoord x1, gCoord y1, gColor color)
Draw a line.
gI16 gCoord
The type for a coordinate or length on the screen.
void * gfxAlloc(gMemSize sz)
Allocate memory.
void gfxFree(void *ptr)
Free memory.
#define GWIN_CONSOLE_USE_HISTORY
Should the content of the console be saved for redrawing.
void gwinSetVisible(GHandle gh, gBool visible)
Sets whether a window is visible or not.
The structure to initialise a GWIN.
A window object structure.
const struct gwinVMT * vmt
The Virtual Method Table for a GWIN window.