source: mainline/uspace/srv/fb/serial_console.c@ 7122bc7

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

Console color support overhaul. Create C library console interface.

  • Property mode set to 100644
File size: 5.4 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/style.h>
47
48#include "serial_console.h"
49
50#define MAX_CONTROL 20
51
52static int width;
53static int height;
54static putc_function_t putc_function;
55
56/* Allow only 1 connection */
57static int client_connected = 0;
58
59void serial_puts(char *str)
60{
61 while (*str)
62 putc_function(*(str++));
63}
64
65void serial_goto(const unsigned int row, const unsigned int col)
66{
67 if ((row > height) || (col > width))
68 return;
69
70 char control[20];
71 snprintf(control, 20, "\033[%u;%uf", row + 1, col + 1);
72 serial_puts(control);
73}
74
75void serial_clrscr(void)
76{
77 serial_puts("\033[2J");
78}
79
80void serial_scroll(int i)
81{
82 if (i > 0) {
83 serial_goto(height - 1, 0);
84 while (i--)
85 serial_puts("\033D");
86 } else if (i < 0) {
87 serial_goto(0, 0);
88 while (i++)
89 serial_puts("\033M");
90 }
91}
92
93/** ECMA-48 Set Graphics Rendition. */
94static void serial_sgr(const unsigned int mode)
95{
96 char control[MAX_CONTROL];
97 snprintf(control, MAX_CONTROL, "\033[%um", mode);
98 serial_puts(control);
99}
100
101/** Set scrolling region. */
102void serial_set_scroll_region(unsigned last_row)
103{
104 char control[MAX_CONTROL];
105 snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
106 serial_puts(control);
107}
108
109void serial_cursor_disable(void)
110{
111 serial_puts("\033[?25l");
112}
113
114void serial_cursor_enable(void)
115{
116 serial_puts("\033[?25h");
117}
118
119void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
120{
121 width = w;
122 height = h;
123 putc_function = putc_fn;
124}
125
126/**
127 * Main function of the thread serving client connections.
128 */
129void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
130{
131 int retval;
132 ipc_callid_t callid;
133 ipc_call_t call;
134 char c;
135 int lastcol = 0;
136 int lastrow = 0;
137 int newcol;
138 int newrow;
139 int fgcolor;
140 int bgcolor;
141 int style;
142 int i;
143
144 if (client_connected) {
145 ipc_answer_0(iid, ELIMIT);
146 return;
147 }
148
149 client_connected = 1;
150 ipc_answer_0(iid, EOK);
151
152 /* Clear the terminal, set scrolling region
153 to 0 - height rows. */
154 serial_clrscr();
155 serial_goto(0, 0);
156 serial_set_scroll_region(height);
157
158 while (true) {
159 callid = async_get_call(&call);
160 switch (IPC_GET_METHOD(call)) {
161 case IPC_M_PHONE_HUNGUP:
162 client_connected = 0;
163 ipc_answer_0(callid, EOK);
164 return;
165 case FB_PUTCHAR:
166 c = IPC_GET_ARG1(call);
167 newrow = IPC_GET_ARG2(call);
168 newcol = IPC_GET_ARG3(call);
169 if ((lastcol != newcol) || (lastrow != newrow))
170 serial_goto(newrow, newcol);
171 lastcol = newcol + 1;
172 lastrow = newrow;
173 (*putc_function)(c);
174 retval = 0;
175 break;
176 case FB_CURSOR_GOTO:
177 newrow = IPC_GET_ARG1(call);
178 newcol = IPC_GET_ARG2(call);
179 serial_goto(newrow, newcol);
180 lastrow = newrow;
181 lastcol = newcol;
182 retval = 0;
183 break;
184 case FB_GET_CSIZE:
185 ipc_answer_2(callid, EOK, height, width);
186 continue;
187 case FB_CLEAR:
188 serial_clrscr();
189 retval = 0;
190 break;
191 case FB_SET_STYLE:
192 style = IPC_GET_ARG1(call);
193 if (style == STYLE_EMPHASIS)
194 serial_sgr(1);
195 else
196 serial_sgr(0);
197 retval = 0;
198 break;
199 case FB_SET_COLOR:
200 fgcolor = IPC_GET_ARG1(call);
201 bgcolor = IPC_GET_ARG2(call);
202 if (fgcolor < bgcolor)
203 serial_sgr(0);
204 else
205 serial_sgr(7);
206 retval = 0;
207 break;
208 case FB_SET_RGB_COLOR:
209 fgcolor = IPC_GET_ARG1(call);
210 bgcolor = IPC_GET_ARG2(call);
211 if (fgcolor < bgcolor)
212 serial_sgr(0);
213 else
214 serial_sgr(7);
215 retval = 0;
216 break;
217 case FB_SCROLL:
218 i = IPC_GET_ARG1(call);
219 if ((i > height) || (i < -height)) {
220 retval = EINVAL;
221 break;
222 }
223 serial_scroll(i);
224 serial_goto(lastrow, lastcol);
225 retval = 0;
226 break;
227 case FB_CURSOR_VISIBILITY:
228 if(IPC_GET_ARG1(call))
229 serial_cursor_enable();
230 else
231 serial_cursor_disable();
232 retval = 0;
233 break;
234 default:
235 retval = ENOENT;
236 }
237 ipc_answer_0(callid, retval);
238 }
239}
240
241/**
242 * @}
243 */
Note: See TracBrowser for help on using the repository browser.