Subversion Repositories HelenOS

Rev

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

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