aboutsummaryrefslogtreecommitdiffstats
path: root/src/gwin
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-03-14 07:39:38 +1000
committerinmarket <andrewh@inmarket.com.au>2014-03-14 07:39:38 +1000
commitad1d70d2957d95161c831e764c6f81c84c332458 (patch)
tree639cc66297de6fe98e26608003871fe83406879a /src/gwin
parentb82448c3e23663a25a423402343fbca78253b80c (diff)
parentea5a1b849df6e5085a92957ad387f9e653674415 (diff)
downloaduGFX-ad1d70d2957d95161c831e764c6f81c84c332458.tar.gz
uGFX-ad1d70d2957d95161c831e764c6f81c84c332458.tar.bz2
uGFX-ad1d70d2957d95161c831e764c6f81c84c332458.zip
Merge branch 'master' into gwin
Diffstat (limited to 'src/gwin')
-rw-r--r--src/gwin/console.c189
-rw-r--r--src/gwin/console.h6
-rw-r--r--src/gwin/sys_options.h19
3 files changed, 204 insertions, 10 deletions
diff --git a/src/gwin/console.c b/src/gwin/console.c
index 0fe4b722..fa93c79d 100644
--- a/src/gwin/console.c
+++ b/src/gwin/console.c
@@ -26,6 +26,14 @@
#define GCONSOLE_FLG_NOSTORE (GWIN_FIRST_CONTROL_FLAG<<0)
#define GCONSOLE_FLG_OVERRUN (GWIN_FIRST_CONTROL_FLAG<<1)
+// Meaning of our attribute bits.
+#define ESC_REDBIT 0x01
+#define ESC_GREENBIT 0x02
+#define ESC_BLUEBIT 0x04
+#define ESC_USECOLOR 0x08
+#define ESC_UNDERLINE 0x10
+#define ESC_BOLD 0x20
+
/*
* Stream interface implementation. The interface is write only
*/
@@ -58,6 +66,68 @@
};
#endif
+#if GWIN_CONSOLE_ESCSEQ
+ // Convert escape sequences to attributes
+ static bool_t ESCtoAttr(char c, uint8_t *pattr) {
+ uint8_t attr;
+
+ attr = pattr[0];
+ switch(c) {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ attr &= ~(ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT);
+ attr |= (c - '0') | ESC_USECOLOR;
+ break;
+ case 'C':
+ attr &= ~(ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT|ESC_USECOLOR);
+ break;
+ case 'u':
+ attr |= ESC_UNDERLINE;
+ break;
+ case 'U':
+ attr &= ~ESC_UNDERLINE;
+ break;
+ case 'b':
+ attr |= ESC_BOLD;
+ break;
+ case 'B':
+ attr &= ~ESC_BOLD;
+ break;
+ default:
+ return FALSE;
+ }
+ if (attr == pattr[0])
+ return FALSE;
+ pattr[0] = attr;
+ return TRUE;
+ }
+
+ static color_t ESCPrintColor(GConsoleObject *gcw) {
+ switch(gcw->currattr & (ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT|ESC_USECOLOR)) {
+ case (ESC_USECOLOR):
+ return Black;
+ case (ESC_USECOLOR|ESC_REDBIT):
+ return Red;
+ case (ESC_USECOLOR|ESC_GREENBIT):
+ return Green;
+ case (ESC_USECOLOR|ESC_REDBIT|ESC_GREENBIT):
+ return Yellow;
+ case (ESC_USECOLOR|ESC_BLUEBIT):
+ return Blue;
+ case (ESC_USECOLOR|ESC_REDBIT|ESC_BLUEBIT):
+ return Magenta;
+ case (ESC_USECOLOR|ESC_GREENBIT|ESC_BLUEBIT):
+ return Cyan;
+ case (ESC_USECOLOR|ESC_REDBIT|ESC_GREENBIT|ESC_BLUEBIT):
+ return White;
+ default:
+ return gcw->g.color;
+ }
+ }
+#else
+ #define ESCPrintColor(gcw) ((gcw)->g.color)
+#endif
+
#if GWIN_CONSOLE_USE_HISTORY
static void HistoryDestroy(GWindowObject *gh) {
#define gcw ((GConsoleObject *)gh)
@@ -90,13 +160,25 @@
gcw->cx = 0;
gcw->cy = 0;
+ // Reset the current attributes
+ #if GWIN_CONSOLE_ESCSEQ
+ gcw->currattr = gcw->startattr;
+ #endif
+
// Print the buffer
gwinPutCharArray(gh, gcw->buffer, gcw->bufpos);
- #if !GWIN_CONSOLE_USE_CLEAR_LINES
+ #if GWIN_CONSOLE_USE_CLEAR_LINES
// Clear the remaining space
- if (gcw->cy + fy < gh->height)
- gdispGFillArea(gh->display, gh->x, gh->y+gcw->cy+fy, gh->width, gh->height-(gcw->cy+fy), gh->bgcolor);
+ {
+ coord_t y;
+
+ y = gcw->cy;
+ if (gcw->cx)
+ y += gdispGetFontMetric(gh->font, fontHeight);
+ if (y < gh->height)
+ gdispGFillArea(gh->display, gh->x, gh->y+y, gh->width, gh->height-y, gh->bgcolor);
+ }
#endif
// Turn back on storing of buffer contents
@@ -115,7 +197,7 @@
// Do we have enough space in the buffer
if (gcw->bufpos >= gcw->bufsize) {
- char * p;
+ char *p, *ep;
size_t dp;
/**
@@ -130,7 +212,13 @@
*/
// Remove one line from the start
- for(p = gcw->buffer; *p && *p != '\n'; p++);
+ ep = gcw->buffer+gcw->bufpos;
+ for(p = gcw->buffer; p < ep && *p != '\n'; p++) {
+ #if GWIN_CONSOLE_ESCSEQ
+ if (*p == 27)
+ ESCtoAttr(p[1], &gcw->startattr);
+ #endif
+ }
// Was there a newline?
if (*p != '\n')
@@ -153,7 +241,7 @@
* Scroll the history buffer by one line
*/
static void scrollBuffer(GConsoleObject *gcw) {
- char * p;
+ char *p, *ep;
size_t dp;
// Only scroll if we need to
@@ -167,7 +255,13 @@
}
// Remove one line from the start
- for(p = gcw->buffer; *p && *p != '\n'; p++);
+ ep = gcw->buffer+gcw->bufpos;
+ for(p = gcw->buffer; p < ep && *p != '\n'; p++) {
+ #if GWIN_CONSOLE_ESCSEQ
+ if (*p == 27)
+ ESCtoAttr(p[1], &gcw->startattr);
+ #endif
+ }
// Was there a newline, if not delete everything.
if (*p != '\n') {
@@ -205,6 +299,9 @@ static void AfterClear(GWindowObject *gh) {
gcw->cx = 0;
gcw->cy = 0;
clearBuffer(gcw);
+ #if GWIN_CONSOLE_ESCSEQ
+ gcw->startattr = gcw->currattr;
+ #endif
#undef gcw
}
@@ -239,6 +336,11 @@ GHandle gwinGConsoleCreate(GDisplay *g, GConsoleObject *gc, const GWindowInit *p
gc->cx = 0;
gc->cy = 0;
+ #if GWIN_CONSOLE_ESCSEQ
+ gc->startattr = gc->currattr = 0;
+ gc->escstate = 0;
+ #endif
+
gwinSetVisible((GHandle)gc, pInit->show);
return (GHandle)gc;
@@ -313,13 +415,54 @@ void gwinPutChar(GHandle gh, char c) {
#if GDISP_NEED_CLIP
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
-
+
+ #if GWIN_CONSOLE_ESCSEQ
+ /**
+ * Handle escape sequences
+ * ESC color Change subsequent text color
+ * color: "0" = black, "1" = red, "2" = green, "3" = yellow, "4" = blue,
+ * "5" = magenta, "6" = cyan, "7" = white
+ * ESC C Revert subsequent text color to the window default
+ * ESC u Turn on underline
+ * ESC U Turn off underline
+ * ESC b Turn on bold
+ * ESC B Turn off bold
+ * ESC J Clear the window
+ */
+ switch (gcw->escstate) {
+ case 1:
+ gcw->escstate = 0;
+ if (ESCtoAttr(c, &gcw->currattr)) {
+ if (gcw->cx == 0 && gcw->cy == 0)
+ gcw->startattr = gcw->currattr;
+ else {
+ putCharInBuffer(gcw, 27);
+ putCharInBuffer(gcw, c);
+ }
+ } else {
+ switch(c) {
+ case 'J':
+ // Clear the console and reset the cursor
+ clearBuffer(gcw);
+ gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
+ gcw->cx = 0;
+ gcw->cy = 0;
+ gcw->startattr = gcw->currattr;
+ break;
+ }
+ }
+ return;
+ }
+ #endif
+
/**
* Special Characters:
*
* Carriage returns and line feeds (\r & \n) are handled in unix terminal cooked mode; that is,
* line feeds perform both actions and carriage-returns are ignored.
*
+ * if GWIN_CONSOLE_ESCSEQ is turned on then ESC is trapped ready for the escape command.
+ *
* All other characters are treated as printable.
*/
switch (c) {
@@ -339,12 +482,24 @@ void gwinPutChar(GHandle gh, char c) {
case '\r':
// gcw->cx = 0;
return;
+
+ #if GWIN_CONSOLE_ESCSEQ
+ case 27: // ESC
+ gcw->escstate = 1;
+ return;
+ #endif
}
// Characters with no width are ignored
if (!(width = gdispGetCharWidth(c, gh->font)))
return;
+ // Allow space for (very crude) bold
+ #if GWIN_CONSOLE_ESCSEQ
+ if ((gcw->currattr & ESC_BOLD))
+ width++;
+ #endif
+
// Do we need to go to the next line to fit this character?
if (gcw->cx + width >= gh->width) {
gcw->cx = 0;
@@ -378,6 +533,9 @@ void gwinPutChar(GHandle gh, char c) {
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
gcw->cx = 0;
gcw->cy = 0;
+ #if GWIN_CONSOLE_ESCSEQ
+ gcw->startattr = gcw->currattr;
+ #endif
}
#endif
}
@@ -390,12 +548,23 @@ void gwinPutChar(GHandle gh, char c) {
// Draw the character
#if GWIN_CONSOLE_USE_FILLED_CHARS
- gdispGFillChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color, gh->bgcolor);
+ gdispGFillChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw), gh->bgcolor);
#else
- gdispGDrawChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color);
+ gdispGDrawChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
#endif
putCharInBuffer(gcw, c);
+ #if GWIN_CONSOLE_ESCSEQ
+ // Draw the underline
+ if ((gcw->currattr & ESC_UNDERLINE))
+ gdispGDrawLine(gh->display, gh->x + gcw->cx, gh->y + gcw->cy + fy - gdispGetFontMetric(gh->font, fontDescendersHeight),
+ gh->x + gcw->cx + width + gdispGetFontMetric(gh->font, fontCharPadding), gh->y + gcw->cy + fy - gdispGetFontMetric(gh->font, fontDescendersHeight),
+ ESCPrintColor(gcw));
+ // Bold (very crude)
+ if ((gcw->currattr & ESC_BOLD))
+ gdispGDrawChar(gh->display, gh->x + gcw->cx + 1, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
+ #endif
+
// Update the cursor
gcw->cx += width + gdispGetFontMetric(gh->font, fontCharPadding);
diff --git a/src/gwin/console.h b/src/gwin/console.h
index 252b627e..14bc7eb3 100644
--- a/src/gwin/console.h
+++ b/src/gwin/console.h
@@ -31,6 +31,12 @@ typedef struct GConsoleObject {
GWindowObject g;
coord_t cx, cy; // Cursor position
+ #if GWIN_CONSOLE_ESCSEQ
+ uint8_t startattr; // ANSI-like escape sequences
+ uint8_t currattr;
+ uint16_t escstate;
+ #endif
+
#if GWIN_CONSOLE_USE_HISTORY
char * buffer; // buffer to store console content
size_t bufsize; // size of buffer
diff --git a/src/gwin/sys_options.h b/src/gwin/sys_options.h
index 07f63b99..3f7c3893 100644
--- a/src/gwin/sys_options.h
+++ b/src/gwin/sys_options.h
@@ -174,6 +174,25 @@
#define GWIN_CONSOLE_USE_FLOAT FALSE
#endif
/**
+ * @brief Console windows support escape sequences to control display
+ * @details Defaults to FALSE
+ *
+ * @note
+ * Currently supported:
+ * ESC color Change subsequent text color
+ * color: "0" = black, "1" = red, "2" = green, "3" = yellow, "4" = blue,
+ * "5" = magenta, "6" = cyan, "7" = white
+ * ESC C Revert subsequent text color to the window default
+ * ESC u Turn on underline
+ * ESC U Turn off underline
+ * ESC b Turn on bold
+ * ESC B Turn off bold
+ * ESC J Clear the window
+ */
+ #ifndef GWIN_CONSOLE_ESCSEQ
+ #define GWIN_CONSOLE_ESCSEQ FALSE
+ #endif
+ /**
* @brief Console Windows need BaseStreamSequential support (ChibiOS only)
* @details Defaults to FALSE
* @note To use the ChibiOS basestream functions such as chprintf()