| /* |
| * Copyright (c) 2008-2010 Travis Geiselbrecht |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files |
| * (the "Software"), to deal in the Software without restriction, |
| * including without limitation the rights to use, copy, modify, merge, |
| * publish, distribute, sublicense, and/or sell copies of the Software, |
| * and to permit persons to whom the Software is furnished to do so, |
| * subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be |
| * included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| /** |
| * @file |
| * @brief Manage graphics console |
| * |
| * This file contains functions to provide stdout to the graphics console. |
| * |
| * @ingroup graphics |
| */ |
| |
| #include <debug.h> |
| #include <lib/gfx.h> |
| #include <lib/gfxconsole.h> |
| #include <lib/font.h> |
| #include <dev/display.h> |
| |
| /** @addtogroup graphics |
| * @{ |
| */ |
| |
| /** |
| * @brief Represent state of graphics console |
| */ |
| static struct { |
| gfx_surface *surface; |
| uint rows, columns; |
| uint extray; // extra pixels left over if the rows doesn't fit precisely |
| |
| uint x, y; |
| |
| uint32_t front_color; |
| uint32_t back_color; |
| } gfxconsole; |
| |
| static void gfxconsole_putc(char c) |
| { |
| static enum { NORMAL, ESCAPE } state = NORMAL; |
| static uint32_t p_num = 0; |
| |
| switch (state) { |
| case NORMAL: |
| { |
| if(c == '\n' || c == '\r') { |
| gfxconsole.x = 0; |
| gfxconsole.y++; |
| } else if (c == 0x1b) { |
| p_num = 0; |
| state = ESCAPE; |
| } else { |
| font_draw_char(gfxconsole.surface, c, gfxconsole.x * FONT_X, gfxconsole.y * FONT_Y, gfxconsole.front_color); |
| gfxconsole.x++; |
| } |
| break; |
| } |
| |
| case ESCAPE: |
| { |
| if (c >= '0' && c <= '9') { |
| p_num = (p_num * 10) + (c - '0'); |
| } else if (c == 'D') { |
| if (p_num <= gfxconsole.x) |
| gfxconsole.x -= p_num; |
| state = NORMAL; |
| } else if (c == '[') { |
| // eat this character |
| } else { |
| font_draw_char(gfxconsole.surface, c, gfxconsole.x * FONT_X, gfxconsole.y * FONT_Y, gfxconsole.front_color); |
| gfxconsole.x++; |
| state = NORMAL; |
| } |
| break; |
| } |
| } |
| |
| if(gfxconsole.x >= gfxconsole.columns) { |
| gfxconsole.x = 0; |
| gfxconsole.y++; |
| } |
| if(gfxconsole.y >= gfxconsole.rows) { |
| // scroll up |
| gfx_copyrect(gfxconsole.surface, 0, FONT_Y, gfxconsole.surface->width, gfxconsole.surface->height - FONT_Y - gfxconsole.extray, 0, 0); |
| gfxconsole.y--; |
| gfx_fillrect(gfxconsole.surface, 0, gfxconsole.surface->height - FONT_Y - gfxconsole.extray, gfxconsole.surface->width, FONT_Y, gfxconsole.back_color); |
| gfx_flush(gfxconsole.surface); |
| } |
| } |
| |
| /** |
| * @brief Initialize graphics console on given drawing surface. |
| * |
| * The graphics console subsystem is initialized, and registered as |
| * an output device for debug output. |
| */ |
| void gfxconsole_start(gfx_surface *surface) |
| { |
| DEBUG_ASSERT(gfxconsole.surface == NULL); |
| |
| // set up the surface |
| gfxconsole.surface = surface; |
| |
| // calculate how many rows/columns we have |
| gfxconsole.rows = surface->height / FONT_Y; |
| gfxconsole.columns = surface->width / FONT_X; |
| gfxconsole.extray = surface->height - (gfxconsole.rows * FONT_Y); |
| |
| dprintf(SPEW, "gfxconsole: rows %d, columns %d, extray %d\n", gfxconsole.rows, gfxconsole.columns, gfxconsole.extray); |
| |
| // start in the upper left |
| gfxconsole.x = 0; |
| gfxconsole.y = 0; |
| |
| // colors are white and black for now |
| gfxconsole.front_color = 0xffffffff; |
| gfxconsole.back_color = 0; |
| |
| // register for debug callbacks |
| register_debug_output(&gfxconsole_putc); |
| } |
| |
| /** |
| * @brief Initialize graphics console on default display |
| */ |
| void gfxconsole_start_on_display(void) |
| { |
| static bool started = false; |
| |
| if (started) |
| return; |
| |
| /* pop up the console */ |
| struct display_info info; |
| display_get_info(&info); |
| gfx_surface *s = gfx_create_surface_from_display(&info); |
| gfxconsole_start(s); |
| started = true; |
| } |
| |