Subversion Repositories HelenOS

Rev

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