First version
[3rdparty/ote_partner/tlk.git] / lib / gfxconsole / gfxconsole.c
1 /*
2  * Copyright (c) 2008-2010 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 /**
25  * @file
26  * @brief  Manage graphics console
27  *
28  * This file contains functions to provide stdout to the graphics console.
29  *
30  * @ingroup graphics
31  */
32
33 #include <debug.h>
34 #include <assert.h>
35 #include <lib/gfx.h>
36 #include <lib/gfxconsole.h>
37 #include <lib/font.h>
38 #include <dev/display.h>
39
40 /** @addtogroup graphics
41  * @{
42  */
43
44 /**
45  * @brief  Represent state of graphics console
46  */
47 static struct {
48         gfx_surface *surface;
49         uint rows, columns;
50         uint extray; // extra pixels left over if the rows doesn't fit precisely
51
52         uint x, y;
53
54         uint32_t front_color;
55         uint32_t back_color;
56 } gfxconsole;
57
58 static void gfxconsole_putc(char c)
59 {
60         static enum { NORMAL, ESCAPE } state = NORMAL;
61         static uint32_t p_num = 0;
62
63         switch (state) {
64                 case NORMAL:
65                 {
66                         if(c == '\n' || c == '\r') {
67                                 gfxconsole.x = 0;
68                                 gfxconsole.y++;
69                         } else if (c == 0x1b) {
70                                 p_num = 0;
71                                 state = ESCAPE;
72                         } else {
73                                 font_draw_char(gfxconsole.surface, c, gfxconsole.x * FONT_X, gfxconsole.y * FONT_Y, gfxconsole.front_color);
74                                 gfxconsole.x++;
75                         }
76                         break;
77                 }
78
79                 case ESCAPE:
80                 {
81                         if (c >= '0' && c <= '9') {
82                                 p_num = (p_num * 10) + (c - '0');
83                         } else if (c == 'D') {
84                                 if (p_num <= gfxconsole.x)
85                                         gfxconsole.x -= p_num;
86                                 state = NORMAL;
87                         } else if (c == '[') {
88                                 // eat this character
89                         } else {
90                                 font_draw_char(gfxconsole.surface, c, gfxconsole.x * FONT_X, gfxconsole.y * FONT_Y, gfxconsole.front_color);
91                                 gfxconsole.x++;
92                                 state = NORMAL;
93                         }
94                         break;
95                 }
96         }
97
98         if(gfxconsole.x >= gfxconsole.columns) {
99                 gfxconsole.x = 0;
100                 gfxconsole.y++;
101         }
102         if(gfxconsole.y >= gfxconsole.rows) {
103                 // scroll up
104                 gfx_copyrect(gfxconsole.surface, 0, FONT_Y, gfxconsole.surface->width, gfxconsole.surface->height - FONT_Y - gfxconsole.extray, 0, 0);
105                 gfxconsole.y--;
106                 gfx_fillrect(gfxconsole.surface, 0, gfxconsole.surface->height - FONT_Y - gfxconsole.extray, gfxconsole.surface->width, FONT_Y, gfxconsole.back_color);
107                 gfx_flush(gfxconsole.surface);
108         }
109 }
110
111 /**
112  * @brief  Initialize graphics console on given drawing surface.
113  *
114  * The graphics console subsystem is initialized, and registered as
115  * an output device for debug output.
116  */
117 void gfxconsole_start(gfx_surface *surface)
118 {
119         DEBUG_ASSERT(gfxconsole.surface == NULL);
120
121         // set up the surface
122         gfxconsole.surface = surface;
123
124         // calculate how many rows/columns we have
125         gfxconsole.rows = surface->height / FONT_Y;
126         gfxconsole.columns = surface->width / FONT_X;
127         gfxconsole.extray = surface->height - (gfxconsole.rows * FONT_Y);
128
129         dprintf(SPEW, "gfxconsole: rows %d, columns %d, extray %d\n", gfxconsole.rows, gfxconsole.columns, gfxconsole.extray);
130
131         // start in the upper left
132         gfxconsole.x = 0;
133         gfxconsole.y = 0;
134
135         // colors are white and black for now
136         gfxconsole.front_color = 0xffffffff;
137         gfxconsole.back_color = 0;
138
139         // register for debug callbacks
140         //register_debug_output(&gfxconsole_putc);
141 }
142
143 /**
144  * @brief  Initialize graphics console on default display
145  */
146 void gfxconsole_start_on_display(void)
147 {
148         static bool started = false;
149
150         if (started)
151                 return;
152
153         /* pop up the console */
154         struct display_info info;
155         display_get_info(&info);
156         gfx_surface *s = gfx_create_surface_from_display(&info);
157         gfxconsole_start(s);
158         started = true;
159 }
160