Rev 2479 | Rev 2566 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2479 | Rev 2539 | ||
---|---|---|---|
Line 65... | Line 65... | ||
65 | int phone; /**< Framebuffer phone */ |
65 | int phone; /**< Framebuffer phone */ |
66 | ipcarg_t rows; /**< Framebuffer rows */ |
66 | ipcarg_t rows; /**< Framebuffer rows */ |
67 | ipcarg_t cols; /**< Framebuffer columns */ |
67 | ipcarg_t cols; /**< Framebuffer columns */ |
68 | } fb_info; |
68 | } fb_info; |
69 | 69 | ||
70 | - | ||
71 | typedef struct { |
70 | typedef struct { |
72 | keybuffer_t keybuffer; /**< Buffer for incoming keys. */ |
71 | keybuffer_t keybuffer; /**< Buffer for incoming keys. */ |
73 | /** Buffer for unsatisfied request for keys. */ |
72 | /** Buffer for unsatisfied request for keys. */ |
74 | FIFO_CREATE_STATIC(keyrequests, ipc_callid_t, |
73 | FIFO_CREATE_STATIC(keyrequests, ipc_callid_t, |
75 | MAX_KEYREQUESTS_BUFFERED); |
74 | MAX_KEYREQUESTS_BUFFERED); |
Line 122... | Line 121... | ||
122 | } |
121 | } |
123 | 122 | ||
124 | static void set_style(style_t *style) |
123 | static void set_style(style_t *style) |
125 | { |
124 | { |
126 | async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, |
125 | async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, |
127 | style->bg_color); |
126 | style->bg_color); |
128 | } |
127 | } |
129 | 128 | ||
130 | static void set_style_col(int fgcolor, int bgcolor) |
129 | static void set_style_col(int fgcolor, int bgcolor) |
131 | { |
130 | { |
132 | async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); |
131 | async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); |
Line 258... | Line 257... | ||
258 | 257 | ||
259 | set_style(&conn->screenbuffer.style); |
258 | set_style(&conn->screenbuffer.style); |
260 | curs_visibility(0); |
259 | curs_visibility(0); |
261 | if (interbuffer) { |
260 | if (interbuffer) { |
262 | for (i = 0; i < conn->screenbuffer.size_x; i++) |
261 | for (i = 0; i < conn->screenbuffer.size_x; i++) |
263 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
262 | for (j = 0; j < conn->screenbuffer.size_y; j++) { |
- | 263 | unsigned int size_x; |
|
- | 264 | ||
264 | interbuffer[i + j * conn->screenbuffer.size_x] = |
265 | size_x = conn->screenbuffer.size_x; |
- | 266 | interbuffer[i + j * size_x] = |
|
265 | *get_field_at(&(conn->screenbuffer), |
267 | *get_field_at(&conn->screenbuffer, i, j); |
266 | i, j); |
268 | } |
267 | /* This call can preempt, but we are already at the end */ |
269 | /* This call can preempt, but we are already at the end */ |
268 | rc = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, |
270 | rc = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, |
269 | NULL); |
271 | NULL); |
270 | }; |
272 | } |
271 | 273 | ||
272 | if ((!interbuffer) || (rc != 0)) { |
274 | if ((!interbuffer) || (rc != 0)) { |
273 | set_style(&conn->screenbuffer.style); |
275 | set_style(&conn->screenbuffer.style); |
274 | clrscr(); |
276 | clrscr(); |
275 | style = &conn->screenbuffer.style; |
277 | style = &conn->screenbuffer.style; |
276 | 278 | ||
277 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
279 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
278 | for (i = 0; i < conn->screenbuffer.size_x; i++) { |
280 | for (i = 0; i < conn->screenbuffer.size_x; i++) { |
279 | field = get_field_at(&(conn->screenbuffer), i, |
281 | field = get_field_at(&conn->screenbuffer, i, |
280 | j); |
282 | j); |
281 | if (!style_same(*style, field->style)) |
283 | if (!style_same(*style, field->style)) |
282 | set_style(&field->style); |
284 | set_style(&field->style); |
283 | style = &field->style; |
285 | style = &field->style; |
284 | if ((field->character == ' ') && |
286 | if ((field->character == ' ') && |
285 | (style_same(field->style, |
287 | (style_same(field->style, |
286 | conn->screenbuffer.style))) |
288 | conn->screenbuffer.style))) |
287 | continue; |
289 | continue; |
288 | 290 | ||
289 | prtchr(field->character, j, i); |
291 | prtchr(field->character, j, i); |
290 | } |
292 | } |
291 | } |
293 | } |
292 | 294 | ||
293 | curs_goto(conn->screenbuffer.position_y, |
295 | curs_goto(conn->screenbuffer.position_y, |
294 | conn->screenbuffer.position_x); |
296 | conn->screenbuffer.position_x); |
295 | curs_visibility(conn->screenbuffer.is_cursor_visible); |
297 | curs_visibility(conn->screenbuffer.is_cursor_visible); |
296 | 298 | ||
297 | async_serialize_end(); |
299 | async_serialize_end(); |
298 | } |
300 | } |
299 | 301 | ||
Line 320... | Line 322... | ||
320 | change_console(newcon); |
322 | change_console(newcon); |
321 | retval = 0; |
323 | retval = 0; |
322 | break; |
324 | break; |
323 | case KBD_MS_MOVE: |
325 | case KBD_MS_MOVE: |
324 | gcons_mouse_move(IPC_GET_ARG1(call), |
326 | gcons_mouse_move(IPC_GET_ARG1(call), |
325 | IPC_GET_ARG2(call)); |
327 | IPC_GET_ARG2(call)); |
326 | retval = 0; |
328 | retval = 0; |
327 | break; |
329 | break; |
328 | case KBD_PUSHCHAR: |
330 | case KBD_PUSHCHAR: |
329 | /* got key from keyboard driver */ |
331 | /* got key from keyboard driver */ |
330 | 332 | ||
Line 347... | Line 349... | ||
347 | 349 | ||
348 | /* if client is awaiting key, send it */ |
350 | /* if client is awaiting key, send it */ |
349 | if (conn->keyrequest_counter > 0) { |
351 | if (conn->keyrequest_counter > 0) { |
350 | conn->keyrequest_counter--; |
352 | conn->keyrequest_counter--; |
351 | ipc_answer_fast(fifo_pop(conn->keyrequests), 0, |
353 | ipc_answer_fast(fifo_pop(conn->keyrequests), 0, |
352 | c, 0); |
354 | c, 0); |
353 | break; |
355 | break; |
354 | } |
356 | } |
355 | 357 | ||
356 | keybuffer_push(&conn->keybuffer, c); |
358 | keybuffer_push(&conn->keybuffer, c); |
357 | retval = 0; |
359 | retval = 0; |
Line 400... | Line 402... | ||
400 | 402 | ||
401 | /* Answer all pending requests */ |
403 | /* Answer all pending requests */ |
402 | while (conn->keyrequest_counter > 0) { |
404 | while (conn->keyrequest_counter > 0) { |
403 | conn->keyrequest_counter--; |
405 | conn->keyrequest_counter--; |
404 | ipc_answer_fast(fifo_pop(conn->keyrequests), |
406 | ipc_answer_fast(fifo_pop(conn->keyrequests), |
405 | ENOENT, 0, 0); |
407 | ENOENT, 0, 0); |
406 | break; |
408 | break; |
407 | } |
409 | } |
408 | conn->used = 0; |
410 | conn->used = 0; |
409 | return; |
411 | return; |
410 | case CONSOLE_PUTCHAR: |
412 | case CONSOLE_PUTCHAR: |
Line 420... | Line 422... | ||
420 | screenbuffer_clear(&conn->screenbuffer); |
422 | screenbuffer_clear(&conn->screenbuffer); |
421 | 423 | ||
422 | break; |
424 | break; |
423 | case CONSOLE_GOTO: |
425 | case CONSOLE_GOTO: |
424 | screenbuffer_goto(&conn->screenbuffer, |
426 | screenbuffer_goto(&conn->screenbuffer, |
425 | IPC_GET_ARG2(call), IPC_GET_ARG1(call)); |
427 | IPC_GET_ARG2(call), IPC_GET_ARG1(call)); |
426 | if (consnum == active_console) |
428 | if (consnum == active_console) |
427 | curs_goto(IPC_GET_ARG1(call), |
429 | curs_goto(IPC_GET_ARG1(call), |
428 | IPC_GET_ARG2(call)); |
430 | IPC_GET_ARG2(call)); |
429 | break; |
431 | break; |
430 | case CONSOLE_GETSIZE: |
432 | case CONSOLE_GETSIZE: |
431 | arg1 = fb_info.rows; |
433 | arg1 = fb_info.rows; |
432 | arg2 = fb_info.cols; |
434 | arg2 = fb_info.cols; |
433 | break; |
435 | break; |
434 | case CONSOLE_FLUSH: |
436 | case CONSOLE_FLUSH: |
435 | if (consnum == active_console) |
437 | if (consnum == active_console) |
436 | async_req_2(fb_info.phone, FB_FLUSH, 0, 0, |
438 | async_req_2(fb_info.phone, FB_FLUSH, 0, 0, |
437 | NULL, NULL); |
439 | NULL, NULL); |
438 | break; |
440 | break; |
439 | case CONSOLE_SET_STYLE: |
441 | case CONSOLE_SET_STYLE: |
440 | arg1 = IPC_GET_ARG1(call); |
442 | arg1 = IPC_GET_ARG1(call); |
441 | arg2 = IPC_GET_ARG2(call); |
443 | arg2 = IPC_GET_ARG2(call); |
442 | screenbuffer_set_style(&conn->screenbuffer, arg1, arg2); |
444 | screenbuffer_set_style(&conn->screenbuffer, arg1, |
- | 445 | arg2); |
|
443 | if (consnum == active_console) |
446 | if (consnum == active_console) |
444 | set_style_col(arg1, arg2); |
447 | set_style_col(arg1, arg2); |
445 | break; |
448 | break; |
446 | case CONSOLE_CURSOR_VISIBILITY: |
449 | case CONSOLE_CURSOR_VISIBILITY: |
447 | arg1 = IPC_GET_ARG1(call); |
450 | arg1 = IPC_GET_ARG1(call); |
Line 508... | Line 511... | ||
508 | /* Synchronize, the gcons can have something in queue */ |
511 | /* Synchronize, the gcons can have something in queue */ |
509 | async_req(fb_info.phone, FB_FLUSH, 0, NULL); |
512 | async_req(fb_info.phone, FB_FLUSH, 0, NULL); |
510 | /* Enable double buffering */ |
513 | /* Enable double buffering */ |
511 | async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1); |
514 | async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1); |
512 | 515 | ||
513 | async_req_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &(fb_info.rows), |
516 | async_req_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &fb_info.rows, |
514 | &(fb_info.cols)); |
517 | &fb_info.cols); |
515 | set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
518 | set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
516 | clrscr(); |
519 | clrscr(); |
517 | 520 | ||
518 | /* Init virtual consoles */ |
521 | /* Init virtual consoles */ |
519 | for (i = 0; i < CONSOLE_COUNT; i++) { |
522 | for (i = 0; i < CONSOLE_COUNT; i++) { |
520 | connections[i].used = 0; |
523 | connections[i].used = 0; |
521 | keybuffer_init(&(connections[i].keybuffer)); |
524 | keybuffer_init(&connections[i].keybuffer); |
522 | 525 | ||
523 | connections[i].keyrequests.head = |
526 | connections[i].keyrequests.head = 0; |
524 | connections[i].keyrequests.tail = 0; |
527 | connections[i].keyrequests.tail = 0; |
525 | connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED; |
528 | connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED; |
526 | connections[i].keyrequest_counter = 0; |
529 | connections[i].keyrequest_counter = 0; |
527 | 530 | ||
528 | if (screenbuffer_init(&(connections[i].screenbuffer), |
531 | if (screenbuffer_init(&connections[i].screenbuffer, |
529 | fb_info.cols, fb_info.rows) == NULL) { |
532 | fb_info.cols, fb_info.rows) == NULL) { |
530 | /* FIXME: handle error */ |
533 | /* FIXME: handle error */ |
531 | return -1; |
534 | return -1; |
532 | } |
535 | } |
533 | } |
536 | } |
534 | connections[KERNEL_CONSOLE].used = 1; |
537 | connections[KERNEL_CONSOLE].used = 1; |
535 | 538 | ||
536 | interbuffer = mmap(NULL, |
539 | interbuffer = mmap(NULL, |
537 | sizeof(keyfield_t) * fb_info.cols * fb_info.rows, |
540 | sizeof(keyfield_t) * fb_info.cols * fb_info.rows, |
538 | PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
541 | PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
539 | if (!interbuffer) { |
542 | if (!interbuffer) { |
540 | if (async_req_3(fb_info.phone, IPC_M_AS_AREA_SEND, (ipcarg_t) |
543 | if (async_req_3(fb_info.phone, IPC_M_AS_AREA_SEND, |
541 | interbuffer, 0, AS_AREA_READ, NULL, NULL, NULL) != 0) { |
544 | (ipcarg_t) interbuffer, 0, AS_AREA_READ, NULL, NULL, |
- | 545 | NULL) != 0) { |
|
542 | munmap(interbuffer, sizeof(keyfield_t) * fb_info.cols |
546 | munmap(interbuffer, |
543 | * fb_info.rows); |
547 | sizeof(keyfield_t) * fb_info.cols * fb_info.rows); |
544 | interbuffer = NULL; |
548 | interbuffer = NULL; |
545 | } |
549 | } |
546 | } |
550 | } |
547 | 551 | ||
548 | curs_goto(0, 0); |
552 | curs_goto(0, 0); |
- | 553 | curs_visibility( |
|
549 | curs_visibility(connections[active_console].screenbuffer.is_cursor_visible); |
554 | connections[active_console].screenbuffer.is_cursor_visible); |
550 | 555 | ||
551 | /* Register at NS */ |
556 | /* Register at NS */ |
552 | if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, &phonehash) != 0) { |
557 | if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, &phonehash) != 0) { |
553 | return -1; |
558 | return -1; |
554 | } |
559 | } |