/* ChibiOS/GFX - Copyright (C) 2012 Joel Bodenmann aka Tectu This file is part of ChibiOS/GFX. ChibiOS/GFX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS/GFX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** * @file src/console.c * @brief CONSOLE code. * * @addtogroup CONSOLE * @{ */ #include "ch.h" #include "hal.h" #include "console.h" #if GFX_USE_CONSOLE || defined(__DOXYGEN__) /* * Interface implementation. The interface is write only */ static size_t write(void *ip, const uint8_t *bp, size_t n) { return gfxConsoleWrite((GConsole *)ip, bp, n); } static size_t read(void *ip, uint8_t *bp, size_t n) { (void)ip; (void)bp; (void)n; return 0; } static msg_t put(void *ip, uint8_t b) { (void)ip; return gfxConsolePut((GConsole *)ip, (char)b); } static msg_t get(void *ip) { (void)ip; return RDY_OK; } static msg_t putt(void *ip, uint8_t b, systime_t timeout) { (void)timeout; /* TODO: handle timeout */ return gfxConsolePut((GConsole *)ip, (char)b); } static msg_t gett(void *ip, systime_t timeout) { (void)ip; (void)timeout; return RDY_OK; } static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) { (void)time; return gfxConsoleWrite((GConsole *)ip, bp, n); } static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) { (void)ip; (void)bp; (void)n; (void)time; return 0; } static const struct GConsoleVMT vmt = { write, read, put, get, putt, gett, writet, readt }; /** * @brief Initializes a console. * * @param[in] console The console driver struct * @param[in] x0,y0 The location of the upper left corner of the resulting window * @param[in] width, height The width and height of the window * @param[in] font The font to be used when printing to the console * @param[in] bkcolor The background color * @param[in] color The foreground / font color * * @return RDY_OK if done */ msg_t gfxConsoleInit(GConsole *console, coord_t x0, coord_t y0, coord_t width, coord_t height, font_t font, pixel_t bkcolor, pixel_t color) { console->vmt = &vmt; /* read font, get height & padding */ console->fy = gdispGetFontMetric(font, fontHeight); console->fp = gdispGetFontMetric(font, fontCharPadding); /* calculate the size of the console as an integer multiple of characters height*/ console->sx = width; console->sy = (((int16_t)(height/console->fy))-1)*console->fy; console->cx = 0; console->cy = 0; console->x0 = x0; console->y0 = y0; console->bkcolor = bkcolor; console->color = color; console->font = font; gdispFillArea(x0, y0, x0 + width, y0 + height, console->bkcolor); return RDY_OK; } /** * @brief Write a single character to the console. * * @param[in] console The console driver struct * @param[in] c The char to be written * * @return RDY_OK if done */ msg_t gfxConsolePut(GConsole *console, char c) { uint8_t width; if(c == '\n') { /* clear the text at the end of the line */ if(console->cx < console->sx) gdispFillArea(console->x0 + console->cx, console->y0 + console->cy, console->sx - console->cx, console->fy, console->bkcolor); console->cx = 0; console->cy += console->fy; } else if(c == '\r') { /* TODO: work backwards through the buffer to the start of the current line */ //console->cx = 0; } else { width = gdispGetCharWidth(c, console->font) + console->fp; if((console->cx + width) >= console->sx) { /* clear the text at the end of the line */ if (console->cy <= console->sy) gdispFillArea(console->x0 + console->cx, console->y0 + console->cy, console->sx - (console->cx + width), console->fy, console->bkcolor); console->cx = 0; console->cy += console->fy; } if((console->cy > console->sy)) { #if GDISP_NEED_SCROLL /* scroll the console */ gdispVerticalScroll(console->x0, console->y0, console->sx, console->sy + console->fy, console->fy, console->bkcolor); /* reset the cursor to the start of the line */ console->cx = 0; console->cy = console->sy; #else /* clear the console */ gdispFillArea(console->x0, console->y0, console->sx, console->sy + console->fy, console->bkcolor); /* reset the cursor to the top of the console */ console->cx = 0; console->cy = 0; #endif } gdispDrawChar(console->x0 + console->cx, console->y0 + console->cy, c, console->font, console->color); /* update cursor */ console->cx += width; } return RDY_OK; } /** * @brief Write a string to the console. * * @param[in] console The console driver struct * @param[in] bp The buffer / string * @param[in] n The size of the buffer * * @return RDY_OK if done * * @api */ msg_t gfxConsoleWrite(GConsole *console, const uint8_t *bp, size_t n) { size_t i; for(i = 0; i < n; i++) gfxConsolePut(console, bp[i]); return RDY_OK; } #endif /* GFX_USE_CONSOLE */ /** @} */