Subversion Repositories HelenOS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3767 svoboda 1
/*
4154 svoboda 2
 * Copyright (c) 2006 Josef Cejka
3
 * Copyright (c) 2006 Jakub Vana
3767 svoboda 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>
4154 svoboda 40
#include <ipc/services.h>
4164 svoboda 41
#include <errno.h>
42
#include <string.h>
3767 svoboda 43
#include <console.h>
44
 
4154 svoboda 45
static int console_phone = -1;
46
 
4164 svoboda 47
/** Size of cbuffer. */
48
#define CBUFFER_SIZE 256
49
 
50
/** Buffer for writing characters to the console. */
51
static char cbuffer[CBUFFER_SIZE];
52
 
53
/** Pointer to end of cbuffer. */
54
static char *cbuffer_end = cbuffer + CBUFFER_SIZE;
55
 
56
/** Pointer to first available field in cbuffer. */
57
static char *cbp = cbuffer;
58
 
59
static ssize_t cons_write(const char *buf, size_t nbyte);
60
static void cons_putchar(int c);
61
 
62
static void cbuffer_flush(void);
63
static void cbuffer_drain(void);
64
static void cbuffer_putc(int c);
65
 
66
 
4160 jermar 67
void console_open(bool blocking)
4154 svoboda 68
{
69
	if (console_phone < 0) {
4160 jermar 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
		}
4154 svoboda 78
		if (phone >= 0)
79
			console_phone = phone;
80
	}
81
}
82
 
83
void console_close(void)
84
{
85
	if (console_phone >= 0) {
86
		if (ipc_hangup(console_phone) == 0) {
87
			console_phone = -1;
88
		}
89
	}
90
}
91
 
4160 jermar 92
int console_phone_get(bool blocking)
4154 svoboda 93
{
94
	if (console_phone < 0)
4160 jermar 95
		console_open(blocking);
4154 svoboda 96
 
97
	return console_phone;
98
}
99
 
100
void console_wait(void)
101
{
102
	while (console_phone < 0)
4160 jermar 103
		console_open(true);
4154 svoboda 104
}
105
 
3768 svoboda 106
void console_clear(void)
107
{
4160 jermar 108
	int cons_phone = console_phone_get(true);
4164 svoboda 109
 
110
	cbuffer_drain();
3768 svoboda 111
	async_msg_0(cons_phone, CONSOLE_CLEAR);
112
}
113
 
114
void console_goto(int row, int col)
115
{
4160 jermar 116
	int cons_phone = console_phone_get(true);
4164 svoboda 117
 
118
	cbuffer_flush();
3768 svoboda 119
	async_msg_2(cons_phone, CONSOLE_GOTO, row, col);
120
}
121
 
4154 svoboda 122
void console_putchar(int c)
123
{
4164 svoboda 124
	cbuffer_putc(c);
125
}
126
 
127
/** Write all data from output buffer to the console. */
128
static 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. */
147
static void cbuffer_drain(void)
148
{
149
	cbp = cbuffer;
150
}
151
 
152
/** Write one character to the output buffer. */
153
static 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. */
165
static void cons_putchar(int c)
166
{
4160 jermar 167
	int cons_phone = console_phone_get(true);
4154 svoboda 168
	async_msg_1(cons_phone, CONSOLE_PUTCHAR, c);
169
}
170
 
4164 svoboda 171
/** Write characters to the console via IPC. */
172
static 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. */
200
ssize_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. */
215
void 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. */
3768 svoboda 231
void console_flush(void)
232
{
4164 svoboda 233
	int cons_phone = console_phone_get(false);
234
 
235
	cbuffer_flush();
3768 svoboda 236
	async_msg_0(cons_phone, CONSOLE_FLUSH);
237
}
238
 
239
int console_get_size(int *rows, int *cols)
240
{
4160 jermar 241
	int cons_phone = console_phone_get(true);
3768 svoboda 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
 
3767 svoboda 253
void console_set_style(int style)
254
{
4160 jermar 255
	int cons_phone = console_phone_get(true);
4164 svoboda 256
 
257
	cbuffer_flush();
3767 svoboda 258
	async_msg_1(cons_phone, CONSOLE_SET_STYLE, style);
259
}
260
 
261
void console_set_color(int fg_color, int bg_color, int flags)
262
{
4160 jermar 263
	int cons_phone = console_phone_get(true);
4164 svoboda 264
 
265
	cbuffer_flush();
3767 svoboda 266
	async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
267
}
268
 
269
void console_set_rgb_color(int fg_color, int bg_color)
270
{
4160 jermar 271
	int cons_phone = console_phone_get(true);
4164 svoboda 272
 
273
	cbuffer_flush();
3767 svoboda 274
	async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
275
}
276
 
3768 svoboda 277
void console_cursor_visibility(int show)
278
{
4160 jermar 279
	int cons_phone = console_phone_get(true);
4164 svoboda 280
 
281
	cbuffer_flush();
3768 svoboda 282
	async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
283
}
284
 
4168 svoboda 285
void 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
 
3767 svoboda 293
/** @}
294
 */