source: mainline/uspace/srv/fb/serial_console.c@ fb69f39

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fb69f39 was fb69f39, checked in by Jiri Svoboda <jirik.svoboda@…>, 16 years ago

Color support in serial fb driver.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
3 * Copyright (c) 2008 Martin Decky
4 * Copyright (c) 2008 Pavel Rimsky
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * @defgroup serial Serial console
33 * @brief Serial console services (putc, puts, clear screen, cursor goto,...)
34 * @{
35 */
36
37/** @file
38 */
39
40#include <stdio.h>
41#include <ipc/ipc.h>
42#include <async.h>
43#include <ipc/fb.h>
44#include <bool.h>
45#include <errno.h>
46#include <console/color.h>
47#include <console/style.h>
48
49#include "serial_console.h"
50
51#define MAX_CONTROL 20
52
53static void serial_sgr(const unsigned int mode);
54
55static int width;
56static int height;
57static bool color = true; /** True if producing color output. */
58static putc_function_t putc_function;
59
60/* Allow only 1 connection */
61static int client_connected = 0;
62
63enum sgr_color_index {
64 CI_BLACK = 0,
65 CI_RED = 1,
66 CI_GREEN = 2,
67 CI_BROWN = 3,
68 CI_BLUE = 4,
69 CI_MAGENTA = 5,
70 CI_CYAN = 6,
71 CI_WHITE = 7,
72};
73
74enum sgr_command {
75 SGR_RESET = 0,
76 SGR_BOLD = 1,
77 SGR_BLINK = 5,
78 SGR_REVERSE = 7,
79 SGR_NORMAL_INT = 22,
80 SGR_BLINK_OFF = 25,
81 SGR_REVERSE_OFF = 27,
82 SGR_FGCOLOR = 30,
83 SGR_BGCOLOR = 40
84};
85
86static int color_map[] = {
87 [COLOR_BLACK] = CI_BLACK,
88 [COLOR_BLUE] = CI_RED,
89 [COLOR_GREEN] = CI_GREEN,
90 [COLOR_CYAN] = CI_CYAN,
91 [COLOR_RED] = CI_RED,
92 [COLOR_MAGENTA] = CI_MAGENTA,
93 [COLOR_YELLOW] = CI_BROWN,
94 [COLOR_WHITE] = CI_WHITE
95};
96
97void serial_puts(char *str)
98{
99 while (*str)
100 putc_function(*(str++));
101}
102
103void serial_goto(const unsigned int row, const unsigned int col)
104{
105 if ((row > height) || (col > width))
106 return;
107
108 char control[MAX_CONTROL];
109 snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
110 serial_puts(control);
111}
112
113void serial_clrscr(void)
114{
115 /* Initialize graphic rendition attributes. */
116 serial_sgr(SGR_RESET);
117 if (color) {
118 serial_sgr(SGR_FGCOLOR + CI_BLACK);
119 serial_sgr(SGR_BGCOLOR + CI_WHITE);
120 }
121
122 serial_puts("\033[2J");
123}
124
125void serial_scroll(int i)
126{
127 if (i > 0) {
128 serial_goto(height - 1, 0);
129 while (i--)
130 serial_puts("\033D");
131 } else if (i < 0) {
132 serial_goto(0, 0);
133 while (i++)
134 serial_puts("\033M");
135 }
136}
137
138/** ECMA-48 Set Graphics Rendition. */
139static void serial_sgr(const unsigned int mode)
140{
141 char control[MAX_CONTROL];
142 snprintf(control, MAX_CONTROL, "\033[%um", mode);
143 serial_puts(control);
144}
145
146/** Set scrolling region. */
147void serial_set_scroll_region(unsigned last_row)
148{
149 char control[MAX_CONTROL];
150 snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
151 serial_puts(control);
152}
153
154void serial_cursor_disable(void)
155{
156 serial_puts("\033[?25l");
157}
158
159void serial_cursor_enable(void)
160{
161 serial_puts("\033[?25h");
162}
163
164void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
165{
166 width = w;
167 height = h;
168 putc_function = putc_fn;
169}
170
171/**
172 * Main function of the thread serving client connections.
173 */
174void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
175{
176 int retval;
177 ipc_callid_t callid;
178 ipc_call_t call;
179 char c;
180 int lastcol = 0;
181 int lastrow = 0;
182 int newcol;
183 int newrow;
184 int fgcolor;
185 int bgcolor;
186 int style;
187 int i;
188
189 if (client_connected) {
190 ipc_answer_0(iid, ELIMIT);
191 return;
192 }
193
194 client_connected = 1;
195 ipc_answer_0(iid, EOK);
196
197 /* Clear the terminal, set scrolling region
198 to 0 - height rows. */
199 serial_clrscr();
200 serial_goto(0, 0);
201 serial_set_scroll_region(height);
202
203 while (true) {
204 callid = async_get_call(&call);
205 switch (IPC_GET_METHOD(call)) {
206 case IPC_M_PHONE_HUNGUP:
207 client_connected = 0;
208 ipc_answer_0(callid, EOK);
209 return;
210 case FB_PUTCHAR:
211 c = IPC_GET_ARG1(call);
212 newrow = IPC_GET_ARG2(call);
213 newcol = IPC_GET_ARG3(call);
214 if ((lastcol != newcol) || (lastrow != newrow))
215 serial_goto(newrow, newcol);
216 lastcol = newcol + 1;
217 lastrow = newrow;
218 (*putc_function)(c);
219 retval = 0;
220 break;
221 case FB_CURSOR_GOTO:
222 newrow = IPC_GET_ARG1(call);
223 newcol = IPC_GET_ARG2(call);
224 serial_goto(newrow, newcol);
225 lastrow = newrow;
226 lastcol = newcol;
227 retval = 0;
228 break;
229 case FB_GET_CSIZE:
230 ipc_answer_2(callid, EOK, height, width);
231 continue;
232 case FB_CLEAR:
233 serial_clrscr();
234 retval = 0;
235 break;
236 case FB_SET_STYLE:
237 style = IPC_GET_ARG1(call);
238 if (style == STYLE_EMPHASIS) {
239 if (color) {
240 serial_sgr(SGR_RESET);
241 serial_sgr(SGR_FGCOLOR + CI_RED);
242 serial_sgr(SGR_BGCOLOR + CI_WHITE);
243 }
244 serial_sgr(SGR_BOLD);
245 } else {
246 if (color) {
247 serial_sgr(SGR_RESET);
248 serial_sgr(SGR_FGCOLOR + CI_BLACK);
249 serial_sgr(SGR_BGCOLOR + CI_WHITE);
250 }
251 serial_sgr(SGR_NORMAL_INT);
252 }
253 retval = 0;
254 break;
255 case FB_SET_COLOR:
256 fgcolor = IPC_GET_ARG1(call);
257 bgcolor = IPC_GET_ARG2(call);
258
259 if (color) {
260 serial_sgr(SGR_RESET);
261 serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
262 serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
263 } else {
264 if (fgcolor < bgcolor)
265 serial_sgr(SGR_RESET);
266 else
267 serial_sgr(SGR_REVERSE);
268 }
269 retval = 0;
270 break;
271 case FB_SET_RGB_COLOR:
272 fgcolor = IPC_GET_ARG1(call);
273 bgcolor = IPC_GET_ARG2(call);
274 if (fgcolor < bgcolor)
275 serial_sgr(SGR_REVERSE_OFF);
276 else
277 serial_sgr(SGR_REVERSE);
278 retval = 0;
279 break;
280 case FB_SCROLL:
281 i = IPC_GET_ARG1(call);
282 if ((i > height) || (i < -height)) {
283 retval = EINVAL;
284 break;
285 }
286 serial_scroll(i);
287 serial_goto(lastrow, lastcol);
288 retval = 0;
289 break;
290 case FB_CURSOR_VISIBILITY:
291 if(IPC_GET_ARG1(call))
292 serial_cursor_enable();
293 else
294 serial_cursor_disable();
295 retval = 0;
296 break;
297 default:
298 retval = ENOENT;
299 }
300 ipc_answer_0(callid, retval);
301 }
302}
303
304/**
305 * @}
306 */
Note: See TracBrowser for help on using the repository browser.