Subversion Repositories HelenOS

Rev

Rev 4317 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4317 Rev 4482
Line 34... Line 34...
34
/** @file
34
/** @file
35
 */
35
 */
36
 
36
 
37
#include <libc.h>
37
#include <libc.h>
38
#include <async.h>
38
#include <async.h>
39
#include <io/stream.h>
39
#include <io/console.h>
40
#include <ipc/console.h>
40
#include <ipc/console.h>
41
#include <ipc/services.h>
-
 
42
#include <errno.h>
-
 
43
#include <string.h>
-
 
44
#include <console.h>
-
 
45
 
41
 
46
static int console_phone = -1;
-
 
47
 
-
 
48
/** Size of cbuffer. */
-
 
49
#define CBUFFER_SIZE  256
-
 
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
 
-
 
61
/** Write one character to the console via IPC. */
-
 
62
static void cons_putchar(wchar_t c)
42
void console_clear(int phone)
63
{
43
{
64
    console_wait();
-
 
65
    async_msg_1(console_phone, CONSOLE_PUTCHAR, c);
44
    async_msg_0(phone, CONSOLE_CLEAR);
66
}
45
}
67
 
46
 
68
/** Write characters to the console via IPC or to klog */
-
 
69
static ssize_t cons_write(const char *buf, size_t size)
47
int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)
70
{
48
{
71
    console_open(false);
-
 
72
   
-
 
73
    if (console_phone >= 0) {
-
 
74
        async_serialize_start();
-
 
75
       
-
 
76
        ipc_call_t answer;
-
 
77
        aid_t req = async_send_0(console_phone, CONSOLE_WRITE, &answer);
49
    return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols);
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;
-
 
84
        }
-
 
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);
-
 
95
}
50
}
96
 
51
 
97
/** Write all data from output buffer to the console. */
52
void console_set_style(int phone, int style)
98
static void cbuffer_flush(void)
-
 
99
{
53
{
100
    size_t len = cbp - cbuffer;
-
 
101
   
-
 
102
    while (len > 0) {
-
 
103
        ssize_t rc = cons_write(cbuffer, cbp - cbuffer);
54
    async_msg_1(phone, CONSOLE_SET_STYLE, style);
104
        if (rc < 0)
-
 
105
            return;
-
 
106
       
-
 
107
        len -= rc;
-
 
108
    }
-
 
109
   
-
 
110
    cbp = cbuffer;
-
 
111
}
55
}
112
 
56
 
113
/** Drop all data in console output buffer. */
57
void console_set_color(int phone, int fg_color, int bg_color, int flags)
114
static void cbuffer_drain(void)
-
 
115
{
58
{
116
    cbp = cbuffer;
59
    async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
117
}
60
}
118
 
61
 
119
/** Write one character to the output buffer. */
62
void console_set_rgb_color(int phone, int fg_color, int bg_color)
120
static inline void cbuffer_putc(char c)
-
 
121
{
63
{
122
    if (cbp == cbuffer_end)
64
    async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
123
        cbuffer_flush();
-
 
124
   
-
 
125
    *cbp++ = c;
-
 
126
   
-
 
127
    if (c == '\n')
-
 
128
        cbuffer_flush();
-
 
129
}
65
}
130
 
66
 
131
int console_open(bool blocking)
67
void console_cursor_visibility(int phone, bool show)
132
{
68
{
133
    if (console_phone < 0) {
-
 
134
        int phone;
-
 
135
       
-
 
136
        if (blocking)
-
 
137
            phone = ipc_connect_me_to_blocking(PHONE_NS,
69
    async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
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
    }
-
 
146
   
-
 
147
    return console_phone;
-
 
148
}
70
}
149
 
71
 
150
void console_close(void)
72
void console_kcon_enable(int phone)
151
{
73
{
152
    if (console_phone >= 0) {
-
 
153
        if (ipc_hangup(console_phone) == 0)
74
    async_msg_0(phone, CONSOLE_KCON_ENABLE);
154
            console_phone = -1;
-
 
155
    }
-
 
156
}
75
}
157
 
76
 
158
void console_wait(void)
77
void console_goto(int phone, ipcarg_t row, ipcarg_t col)
159
{
78
{
160
    while (console_phone < 0)
79
    async_msg_2(phone, CONSOLE_GOTO, row, col);
161
        console_open(true);
-
 
162
}
80
}
163
 
81
 
164
void console_clear(void)
82
bool console_get_event(int phone, console_event_t *event)
165
{
83
{
166
    console_wait();
84
    ipcarg_t type;
167
    cbuffer_drain();
-
 
168
    async_msg_0(console_phone, CONSOLE_CLEAR);
-
 
169
}
-
 
170
 
-
 
171
int console_get_size(int *rows, int *cols)
-
 
172
{
-
 
173
    console_wait();
85
    ipcarg_t key;
174
   
-
 
175
    ipcarg_t r;
86
    ipcarg_t mods;
176
    ipcarg_t c;
87
    ipcarg_t c;
177
    int rc = async_req_0_2(console_phone, CONSOLE_GETSIZE, &r, &c);
-
 
178
   
-
 
179
    *rows = (int) r;
-
 
180
    *cols = (int) c;
-
 
181
   
-
 
182
    return rc;
-
 
183
}
-
 
184
 
-
 
185
void console_set_style(int style)
-
 
186
{
-
 
187
    console_wait();
-
 
188
    cbuffer_flush();
-
 
189
    async_msg_1(console_phone, CONSOLE_SET_STYLE, style);
-
 
190
}
-
 
191
 
-
 
192
void console_set_color(int fg_color, int bg_color, int flags)
-
 
193
{
-
 
194
    console_wait();
-
 
195
    cbuffer_flush();
-
 
196
    async_msg_3(console_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
-
 
197
}
-
 
198
 
-
 
199
void console_set_rgb_color(int fg_color, int bg_color)
-
 
200
{
-
 
201
    console_wait();
-
 
202
    cbuffer_flush();
-
 
203
    async_msg_2(console_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
-
 
204
}
-
 
205
 
-
 
206
void console_cursor_visibility(int show)
-
 
207
{
-
 
208
    console_wait();
-
 
209
    cbuffer_flush();
-
 
210
    async_msg_1(console_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
-
 
211
}
-
 
212
 
-
 
213
void console_kcon_enable(void)
-
 
214
{
-
 
215
    console_wait();
-
 
216
    cbuffer_flush();
-
 
217
    async_msg_0(console_phone, CONSOLE_KCON_ENABLE);
-
 
218
}
-
 
219
 
-
 
220
void console_goto(int row, int col)
-
 
221
{
-
 
222
    console_wait();
-
 
223
    cbuffer_flush();
-
 
224
    async_msg_2(console_phone, CONSOLE_GOTO, row, col);
-
 
225
}
-
 
226
 
-
 
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
   
88
   
-
 
89
    int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
-
 
90
    if (rc < 0)
244
    return size;
91
        return false;
245
}
92
   
246
 
-
 
247
/** Write a NULL-terminated string to the console. */
93
    event->type = type;
248
void console_putstr(const char *str)
94
    event->key = key;
249
{
-
 
250
    size_t left = str_size(str);
95
    event->mods = mods;
-
 
96
    event->c = c;
251
   
97
   
252
    while (left > 0) {
-
 
253
        ssize_t rc = console_write(str, left);
-
 
254
       
-
 
255
        if (rc < 0) {
-
 
256
            /* Error */
-
 
257
            return;
98
    return true;
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
}
99
}
272
 
100
 
273
/** @}
101
/** @}
274
 */
102
 */