Subversion Repositories HelenOS

Rev

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

Rev 4148 Rev 4164
Line 87... Line 87...
87
                         * consoles */
87
                         * consoles */
88
static keyfield_t *interbuffer = NULL;      /**< Pointer to memory shared
88
static keyfield_t *interbuffer = NULL;      /**< Pointer to memory shared
89
                         * with framebufer used for
89
                         * with framebufer used for
90
                         * faster virtual console
90
                         * faster virtual console
91
                         * switching */
91
                         * switching */
-
 
92
/** Size of fb_buf. */
-
 
93
#define FB_BUF_SIZE 256
-
 
94
 
-
 
95
/** Buffer for sending characters to FB driver. */
-
 
96
static char fb_buf[FB_BUF_SIZE];
-
 
97
 
-
 
98
/* Properties of fb_buf data. */
-
 
99
static int fb_buf_row;      /**< Row where fb_buf data belong. */
-
 
100
static int fb_buf_col;      /**< Column where fb_buf data start. */
-
 
101
static int fb_console;      /**< VC to which fb_buf data belong. */
-
 
102
int fb_bi = 0;          /**< Number of valid chars in fb_buf. */
-
 
103
 
-
 
104
/** Size of cwrite_buf. */
-
 
105
#define CWRITE_BUF_SIZE 256
-
 
106
 
-
 
107
/** Buffer for receiving data via the CONSOLE_WRITE call from the client. */
-
 
108
static char cwrite_buf[CWRITE_BUF_SIZE];
92
 
109
 
93
 
110
 
94
/** Find unused virtual console.
111
/** Find unused virtual console.
95
 *
112
 *
96
 */
113
 */
Line 156... Line 173...
156
        set_rgb_color(attrs->a.r.fg_color, attrs->a.r.bg_color);
173
        set_rgb_color(attrs->a.r.fg_color, attrs->a.r.bg_color);
157
        break;
174
        break;
158
    }
175
    }
159
}
176
}
160
 
177
 
-
 
178
/** Write a character vector to FB driver via IPC. */
-
 
179
static ssize_t fb_write(const char *buf, size_t nbyte, int row, int col)
-
 
180
{
-
 
181
    ipcarg_t rc;
-
 
182
    ipc_call_t answer;
-
 
183
    aid_t req;
-
 
184
 
-
 
185
    async_serialize_start();
-
 
186
   
-
 
187
    req = async_send_2(fb_info.phone, FB_WRITE, row, col, &answer);
-
 
188
    rc = ipc_data_write_start(fb_info.phone, (void *) buf, nbyte);
-
 
189
 
-
 
190
    if (rc != EOK) {
-
 
191
        async_wait_for(req, NULL);
-
 
192
        async_serialize_end();
-
 
193
        return (ssize_t) rc;
-
 
194
    }
-
 
195
 
-
 
196
    async_wait_for(req, &rc);
-
 
197
    async_serialize_end();
-
 
198
 
-
 
199
    if (rc == EOK)
-
 
200
        return (ssize_t) IPC_GET_ARG1(answer);
-
 
201
    else
-
 
202
        return -1;
-
 
203
}
-
 
204
 
-
 
205
/** Flush buffered characters to FB. */
-
 
206
static void fb_buf_flush(void)
-
 
207
{
-
 
208
    screenbuffer_t *scr;
-
 
209
    int i;
-
 
210
 
-
 
211
    scr = &(connections[fb_console].screenbuffer);
-
 
212
 
-
 
213
    if (fb_bi > 0) {
-
 
214
        if (fb_write(fb_buf, fb_bi, fb_buf_row, fb_buf_col) < 0) {
-
 
215
            /* Try falling back to char-by-char. */
-
 
216
            for (i = 0; i < fb_bi; i++) {
-
 
217
                async_msg_3(fb_info.phone, FB_PUTCHAR, fb_buf[i],
-
 
218
                    fb_buf_row, fb_buf_col + i);
-
 
219
            }
-
 
220
        }
-
 
221
        fb_bi = 0;
-
 
222
    }
-
 
223
}
-
 
224
 
-
 
225
/** Print a character to the active VC with buffering. */
161
static void prtchr(char c, int row, int col)
226
static void prtchr(char c, int row, int col)
162
{
227
{
-
 
228
    if (fb_bi >= FB_BUF_SIZE)
-
 
229
        fb_buf_flush();
-
 
230
 
-
 
231
    if (fb_bi == 0) {
-
 
232
        fb_buf_row = row;
-
 
233
        fb_buf_col = col;
163
    async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
234
        fb_console = active_console;
-
 
235
    }
-
 
236
 
-
 
237
    fb_buf[fb_bi++] = c;
164
}
238
}
165
 
239
 
166
/** Check key and process special keys.
240
/** Check key and process special keys.
167
 *
241
 *
168
 *
242
 *
169
 */
243
 */
170
static void write_char(int console, char key)
244
static void write_char(int console, char key)
171
{
245
{
-
 
246
    bool flush_cursor = false;
172
    screenbuffer_t *scr = &(connections[console].screenbuffer);
247
    screenbuffer_t *scr = &(connections[console].screenbuffer);
173
   
248
 
174
    switch (key) {
249
    switch (key) {
175
    case '\n':
250
    case '\n':
-
 
251
        fb_buf_flush();
-
 
252
        flush_cursor = true;
176
        scr->position_y++;
253
        scr->position_y++;
177
        scr->position_x = 0;
254
        scr->position_x = 0;
178
        break;
255
        break;
179
    case '\r':
256
    case '\r':
-
 
257
        fb_buf_flush();
180
        break;
258
        break;
181
    case '\t':
259
    case '\t':
-
 
260
        fb_buf_flush();
182
        scr->position_x += 8;
261
        scr->position_x += 8;
183
        scr->position_x -= scr->position_x % 8;
262
        scr->position_x -= scr->position_x % 8;
184
        break;
263
        break;
185
    case '\b':
264
    case '\b':
-
 
265
        fb_buf_flush();
186
        if (scr->position_x == 0)
266
        if (scr->position_x == 0)
187
            break;
267
            break;
188
        scr->position_x--;
268
        scr->position_x--;
189
        if (console == active_console)
269
        if (console == active_console)
190
            prtchr(' ', scr->position_y, scr->position_x);
270
            prtchr(' ', scr->position_y, scr->position_x);
Line 195... Line 275...
195
            prtchr(key, scr->position_y, scr->position_x);
275
            prtchr(key, scr->position_y, scr->position_x);
196
 
276
 
197
        screenbuffer_putchar(scr, key);
277
        screenbuffer_putchar(scr, key);
198
        scr->position_x++;
278
        scr->position_x++;
199
    }
279
    }
200
   
280
 
201
    scr->position_y += (scr->position_x >= scr->size_x);
281
    if (scr->position_x >= scr->size_x) {
-
 
282
        fb_buf_flush();
-
 
283
        flush_cursor = true;
-
 
284
        scr->position_y++;
-
 
285
    }
202
   
286
   
203
    if (scr->position_y >= scr->size_y) {
287
    if (scr->position_y >= scr->size_y) {
204
        scr->position_y = scr->size_y - 1;
288
        scr->position_y = scr->size_y - 1;
205
        screenbuffer_clear_line(scr, scr->top_line);
289
        screenbuffer_clear_line(scr, scr->top_line);
206
        scr->top_line = (scr->top_line + 1) % scr->size_y;
290
        scr->top_line = (scr->top_line + 1) % scr->size_y;
207
        if (console == active_console)
291
        if (console == active_console)
208
            async_msg_1(fb_info.phone, FB_SCROLL, 1);
292
            async_msg_1(fb_info.phone, FB_SCROLL, 1);
209
    }
293
    }
210
   
294
 
211
    scr->position_x = scr->position_x % scr->size_x;
295
    scr->position_x = scr->position_x % scr->size_x;
212
   
296
 
213
    if (console == active_console)
297
    if (console == active_console && flush_cursor)
214
        curs_goto(scr->position_y, scr->position_x);
298
        curs_goto(scr->position_y, scr->position_x);
215
   
-
 
216
}
299
}
217
 
300
 
218
/** Switch to new console */
301
/** Switch to new console */
219
static void change_console(int newcons)
302
static void change_console(int newcons)
220
{
303
{
Line 223... Line 306...
223
    keyfield_t *field;
306
    keyfield_t *field;
224
    attrs_t *attrs;
307
    attrs_t *attrs;
225
   
308
   
226
    if (newcons == active_console)
309
    if (newcons == active_console)
227
        return;
310
        return;
-
 
311
 
-
 
312
    fb_buf_flush();
228
   
313
 
229
    if (newcons == KERNEL_CONSOLE) {
314
    if (newcons == KERNEL_CONSOLE) {
230
        async_serialize_start();
315
        async_serialize_start();
231
        curs_hide_sync();
316
        curs_hide_sync();
232
        gcons_in_kernel();
317
        gcons_in_kernel();
233
        async_serialize_end();
318
        async_serialize_end();
Line 358... Line 443...
358
        }
443
        }
359
        ipc_answer_0(callid, retval);
444
        ipc_answer_0(callid, retval);
360
    }
445
    }
361
}
446
}
362
 
447
 
-
 
448
/** Handle CONSOLE_WRITE call. */
-
 
449
static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request)
-
 
450
{
-
 
451
    ipc_callid_t callid;
-
 
452
    size_t len;
-
 
453
    size_t i;
-
 
454
 
-
 
455
    if (!ipc_data_write_receive(&callid, &len)) {
-
 
456
        ipc_answer_0(callid, EINVAL);
-
 
457
        ipc_answer_0(rid, EINVAL);
-
 
458
    }
-
 
459
 
-
 
460
    if (len > CWRITE_BUF_SIZE)
-
 
461
        len = CWRITE_BUF_SIZE;
-
 
462
 
-
 
463
    (void) ipc_data_write_finalize(callid, cwrite_buf, len);
-
 
464
 
-
 
465
    for (i = 0; i < len; i++) {
-
 
466
        write_char(consnum, cwrite_buf[i]);
-
 
467
    }
-
 
468
 
-
 
469
    gcons_notify_char(consnum);
-
 
470
    ipc_answer_1(rid, EOK, len);
-
 
471
}
-
 
472
 
363
/** Default thread for new connections */
473
/** Default thread for new connections */
364
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
474
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
365
{
475
{
366
    ipc_callid_t callid;
476
    ipc_callid_t callid;
367
    ipc_call_t call;
477
    ipc_call_t call;
Line 409... Line 519...
409
            return;
519
            return;
410
        case CONSOLE_PUTCHAR:
520
        case CONSOLE_PUTCHAR:
411
            write_char(consnum, IPC_GET_ARG1(call));
521
            write_char(consnum, IPC_GET_ARG1(call));
412
            gcons_notify_char(consnum);
522
            gcons_notify_char(consnum);
413
            break;
523
            break;
-
 
524
        case CONSOLE_WRITE:
-
 
525
            cons_write(consnum, callid, &call);
-
 
526
            continue;
414
        case CONSOLE_CLEAR:
527
        case CONSOLE_CLEAR:
415
            /* Send message to fb */
528
            /* Send message to fb */
416
            if (consnum == active_console) {
529
            if (consnum == active_console) {
417
                async_msg_0(fb_info.phone, FB_CLEAR);
530
                async_msg_0(fb_info.phone, FB_CLEAR);
418
            }
531
            }
419
           
532
           
420
            screenbuffer_clear(&conn->screenbuffer);
533
            screenbuffer_clear(&conn->screenbuffer);
421
           
534
           
422
            break;
535
            break;
423
        case CONSOLE_GOTO:
536
        case CONSOLE_GOTO:
-
 
537
            fb_buf_flush();
424
            screenbuffer_goto(&conn->screenbuffer,
538
            screenbuffer_goto(&conn->screenbuffer,
425
                IPC_GET_ARG2(call), IPC_GET_ARG1(call));
539
                IPC_GET_ARG2(call), IPC_GET_ARG1(call));
426
            if (consnum == active_console)
540
            if (consnum == active_console)
427
                curs_goto(IPC_GET_ARG1(call),
541
                curs_goto(IPC_GET_ARG1(call),
428
                    IPC_GET_ARG2(call));
542
                    IPC_GET_ARG2(call));
Line 430... Line 544...
430
        case CONSOLE_GETSIZE:
544
        case CONSOLE_GETSIZE:
431
            arg1 = fb_info.rows;
545
            arg1 = fb_info.rows;
432
            arg2 = fb_info.cols;
546
            arg2 = fb_info.cols;
433
            break;
547
            break;
434
        case CONSOLE_FLUSH:
548
        case CONSOLE_FLUSH:
-
 
549
            fb_buf_flush();
435
            if (consnum == active_console)
550
            if (consnum == active_console)
436
                async_req_0_0(fb_info.phone, FB_FLUSH);
551
                async_req_0_0(fb_info.phone, FB_FLUSH);
437
            break;
552
            break;
438
        case CONSOLE_SET_STYLE:
553
        case CONSOLE_SET_STYLE:
-
 
554
            fb_buf_flush();
439
            arg1 = IPC_GET_ARG1(call);
555
            arg1 = IPC_GET_ARG1(call);
440
            screenbuffer_set_style(&conn->screenbuffer, arg1);
556
            screenbuffer_set_style(&conn->screenbuffer, arg1);
441
            if (consnum == active_console)
557
            if (consnum == active_console)
442
                set_style(arg1);
558
                set_style(arg1);
443
            break;
559
            break;
444
        case CONSOLE_SET_COLOR:
560
        case CONSOLE_SET_COLOR:
-
 
561
            fb_buf_flush();
445
            arg1 = IPC_GET_ARG1(call);
562
            arg1 = IPC_GET_ARG1(call);
446
            arg2 = IPC_GET_ARG2(call);
563
            arg2 = IPC_GET_ARG2(call);
447
            arg3 = IPC_GET_ARG3(call);
564
            arg3 = IPC_GET_ARG3(call);
448
            screenbuffer_set_color(&conn->screenbuffer, arg1,
565
            screenbuffer_set_color(&conn->screenbuffer, arg1,
449
                arg2, arg3);
566
                arg2, arg3);
450
            if (consnum == active_console)
567
            if (consnum == active_console)
451
                set_color(arg1, arg2, arg3);
568
                set_color(arg1, arg2, arg3);
452
            break;
569
            break;
453
        case CONSOLE_SET_RGB_COLOR:
570
        case CONSOLE_SET_RGB_COLOR:
-
 
571
            fb_buf_flush();
454
            arg1 = IPC_GET_ARG1(call);
572
            arg1 = IPC_GET_ARG1(call);
455
            arg2 = IPC_GET_ARG2(call);
573
            arg2 = IPC_GET_ARG2(call);
456
            screenbuffer_set_rgb_color(&conn->screenbuffer, arg1,
574
            screenbuffer_set_rgb_color(&conn->screenbuffer, arg1,
457
                arg2);
575
                arg2);
458
            if (consnum == active_console)
576
            if (consnum == active_console)
459
                set_rgb_color(arg1, arg2);
577
                set_rgb_color(arg1, arg2);
460
            break;
578
            break;
461
        case CONSOLE_CURSOR_VISIBILITY:
579
        case CONSOLE_CURSOR_VISIBILITY:
-
 
580
            fb_buf_flush();
462
            arg1 = IPC_GET_ARG1(call);
581
            arg1 = IPC_GET_ARG1(call);
463
            conn->screenbuffer.is_cursor_visible = arg1;
582
            conn->screenbuffer.is_cursor_visible = arg1;
464
            if (consnum == active_console)
583
            if (consnum == active_console)
465
                curs_visibility(arg1);
584
                curs_visibility(arg1);
466
            break;
585
            break;