Subversion Repositories HelenOS

Rev

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

Rev 4347 Rev 4348
Line 46... Line 46...
46
#include <async.h>
46
#include <async.h>
47
#include <libadt/fifo.h>
47
#include <libadt/fifo.h>
48
#include <screenbuffer.h>
48
#include <screenbuffer.h>
49
#include <sys/mman.h>
49
#include <sys/mman.h>
50
#include <stdio.h>
50
#include <stdio.h>
-
 
51
#include <string.h>
51
#include <sysinfo.h>
52
#include <sysinfo.h>
52
#include <event.h>
53
#include <event.h>
53
 
54
 
54
#include "console.h"
55
#include "console.h"
55
#include "gcons.h"
56
#include "gcons.h"
Line 61... Line 62...
61
/** Index of currently used virtual console.
62
/** Index of currently used virtual console.
62
 */
63
 */
63
int active_console = 0;
64
int active_console = 0;
64
int prev_console = 0;
65
int prev_console = 0;
65
 
66
 
-
 
67
/** Phone to the keyboard driver. */
-
 
68
static int kbd_phone;
-
 
69
 
66
/** Information about framebuffer */
70
/** Information about framebuffer */
67
struct {
71
struct {
68
    int phone;      /**< Framebuffer phone */
72
    int phone;      /**< Framebuffer phone */
69
    ipcarg_t rows;      /**< Framebuffer rows */
73
    ipcarg_t rows;      /**< Framebuffer rows */
70
    ipcarg_t cols;      /**< Framebuffer columns */
74
    ipcarg_t cols;      /**< Framebuffer columns */
Line 101... Line 105...
101
#define CWRITE_BUF_SIZE 256
105
#define CWRITE_BUF_SIZE 256
102
 
106
 
103
/** Buffer for receiving data via the CONSOLE_WRITE call from the client. */
107
/** Buffer for receiving data via the CONSOLE_WRITE call from the client. */
104
static char cwrite_buf[CWRITE_BUF_SIZE];
108
static char cwrite_buf[CWRITE_BUF_SIZE];
105
 
109
 
106
static void fb_putchar(char c, int row, int col);
110
static void fb_putchar(wchar_t c, int row, int col);
107
 
111
 
108
 
112
 
109
/** Find unused virtual console.
113
/** Find unused virtual console.
110
 *
114
 *
111
 */
115
 */
Line 138... Line 142...
138
static void curs_goto(int row, int col)
142
static void curs_goto(int row, int col)
139
{
143
{
140
    async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
144
    async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
141
}
145
}
142
 
146
 
-
 
147
static void screen_yield(void)
-
 
148
{
-
 
149
    ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_YIELD);
-
 
150
}
-
 
151
 
-
 
152
static void screen_reclaim(void)
-
 
153
{
-
 
154
    ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
-
 
155
}
-
 
156
 
-
 
157
static void kbd_yield(void)
-
 
158
{
-
 
159
    ipc_call_sync_0_0(kbd_phone, KBD_YIELD);
-
 
160
}
-
 
161
 
-
 
162
static void kbd_reclaim(void)
-
 
163
{
-
 
164
    ipc_call_sync_0_0(kbd_phone, KBD_RECLAIM);
-
 
165
}
-
 
166
 
143
static void set_style(int style)
167
static void set_style(int style)
144
{
168
{
145
    async_msg_1(fb_info.phone, FB_SET_STYLE, style);
169
    async_msg_1(fb_info.phone, FB_SET_STYLE, style);
146
}
170
}
147
 
171
 
Line 195... Line 219...
195
    } else {
219
    } else {
196
        rc = ENOTSUP;
220
        rc = ENOTSUP;
197
    }
221
    }
198
 
222
 
199
    if (rc != 0) {
223
    if (rc != 0) {
-
 
224
        /*
200
        attrs = &conn->screenbuffer.attrs;
225
        attrs = &conn->screenbuffer.attrs;
201
 
226
 
202
        for (j = 0; j < h; j++) {
227
        for (j = 0; j < h; j++) {
203
            for (i = 0; i < w; i++) {
228
            for (i = 0; i < w; i++) {
204
                field = get_field_at(&conn->screenbuffer,
229
                field = get_field_at(&conn->screenbuffer,
Line 207... Line 232...
207
                    set_attrs(&field->attrs);
232
                    set_attrs(&field->attrs);
208
                attrs = &field->attrs;
233
                attrs = &field->attrs;
209
 
234
 
210
                fb_putchar(field->character, y + j, x + i);
235
                fb_putchar(field->character, y + j, x + i);
211
            }
236
            }
212
        }
237
        }*/
213
    }
238
    }
214
}
239
}
215
 
240
 
216
/** Flush pending cells to FB. */
241
/** Flush pending cells to FB. */
217
static void fb_pending_flush(void)
242
static void fb_pending_flush(void)
Line 249... Line 274...
249
    ++fb_pending.n;
274
    ++fb_pending.n;
250
}
275
}
251
 
276
 
252
 
277
 
253
/** Print a character to the active VC with buffering. */
278
/** Print a character to the active VC with buffering. */
254
static void fb_putchar(char c, int row, int col)
279
static void fb_putchar(wchar_t c, int row, int col)
255
{
280
{
256
    async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
281
    async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
257
}
282
}
258
 
283
 
259
/** Process a character from the client (TTY emulation). */
284
/** Process a character from the client (TTY emulation). */
260
static void write_char(int console, char key)
285
static void write_char(int console, wchar_t ch)
261
{
286
{
262
    bool flush_cursor = false;
287
    bool flush_cursor = false;
263
    screenbuffer_t *scr = &(connections[console].screenbuffer);
288
    screenbuffer_t *scr = &(connections[console].screenbuffer);
264
 
289
 
265
    switch (key) {
290
    switch (ch) {
266
    case '\n':
291
    case '\n':
267
        fb_pending_flush();
292
        fb_pending_flush();
268
        flush_cursor = true;
293
        flush_cursor = true;
269
        scr->position_y++;
294
        scr->position_y++;
270
        scr->position_x = 0;
295
        scr->position_x = 0;
Line 285... Line 310...
285
        break;
310
        break;
286
    default:   
311
    default:   
287
        if (console == active_console)
312
        if (console == active_console)
288
            cell_mark_changed(scr->position_y, scr->position_x);
313
            cell_mark_changed(scr->position_y, scr->position_x);
289
 
314
 
290
        screenbuffer_putchar(scr, key);
315
        screenbuffer_putchar(scr, ch);
291
        scr->position_x++;
316
        scr->position_x++;
292
    }
317
    }
293
 
318
 
294
    if (scr->position_x >= scr->size_x) {
319
    if (scr->position_x >= scr->size_x) {
295
        flush_cursor = true;
320
        flush_cursor = true;
Line 326... Line 351...
326
 
351
 
327
    if (newcons == KERNEL_CONSOLE) {
352
    if (newcons == KERNEL_CONSOLE) {
328
        async_serialize_start();
353
        async_serialize_start();
329
        curs_hide_sync();
354
        curs_hide_sync();
330
        gcons_in_kernel();
355
        gcons_in_kernel();
-
 
356
        screen_yield();
-
 
357
        kbd_yield();
331
        async_serialize_end();
358
        async_serialize_end();
-
 
359
 
332
       
360
       
333
        if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
361
        if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
334
            prev_console = active_console;
362
            prev_console = active_console;
335
            active_console = KERNEL_CONSOLE;
363
            active_console = KERNEL_CONSOLE;
336
        } else
364
        } else
Line 338... Line 366...
338
    }
366
    }
339
   
367
   
340
    if (newcons != KERNEL_CONSOLE) {
368
    if (newcons != KERNEL_CONSOLE) {
341
        async_serialize_start();
369
        async_serialize_start();
342
       
370
       
343
        if (active_console == KERNEL_CONSOLE)
371
        if (active_console == KERNEL_CONSOLE) {
-
 
372
            screen_reclaim();
-
 
373
            kbd_reclaim();
344
            gcons_redraw_console();
374
            gcons_redraw_console();
-
 
375
        }
345
       
376
       
346
        active_console = newcons;
377
        active_console = newcons;
347
        gcons_change_console(newcons);
378
        gcons_change_console(newcons);
348
        conn = &connections[active_console];
379
        conn = &connections[active_console];
349
       
380
       
Line 432... Line 463...
432
            /* switch to another virtual console */
463
            /* switch to another virtual console */
433
           
464
           
434
            conn = &connections[active_console];
465
            conn = &connections[active_console];
435
 
466
 
436
            if ((ev.key >= KC_F1) && (ev.key < KC_F1 +
467
            if ((ev.key >= KC_F1) && (ev.key < KC_F1 +
437
                CONSOLE_COUNT)) {
468
                CONSOLE_COUNT) && ((ev.mods & KM_CTRL) == 0)) {
438
                if (ev.key == KC_F12)
469
                if (ev.key == KC_F12)
439
                    change_console(KERNEL_CONSOLE);
470
                    change_console(KERNEL_CONSOLE);
440
                else
471
                else
441
                    change_console(ev.key - KC_F1);
472
                    change_console(ev.key - KC_F1);
442
                break;
473
                break;
Line 463... Line 494...
463
 
494
 
464
/** Handle CONSOLE_WRITE call. */
495
/** Handle CONSOLE_WRITE call. */
465
static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request)
496
static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request)
466
{
497
{
467
    ipc_callid_t callid;
498
    ipc_callid_t callid;
468
    size_t len;
499
    size_t size;
-
 
500
    wchar_t ch;
469
    size_t i;
501
    size_t off;
470
 
502
 
471
    if (!ipc_data_write_receive(&callid, &len)) {
503
    if (!ipc_data_write_receive(&callid, &size)) {
472
        ipc_answer_0(callid, EINVAL);
504
        ipc_answer_0(callid, EINVAL);
473
        ipc_answer_0(rid, EINVAL);
505
        ipc_answer_0(rid, EINVAL);
474
    }
506
    }
475
 
507
 
476
    if (len > CWRITE_BUF_SIZE)
508
    if (size > CWRITE_BUF_SIZE)
477
        len = CWRITE_BUF_SIZE;
509
        size = CWRITE_BUF_SIZE;
478
 
510
 
479
    (void) ipc_data_write_finalize(callid, cwrite_buf, len);
511
    (void) ipc_data_write_finalize(callid, cwrite_buf, size);
480
 
512
 
-
 
513
    off = 0;
481
    for (i = 0; i < len; i++) {
514
    while (off < size) {
-
 
515
        ch = str_decode(cwrite_buf, &off, size);
482
        write_char(consnum, cwrite_buf[i]);
516
        write_char(consnum, ch);
483
    }
517
    }
484
 
518
 
485
    gcons_notify_char(consnum);
519
    gcons_notify_char(consnum);
486
    ipc_answer_1(rid, EOK, len);
520
    ipc_answer_1(rid, EOK, size);
487
}
521
}
488
 
522
 
489
/** Default thread for new connections */
523
/** Default thread for new connections */
490
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
524
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
491
{
525
{
Line 505... Line 539...
505
   
539
   
506
    async_serialize_start();
540
    async_serialize_start();
507
    gcons_notify_connect(consnum);
541
    gcons_notify_connect(consnum);
508
    conn->client_phone = IPC_GET_ARG5(*icall);
542
    conn->client_phone = IPC_GET_ARG5(*icall);
509
    screenbuffer_clear(&conn->screenbuffer);
543
    screenbuffer_clear(&conn->screenbuffer);
-
 
544
    if (consnum == active_console)
-
 
545
        clrscr();
510
   
546
   
511
    /* Accept the connection */
547
    /* Accept the connection */
512
    ipc_answer_0(iid, EOK);
548
    ipc_answer_0(iid, EOK);
513
   
549
   
514
    while (1) {
550
    while (1) {
Line 642... Line 678...
642
int main(int argc, char *argv[])
678
int main(int argc, char *argv[])
643
{
679
{
644
    printf(NAME ": HelenOS Console service\n");
680
    printf(NAME ": HelenOS Console service\n");
645
   
681
   
646
    ipcarg_t phonehash;
682
    ipcarg_t phonehash;
647
    int kbd_phone;
-
 
648
    size_t ib_size;
683
    size_t ib_size;
649
    int i;
684
    int i;
650
   
685
   
651
    async_set_client_connection(client_connection);
686
    async_set_client_connection(client_connection);
652
   
687