Changeset 424cd43 in mainline
- Timestamp:
- 2009-06-03T18:39:12Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8dc12ac
- Parents:
- b0a91acb
- Location:
- uspace/srv/console
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/console/Makefile
rb0a91acb r424cd43 47 47 console.c \ 48 48 screenbuffer.c \ 49 ../kbd/generic/key _buffer.c \49 ../kbd/generic/keybuffer.c \ 50 50 gcons.c 51 51 -
uspace/srv/console/console.c
rb0a91acb r424cd43 37 37 #include <ipc/ipc.h> 38 38 #include <kbd.h> 39 #include < kbd/keycode.h>39 #include <io/keycode.h> 40 40 #include <ipc/fb.h> 41 41 #include <ipc/services.h> 42 42 #include <errno.h> 43 #include <key _buffer.h>43 #include <keybuffer.h> 44 44 #include <ipc/console.h> 45 45 #include <unistd.h> 46 46 #include <async.h> 47 47 #include <libadt/fifo.h> 48 #include <screenbuffer.h>49 48 #include <sys/mman.h> 50 49 #include <stdio.h> … … 52 51 #include <sysinfo.h> 53 52 #include <event.h> 53 #include <devmap.h> 54 54 55 55 #include "console.h" 56 56 #include "gcons.h" 57 #include "screenbuffer.h" 57 58 58 59 #define NAME "console" 59 60 60 #define MAX_KEYREQUESTS_BUFFERED 32 61 62 /** Size of cwrite_buf. */ 63 #define CWRITE_BUF_SIZE 256 64 65 /** Index of currently used virtual console. 66 */ 67 int active_console = 0; 68 int prev_console = 0; 61 #define MAX_DEVICE_NAME 32 69 62 70 63 /** Phone to the keyboard driver. */ … … 74 67 struct { 75 68 int phone; /**< Framebuffer phone */ 69 ipcarg_t cols; /**< Framebuffer columns */ 76 70 ipcarg_t rows; /**< Framebuffer rows */ 77 ipcarg_t cols; /**< Framebuffer columns */78 71 } fb_info; 79 72 80 73 typedef struct { 81 keybuffer_t keybuffer; /**< Buffer for incoming keys. */ 82 83 /** Buffer for unsatisfied request for keys. */ 84 FIFO_CREATE_STATIC(keyrequests, ipc_callid_t, 85 MAX_KEYREQUESTS_BUFFERED); 86 87 int keyrequest_counter; /**< Number of requests in buffer. */ 88 int client_phone; /**< Phone to connected client. */ 89 int used; /**< 1 if this virtual console is 90 connected to some client. */ 91 screenbuffer_t screenbuffer; /**< Screenbuffer for saving screen 92 contents and related settings. */ 93 } connection_t; 74 size_t index; /**< Console index */ 75 size_t refcount; /**< Connection reference count */ 76 dev_handle_t dev_handle; /**< Device handle */ 77 keybuffer_t keybuffer; /**< Buffer for incoming keys. */ 78 screenbuffer_t scr; /**< Screenbuffer for saving screen 79 contents and related settings. */ 80 } console_t; 94 81 95 82 /** Array of data for virtual consoles */ 96 static connection_t connections[CONSOLE_COUNT]; 83 static console_t consoles[CONSOLE_COUNT]; 84 85 static console_t *active_console = &consoles[0]; 86 static console_t *prev_console = &consoles[0]; 87 static console_t *kernel_console = &consoles[KERNEL_CONSOLE]; 97 88 98 89 /** Pointer to memory shared with framebufer used for … … 102 93 /** Information on row-span yet unsent to FB driver. */ 103 94 struct { 104 int row; /**< Row where the span lies. */105 int col; /**< Leftmost column of the span. */106 int cnt; /**< Width of the span. */95 size_t col; /**< Leftmost column of the span. */ 96 size_t row; /**< Row where the span lies. */ 97 size_t cnt; /**< Width of the span. */ 107 98 } fb_pending; 108 99 109 /** Buffer for receiving data via the CONSOLE_WRITE call from the client. */ 110 static char cwrite_buf[CWRITE_BUF_SIZE]; 111 112 /** Find unused virtual console. 113 * 114 */ 115 static int find_free_connection(void) 116 { 117 int i; 118 119 for (i = 0; i < CONSOLE_COUNT; i++) { 120 if (!connections[i].used) 121 return i; 122 } 123 124 return -1; 125 } 126 127 static void clrscr(void) 100 /** Pending input structure. */ 101 typedef struct { 102 link_t link; 103 console_t *cons; /**< Console waiting for input */ 104 ipc_callid_t rid; /**< Call ID waiting for input */ 105 ipc_callid_t callid; /**< Call ID waiting for IPC_DATA_READ */ 106 107 size_t pos; /**< Position of the last stored data */ 108 size_t size; /**< Size of ther buffer */ 109 char *data; /**< Already stored data */ 110 } pending_input_t; 111 112 LIST_INITIALIZE(pending_input); 113 114 /** Process pending input requests */ 115 static void process_pending_input(void) 116 { 117 async_serialize_start(); 118 119 link_t *cur; 120 121 loop: 122 for (cur = pending_input.next; cur != &pending_input; cur = cur->next) { 123 pending_input_t *pr = list_get_instance(cur, pending_input_t, link); 124 125 console_event_t ev; 126 if (keybuffer_pop(&pr->cons->keybuffer, &ev)) { 127 128 if (pr->data != NULL) { 129 if (ev.type == KEY_PRESS) { 130 pr->data[pr->pos] = ev.c; 131 pr->pos++; 132 } 133 } else { 134 ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c); 135 136 list_remove(cur); 137 free(pr); 138 139 goto loop; 140 } 141 } 142 143 if ((pr->data != NULL) && (pr->pos == pr->size)) { 144 (void) ipc_data_read_finalize(pr->callid, pr->data, pr->size); 145 ipc_answer_1(pr->rid, EOK, pr->size); 146 147 free(pr->data); 148 list_remove(cur); 149 free(pr); 150 151 goto loop; 152 } 153 } 154 155 async_serialize_end(); 156 } 157 158 static void curs_visibility(bool visible) 159 { 160 async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); 161 } 162 163 static void curs_hide_sync(void) 164 { 165 ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 166 } 167 168 static void curs_goto(size_t x, size_t y) 169 { 170 async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y); 171 } 172 173 static void screen_clear(void) 128 174 { 129 175 async_msg_0(fb_info.phone, FB_CLEAR); 130 176 } 131 177 132 static void curs_visibility(bool visible)133 {134 async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);135 }136 137 static void curs_hide_sync(void)138 {139 ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);140 }141 142 static void curs_goto(int row, int col)143 {144 async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);145 }146 147 178 static void screen_yield(void) 148 179 { … … 167 198 static void set_style(int style) 168 199 { 169 async_msg_1(fb_info.phone, FB_SET_STYLE, style); 200 async_msg_1(fb_info.phone, FB_SET_STYLE, style); 170 201 } 171 202 … … 197 228 198 229 /** Send an area of screenbuffer to the FB driver. */ 199 static void fb_update_area(connection_t *conn, int x, int y, int w, int h) 200 { 201 int i; 202 int j; 203 attrs_t *attrs; 204 keyfield_t *field; 205 230 static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height) 231 { 206 232 if (interbuffer) { 207 for (j = 0; j < h; j++) { 208 for (i = 0; i < w; i++) { 209 interbuffer[i + j * w] = 210 *get_field_at(&conn->screenbuffer, x + i, y + j); 233 ipcarg_t x; 234 ipcarg_t y; 235 236 for (y = 0; y < height; y++) { 237 for (x = 0; x < width; x++) { 238 interbuffer[y * width + x] = 239 *get_field_at(&cons->scr, x0 + x, y0 + y); 211 240 } 212 241 } 213 242 214 243 async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA, 215 x , y, w, h);244 x0, y0, width, height); 216 245 } 217 246 } … … 220 249 static void fb_pending_flush(void) 221 250 { 222 screenbuffer_t *scr223 = &(connections[active_console].screenbuffer);224 225 251 if (fb_pending.cnt > 0) { 226 fb_update_area( &connections[active_console], fb_pending.col,252 fb_update_area(active_console, fb_pending.col, 227 253 fb_pending.row, fb_pending.cnt, 1); 228 254 fb_pending.cnt = 0; … … 236 262 * 237 263 */ 238 static void cell_mark_changed( int row, int col)264 static void cell_mark_changed(size_t col, size_t row) 239 265 { 240 266 if (fb_pending.cnt != 0) { 241 if (( row != fb_pending.row)242 || ( col != fb_pending.col + fb_pending.cnt)) {267 if ((col != fb_pending.col + fb_pending.cnt) 268 || (row != fb_pending.row)) { 243 269 fb_pending_flush(); 244 270 } … … 246 272 247 273 if (fb_pending.cnt == 0) { 274 fb_pending.col = col; 248 275 fb_pending.row = row; 249 fb_pending.col = col;250 276 } 251 277 … … 254 280 255 281 /** Print a character to the active VC with buffering. */ 256 static void fb_putchar(wchar_t c, i nt row, int col)257 { 258 async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);282 static void fb_putchar(wchar_t c, ipcarg_t col, ipcarg_t row) 283 { 284 async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row); 259 285 } 260 286 261 287 /** Process a character from the client (TTY emulation). */ 262 static void write_char(int console, wchar_t ch) 263 { 264 bool flush_cursor = false; 265 screenbuffer_t *scr = &(connections[console].screenbuffer); 266 288 static void write_char(console_t *cons, wchar_t ch) 289 { 267 290 switch (ch) { 268 291 case '\n': 269 292 fb_pending_flush(); 270 flush_cursor = true; 271 scr->position_y++; 272 scr->position_x = 0; 293 cons->scr.position_y++; 294 cons->scr.position_x = 0; 273 295 break; 274 296 case '\r': 275 297 break; 276 298 case '\t': 277 scr->position_x += 8;278 scr->position_x -= scr->position_x % 8;299 cons->scr.position_x += 8; 300 cons->scr.position_x -= cons->scr.position_x % 8; 279 301 break; 280 302 case '\b': 281 if ( scr->position_x == 0)282 break; 283 scr->position_x--;284 if (cons ole== active_console)285 cell_mark_changed( scr->position_y, scr->position_x);286 screenbuffer_putchar( scr, ' ');303 if (cons->scr.position_x == 0) 304 break; 305 cons->scr.position_x--; 306 if (cons == active_console) 307 cell_mark_changed(cons->scr.position_x, cons->scr.position_y); 308 screenbuffer_putchar(&cons->scr, ' '); 287 309 break; 288 310 default: 289 if (console == active_console) 290 cell_mark_changed(scr->position_y, scr->position_x); 291 292 screenbuffer_putchar(scr, ch); 293 scr->position_x++; 294 } 295 296 if (scr->position_x >= scr->size_x) { 297 flush_cursor = true; 298 scr->position_y++; 299 } 300 301 if (scr->position_y >= scr->size_y) { 311 if (cons == active_console) 312 cell_mark_changed(cons->scr.position_x, cons->scr.position_y); 313 314 screenbuffer_putchar(&cons->scr, ch); 315 cons->scr.position_x++; 316 } 317 318 if (cons->scr.position_x >= cons->scr.size_x) 319 cons->scr.position_y++; 320 321 if (cons->scr.position_y >= cons->scr.size_y) { 302 322 fb_pending_flush(); 303 scr->position_y = scr->size_y - 1; 304 screenbuffer_clear_line(scr, scr->top_line); 305 scr->top_line = (scr->top_line + 1) % scr->size_y; 306 if (console == active_console) 323 cons->scr.position_y = cons->scr.size_y - 1; 324 screenbuffer_clear_line(&cons->scr, cons->scr.top_line); 325 cons->scr.top_line = (cons->scr.top_line + 1) % cons->scr.size_y; 326 327 if (cons == active_console) 307 328 async_msg_1(fb_info.phone, FB_SCROLL, 1); 308 329 } 309 330 310 scr->position_x = scr->position_x % scr->size_x; 311 312 if (console == active_console && flush_cursor) 313 curs_goto(scr->position_y, scr->position_x); 331 cons->scr.position_x = cons->scr.position_x % cons->scr.size_x; 314 332 } 315 333 316 334 /** Switch to new console */ 317 static void change_console(int newcons) 318 { 319 connection_t *conn; 320 int i; 321 int j; 322 int rc; 323 keyfield_t *field; 324 attrs_t *attrs; 325 326 if (newcons == active_console) 335 static void change_console(console_t *cons) 336 { 337 if (cons == active_console) 327 338 return; 328 339 329 340 fb_pending_flush(); 330 341 331 if ( newcons == KERNEL_CONSOLE) {342 if (cons == kernel_console) { 332 343 async_serialize_start(); 333 344 curs_hide_sync(); … … 337 348 async_serialize_end(); 338 349 339 340 350 if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) { 341 351 prev_console = active_console; 342 active_console = KERNEL_CONSOLE;352 active_console = kernel_console; 343 353 } else 344 newcons = active_console; 345 } 346 347 if (newcons != KERNEL_CONSOLE) { 354 cons = active_console; 355 } 356 357 if (cons != kernel_console) { 358 size_t x; 359 size_t y; 360 int rc = 0; 361 348 362 async_serialize_start(); 349 363 350 if (active_console == KERNEL_CONSOLE) {364 if (active_console == kernel_console) { 351 365 screen_reclaim(); 352 366 kbd_reclaim(); … … 354 368 } 355 369 356 active_console = newcons; 357 gcons_change_console(newcons); 358 conn = &connections[active_console]; 359 360 set_attrs(&conn->screenbuffer.attrs); 370 active_console = cons; 371 gcons_change_console(cons->index); 372 373 set_attrs(&cons->scr.attrs); 361 374 curs_visibility(false); 362 375 if (interbuffer) { 363 for (j = 0; j < conn->screenbuffer.size_y; j++) { 364 for (i = 0; i < conn->screenbuffer.size_x; i++) { 365 unsigned int size_x; 366 367 size_x = conn->screenbuffer.size_x; 368 interbuffer[j * size_x + i] = 369 *get_field_at(&conn->screenbuffer, i, j); 376 for (y = 0; y < cons->scr.size_y; y++) { 377 for (x = 0; x < cons->scr.size_x; x++) { 378 interbuffer[y * cons->scr.size_x + x] = 379 *get_field_at(&cons->scr, x, y); 370 380 } 371 381 } 382 372 383 /* This call can preempt, but we are already at the end */ 373 384 rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA, 374 0, 0, con n->screenbuffer.size_x,375 con n->screenbuffer.size_y);385 0, 0, cons->scr.size_x, 386 cons->scr.size_y); 376 387 } 377 388 378 389 if ((!interbuffer) || (rc != 0)) { 379 set_attrs(&con n->screenbuffer.attrs);380 clrscr();381 attrs = &conn->screenbuffer.attrs;382 383 for (j = 0; j < conn->screenbuffer.size_y; j++)384 for (i = 0; i < conn->screenbuffer.size_x; i++) {385 field = get_field_at(&conn->screenbuffer, i, j);386 if (!attrs_same( *attrs, field->attrs))390 set_attrs(&cons->scr.attrs); 391 screen_clear(); 392 393 for (y = 0; y < cons->scr.size_y; y++) 394 for (x = 0; x < cons->scr.size_x; x++) { 395 keyfield_t *field = get_field_at(&cons->scr, x, y); 396 397 if (!attrs_same(cons->scr.attrs, field->attrs)) 387 398 set_attrs(&field->attrs); 388 attrs = &field->attrs; 399 400 cons->scr.attrs = field->attrs; 389 401 if ((field->character == ' ') && 390 (attrs_same(field->attrs, con n->screenbuffer.attrs)))402 (attrs_same(field->attrs, cons->scr.attrs))) 391 403 continue; 392 404 393 fb_putchar(field->character, j, i);405 fb_putchar(field->character, x, y); 394 406 } 395 407 } 396 408 397 curs_goto(conn->screenbuffer.position_y, 398 conn->screenbuffer.position_x); 399 curs_visibility(conn->screenbuffer.is_cursor_visible); 409 curs_goto(cons->scr.position_x, cons->scr.position_y); 410 curs_visibility(cons->scr.is_cursor_visible); 400 411 401 412 async_serialize_end(); … … 406 417 static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall) 407 418 { 408 ipc_callid_t callid; 409 ipc_call_t call; 410 int retval; 411 kbd_event_t ev; 412 connection_t *conn; 413 int newcon; 414 415 /* Ignore parameters, the connection is alread opened */ 419 /* Ignore parameters, the connection is already opened */ 416 420 while (true) { 417 callid = async_get_call(&call); 421 422 ipc_call_t call; 423 ipc_callid_t callid = async_get_call(&call); 424 425 int retval; 426 console_event_t ev; 427 418 428 switch (IPC_GET_METHOD(call)) { 419 429 case IPC_M_PHONE_HUNGUP: 420 430 /* TODO: Handle hangup */ 421 431 return; 422 case KBD_MS_LEFT:423 newcon = gcons_mouse_btn(IPC_GET_ARG1(call));424 if (newcon != -1)425 change_console(newcon);426 retval = 0;427 break;428 case KBD_MS_MOVE:429 gcons_mouse_move(IPC_GET_ARG1(call),430 IPC_GET_ARG2(call));431 retval = 0;432 break;433 432 case KBD_EVENT: 434 433 /* Got event from keyboard driver. */ … … 439 438 ev.c = IPC_GET_ARG4(call); 440 439 441 /* Switch to another virtual console */442 conn = &connections[active_console];443 444 440 if ((ev.key >= KC_F1) && (ev.key < KC_F1 + 445 441 CONSOLE_COUNT) && ((ev.mods & KM_CTRL) == 0)) { 446 if (ev.key == KC_F1 2)447 change_console( KERNEL_CONSOLE);442 if (ev.key == KC_F1 + KERNEL_CONSOLE) 443 change_console(kernel_console); 448 444 else 449 change_console( ev.key - KC_F1);445 change_console(&consoles[ev.key - KC_F1]); 450 446 break; 451 447 } 452 448 453 /* If client is awaiting key, send it */ 454 if (conn->keyrequest_counter > 0) { 455 conn->keyrequest_counter--; 456 ipc_answer_4(fifo_pop(conn->keyrequests), EOK, 457 ev.type, ev.key, ev.mods, ev.c); 458 break; 459 } 460 461 keybuffer_push(&conn->keybuffer, &ev); 462 retval = 0; 463 449 keybuffer_push(&active_console->keybuffer, &ev); 464 450 break; 465 451 default: … … 470 456 } 471 457 472 /** Handle CONSOLE_WRITE call. */ 473 static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request) 458 static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request) 474 459 { 475 460 ipc_callid_t callid; 476 461 size_t size; 477 wchar_t ch;478 size_t off;479 480 462 if (!ipc_data_write_receive(&callid, &size)) { 481 463 ipc_answer_0(callid, EINVAL); … … 484 466 } 485 467 486 if (size > CWRITE_BUF_SIZE) 487 size = CWRITE_BUF_SIZE; 488 489 (void) ipc_data_write_finalize(callid, cwrite_buf, size); 468 char *buf = (char *) malloc(size); 469 if (buf == NULL) { 470 ipc_answer_0(callid, ENOMEM); 471 ipc_answer_0(rid, ENOMEM); 472 return; 473 } 474 475 (void) ipc_data_write_finalize(callid, buf, size); 490 476 491 477 async_serialize_start(); 492 478 493 off = 0;479 size_t off = 0; 494 480 while (off < size) { 495 ch = str_decode(cwrite_buf, &off, size); 496 write_char(consnum, ch); 497 } 481 wchar_t ch = str_decode(buf, &off, size); 482 write_char(cons, ch); 483 } 484 485 if (cons == active_console) 486 curs_goto(cons->scr.position_x, cons->scr.position_y); 498 487 499 488 async_serialize_end(); 500 489 501 gcons_notify_char(cons num);490 gcons_notify_char(cons->index); 502 491 ipc_answer_1(rid, EOK, size); 492 493 free(buf); 494 } 495 496 static void cons_read(console_t *cons, ipc_callid_t rid, ipc_call_t *request) 497 { 498 ipc_callid_t callid; 499 size_t size; 500 if (!ipc_data_read_receive(&callid, &size)) { 501 ipc_answer_0(callid, EINVAL); 502 ipc_answer_0(rid, EINVAL); 503 return; 504 } 505 506 char *buf = (char *) malloc(size); 507 if (buf == NULL) { 508 ipc_answer_0(callid, ENOMEM); 509 ipc_answer_0(rid, ENOMEM); 510 return; 511 } 512 513 async_serialize_start(); 514 515 size_t pos = 0; 516 console_event_t ev; 517 while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) { 518 if (ev.type == KEY_PRESS) { 519 buf[pos] = ev.c; 520 pos++; 521 } 522 } 523 524 if (pos == size) { 525 (void) ipc_data_read_finalize(callid, buf, size); 526 ipc_answer_1(rid, EOK, size); 527 free(buf); 528 } else { 529 pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t)); 530 if (!pr) { 531 ipc_answer_0(rid, ENOMEM); 532 free(buf); 533 async_serialize_end(); 534 return; 535 } 536 537 pr->cons = cons; 538 pr->rid = rid; 539 pr->callid = callid; 540 pr->pos = pos; 541 pr->size = size; 542 pr->data = buf; 543 list_append(&pr->link, &pending_input); 544 } 545 546 async_serialize_end(); 547 } 548 549 static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request) 550 { 551 async_serialize_start(); 552 553 console_event_t ev; 554 if (keybuffer_pop(&cons->keybuffer, &ev)) { 555 ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c); 556 } else { 557 pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t)); 558 if (!pr) { 559 ipc_answer_0(rid, ENOMEM); 560 async_serialize_end(); 561 return; 562 } 563 564 pr->cons = cons; 565 pr->rid = rid; 566 pr->callid = 0; 567 pr->data = NULL; 568 list_append(&pr->link, &pending_input); 569 } 570 571 async_serialize_end(); 503 572 } 504 573 … … 506 575 static void client_connection(ipc_callid_t iid, ipc_call_t *icall) 507 576 { 577 console_t *cons = NULL; 578 579 size_t i; 580 for (i = 0; i < CONSOLE_COUNT; i++) { 581 if (i == KERNEL_CONSOLE) 582 continue; 583 584 if (consoles[i].dev_handle == (dev_handle_t) IPC_GET_ARG1(*icall)) { 585 cons = &consoles[i]; 586 break; 587 } 588 } 589 590 if (cons == NULL) { 591 ipc_answer_0(iid, ENOENT); 592 return; 593 } 594 508 595 ipc_callid_t callid; 509 596 ipc_call_t call; 510 int consnum; 511 ipcarg_t arg1, arg2, arg3, arg4; 512 connection_t *conn; 513 screenbuffer_t *scr; 514 515 if ((consnum = find_free_connection()) == -1) { 516 ipc_answer_0(iid, ELIMIT); 517 return; 518 } 519 conn = &connections[consnum]; 520 conn->used = 1; 597 ipcarg_t arg1; 598 ipcarg_t arg2; 599 ipcarg_t arg3; 521 600 522 601 async_serialize_start(); 523 gcons_notify_connect(consnum); 524 conn->client_phone = IPC_GET_ARG5(*icall); 525 screenbuffer_clear(&conn->screenbuffer); 526 if (consnum == active_console) 527 clrscr(); 602 if (cons->refcount == 0) 603 gcons_notify_connect(cons->index); 604 605 cons->refcount++; 528 606 529 607 /* Accept the connection */ … … 538 616 arg2 = 0; 539 617 arg3 = 0; 540 arg4 = 0;541 618 542 619 switch (IPC_GET_METHOD(call)) { 543 620 case IPC_M_PHONE_HUNGUP: 544 gcons_notify_disconnect(consnum); 545 546 /* Answer all pending requests */ 547 while (conn->keyrequest_counter > 0) { 548 conn->keyrequest_counter--; 549 ipc_answer_0(fifo_pop(conn->keyrequests), 550 ENOENT); 551 break; 552 } 553 conn->used = 0; 621 cons->refcount--; 622 if (cons->refcount == 0) 623 gcons_notify_disconnect(cons->index); 554 624 return; 555 case CONSOLE_PUTCHAR: 556 write_char(consnum, IPC_GET_ARG1(call)); 557 gcons_notify_char(consnum); 558 break; 559 case CONSOLE_WRITE: 625 case VFS_READ: 560 626 async_serialize_end(); 561 cons_ write(consnum, callid, &call);627 cons_read(cons, callid, &call); 562 628 async_serialize_start(); 563 629 continue; 630 case VFS_WRITE: 631 async_serialize_end(); 632 cons_write(cons, callid, &call); 633 async_serialize_start(); 634 continue; 635 case VFS_SYNC: 636 fb_pending_flush(); 637 if (cons == active_console) { 638 async_req_0_0(fb_info.phone, FB_FLUSH); 639 640 curs_goto(cons->scr.position_x, cons->scr.position_y); 641 } 642 break; 564 643 case CONSOLE_CLEAR: 565 644 /* Send message to fb */ 566 if (consnum == active_console) { 567 async_msg_0(fb_info.phone, FB_CLEAR); 568 } 569 570 screenbuffer_clear(&conn->screenbuffer); 645 if (cons == active_console) 646 async_msg_0(fb_info.phone, FB_CLEAR); 647 648 screenbuffer_clear(&cons->scr); 571 649 572 650 break; 573 651 case CONSOLE_GOTO: 574 screenbuffer_goto(&con n->screenbuffer,575 IPC_GET_ARG 2(call), IPC_GET_ARG1(call));576 if (cons num== active_console)652 screenbuffer_goto(&cons->scr, 653 IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 654 if (cons == active_console) 577 655 curs_goto(IPC_GET_ARG1(call), 578 656 IPC_GET_ARG2(call)); 579 657 break; 580 case CONSOLE_GETSIZE: 581 arg1 = fb_info.rows; 582 arg2 = fb_info.cols; 583 break; 584 case CONSOLE_FLUSH: 585 fb_pending_flush(); 586 if (consnum == active_console) { 587 async_req_0_0(fb_info.phone, FB_FLUSH); 588 589 scr = &(connections[consnum].screenbuffer); 590 curs_goto(scr->position_y, scr->position_x); 591 } 658 case CONSOLE_GET_SIZE: 659 arg1 = fb_info.cols; 660 arg2 = fb_info.rows; 592 661 break; 593 662 case CONSOLE_SET_STYLE: 594 663 fb_pending_flush(); 595 664 arg1 = IPC_GET_ARG1(call); 596 screenbuffer_set_style(&con n->screenbuffer, arg1);597 if (cons num== active_console)665 screenbuffer_set_style(&cons->scr, arg1); 666 if (cons == active_console) 598 667 set_style(arg1); 599 668 break; … … 603 672 arg2 = IPC_GET_ARG2(call); 604 673 arg3 = IPC_GET_ARG3(call); 605 screenbuffer_set_color(&conn->screenbuffer, arg1, 606 arg2, arg3); 607 if (consnum == active_console) 674 screenbuffer_set_color(&cons->scr, arg1, arg2, arg3); 675 if (cons == active_console) 608 676 set_color(arg1, arg2, arg3); 609 677 break; … … 612 680 arg1 = IPC_GET_ARG1(call); 613 681 arg2 = IPC_GET_ARG2(call); 614 screenbuffer_set_rgb_color(&conn->screenbuffer, arg1, 615 arg2); 616 if (consnum == active_console) 682 screenbuffer_set_rgb_color(&cons->scr, arg1, arg2); 683 if (cons == active_console) 617 684 set_rgb_color(arg1, arg2); 618 685 break; … … 620 687 fb_pending_flush(); 621 688 arg1 = IPC_GET_ARG1(call); 622 con n->screenbuffer.is_cursor_visible = arg1;623 if (cons num== active_console)689 cons->scr.is_cursor_visible = arg1; 690 if (cons == active_console) 624 691 curs_visibility(arg1); 625 692 break; 626 case CONSOLE_GETKEY: 627 if (keybuffer_empty(&conn->keybuffer)) { 628 /* buffer is empty -> store request */ 629 if (conn->keyrequest_counter < 630 MAX_KEYREQUESTS_BUFFERED) { 631 fifo_push(conn->keyrequests, callid); 632 conn->keyrequest_counter++; 633 } else { 634 /* 635 * No key available and too many 636 * requests => fail. 637 */ 638 ipc_answer_0(callid, ELIMIT); 639 } 640 continue; 641 } 642 kbd_event_t ev; 643 keybuffer_pop(&conn->keybuffer, &ev); 644 arg1 = ev.type; 645 arg2 = ev.key; 646 arg3 = ev.mods; 647 arg4 = ev.c; 648 break; 693 case CONSOLE_GET_EVENT: 694 async_serialize_end(); 695 cons_get_event(cons, callid, &call); 696 async_serialize_start(); 697 continue; 649 698 case CONSOLE_KCON_ENABLE: 650 change_console( KERNEL_CONSOLE);651 break; 652 } 653 ipc_answer_ 4(callid, EOK, arg1, arg2, arg3, arg4);699 change_console(kernel_console); 700 break; 701 } 702 ipc_answer_3(callid, EOK, arg1, arg2, arg3); 654 703 } 655 704 } … … 660 709 } 661 710 662 int main(int argc, char *argv[]) 663 { 664 printf(NAME ": HelenOS Console service\n"); 665 666 ipcarg_t phonehash; 667 size_t ib_size; 668 int i; 669 670 async_set_client_connection(client_connection); 671 711 static bool console_init(void) 712 { 672 713 /* Connect to keyboard driver */ 714 673 715 kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0); 674 716 if (kbd_phone < 0) { 675 717 printf(NAME ": Failed to connect to keyboard service\n"); 676 return -1; 677 } 678 718 return false; 719 } 720 721 ipcarg_t phonehash; 679 722 if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) { 680 723 printf(NAME ": Failed to create callback from keyboard service\n"); 681 return -1; 682 } 683 724 return false; 725 } 726 727 async_set_pending(process_pending_input); 684 728 async_new_connection(phonehash, 0, NULL, keyboard_events); 685 729 … … 691 735 } 692 736 693 /* Disable kernel output to the console */ 694 __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE); 737 /* Register driver */ 738 int rc = devmap_driver_register(NAME, client_connection); 739 if (rc < 0) { 740 printf(NAME ": Unable to register driver (%d)\n", rc); 741 return false; 742 } 695 743 696 744 /* Initialize gcons */ 697 745 gcons_init(fb_info.phone); 698 /* Synchronize, the gcons can have something in queue */ 746 747 /* Synchronize, the gcons could put something in queue */ 699 748 async_req_0_0(fb_info.phone, FB_FLUSH); 700 701 async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows, 702 &fb_info.cols); 703 set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); 704 clrscr(); 705 706 /* Init virtual consoles */ 707 for (i = 0; i < CONSOLE_COUNT; i++) { 708 connections[i].used = 0; 709 keybuffer_init(&connections[i].keybuffer); 710 711 connections[i].keyrequests.head = 0; 712 connections[i].keyrequests.tail = 0; 713 connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED; 714 connections[i].keyrequest_counter = 0; 715 716 if (screenbuffer_init(&connections[i].screenbuffer, 717 fb_info.cols, fb_info.rows) == NULL) { 718 /* FIXME: handle error */ 719 return -1; 720 } 721 } 722 connections[KERNEL_CONSOLE].used = 1; 749 async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows); 723 750 724 751 /* Set up shared memory buffer. */ 725 ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;752 size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows; 726 753 interbuffer = as_get_mappable_page(ib_size); 727 754 728 fb_pending.cnt = 0;729 730 755 if (as_area_create(interbuffer, ib_size, AS_AREA_READ | 731 AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) {756 AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) 732 757 interbuffer = NULL; 733 }734 758 735 759 if (interbuffer) { … … 741 765 } 742 766 767 fb_pending.cnt = 0; 768 769 /* Inititalize consoles */ 770 size_t i; 771 for (i = 0; i < CONSOLE_COUNT; i++) { 772 if (i != KERNEL_CONSOLE) { 773 if (screenbuffer_init(&consoles[i].scr, 774 fb_info.cols, fb_info.rows) == NULL) { 775 printf(NAME ": Unable to allocate screen buffer %u\n", i); 776 return false; 777 } 778 screenbuffer_clear(&consoles[i].scr); 779 keybuffer_init(&consoles[i].keybuffer); 780 consoles[i].index = i; 781 consoles[i].refcount = 0; 782 783 char vc[MAX_DEVICE_NAME]; 784 snprintf(vc, MAX_DEVICE_NAME, "vc%u", i); 785 786 if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) { 787 devmap_hangup_phone(DEVMAP_DRIVER); 788 printf(NAME ": Unable to register device %s\n", vc); 789 return false; 790 } 791 } 792 } 793 794 /* Initialize the screen */ 795 set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); 796 screen_clear(); 743 797 curs_goto(0, 0); 744 curs_visibility( 745 connections[active_console].screenbuffer.is_cursor_visible); 746 747 /* Register at NS */ 748 if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) 749 return -1; 798 curs_visibility(active_console->scr.is_cursor_visible); 750 799 751 800 /* Receive kernel notifications */ … … 755 804 async_set_interrupt_received(interrupt_received); 756 805 757 // FIXME: avoid connectiong to itself, keep using klog 758 // printf(NAME ": Accepting connections\n"); 806 return true; 807 } 808 809 int main(int argc, char *argv[]) 810 { 811 printf(NAME ": HelenOS Console service\n"); 812 813 /* Disable kernel output to the console */ 814 __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE); 815 816 if (!console_init()) { 817 __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE); 818 return -1; 819 } 820 821 printf(NAME ": Accepting connections\n"); 759 822 async_manager(); 760 823 -
uspace/srv/console/gcons.c
rb0a91acb r424cd43 40 40 #include <string.h> 41 41 #include <align.h> 42 #include <bool.h> 42 43 43 44 #include "console.h" … … 55 56 #define MAIN_COLOR 0xffffff 56 57 57 static int use_gcons = 0; 58 static ipcarg_t xres,yres; 58 static bool use_gcons = false; 59 static ipcarg_t xres; 60 static ipcarg_t yres; 59 61 60 62 enum butstate { … … 78 80 static int animation = -1; 79 81 80 static int active_console = 0; 82 static size_t active_console = 0; 83 84 size_t mouse_x; 85 size_t mouse_y; 86 87 bool btn_pressed; 88 size_t btn_x; 89 size_t btn_y; 81 90 82 91 static void vp_switch(int vp) … … 86 95 87 96 /** Create view port */ 88 static int vp_create(unsigned int x, unsigned int y, unsigned int width, 89 unsigned int height) 97 static int vp_create(size_t x, size_t y, size_t width, size_t height) 90 98 { 91 99 return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y, … … 98 106 } 99 107 100 static void set_rgb_color( int fgcolor, int bgcolor)108 static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor) 101 109 { 102 110 async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor); … … 104 112 105 113 /** Transparent putchar */ 106 static void tran_putch( char c, int row, int col)107 { 108 async_msg_3(fbphone, FB_PUTCHAR, c , row, col);114 static void tran_putch(wchar_t ch, size_t col, size_t row) 115 { 116 async_msg_3(fbphone, FB_PUTCHAR, ch, col, row); 109 117 } 110 118 111 119 /** Redraw the button showing state of a given console */ 112 static void redraw_state(int consnum) 113 { 114 char data[5]; 115 int i; 116 enum butstate state = console_state[consnum]; 117 118 vp_switch(cstatus_vp[consnum]); 120 static void redraw_state(size_t index) 121 { 122 vp_switch(cstatus_vp[index]); 123 124 enum butstate state = console_state[index]; 125 119 126 if (ic_pixmaps[state] != -1) 120 async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[ consnum],127 async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index], 121 128 ic_pixmaps[state]); 122 129 123 if (state != CONS_DISCONNECTED && state != CONS_KERNEL && 124 state != CONS_DISCONNECTED_SEL) { 125 snprintf(data, 5, "%d", consnum + 1); 126 for (i = 0; data[i]; i++) 127 tran_putch(data[i], 1, 2 + i); 130 if ((state != CONS_DISCONNECTED) && (state != CONS_KERNEL) 131 && (state != CONS_DISCONNECTED_SEL)) { 132 133 char data[5]; 134 snprintf(data, 5, "%u", index + 1); 135 136 size_t i; 137 for (i = 0; data[i] != 0; i++) 138 tran_putch(data[i], 2 + i, 1); 128 139 } 129 140 } 130 141 131 142 /** Notification run on changing console (except kernel console) */ 132 void gcons_change_console(int consnum) 133 { 134 int i; 135 143 void gcons_change_console(size_t index) 144 { 136 145 if (!use_gcons) 137 146 return; 138 147 139 148 if (active_console == KERNEL_CONSOLE) { 149 size_t i; 150 140 151 for (i = 0; i < CONSOLE_COUNT; i++) 141 152 redraw_state(i); 153 142 154 if (animation != -1) 143 155 async_msg_1(fbphone, FB_ANIM_START, animation); … … 147 159 else 148 160 console_state[active_console] = CONS_IDLE; 161 149 162 redraw_state(active_console); 150 163 } 151 active_console = consnum; 152 153 if (console_state[consnum] == CONS_DISCONNECTED) { 154 console_state[consnum] = CONS_DISCONNECTED_SEL; 155 redraw_state(consnum); 156 } else 157 console_state[consnum] = CONS_SELECTED; 158 redraw_state(consnum); 159 164 165 active_console = index; 166 167 if ((console_state[index] == CONS_DISCONNECTED) 168 || (console_state[index] == CONS_DISCONNECTED_SEL)) 169 console_state[index] = CONS_DISCONNECTED_SEL; 170 else 171 console_state[index] = CONS_SELECTED; 172 173 redraw_state(index); 160 174 vp_switch(console_vp); 161 175 } 162 176 163 177 /** Notification function that gets called on new output to virtual console */ 164 void gcons_notify_char( int consnum)178 void gcons_notify_char(size_t index) 165 179 { 166 180 if (!use_gcons) 167 181 return; 168 182 169 if (( consnum == active_console) ||170 (console_state[consnum] == CONS_HAS_DATA))171 return; 172 173 console_state[ consnum] = CONS_HAS_DATA;183 if ((index == active_console) 184 || (console_state[index] == CONS_HAS_DATA)) 185 return; 186 187 console_state[index] = CONS_HAS_DATA; 174 188 175 189 if (active_console == KERNEL_CONSOLE) 176 190 return; 177 191 178 redraw_state(consnum); 179 192 redraw_state(index); 180 193 vp_switch(console_vp); 181 194 } 182 195 183 196 /** Notification function called on service disconnect from console */ 184 void gcons_notify_disconnect( int consnum)197 void gcons_notify_disconnect(size_t index) 185 198 { 186 199 if (!use_gcons) 187 200 return; 188 201 189 if ( active_console == consnum)190 console_state[ consnum] = CONS_DISCONNECTED_SEL;202 if (index == active_console) 203 console_state[index] = CONS_DISCONNECTED_SEL; 191 204 else 192 console_state[ consnum] = CONS_DISCONNECTED;205 console_state[index] = CONS_DISCONNECTED; 193 206 194 207 if (active_console == KERNEL_CONSOLE) 195 208 return; 196 209 197 redraw_state( consnum);210 redraw_state(index); 198 211 vp_switch(console_vp); 199 212 } 200 213 201 214 /** Notification function called on console connect */ 202 void gcons_notify_connect( int consnum)215 void gcons_notify_connect(size_t index) 203 216 { 204 217 if (!use_gcons) 205 218 return; 206 219 207 if ( active_console == consnum)208 console_state[ consnum] = CONS_SELECTED;220 if (index == active_console) 221 console_state[index] = CONS_SELECTED; 209 222 else 210 console_state[ consnum] = CONS_IDLE;223 console_state[index] = CONS_IDLE; 211 224 212 225 if (active_console == KERNEL_CONSOLE) 213 226 return; 214 227 215 redraw_state( consnum);228 redraw_state(index); 216 229 vp_switch(console_vp); 217 230 } … … 227 240 } 228 241 229 /** Return x, where left <= x <= right && |a-x| ==min(|a-x|) is smallest */230 static inline int limit( int a, int left, int right)242 /** Return x, where left <= x <= right && |a-x| == min(|a-x|) is smallest */ 243 static inline int limit(size_t a, size_t left, size_t right) 231 244 { 232 245 if (a < left) 233 246 a = left; 247 234 248 if (a >= right) 235 249 a = right - 1; 250 236 251 return a; 237 252 } 238 239 int mouse_x, mouse_y;240 int btn_pressed, btn_x, btn_y;241 253 242 254 /** Handle mouse move … … 245 257 * @param dy Delta Y of mouse move 246 258 */ 247 void gcons_mouse_move( int dx, int dy)259 void gcons_mouse_move(ssize_t dx, ssize_t dy) 248 260 { 249 261 mouse_x = limit(mouse_x + dx, 0, xres); … … 273 285 /** Handle mouse click 274 286 * 275 * @param state New state ( 1-pressed, 0-depressed)276 */ 277 int gcons_mouse_btn( intstate)287 * @param state New state (true - pressed, false - depressed) 288 */ 289 int gcons_mouse_btn(bool state) 278 290 { 279 291 int conbut; … … 282 294 conbut = gcons_find_conbut(mouse_x, mouse_y); 283 295 if (conbut != -1) { 284 btn_pressed = 1;296 btn_pressed = true; 285 297 btn_x = mouse_x; 286 298 btn_y = mouse_y; … … 292 304 return -1; 293 305 294 btn_pressed = 0;306 btn_pressed = false; 295 307 296 308 conbut = gcons_find_conbut(mouse_x, mouse_y); … … 374 386 * @param data PPM data 375 387 * @param size PPM data size 388 * 376 389 * @return Pixmap identification 377 */ 378 static int make_pixmap(char *data, int size) 390 * 391 */ 392 static int make_pixmap(char *data, size_t size) 379 393 { 380 394 char *shm; … … 465 479 void gcons_init(int phone) 466 480 { 467 int rc;468 int i;469 int status_start = STATUS_START;470 471 481 fbphone = phone; 472 482 473 rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);483 int rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres); 474 484 if (rc) 475 485 return; … … 484 494 ALIGN_DOWN(xres - 2 * CONSOLE_MARGIN, 8), 485 495 ALIGN_DOWN(yres - (CONSOLE_TOP + CONSOLE_MARGIN), 16)); 496 486 497 if (console_vp < 0) 487 498 return; 488 499 489 500 /* Create status buttons */ 490 status_start += (xres - 800) / 2; 501 size_t status_start = STATUS_START + (xres - 800) / 2; 502 size_t i; 491 503 for (i = 0; i < CONSOLE_COUNT; i++) { 492 504 cstatus_vp[i] = vp_create(status_start + CONSOLE_MARGIN + 493 505 i * (STATUS_WIDTH + STATUS_SPACE), STATUS_TOP, 494 506 STATUS_WIDTH, STATUS_HEIGHT); 507 495 508 if (cstatus_vp[i] < 0) 496 509 return; 510 497 511 vp_switch(cstatus_vp[i]); 498 512 set_rgb_color(0x202020, 0xffffff); … … 502 516 ic_pixmaps[CONS_SELECTED] = 503 517 make_pixmap(_binary_gfx_cons_selected_ppm_start, 504 ( int) &_binary_gfx_cons_selected_ppm_size);518 (size_t) &_binary_gfx_cons_selected_ppm_size); 505 519 ic_pixmaps[CONS_IDLE] = 506 520 make_pixmap(_binary_gfx_cons_idle_ppm_start, 507 ( int) &_binary_gfx_cons_idle_ppm_size);521 (size_t) &_binary_gfx_cons_idle_ppm_size); 508 522 ic_pixmaps[CONS_HAS_DATA] = 509 523 make_pixmap(_binary_gfx_cons_has_data_ppm_start, 510 ( int) &_binary_gfx_cons_has_data_ppm_size);524 (size_t) &_binary_gfx_cons_has_data_ppm_size); 511 525 ic_pixmaps[CONS_DISCONNECTED] = 512 526 make_pixmap(_binary_gfx_cons_idle_ppm_start, 513 ( int) &_binary_gfx_cons_idle_ppm_size);527 (size_t) &_binary_gfx_cons_idle_ppm_size); 514 528 ic_pixmaps[CONS_KERNEL] = 515 529 make_pixmap(_binary_gfx_cons_kernel_ppm_start, 516 ( int) &_binary_gfx_cons_kernel_ppm_size);530 (size_t) &_binary_gfx_cons_kernel_ppm_size); 517 531 ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED]; 518 532 519 533 make_anim(); 520 534 521 use_gcons = 1;535 use_gcons = true; 522 536 console_state[0] = CONS_DISCONNECTED_SEL; 523 537 console_state[KERNEL_CONSOLE] = CONS_KERNEL; 538 524 539 gcons_redraw_console(); 525 540 } -
uspace/srv/console/gcons.h
rb0a91acb r424cd43 33 33 */ 34 34 35 #ifndef _GCONS_H_ 36 #define _GCONS_H_ 35 #ifndef GCONS_H_ 36 #define GCONS_H_ 37 38 #include <sys/types.h> 37 39 38 40 void gcons_init(int phone); 41 39 42 void gcons_redraw_console(void); 40 void gcons_change_console( int consnum);41 void gcons_notify_char( int consnum);43 void gcons_change_console(size_t index); 44 void gcons_notify_char(size_t index); 42 45 void gcons_in_kernel(void); 43 void gcons_notify_connect(int consnum); 44 void gcons_notify_disconnect(int consnum); 45 void gcons_mouse_move(int dx, int dy); 46 int gcons_mouse_btn(int state); 46 47 void gcons_notify_connect(size_t index); 48 void gcons_notify_disconnect(size_t index); 49 50 void gcons_mouse_move(ssize_t dx, ssize_t dy); 51 int gcons_mouse_btn(bool state); 47 52 48 53 #endif -
uspace/srv/console/screenbuffer.c
rb0a91acb r424cd43 34 34 35 35 #include <screenbuffer.h> 36 #include < console/style.h>36 #include <io/style.h> 37 37 #include <malloc.h> 38 38 #include <unistd.h> … … 67 67 * 68 68 */ 69 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y)69 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y) 70 70 { 71 71 scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y); … … 91 91 void screenbuffer_clear(screenbuffer_t *scr) 92 92 { 93 unsigned int i;93 size_t i; 94 94 95 95 for (i = 0; i < (scr->size_x * scr->size_y); i++) { … … 99 99 100 100 scr->top_line = 0; 101 scr->position_x = 0; 101 102 scr->position_y = 0; 102 scr->position_x = 0;103 103 } 104 104 … … 109 109 * 110 110 */ 111 void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line)111 void screenbuffer_clear_line(screenbuffer_t *scr, size_t line) 112 112 { 113 unsigned int i;113 size_t x; 114 114 115 for ( i = 0; i < scr->size_x; i++) {116 scr->buffer[ i+ line * scr->size_x].character = ' ';117 scr->buffer[ i+ line * scr->size_x].attrs = scr->attrs;115 for (x = 0; x < scr->size_x; x++) { 116 scr->buffer[x + line * scr->size_x].character = ' '; 117 scr->buffer[x + line * scr->size_x].attrs = scr->attrs; 118 118 } 119 119 } … … 125 125 * 126 126 */ 127 void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest) 127 void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest) 128 128 { 129 unsigned int i;129 size_t i; 130 130 131 for (i = 0; i < scr->size_x * scr->size_y; i++)131 for (i = 0; i < (scr->size_x * scr->size_y); i++) 132 132 dest[i] = scr->buffer[i]; 133 133 } … … 140 140 * 141 141 */ 142 void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y)142 void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y) 143 143 { 144 144 scr->position_x = x % scr->size_x; … … 153 153 * 154 154 */ 155 void screenbuffer_set_style(screenbuffer_t *scr, int style)155 void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style) 156 156 { 157 157 scr->attrs.t = at_style; … … 166 166 * 167 167 */ 168 void screenbuffer_set_color(screenbuffer_t *scr, u nsigned int fg_color, unsigned int bg_color, unsigned int flags)168 void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, uint8_t bg_color, uint8_t flags) 169 169 { 170 170 scr->attrs.t = at_idx; … … 181 181 * 182 182 */ 183 void screenbuffer_set_rgb_color(screenbuffer_t *scr, u nsigned int fg_color, unsigned int bg_color)183 void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, uint32_t bg_color) 184 184 { 185 185 scr->attrs.t = at_rgb; -
uspace/srv/console/screenbuffer.h
rb0a91acb r424cd43 38 38 #include <stdint.h> 39 39 #include <sys/types.h> 40 #include <bool.h> 40 41 41 #define DEFAULT_FOREGROUND 0x0 /**< default console foreground color */42 #define DEFAULT_BACKGROUND 0xf0f0f0 /**< default console background color */42 #define DEFAULT_FOREGROUND 0x0 /**< default console foreground color */ 43 #define DEFAULT_BACKGROUND 0xf0f0f0 /**< default console background color */ 43 44 44 45 typedef struct { … … 73 74 typedef struct { 74 75 wchar_t character; /**< Character itself */ 75 attrs_t attrs; /**< Character `sattributes */76 attrs_t attrs; /**< Character attributes */ 76 77 } keyfield_t; 77 78 … … 79 80 */ 80 81 typedef struct { 81 keyfield_t *buffer; 82 83 unsigned int size_x;/**< Number of columns */84 unsigned int size_y;/**< Number of rows */82 keyfield_t *buffer; /**< Screen content - characters and 83 their attributes (used as a circular buffer) */ 84 size_t size_x; /**< Number of columns */ 85 size_t size_y; /**< Number of rows */ 85 86 86 87 /** Coordinates of last printed character for determining cursor position */ 87 unsigned int position_x;88 unsigned int position_y;88 size_t position_x; 89 size_t position_y; 89 90 90 attrs_t attrs; 91 unsigned int top_line;/**< Points to buffer[][] line that will92 93 unsigned charis_cursor_visible; /**< Cursor state - default is visible */91 attrs_t attrs; /**< Current attributes. */ 92 size_t top_line; /**< Points to buffer[][] line that will 93 be printed at screen as the first line */ 94 bool is_cursor_visible; /**< Cursor state - default is visible */ 94 95 } screenbuffer_t; 95 96 … … 106 107 * 107 108 */ 108 static inline keyfield_t *get_field_at(screenbuffer_t *scr, unsigned int x, unsigned int y)109 static inline keyfield_t *get_field_at(screenbuffer_t *scr, size_t x, size_t y) 109 110 { 110 111 return scr->buffer + x + ((y + scr->top_line) % scr->size_y) * scr->size_x; … … 139 140 140 141 void screenbuffer_putchar(screenbuffer_t *scr, wchar_t c); 141 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y);142 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y); 142 143 143 144 void screenbuffer_clear(screenbuffer_t *scr); 144 void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line);145 void screenbuffer_clear_line(screenbuffer_t *scr, size_t line); 145 146 void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest); 146 void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y);147 void screenbuffer_set_style(screenbuffer_t *scr, int style);148 void screenbuffer_set_color(screenbuffer_t *scr, u nsigned int fg_color,149 u nsigned int bg_color, unsigned int attr);150 void screenbuffer_set_rgb_color(screenbuffer_t *scr, u nsigned int fg_color,151 u nsigned int bg_color);147 void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y); 148 void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style); 149 void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, 150 uint8_t bg_color, uint8_t attr); 151 void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, 152 uint32_t bg_color); 152 153 153 154 #endif
Note:
See TracChangeset
for help on using the changeset viewer.