Changeset 33fee91 in mainline for uspace/srv/hid/console/console.c
- Timestamp:
- 2012-08-31T07:35:27Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a3da2b2
- Parents:
- 72cf064 (diff), 0d57c3e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
uspace/srv/hid/console/console.c (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
r72cf064 r33fee91 36 36 #include <stdio.h> 37 37 #include <adt/prodcons.h> 38 #include <ipc/input.h> 39 #include <ipc/console.h> 38 #include <io/input.h> 40 39 #include <ipc/vfs.h> 41 40 #include <errno.h> … … 43 42 #include <loc.h> 44 43 #include <event.h> 44 #include <io/con_srv.h> 45 #include <io/kbd_event.h> 45 46 #include <io/keycode.h> 46 #include <screenbuffer.h> 47 #include <fb.h> 48 #include <imgmap.h> 47 #include <io/chargrid.h> 48 #include <io/output.h> 49 49 #include <align.h> 50 50 #include <malloc.h> 51 51 #include <as.h> 52 52 #include <fibril_synch.h> 53 #include "images.h"54 53 #include "console.h" 55 54 … … 57 56 #define NAMESPACE "term" 58 57 59 #define CONSOLE_TOP 66 60 #define CONSOLE_MARGIN 12 61 62 #define STATE_START 100 63 #define STATE_TOP 8 64 #define STATE_SPACE 4 65 #define STATE_WIDTH 48 66 #define STATE_HEIGHT 48 67 68 typedef enum { 69 CONS_DISCONNECTED = 0, 70 CONS_DISCONNECTED_SELECTED, 71 CONS_SELECTED, 72 CONS_IDLE, 73 CONS_DATA, 74 CONS_KERNEL, 75 CONS_LAST 76 } console_state_t; 77 78 #define UTF8_CHAR_BUFFER_SIZE (STR_BOUNDS(1) + 1) 58 #define UTF8_CHAR_BUFFER_SIZE (STR_BOUNDS(1) + 1) 79 59 80 60 typedef struct { 81 atomic_t refcnt; /**< Connection reference count */ 82 prodcons_t input_pc; /**< Incoming keyboard events */ 83 char char_remains[UTF8_CHAR_BUFFER_SIZE]; /**< Not yet sent bytes of last char event. */ 84 size_t char_remains_len; /**< Number of not yet sent bytes. */ 85 86 fibril_mutex_t mtx; /**< Lock protecting mutable fields */ 87 88 size_t index; /**< Console index */ 89 console_state_t state; /**< Console state */ 90 service_id_t dsid; /**< Service handle */ 91 92 vp_handle_t state_vp; /**< State icon viewport */ 93 sysarg_t cols; /**< Number of columns */ 94 sysarg_t rows; /**< Number of rows */ 95 console_caps_t ccaps; /**< Console capabilities */ 96 97 screenbuffer_t *frontbuf; /**< Front buffer */ 98 frontbuf_handle_t fbid; /**< Front buffer handle */ 61 atomic_t refcnt; /**< Connection reference count */ 62 prodcons_t input_pc; /**< Incoming keyboard events */ 63 64 /** 65 * Not yet sent bytes of last char event. 66 */ 67 char char_remains[UTF8_CHAR_BUFFER_SIZE]; 68 size_t char_remains_len; /**< Number of not yet sent bytes. */ 69 70 fibril_mutex_t mtx; /**< Lock protecting mutable fields */ 71 72 size_t index; /**< Console index */ 73 service_id_t dsid; /**< Service handle */ 74 75 sysarg_t cols; /**< Number of columns */ 76 sysarg_t rows; /**< Number of rows */ 77 console_caps_t ccaps; /**< Console capabilities */ 78 79 chargrid_t *frontbuf; /**< Front buffer */ 80 frontbuf_handle_t fbid; /**< Front buffer handle */ 81 con_srvs_t srvs; /**< Console service setup */ 99 82 } console_t; 100 83 101 typedef enum { 102 GRAPHICS_NONE = 0, 103 GRAPHICS_BASIC = 1, 104 GRAPHICS_FULL = 2 105 } graphics_state_t; 106 107 /** Current console state */ 108 static graphics_state_t graphics_state = GRAPHICS_NONE; 109 110 /** State icons */ 111 static imagemap_handle_t state_icons[CONS_LAST]; 112 113 /** Session to the input server */ 114 static async_sess_t *input_sess; 115 116 /** Session to the framebuffer server */ 117 static async_sess_t *fb_sess; 118 119 /** Framebuffer resolution */ 120 static sysarg_t xres; 121 static sysarg_t yres; 84 /** Input server proxy */ 85 static input_t *input; 86 87 /** Session to the output server */ 88 static async_sess_t *output_sess; 89 90 /** Output dimensions */ 91 static sysarg_t cols; 92 static sysarg_t rows; 122 93 123 94 /** Array of data for virtual consoles */ … … 131 102 static console_t *kernel_console = &consoles[KERNEL_CONSOLE]; 132 103 133 static imgmap_t *logo_img; 134 static imgmap_t *nameic_img; 135 136 static imgmap_t *anim_1_img; 137 static imgmap_t *anim_2_img; 138 static imgmap_t *anim_3_img; 139 static imgmap_t *anim_4_img; 140 141 static imagemap_handle_t anim_1; 142 static imagemap_handle_t anim_2; 143 static imagemap_handle_t anim_3; 144 static imagemap_handle_t anim_4; 145 146 static sequence_handle_t anim_seq; 147 148 static imgmap_t *cons_data_img; 149 static imgmap_t *cons_dis_img; 150 static imgmap_t *cons_dis_sel_img; 151 static imgmap_t *cons_idle_img; 152 static imgmap_t *cons_kernel_img; 153 static imgmap_t *cons_sel_img; 154 155 static vp_handle_t logo_vp; 156 static imagemap_handle_t logo_handle; 157 158 static vp_handle_t nameic_vp; 159 static imagemap_handle_t nameic_handle; 160 161 static vp_handle_t screen_vp; 162 static vp_handle_t console_vp; 163 164 struct { 165 sysarg_t x; 166 sysarg_t y; 167 168 sysarg_t btn_x; 169 sysarg_t btn_y; 170 171 bool pressed; 172 } mouse; 173 174 static void cons_redraw_state(console_t *cons) 175 { 176 if (graphics_state == GRAPHICS_FULL) { 177 fibril_mutex_lock(&cons->mtx); 178 179 fb_vp_imagemap_damage(fb_sess, cons->state_vp, 180 state_icons[cons->state], 0, 0, STATE_WIDTH, STATE_HEIGHT); 181 182 if ((cons->state != CONS_DISCONNECTED) && 183 (cons->state != CONS_KERNEL) && 184 (cons->state != CONS_DISCONNECTED_SELECTED)) { 185 char data[5]; 186 snprintf(data, 5, "%zu", cons->index + 1); 187 188 for (size_t i = 0; data[i] != 0; i++) 189 fb_vp_putchar(fb_sess, cons->state_vp, i + 2, 1, data[i]); 190 } 191 192 fibril_mutex_unlock(&cons->mtx); 193 } 194 } 195 196 static void cons_kernel_sequence_start(console_t *cons) 197 { 198 if (graphics_state == GRAPHICS_FULL) { 199 fibril_mutex_lock(&cons->mtx); 200 201 fb_vp_sequence_start(fb_sess, cons->state_vp, anim_seq); 202 fb_vp_imagemap_damage(fb_sess, cons->state_vp, 203 state_icons[cons->state], 0, 0, STATE_WIDTH, STATE_HEIGHT); 204 205 fibril_mutex_unlock(&cons->mtx); 206 } 207 } 208 209 static void cons_update_state(console_t *cons, console_state_t state) 210 { 211 bool update = false; 212 213 fibril_mutex_lock(&cons->mtx); 214 215 if (cons->state != state) { 216 cons->state = state; 217 update = true; 218 } 219 220 fibril_mutex_unlock(&cons->mtx); 221 222 if (update) 223 cons_redraw_state(cons); 224 } 225 226 static void cons_notify_data(console_t *cons) 104 static int input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 105 static int input_ev_move(input_t *, int, int); 106 static int input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned); 107 static int input_ev_button(input_t *, int, int); 108 109 static input_ev_ops_t input_ev_ops = { 110 .key = input_ev_key, 111 .move = input_ev_move, 112 .abs_move = input_ev_abs_move, 113 .button = input_ev_button 114 }; 115 116 static int cons_open(con_srvs_t *, con_srv_t *); 117 static int cons_close(con_srv_t *); 118 static int cons_read(con_srv_t *, void *, size_t); 119 static int cons_write(con_srv_t *, void *, size_t); 120 static void cons_sync(con_srv_t *); 121 static void cons_clear(con_srv_t *); 122 static void cons_set_pos(con_srv_t *, sysarg_t col, sysarg_t row); 123 static int cons_get_pos(con_srv_t *, sysarg_t *, sysarg_t *); 124 static int cons_get_size(con_srv_t *, sysarg_t *, sysarg_t *); 125 static int cons_get_color_cap(con_srv_t *, console_caps_t *); 126 static void cons_set_style(con_srv_t *, console_style_t); 127 static void cons_set_color(con_srv_t *, console_color_t, console_color_t, 128 console_color_attr_t); 129 static void cons_set_rgb_color(con_srv_t *, pixel_t, pixel_t); 130 static void cons_set_cursor_visibility(con_srv_t *, bool); 131 static int cons_get_event(con_srv_t *, kbd_event_t *); 132 133 static con_ops_t con_ops = { 134 .open = cons_open, 135 .close = cons_close, 136 .read = cons_read, 137 .write = cons_write, 138 .sync = cons_sync, 139 .clear = cons_clear, 140 .set_pos = cons_set_pos, 141 .get_pos = cons_get_pos, 142 .get_size = cons_get_size, 143 .get_color_cap = cons_get_color_cap, 144 .set_style = cons_set_style, 145 .set_color = cons_set_color, 146 .set_rgb_color = cons_set_rgb_color, 147 .set_cursor_visibility = cons_set_cursor_visibility, 148 .get_event = cons_get_event 149 }; 150 151 static console_t *srv_to_console(con_srv_t *srv) 152 { 153 return srv->srvs->sarg; 154 } 155 156 static void cons_update(console_t *cons) 227 157 { 228 158 fibril_mutex_lock(&switch_mtx); 229 230 if (cons != active_console) 231 cons_update_state(cons, CONS_DATA); 232 159 fibril_mutex_lock(&cons->mtx); 160 161 if ((cons == active_console) && (active_console != kernel_console)) { 162 output_update(output_sess, cons->fbid); 163 output_cursor_update(output_sess, cons->fbid); 164 } 165 166 fibril_mutex_unlock(&cons->mtx); 233 167 fibril_mutex_unlock(&switch_mtx); 234 168 } 235 169 236 static void cons_ notify_connect(console_t *cons)170 static void cons_update_cursor(console_t *cons) 237 171 { 238 172 fibril_mutex_lock(&switch_mtx); 239 240 if (cons == active_console)241 cons_update_state(cons, CONS_SELECTED);242 else243 cons_update_state(cons, CONS_IDLE);244 173 fibril_mutex_lock(&cons->mtx); 174 175 if ((cons == active_console) && (active_console != kernel_console)) 176 output_cursor_update(output_sess, cons->fbid); 177 178 fibril_mutex_unlock(&cons->mtx); 245 179 fibril_mutex_unlock(&switch_mtx); 246 180 } 247 181 248 static void cons_ notify_disconnect(console_t *cons)182 static void cons_damage(console_t *cons) 249 183 { 250 184 fibril_mutex_lock(&switch_mtx); 251 252 if (cons == active_console)253 cons_update_state(cons, CONS_DISCONNECTED_SELECTED);254 else255 cons_update_state(cons, CONS_DISCONNECTED);256 257 fibril_mutex_unlock(&switch_mtx);258 }259 260 static void cons_update(console_t *cons)261 {262 fibril_mutex_lock(&switch_mtx);263 185 fibril_mutex_lock(&cons->mtx); 264 186 265 187 if ((cons == active_console) && (active_console != kernel_console)) { 266 fb_vp_update(fb_sess, console_vp, cons->fbid); 267 fb_vp_cursor_update(fb_sess, console_vp, cons->fbid); 268 } 269 270 fibril_mutex_unlock(&cons->mtx); 271 fibril_mutex_unlock(&switch_mtx); 272 } 273 274 static void cons_update_cursor(console_t *cons) 275 { 276 fibril_mutex_lock(&switch_mtx); 277 fibril_mutex_lock(&cons->mtx); 278 279 if ((cons == active_console) && (active_console != kernel_console)) 280 fb_vp_cursor_update(fb_sess, console_vp, cons->fbid); 281 282 fibril_mutex_unlock(&cons->mtx); 283 fibril_mutex_unlock(&switch_mtx); 284 } 285 286 static void cons_clear(console_t *cons) 287 { 288 fibril_mutex_lock(&cons->mtx); 289 screenbuffer_clear(cons->frontbuf); 290 fibril_mutex_unlock(&cons->mtx); 291 292 cons_update(cons); 293 } 294 295 static void cons_damage_all(console_t *cons) 296 { 297 fibril_mutex_lock(&switch_mtx); 298 fibril_mutex_lock(&cons->mtx); 299 300 if ((cons == active_console) && (active_console != kernel_console)) { 301 fb_vp_damage(fb_sess, console_vp, cons->fbid, 0, 0, cons->cols, 188 output_damage(output_sess, cons->fbid, 0, 0, cons->cols, 302 189 cons->rows); 303 fb_vp_cursor_update(fb_sess, console_vp, cons->fbid);190 output_cursor_update(output_sess, cons->fbid); 304 191 } 305 192 … … 318 205 319 206 if (cons == kernel_console) { 320 fb_yield(fb_sess);207 output_yield(output_sess); 321 208 if (!console_kcon()) { 322 fb_claim(fb_sess);209 output_claim(output_sess); 323 210 fibril_mutex_unlock(&switch_mtx); 324 211 return; … … 327 214 328 215 if (active_console == kernel_console) 329 fb_claim(fb_sess);216 output_claim(output_sess); 330 217 331 218 prev_console = active_console; 332 219 active_console = cons; 333 220 334 if (prev_console->state == CONS_DISCONNECTED_SELECTED)335 cons_update_state(prev_console, CONS_DISCONNECTED);336 else337 cons_update_state(prev_console, CONS_IDLE);338 339 if ((cons->state == CONS_DISCONNECTED) ||340 (cons->state == CONS_DISCONNECTED_SELECTED))341 cons_update_state(cons, CONS_DISCONNECTED_SELECTED);342 else343 cons_update_state(cons, CONS_SELECTED);344 345 221 fibril_mutex_unlock(&switch_mtx); 346 222 347 cons_damage _all(cons);223 cons_damage(cons); 348 224 } 349 225 … … 351 227 { 352 228 fibril_mutex_lock(&switch_mtx); 353 229 354 230 console_t *active_uspace = active_console; 355 if (active_uspace == kernel_console) {231 if (active_uspace == kernel_console) 356 232 active_uspace = prev_console; 357 }233 358 234 assert(active_uspace != kernel_console); 359 235 360 236 fibril_mutex_unlock(&switch_mtx); 361 237 362 238 return active_uspace; 363 239 } 364 240 365 static ssize_t limit(ssize_t val, ssize_t lo, ssize_t hi) 366 { 367 if (val > hi) 368 return hi; 369 370 if (val < lo) 371 return lo; 372 373 return val; 374 } 375 376 static void cons_mouse_move(sysarg_t dx, sysarg_t dy) 377 { 378 ssize_t sx = (ssize_t) dx; 379 ssize_t sy = (ssize_t) dy; 380 381 mouse.x = limit(mouse.x + sx, 0, xres); 382 mouse.y = limit(mouse.y + sy, 0, yres); 383 384 fb_pointer_update(fb_sess, mouse.x, mouse.y, true); 385 } 386 387 static console_t *cons_find_icon(sysarg_t x, sysarg_t y) 388 { 389 sysarg_t status_start = 390 STATE_START + (xres - 800) / 2 + CONSOLE_MARGIN; 391 392 if ((y < STATE_TOP) || (y >= STATE_TOP + STATE_HEIGHT)) 393 return NULL; 394 395 if (x < status_start) 396 return NULL; 397 398 if (x >= status_start + (STATE_WIDTH + STATE_SPACE) * CONSOLE_COUNT) 399 return NULL; 400 401 if (((x - status_start) % (STATE_WIDTH + STATE_SPACE)) >= STATE_WIDTH) 402 return NULL; 403 404 sysarg_t btn = (x - status_start) / (STATE_WIDTH + STATE_SPACE); 405 406 if (btn < CONSOLE_COUNT) 407 return consoles + btn; 408 409 return NULL; 410 } 411 412 /** Handle mouse click 413 * 414 * @param state Button state (true - pressed, false - depressed) 415 * 416 */ 417 static console_t *cons_mouse_button(bool state) 418 { 419 if (graphics_state != GRAPHICS_FULL) 420 return NULL; 421 422 if (state) { 423 console_t *cons = cons_find_icon(mouse.x, mouse.y); 424 if (cons != NULL) { 425 mouse.btn_x = mouse.x; 426 mouse.btn_y = mouse.y; 427 mouse.pressed = true; 428 } 429 430 return NULL; 431 } 432 433 if ((!state) && (!mouse.pressed)) 434 return NULL; 435 436 console_t *cons = cons_find_icon(mouse.x, mouse.y); 437 if (cons == cons_find_icon(mouse.btn_x, mouse.btn_y)) 438 return cons; 439 440 mouse.pressed = false; 441 return NULL; 442 } 443 444 static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg) 445 { 446 /* Ignore parameters, the connection is already opened */ 447 while (true) { 448 ipc_call_t call; 449 ipc_callid_t callid = async_get_call(&call); 450 451 if (!IPC_GET_IMETHOD(call)) { 452 /* TODO: Handle hangup */ 453 async_hangup(input_sess); 454 return; 455 } 456 457 kbd_event_type_t type; 458 keycode_t key; 459 keymod_t mods; 460 wchar_t c; 461 462 switch (IPC_GET_IMETHOD(call)) { 463 case INPUT_EVENT_KEY: 464 type = IPC_GET_ARG1(call); 465 key = IPC_GET_ARG2(call); 466 mods = IPC_GET_ARG3(call); 467 c = IPC_GET_ARG4(call); 468 469 if ((key >= KC_F1) && (key < KC_F1 + CONSOLE_COUNT) && 470 ((mods & KM_CTRL) == 0)) 471 cons_switch(&consoles[key - KC_F1]); 472 else { 473 /* Got key press/release event */ 474 kbd_event_t *event = 475 (kbd_event_t *) malloc(sizeof(kbd_event_t)); 476 if (event == NULL) { 477 async_answer_0(callid, ENOMEM); 478 break; 479 } 480 481 link_initialize(&event->link); 482 event->type = type; 483 event->key = key; 484 event->mods = mods; 485 event->c = c; 486 487 /* 488 * Kernel console does not read events 489 * from us, so we will redirect them 490 * to the (last) active userspace console 491 * if necessary. 492 */ 493 console_t *target_console = cons_get_active_uspace(); 494 495 prodcons_produce(&target_console->input_pc, 496 &event->link); 497 } 498 499 async_answer_0(callid, EOK); 500 break; 501 case INPUT_EVENT_MOVE: 502 cons_mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 503 async_answer_0(callid, EOK); 504 break; 505 case INPUT_EVENT_BUTTON: 506 /* Got pointer button press/release event */ 507 if (IPC_GET_ARG1(call) == 1) { 508 console_t *cons = 509 cons_mouse_button((bool) IPC_GET_ARG2(call)); 510 if (cons != NULL) 511 cons_switch(cons); 512 } 513 async_answer_0(callid, EOK); 514 break; 515 default: 516 async_answer_0(callid, EINVAL); 517 } 518 } 241 static int input_ev_key(input_t *input, kbd_event_type_t type, keycode_t key, 242 keymod_t mods, wchar_t c) 243 { 244 if ((key >= KC_F1) && (key < KC_F1 + CONSOLE_COUNT) && 245 ((mods & KM_CTRL) == 0)) { 246 cons_switch(&consoles[key - KC_F1]); 247 } else { 248 /* Got key press/release event */ 249 kbd_event_t *event = 250 (kbd_event_t *) malloc(sizeof(kbd_event_t)); 251 if (event == NULL) { 252 return ENOMEM; 253 } 254 255 link_initialize(&event->link); 256 event->type = type; 257 event->key = key; 258 event->mods = mods; 259 event->c = c; 260 261 /* 262 * Kernel console does not read events 263 * from us, so we will redirect them 264 * to the (last) active userspace console 265 * if necessary. 266 */ 267 console_t *target_console = cons_get_active_uspace(); 268 269 prodcons_produce(&target_console->input_pc, 270 &event->link); 271 } 272 273 return EOK; 274 } 275 276 static int input_ev_move(input_t *input, int dx, int dy) 277 { 278 return EOK; 279 } 280 281 static int input_ev_abs_move(input_t *input, unsigned x , unsigned y, 282 unsigned max_x, unsigned max_y) 283 { 284 return EOK; 285 } 286 287 static int input_ev_button(input_t *input, int bnum, int bpress) 288 { 289 return EOK; 519 290 } 520 291 … … 528 299 switch (ch) { 529 300 case '\n': 530 updated = screenbuffer_newline(cons->frontbuf);301 updated = chargrid_newline(cons->frontbuf); 531 302 break; 532 303 case '\r': 533 304 break; 534 305 case '\t': 535 updated = screenbuffer_tabstop(cons->frontbuf, 8);306 updated = chargrid_tabstop(cons->frontbuf, 8); 536 307 break; 537 308 case '\b': 538 updated = screenbuffer_backspace(cons->frontbuf);309 updated = chargrid_backspace(cons->frontbuf); 539 310 break; 540 311 default: 541 updated = screenbuffer_putchar(cons->frontbuf, ch, true);312 updated = chargrid_putchar(cons->frontbuf, ch, true); 542 313 } 543 314 … … 548 319 } 549 320 550 static void cons_set_cursor (console_t *cons, sysarg_t col, sysarg_t row)551 { 552 fibril_mutex_lock(&cons->mtx); 553 screenbuffer_set_cursor(cons->frontbuf, col, row);321 static void cons_set_cursor_vis(console_t *cons, bool visible) 322 { 323 fibril_mutex_lock(&cons->mtx); 324 chargrid_set_cursor_visibility(cons->frontbuf, visible); 554 325 fibril_mutex_unlock(&cons->mtx); 555 326 … … 557 328 } 558 329 559 static void cons_set_cursor_visibility(console_t *cons, bool visible) 560 { 561 fibril_mutex_lock(&cons->mtx); 562 screenbuffer_set_cursor_visibility(cons->frontbuf, visible); 563 fibril_mutex_unlock(&cons->mtx); 564 565 cons_update_cursor(cons); 566 } 567 568 static void cons_get_cursor(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 569 { 570 sysarg_t col; 571 sysarg_t row; 572 573 fibril_mutex_lock(&cons->mtx); 574 screenbuffer_get_cursor(cons->frontbuf, &col, &row); 575 fibril_mutex_unlock(&cons->mtx); 576 577 async_answer_2(iid, EOK, col, row); 578 } 579 580 static void cons_write(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 581 { 582 void *buf; 583 size_t size; 584 int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size); 585 586 if (rc != EOK) { 587 async_answer_0(iid, rc); 588 return; 589 } 590 591 size_t off = 0; 592 while (off < size) 593 cons_write_char(cons, str_decode(buf, &off, size)); 594 595 async_answer_1(iid, EOK, size); 596 free(buf); 597 598 cons_notify_data(cons); 599 } 600 601 static void cons_read(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 602 { 603 ipc_callid_t callid; 604 size_t size; 605 if (!async_data_read_receive(&callid, &size)) { 606 async_answer_0(callid, EINVAL); 607 async_answer_0(iid, EINVAL); 608 return; 609 } 610 611 char *buf = (char *) malloc(size); 612 if (buf == NULL) { 613 async_answer_0(callid, ENOMEM); 614 async_answer_0(iid, ENOMEM); 615 return; 616 } 617 330 static int cons_open(con_srvs_t *srvs, con_srv_t *srv) 331 { 332 return EOK; 333 } 334 335 static int cons_close(con_srv_t *srv) 336 { 337 return EOK; 338 } 339 340 static int cons_read(con_srv_t *srv, void *buf, size_t size) 341 { 342 uint8_t *bbuf = buf; 343 console_t *cons = srv_to_console(srv); 618 344 size_t pos = 0; 619 345 … … 626 352 /* Copy to the buffer remaining characters. */ 627 353 while ((pos < size) && (cons->char_remains_len > 0)) { 628 b uf[pos] = cons->char_remains[0];354 bbuf[pos] = cons->char_remains[0]; 629 355 pos++; 630 356 … … 651 377 } 652 378 } 653 654 (void) async_data_read_finalize(callid, buf, size); 655 async_answer_1(iid, EOK, size); 656 free(buf); 657 } 658 659 static void cons_set_style(console_t *cons, console_style_t style) 660 { 661 fibril_mutex_lock(&cons->mtx); 662 screenbuffer_set_style(cons->frontbuf, style); 663 fibril_mutex_unlock(&cons->mtx); 664 } 665 666 static void cons_set_color(console_t *cons, console_color_t bgcolor, 379 380 return size; 381 } 382 383 static int cons_write(con_srv_t *srv, void *data, size_t size) 384 { 385 console_t *cons = srv_to_console(srv); 386 387 size_t off = 0; 388 while (off < size) 389 cons_write_char(cons, str_decode(data, &off, size)); 390 return size; 391 } 392 393 static void cons_sync(con_srv_t *srv) 394 { 395 console_t *cons = srv_to_console(srv); 396 397 cons_update(cons); 398 } 399 400 static void cons_clear(con_srv_t *srv) 401 { 402 console_t *cons = srv_to_console(srv); 403 404 fibril_mutex_lock(&cons->mtx); 405 chargrid_clear(cons->frontbuf); 406 fibril_mutex_unlock(&cons->mtx); 407 408 cons_update(cons); 409 } 410 411 static void cons_set_pos(con_srv_t *srv, sysarg_t col, sysarg_t row) 412 { 413 console_t *cons = srv_to_console(srv); 414 415 fibril_mutex_lock(&cons->mtx); 416 chargrid_set_cursor(cons->frontbuf, col, row); 417 fibril_mutex_unlock(&cons->mtx); 418 419 cons_update_cursor(cons); 420 } 421 422 static int cons_get_pos(con_srv_t *srv, sysarg_t *col, sysarg_t *row) 423 { 424 console_t *cons = srv_to_console(srv); 425 426 fibril_mutex_lock(&cons->mtx); 427 chargrid_get_cursor(cons->frontbuf, col, row); 428 fibril_mutex_unlock(&cons->mtx); 429 430 return EOK; 431 } 432 433 static int cons_get_size(con_srv_t *srv, sysarg_t *cols, sysarg_t *rows) 434 { 435 console_t *cons = srv_to_console(srv); 436 437 fibril_mutex_lock(&cons->mtx); 438 *cols = cons->cols; 439 *rows = cons->rows; 440 fibril_mutex_unlock(&cons->mtx); 441 442 return EOK; 443 } 444 445 static int cons_get_color_cap(con_srv_t *srv, console_caps_t *ccaps) 446 { 447 console_t *cons = srv_to_console(srv); 448 449 fibril_mutex_lock(&cons->mtx); 450 *ccaps = cons->ccaps; 451 fibril_mutex_unlock(&cons->mtx); 452 453 return EOK; 454 } 455 456 static void cons_set_style(con_srv_t *srv, console_style_t style) 457 { 458 console_t *cons = srv_to_console(srv); 459 460 fibril_mutex_lock(&cons->mtx); 461 chargrid_set_style(cons->frontbuf, style); 462 fibril_mutex_unlock(&cons->mtx); 463 } 464 465 static void cons_set_color(con_srv_t *srv, console_color_t bgcolor, 667 466 console_color_t fgcolor, console_color_attr_t attr) 668 467 { 669 fibril_mutex_lock(&cons->mtx); 670 screenbuffer_set_color(cons->frontbuf, bgcolor, fgcolor, attr); 671 fibril_mutex_unlock(&cons->mtx); 672 } 673 674 static void cons_set_rgb_color(console_t *cons, pixel_t bgcolor, 468 console_t *cons = srv_to_console(srv); 469 470 fibril_mutex_lock(&cons->mtx); 471 chargrid_set_color(cons->frontbuf, bgcolor, fgcolor, attr); 472 fibril_mutex_unlock(&cons->mtx); 473 } 474 475 static void cons_set_rgb_color(con_srv_t *srv, pixel_t bgcolor, 675 476 pixel_t fgcolor) 676 477 { 677 fibril_mutex_lock(&cons->mtx); 678 screenbuffer_set_rgb_color(cons->frontbuf, bgcolor, fgcolor); 679 fibril_mutex_unlock(&cons->mtx); 680 } 681 682 static void cons_get_event(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 683 { 478 console_t *cons = srv_to_console(srv); 479 480 fibril_mutex_lock(&cons->mtx); 481 chargrid_set_rgb_color(cons->frontbuf, bgcolor, fgcolor); 482 fibril_mutex_unlock(&cons->mtx); 483 } 484 485 static void cons_set_cursor_visibility(con_srv_t *srv, bool visible) 486 { 487 console_t *cons = srv_to_console(srv); 488 489 cons_set_cursor_vis(cons, visible); 490 } 491 492 static int cons_get_event(con_srv_t *srv, kbd_event_t *event) 493 { 494 console_t *cons = srv_to_console(srv); 684 495 link_t *link = prodcons_consume(&cons->input_pc); 685 kbd_event_t *event = list_get_instance(link, kbd_event_t, link); 686 687 async_answer_4(iid, EOK, event->type, event->key, event->mods, event->c); 688 free(event); 496 kbd_event_t *kevent = list_get_instance(link, kbd_event_t, link); 497 498 *event = *kevent; 499 free(kevent); 500 return EOK; 689 501 } 690 502 … … 708 520 } 709 521 710 if (atomic_postinc(&cons->refcnt) == 0) { 711 cons_set_cursor_visibility(cons, true); 712 cons_notify_connect(cons); 713 } 714 715 /* Accept the connection */ 716 async_answer_0(iid, EOK); 717 718 while (true) { 719 ipc_call_t call; 720 ipc_callid_t callid = async_get_call(&call); 721 722 if (!IPC_GET_IMETHOD(call)) { 723 if (atomic_postdec(&cons->refcnt) == 1) 724 cons_notify_disconnect(cons); 725 726 return; 727 } 728 729 switch (IPC_GET_IMETHOD(call)) { 730 case VFS_OUT_READ: 731 cons_read(cons, callid, &call); 732 break; 733 case VFS_OUT_WRITE: 734 cons_write(cons, callid, &call); 735 break; 736 case VFS_OUT_SYNC: 737 cons_update(cons); 738 async_answer_0(callid, EOK); 739 break; 740 case CONSOLE_CLEAR: 741 cons_clear(cons); 742 async_answer_0(callid, EOK); 743 break; 744 case CONSOLE_GOTO: 745 cons_set_cursor(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 746 async_answer_0(callid, EOK); 747 break; 748 case CONSOLE_GET_POS: 749 cons_get_cursor(cons, callid, &call); 750 break; 751 case CONSOLE_GET_SIZE: 752 async_answer_2(callid, EOK, cons->cols, cons->rows); 753 break; 754 case CONSOLE_GET_COLOR_CAP: 755 async_answer_1(callid, EOK, cons->ccaps); 756 break; 757 case CONSOLE_SET_STYLE: 758 cons_set_style(cons, IPC_GET_ARG1(call)); 759 async_answer_0(callid, EOK); 760 break; 761 case CONSOLE_SET_COLOR: 762 cons_set_color(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call), 763 IPC_GET_ARG3(call)); 764 async_answer_0(callid, EOK); 765 break; 766 case CONSOLE_SET_RGB_COLOR: 767 cons_set_rgb_color(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 768 async_answer_0(callid, EOK); 769 break; 770 case CONSOLE_CURSOR_VISIBILITY: 771 cons_set_cursor_visibility(cons, IPC_GET_ARG1(call)); 772 async_answer_0(callid, EOK); 773 break; 774 case CONSOLE_GET_EVENT: 775 cons_get_event(cons, callid, &call); 776 break; 777 default: 778 async_answer_0(callid, EINVAL); 779 } 780 } 781 } 782 783 static async_sess_t *input_connect(const char *svc) 522 if (atomic_postinc(&cons->refcnt) == 0) 523 cons_set_cursor_vis(cons, true); 524 525 con_conn(iid, icall, &cons->srvs); 526 } 527 528 529 static int input_connect(const char *svc) 784 530 { 785 531 async_sess_t *sess; … … 787 533 788 534 int rc = loc_service_get_id(svc, &dsid, 0); 789 if (rc == EOK) { 790 sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0); 791 if (sess == NULL) { 792 printf("%s: Unable to connect to input service %s\n", NAME, 793 svc); 794 return NULL; 795 } 796 } else 797 return NULL; 798 799 async_exch_t *exch = async_exchange_begin(sess); 800 rc = async_connect_to_me(exch, 0, 0, 0, input_events, NULL); 801 async_exchange_end(exch); 802 535 if (rc != EOK) { 536 printf("%s: Input service %s not found\n", NAME, svc); 537 return rc; 538 } 539 540 sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0); 541 if (sess == NULL) { 542 printf("%s: Unable to connect to input service %s\n", NAME, 543 svc); 544 return EIO; 545 } 546 547 rc = input_open(sess, &input_ev_ops, NULL, &input); 803 548 if (rc != EOK) { 804 549 async_hangup(sess); 805 printf("%s: Unable to c reate callback connection toservice %s (%s)\n",550 printf("%s: Unable to communicate with service %s (%s)\n", 806 551 NAME, svc, str_error(rc)); 807 return NULL;808 } 809 810 return sess;552 return rc; 553 } 554 555 return EOK; 811 556 } 812 557 … … 816 561 } 817 562 818 static async_sess_t * fb_connect(const char *svc)563 static async_sess_t *output_connect(const char *svc) 819 564 { 820 565 async_sess_t *sess; … … 825 570 sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0); 826 571 if (sess == NULL) { 827 printf("%s: Unable to connect to framebufferservice %s\n",572 printf("%s: Unable to connect to output service %s\n", 828 573 NAME, svc); 829 574 return NULL; … … 835 580 } 836 581 837 static bool console_srv_init(char *input_svc, char *fb_svc) 838 { 839 /* Avoid double initialization */ 840 if (graphics_state != GRAPHICS_NONE) 582 static bool console_srv_init(char *input_svc, char *output_svc) 583 { 584 int rc; 585 586 /* Connect to input service */ 587 rc = input_connect(input_svc); 588 if (rc != EOK) 841 589 return false; 842 590 843 /* Connect to input service */ 844 input_sess = input_connect(input_svc); 845 if (input_sess == NULL) 846 return false; 847 848 /* Connect to framebuffer service */ 849 fb_sess = fb_connect(fb_svc); 850 if (fb_sess == NULL) 591 /* Connect to output service */ 592 output_sess = output_connect(output_svc); 593 if (output_sess == NULL) 851 594 return false; 852 595 853 596 /* Register server */ 854 597 async_set_client_connection(client_connection); 855 intrc = loc_server_register(NAME);598 rc = loc_server_register(NAME); 856 599 if (rc != EOK) { 857 600 printf("%s: Unable to register server (%s)\n", NAME, … … 860 603 } 861 604 862 fb_get_resolution(fb_sess, &xres, &yres); 863 864 /* Initialize the screen */ 865 screen_vp = fb_vp_create(fb_sess, 0, 0, xres, yres); 866 867 if ((xres >= 800) && (yres >= 600)) { 868 logo_vp = fb_vp_create(fb_sess, xres - 66, 2, 64, 60); 869 logo_img = imgmap_decode_tga((void *) helenos_tga, 870 helenos_tga_size, IMGMAP_FLAG_SHARED); 871 logo_handle = fb_imagemap_create(fb_sess, logo_img); 872 873 nameic_vp = fb_vp_create(fb_sess, 5, 17, 100, 26); 874 nameic_img = imgmap_decode_tga((void *) nameic_tga, 875 nameic_tga_size, IMGMAP_FLAG_SHARED); 876 nameic_handle = fb_imagemap_create(fb_sess, nameic_img); 877 878 cons_data_img = imgmap_decode_tga((void *) cons_data_tga, 879 cons_data_tga_size, IMGMAP_FLAG_SHARED); 880 cons_dis_img = imgmap_decode_tga((void *) cons_dis_tga, 881 cons_dis_tga_size, IMGMAP_FLAG_SHARED); 882 cons_dis_sel_img = imgmap_decode_tga((void *) cons_dis_sel_tga, 883 cons_dis_sel_tga_size, IMGMAP_FLAG_SHARED); 884 cons_idle_img = imgmap_decode_tga((void *) cons_idle_tga, 885 cons_idle_tga_size, IMGMAP_FLAG_SHARED); 886 cons_kernel_img = imgmap_decode_tga((void *) cons_kernel_tga, 887 cons_kernel_tga_size, IMGMAP_FLAG_SHARED); 888 cons_sel_img = imgmap_decode_tga((void *) cons_sel_tga, 889 cons_sel_tga_size, IMGMAP_FLAG_SHARED); 890 891 state_icons[CONS_DISCONNECTED] = 892 fb_imagemap_create(fb_sess, cons_dis_img); 893 state_icons[CONS_DISCONNECTED_SELECTED] = 894 fb_imagemap_create(fb_sess, cons_dis_sel_img); 895 state_icons[CONS_SELECTED] = 896 fb_imagemap_create(fb_sess, cons_sel_img); 897 state_icons[CONS_IDLE] = 898 fb_imagemap_create(fb_sess, cons_idle_img); 899 state_icons[CONS_DATA] = 900 fb_imagemap_create(fb_sess, cons_data_img); 901 state_icons[CONS_KERNEL] = 902 fb_imagemap_create(fb_sess, cons_kernel_img); 903 904 anim_1_img = imgmap_decode_tga((void *) anim_1_tga, 905 anim_1_tga_size, IMGMAP_FLAG_SHARED); 906 anim_2_img = imgmap_decode_tga((void *) anim_2_tga, 907 anim_2_tga_size, IMGMAP_FLAG_SHARED); 908 anim_3_img = imgmap_decode_tga((void *) anim_3_tga, 909 anim_3_tga_size, IMGMAP_FLAG_SHARED); 910 anim_4_img = imgmap_decode_tga((void *) anim_4_tga, 911 anim_4_tga_size, IMGMAP_FLAG_SHARED); 912 913 anim_1 = fb_imagemap_create(fb_sess, anim_1_img); 914 anim_2 = fb_imagemap_create(fb_sess, anim_2_img); 915 anim_3 = fb_imagemap_create(fb_sess, anim_3_img); 916 anim_4 = fb_imagemap_create(fb_sess, anim_4_img); 917 918 anim_seq = fb_sequence_create(fb_sess); 919 fb_sequence_add_imagemap(fb_sess, anim_seq, anim_1); 920 fb_sequence_add_imagemap(fb_sess, anim_seq, anim_2); 921 fb_sequence_add_imagemap(fb_sess, anim_seq, anim_3); 922 fb_sequence_add_imagemap(fb_sess, anim_seq, anim_4); 923 924 console_vp = fb_vp_create(fb_sess, CONSOLE_MARGIN, CONSOLE_TOP, 925 xres - 2 * CONSOLE_MARGIN, yres - (CONSOLE_TOP + CONSOLE_MARGIN)); 926 927 fb_vp_clear(fb_sess, screen_vp); 928 fb_vp_imagemap_damage(fb_sess, logo_vp, logo_handle, 929 0, 0, 64, 60); 930 fb_vp_imagemap_damage(fb_sess, nameic_vp, nameic_handle, 931 0, 0, 100, 26); 932 933 graphics_state = GRAPHICS_FULL; 934 } else { 935 console_vp = screen_vp; 936 graphics_state = GRAPHICS_BASIC; 937 } 938 939 fb_vp_set_style(fb_sess, console_vp, STYLE_NORMAL); 940 fb_vp_clear(fb_sess, console_vp); 941 942 sysarg_t cols; 943 sysarg_t rows; 944 fb_vp_get_dimensions(fb_sess, console_vp, &cols, &rows); 605 output_get_dimensions(output_sess, &cols, &rows); 606 output_set_style(output_sess, STYLE_NORMAL); 945 607 946 608 console_caps_t ccaps; 947 fb_vp_get_caps(fb_sess, console_vp, &ccaps); 948 949 mouse.x = xres / 2; 950 mouse.y = yres / 2; 951 mouse.pressed = false; 609 output_get_caps(output_sess, &ccaps); 952 610 953 611 /* Inititalize consoles */ … … 959 617 consoles[i].char_remains_len = 0; 960 618 961 if (graphics_state == GRAPHICS_FULL) { 962 /* Create state buttons */ 963 consoles[i].state_vp = 964 fb_vp_create(fb_sess, STATE_START + (xres - 800) / 2 + 965 CONSOLE_MARGIN + i * (STATE_WIDTH + STATE_SPACE), 966 STATE_TOP, STATE_WIDTH, STATE_HEIGHT); 967 } 968 969 if (i == KERNEL_CONSOLE) { 970 consoles[i].state = CONS_KERNEL; 971 cons_redraw_state(&consoles[i]); 972 cons_kernel_sequence_start(&consoles[i]); 619 if (i == KERNEL_CONSOLE) 973 620 continue; 974 }975 976 if (i == 0)977 consoles[i].state = CONS_DISCONNECTED_SELECTED;978 else979 consoles[i].state = CONS_DISCONNECTED;980 621 981 622 consoles[i].cols = cols; … … 983 624 consoles[i].ccaps = ccaps; 984 625 consoles[i].frontbuf = 985 screenbuffer_create(cols, rows, SCREENBUFFER_FLAG_SHARED);626 chargrid_create(cols, rows, CHARGRID_FLAG_SHARED); 986 627 987 628 if (consoles[i].frontbuf == NULL) { … … 990 631 } 991 632 992 consoles[i].fbid = fb_frontbuf_create(fb_sess, consoles[i].frontbuf); 633 consoles[i].fbid = output_frontbuf_create(output_sess, 634 consoles[i].frontbuf); 993 635 if (consoles[i].fbid == 0) { 994 636 printf("%s: Unable to create frontbuffer %zu\n", NAME, i); … … 996 638 } 997 639 998 cons_redraw_state(&consoles[i]); 640 con_srvs_init(&consoles[i].srvs); 641 consoles[i].srvs.ops = &con_ops; 642 consoles[i].srvs.sarg = &consoles[i]; 999 643 1000 644 char vc[LOC_NAME_MAXLEN + 1]; … … 1006 650 } 1007 651 } 652 653 cons_damage(active_console); 1008 654 1009 655 /* Receive kernel notifications */ … … 1017 663 } 1018 664 1019 static void usage( void)1020 { 1021 printf("Usage: console <input_dev> <framebuffer_dev>\n");665 static void usage(char *name) 666 { 667 printf("Usage: %s <input_dev> <output_dev>\n", name); 1022 668 } 1023 669 … … 1025 671 { 1026 672 if (argc < 3) { 1027 usage( );673 usage(argv[0]); 1028 674 return -1; 1029 675 } … … 1038 684 async_manager(); 1039 685 686 /* Never reached */ 1040 687 return 0; 1041 688 }
Note:
See TracChangeset
for help on using the changeset viewer.
