source: mainline/uspace/lib/libc/generic/console.c@ 171f9a1

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

Character encoding/decoding un uspace. Partially fix klog application.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2006 Josef Cejka
3 * Copyright (c) 2006 Jakub Vana
4 * Copyright (c) 2008 Jiri Svoboda
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/** @addtogroup libc
32 * @{
33 */
34/** @file
35 */
36
37#include <async.h>
38#include <io/stream.h>
39#include <ipc/console.h>
40#include <ipc/services.h>
41#include <errno.h>
42#include <string.h>
43#include <console.h>
44
45static int console_phone = -1;
46
47/** Size of cbuffer. */
48#define CBUFFER_SIZE 256
49
50/** Buffer for writing characters to the console. */
51static char cbuffer[CBUFFER_SIZE];
52
53/** Pointer to end of cbuffer. */
54static char *cbuffer_end = cbuffer + CBUFFER_SIZE;
55
56/** Pointer to first available field in cbuffer. */
57static char *cbp = cbuffer;
58
59static ssize_t cons_write(const char *buf, size_t nbyte);
60static void cons_putchar(int c);
61
62static void cbuffer_flush(void);
63static void cbuffer_drain(void);
64static inline void cbuffer_putc(int c);
65
66
67void console_open(bool blocking)
68{
69 if (console_phone < 0) {
70 int phone;
71 if (blocking) {
72 phone = ipc_connect_me_to_blocking(PHONE_NS,
73 SERVICE_CONSOLE, 0, 0);
74 } else {
75 phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0,
76 0);
77 }
78 if (phone >= 0)
79 console_phone = phone;
80 }
81}
82
83void console_close(void)
84{
85 if (console_phone >= 0) {
86 if (ipc_hangup(console_phone) == 0) {
87 console_phone = -1;
88 }
89 }
90}
91
92int console_phone_get(bool blocking)
93{
94 if (console_phone < 0)
95 console_open(blocking);
96
97 return console_phone;
98}
99
100void console_wait(void)
101{
102 while (console_phone < 0)
103 console_open(true);
104}
105
106void console_clear(void)
107{
108 int cons_phone = console_phone_get(true);
109
110 cbuffer_drain();
111 async_msg_0(cons_phone, CONSOLE_CLEAR);
112}
113
114void console_goto(int row, int col)
115{
116 int cons_phone = console_phone_get(true);
117
118 cbuffer_flush();
119 async_msg_2(cons_phone, CONSOLE_GOTO, row, col);
120}
121
122void console_putchar(int c)
123{
124 cbuffer_putc(c);
125}
126
127/** Write all data from output buffer to the console. */
128static void cbuffer_flush(void)
129{
130 int rc;
131 int len;
132
133 len = cbp - cbuffer;
134
135 while (len > 0) {
136 rc = cons_write(cbuffer, cbp - cbuffer);
137 if (rc < 0)
138 return;
139
140 len -= rc;
141 }
142
143 cbp = cbuffer;
144}
145
146/** Drop all data in console output buffer. */
147static void cbuffer_drain(void)
148{
149 cbp = cbuffer;
150}
151
152/** Write one character to the output buffer. */
153static inline void cbuffer_putc(int c)
154{
155 if (cbp == cbuffer_end)
156 cbuffer_flush();
157
158 *cbp++ = c;
159
160 if (c == '\n')
161 cbuffer_flush();
162}
163
164/** Write one character to the console via IPC. */
165static void cons_putchar(int c)
166{
167 int cons_phone = console_phone_get(true);
168 async_msg_1(cons_phone, CONSOLE_PUTCHAR, c);
169}
170
171/** Write characters to the console via IPC. */
172static ssize_t cons_write(const char *buf, size_t nbyte)
173{
174 int cons_phone = console_phone_get(true);
175 ipcarg_t rc;
176 ipc_call_t answer;
177 aid_t req;
178
179 async_serialize_start();
180
181 req = async_send_0(cons_phone, CONSOLE_WRITE, &answer);
182 rc = ipc_data_write_start(cons_phone, (void *) buf, nbyte);
183
184 if (rc != EOK) {
185 async_wait_for(req, NULL);
186 async_serialize_end();
187 return (ssize_t) rc;
188 }
189
190 async_wait_for(req, &rc);
191 async_serialize_end();
192
193 if (rc == EOK)
194 return (ssize_t) IPC_GET_ARG1(answer);
195 else
196 return -1;
197}
198
199/** Write characters to the console. */
200ssize_t console_write(const char *buf, size_t nbyte)
201{
202 size_t left;
203
204 left = nbyte;
205
206 while (left > 0) {
207 cbuffer_putc(*buf++);
208 --left;
209 }
210
211 return nbyte;
212}
213
214/** Write a NULL-terminated string to the console. */
215void console_putstr(const char *s)
216{
217 size_t len;
218 ssize_t rc;
219
220 len = strlen(s);
221 while (len > 0) {
222 rc = console_write(s, len);
223 if (rc < 0)
224 return; /* Error */
225 s += rc;
226 len -= rc;
227 }
228}
229
230/** Flush all output to the console. */
231void console_flush(void)
232{
233 int cons_phone = console_phone_get(false);
234
235 cbuffer_flush();
236 async_msg_0(cons_phone, CONSOLE_FLUSH);
237}
238
239int console_get_size(int *rows, int *cols)
240{
241 int cons_phone = console_phone_get(true);
242 ipcarg_t r, c;
243 int rc;
244
245 rc = async_req_0_2(cons_phone, CONSOLE_GETSIZE, &r, &c);
246
247 *rows = (int) r;
248 *cols = (int) c;
249
250 return rc;
251}
252
253void console_set_style(int style)
254{
255 int cons_phone = console_phone_get(true);
256
257 cbuffer_flush();
258 async_msg_1(cons_phone, CONSOLE_SET_STYLE, style);
259}
260
261void console_set_color(int fg_color, int bg_color, int flags)
262{
263 int cons_phone = console_phone_get(true);
264
265 cbuffer_flush();
266 async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
267}
268
269void console_set_rgb_color(int fg_color, int bg_color)
270{
271 int cons_phone = console_phone_get(true);
272
273 cbuffer_flush();
274 async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
275}
276
277void console_cursor_visibility(int show)
278{
279 int cons_phone = console_phone_get(true);
280
281 cbuffer_flush();
282 async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
283}
284
285void console_kcon_enable(void)
286{
287 int cons_phone = console_phone_get(true);
288
289 cbuffer_flush();
290 async_msg_0(cons_phone, CONSOLE_KCON_ENABLE);
291}
292
293/** @}
294 */
Note: See TracBrowser for help on using the repository browser.