Subversion Repositories HelenOS

Rev

Rev 4201 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3767 svoboda 1
/*
4156 trochtova 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>
4156 trochtova 40
#include <ipc/services.h>
4201 trochtova 41
#include <errno.h>
42
#include <string.h>
3767 svoboda 43
#include <console.h>
44
 
4156 trochtova 45
static int console_phone = -1;
46
 
4201 trochtova 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);
4296 trochtova 60
static void cons_putchar(wchar_t c);
4201 trochtova 61
 
62
static void cbuffer_flush(void);
63
static void cbuffer_drain(void);
4296 trochtova 64
static inline void cbuffer_putc(int c);
4201 trochtova 65
 
66
 
67
void console_open(bool blocking)
4156 trochtova 68
{
69
    if (console_phone < 0) {
4201 trochtova 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
        }
4156 trochtova 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
 
4201 trochtova 92
int console_phone_get(bool blocking)
4156 trochtova 93
{
94
    if (console_phone < 0)
4201 trochtova 95
        console_open(blocking);
4156 trochtova 96
 
97
    return console_phone;
98
}
99
 
100
void console_wait(void)
101
{
102
    while (console_phone < 0)
4201 trochtova 103
        console_open(true);
4156 trochtova 104
}
105
 
3768 svoboda 106
void console_clear(void)
107
{
4201 trochtova 108
    int cons_phone = console_phone_get(true);
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
{
4201 trochtova 116
    int cons_phone = console_phone_get(true);
117
 
118
    cbuffer_flush();
3768 svoboda 119
    async_msg_2(cons_phone, CONSOLE_GOTO, row, col);
120
}
121
 
4296 trochtova 122
void console_putchar(wchar_t c)
4156 trochtova 123
{
4296 trochtova 124
//  cbuffer_putc(c);
125
    cbuffer_flush();
126
    cons_putchar(c);
4201 trochtova 127
}
128
 
129
/** Write all data from output buffer to the console. */
130
static 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. */
149
static void cbuffer_drain(void)
150
{
151
    cbp = cbuffer;
152
}
153
 
154
/** Write one character to the output buffer. */
155
static 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. */
4296 trochtova 167
static void cons_putchar(wchar_t c)
4201 trochtova 168
{
169
    int cons_phone = console_phone_get(true);
4156 trochtova 170
    async_msg_1(cons_phone, CONSOLE_PUTCHAR, c);
171
}
172
 
4201 trochtova 173
/** Write characters to the console via IPC. */
174
static 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. */
202
ssize_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. */
217
void console_putstr(const char *s)
218
{
219
    size_t len;
220
    ssize_t rc;
221
 
4296 trochtova 222
    len = str_size(s);
4201 trochtova 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. */
3768 svoboda 233
void console_flush(void)
234
{
4201 trochtova 235
    int cons_phone = console_phone_get(false);
236
 
237
    cbuffer_flush();
3768 svoboda 238
    async_msg_0(cons_phone, CONSOLE_FLUSH);
239
}
240
 
4296 trochtova 241
void console_flush_optional(void)
242
{
243
    if (console_phone >= 0)
244
        console_flush();
245
}
246
 
3768 svoboda 247
int console_get_size(int *rows, int *cols)
248
{
4201 trochtova 249
    int cons_phone = console_phone_get(true);
3768 svoboda 250
    ipcarg_t r, c;
251
    int rc;
252
 
253
    rc = async_req_0_2(cons_phone, CONSOLE_GETSIZE, &r, &c);
254
 
255
    *rows = (int) r;
256
    *cols = (int) c;
257
 
258
    return rc;
259
}
260
 
3767 svoboda 261
void console_set_style(int style)
262
{
4201 trochtova 263
    int cons_phone = console_phone_get(true);
264
 
265
    cbuffer_flush();
3767 svoboda 266
    async_msg_1(cons_phone, CONSOLE_SET_STYLE, style);
267
}
268
 
269
void console_set_color(int fg_color, int bg_color, int flags)
270
{
4201 trochtova 271
    int cons_phone = console_phone_get(true);
272
 
273
    cbuffer_flush();
3767 svoboda 274
    async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
275
}
276
 
277
void console_set_rgb_color(int fg_color, int bg_color)
278
{
4201 trochtova 279
    int cons_phone = console_phone_get(true);
280
 
281
    cbuffer_flush();
3767 svoboda 282
    async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
283
}
284
 
3768 svoboda 285
void console_cursor_visibility(int show)
286
{
4201 trochtova 287
    int cons_phone = console_phone_get(true);
288
 
289
    cbuffer_flush();
3768 svoboda 290
    async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
291
}
292
 
4201 trochtova 293
void console_kcon_enable(void)
294
{
295
    int cons_phone = console_phone_get(true);
296
 
297
    cbuffer_flush();
298
    async_msg_0(cons_phone, CONSOLE_KCON_ENABLE);
299
}
300
 
3767 svoboda 301
/** @}
302
 */