source: mainline/uspace/lib/libc/generic/console.c@ 56fa418

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

Make Czech layout work partially in bdsh.

  • Property mode set to 100644
File size: 6.2 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(wchar_t 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(wchar_t c)
123{
124// cbuffer_putc(c);
125 cbuffer_flush();
126 cons_putchar(c);
127}
128
129/** Write all data from output buffer to the console. */
130static void cbuffer_flush(void)
131{
132 int rc;
133 int len;
134
135 len = cbp - cbuffer;
136
137 while (len > 0) {
138 rc = cons_write(cbuffer, cbp - cbuffer);
139 if (rc < 0)
140 return;
141
142 len -= rc;
143 }
144
145 cbp = cbuffer;
146}
147
148/** Drop all data in console output buffer. */
149static void cbuffer_drain(void)
150{
151 cbp = cbuffer;
152}
153
154/** Write one character to the output buffer. */
155static inline void cbuffer_putc(int c)
156{
157 if (cbp == cbuffer_end)
158 cbuffer_flush();
159
160 *cbp++ = c;
161
162 if (c == '\n')
163 cbuffer_flush();
164}
165
166/** Write one character to the console via IPC. */
167static void cons_putchar(wchar_t c)
168{
169 int cons_phone = console_phone_get(true);
170 async_msg_1(cons_phone, CONSOLE_PUTCHAR, c);
171}
172
173/** Write characters to the console via IPC. */
174static ssize_t cons_write(const char *buf, size_t nbyte)
175{
176 int cons_phone = console_phone_get(true);
177 ipcarg_t rc;
178 ipc_call_t answer;
179 aid_t req;
180
181 async_serialize_start();
182
183 req = async_send_0(cons_phone, CONSOLE_WRITE, &answer);
184 rc = ipc_data_write_start(cons_phone, (void *) buf, nbyte);
185
186 if (rc != EOK) {
187 async_wait_for(req, NULL);
188 async_serialize_end();
189 return (ssize_t) rc;
190 }
191
192 async_wait_for(req, &rc);
193 async_serialize_end();
194
195 if (rc == EOK)
196 return (ssize_t) IPC_GET_ARG1(answer);
197 else
198 return -1;
199}
200
201/** Write characters to the console. */
202ssize_t console_write(const char *buf, size_t nbyte)
203{
204 size_t left;
205
206 left = nbyte;
207
208 while (left > 0) {
209 cbuffer_putc(*buf++);
210 --left;
211 }
212
213 return nbyte;
214}
215
216/** Write a NULL-terminated string to the console. */
217void console_putstr(const char *s)
218{
219 size_t len;
220 ssize_t rc;
221
222 len = strlen(s);
223 while (len > 0) {
224 rc = console_write(s, len);
225 if (rc < 0)
226 return; /* Error */
227 s += rc;
228 len -= rc;
229 }
230}
231
232/** Flush all output to the console. */
233void console_flush(void)
234{
235 int cons_phone = console_phone_get(false);
236
237 cbuffer_flush();
238 async_msg_0(cons_phone, CONSOLE_FLUSH);
239}
240
241int console_get_size(int *rows, int *cols)
242{
243 int cons_phone = console_phone_get(true);
244 ipcarg_t r, c;
245 int rc;
246
247 rc = async_req_0_2(cons_phone, CONSOLE_GETSIZE, &r, &c);
248
249 *rows = (int) r;
250 *cols = (int) c;
251
252 return rc;
253}
254
255void console_set_style(int style)
256{
257 int cons_phone = console_phone_get(true);
258
259 cbuffer_flush();
260 async_msg_1(cons_phone, CONSOLE_SET_STYLE, style);
261}
262
263void console_set_color(int fg_color, int bg_color, int flags)
264{
265 int cons_phone = console_phone_get(true);
266
267 cbuffer_flush();
268 async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
269}
270
271void console_set_rgb_color(int fg_color, int bg_color)
272{
273 int cons_phone = console_phone_get(true);
274
275 cbuffer_flush();
276 async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
277}
278
279void console_cursor_visibility(int show)
280{
281 int cons_phone = console_phone_get(true);
282
283 cbuffer_flush();
284 async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
285}
286
287void console_kcon_enable(void)
288{
289 int cons_phone = console_phone_get(true);
290
291 cbuffer_flush();
292 async_msg_0(cons_phone, CONSOLE_KCON_ENABLE);
293}
294
295/** @}
296 */
Note: See TracBrowser for help on using the repository browser.