Changes in uspace/app/terminal/terminal.c [266ec54:e273e9e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/terminal/terminal.c
r266ec54 re273e9e 1 1 /* 2 * Copyright (c) 202 0Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * Copyright (c) 2012 Petr Koupy 4 4 * All rights reserved. … … 37 37 #include <adt/list.h> 38 38 #include <adt/prodcons.h> 39 #include <as.h> 39 40 #include <errno.h> 40 41 #include <fbfont/font-8x16.h> 41 #include < io/chargrid.h>42 #include <fibril.h> 42 43 #include <gfx/bitmap.h> 43 44 #include <gfx/context.h> 45 #include <gfx/render.h> 44 46 #include <io/con_srv.h> 45 47 #include <io/concaps.h> 46 48 #include <io/console.h> 47 49 #include <io/pixelmap.h> 50 #include <macros.h> 51 #include <stdarg.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <str_error.h> 55 #include <str.h> 48 56 #include <task.h> 49 #include <stdarg.h>50 #include <stdlib.h>51 #include <str.h>52 57 #include <ui/resource.h> 53 58 #include <ui/ui.h> … … 65 70 66 71 #define TERM_CAPS \ 67 (CONSOLE_CAP_STYLE | CONSOLE_CAP_INDEXED | CONSOLE_CAP_RGB) 72 (CONSOLE_CAP_CURSORCTL | CONSOLE_CAP_STYLE | CONSOLE_CAP_INDEXED | \ 73 CONSOLE_CAP_RGB) 74 75 #define SCROLLBACK_MAX_LINES 1000 76 #define MIN_WINDOW_COLS 8 77 #define MIN_WINDOW_ROWS 4 68 78 69 79 static LIST_INITIALIZE(terms); 80 81 #define COLOR_BRIGHT 8 82 83 static const pixel_t _basic_colors[16] = { 84 [COLOR_BLACK] = PIXEL(255, 0, 0, 0), 85 [COLOR_RED] = PIXEL(255, 170, 0, 0), 86 [COLOR_GREEN] = PIXEL(255, 0, 170, 0), 87 [COLOR_YELLOW] = PIXEL(255, 170, 85, 0), 88 [COLOR_BLUE] = PIXEL(255, 0, 0, 170), 89 [COLOR_MAGENTA] = PIXEL(255, 170, 0, 170), 90 [COLOR_CYAN] = PIXEL(255, 0, 170, 170), 91 [COLOR_WHITE] = PIXEL(255, 170, 170, 170), 92 93 [COLOR_BLACK | COLOR_BRIGHT] = PIXEL(255, 85, 85, 85), 94 [COLOR_RED | COLOR_BRIGHT] = PIXEL(255, 255, 85, 85), 95 [COLOR_GREEN | COLOR_BRIGHT] = PIXEL(255, 85, 255, 85), 96 [COLOR_YELLOW | COLOR_BRIGHT] = PIXEL(255, 255, 255, 85), 97 [COLOR_BLUE | COLOR_BRIGHT] = PIXEL(255, 85, 85, 255), 98 [COLOR_MAGENTA | COLOR_BRIGHT] = PIXEL(255, 255, 85, 255), 99 [COLOR_CYAN | COLOR_BRIGHT] = PIXEL(255, 85, 255, 255), 100 [COLOR_WHITE | COLOR_BRIGHT] = PIXEL(255, 255, 255, 255), 101 }; 70 102 71 103 static errno_t term_open(con_srvs_t *, con_srv_t *); … … 84 116 static void term_set_rgb_color(con_srv_t *, pixel_t, pixel_t); 85 117 static void term_set_cursor_visibility(con_srv_t *, bool); 118 static errno_t term_set_caption(con_srv_t *, const char *); 86 119 static errno_t term_get_event(con_srv_t *, cons_event_t *); 120 static errno_t term_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **); 121 static void term_unmap(con_srv_t *); 122 static void term_buf_update(con_srv_t *, sysarg_t, sysarg_t, sysarg_t, 123 sysarg_t); 87 124 88 125 static con_ops_t con_ops = { … … 101 138 .set_rgb_color = term_set_rgb_color, 102 139 .set_cursor_visibility = term_set_cursor_visibility, 103 .get_event = term_get_event 140 .set_caption = term_set_caption, 141 .get_event = term_get_event, 142 .map = term_map, 143 .unmap = term_unmap, 144 .update = term_buf_update 104 145 }; 105 146 106 147 static void terminal_close_event(ui_window_t *, void *); 107 static void terminal_focus_event(ui_window_t *, void *); 148 static void terminal_focus_event(ui_window_t *, void *, unsigned); 149 static void terminal_resize_event(ui_window_t *, void *); 108 150 static void terminal_kbd_event(ui_window_t *, void *, kbd_event_t *); 109 151 static void terminal_pos_event(ui_window_t *, void *, pos_event_t *); 110 static void terminal_unfocus_event(ui_window_t *, void *); 152 static void terminal_unfocus_event(ui_window_t *, void *, unsigned); 153 static void terminal_maximize_event(ui_window_t *, void *); 154 static void terminal_unmaximize_event(ui_window_t *, void *); 111 155 112 156 static ui_window_cb_t terminal_window_cb = { 113 157 .close = terminal_close_event, 114 158 .focus = terminal_focus_event, 159 .resize = terminal_resize_event, 115 160 .kbd = terminal_kbd_event, 116 161 .pos = terminal_pos_event, 117 .unfocus = terminal_unfocus_event 162 .unfocus = terminal_unfocus_event, 163 .maximize = terminal_maximize_event, 164 .unmaximize = terminal_unmaximize_event, 118 165 }; 119 166 167 static errno_t terminal_wait_fibril(void *); 168 120 169 static terminal_t *srv_to_terminal(con_srv_t *srv) 121 170 { … … 123 172 } 124 173 125 static void getterm(const char *svc, const char *app)126 { 127 task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,174 static errno_t getterm(task_wait_t *wait, const char *svc, const char *app) 175 { 176 return task_spawnl(NULL, wait, APP_GETTERM, APP_GETTERM, svc, 128 177 LOCFS_MOUNT_POINT, "--msg", "--wait", "--", app, NULL); 129 178 } 130 179 131 static pixel_t color_table[16] = { 132 [COLOR_BLACK] = PIXEL(255, 0, 0, 0), 133 [COLOR_BLUE] = PIXEL(255, 0, 0, 240), 134 [COLOR_GREEN] = PIXEL(255, 0, 240, 0), 135 [COLOR_CYAN] = PIXEL(255, 0, 240, 240), 136 [COLOR_RED] = PIXEL(255, 240, 0, 0), 137 [COLOR_MAGENTA] = PIXEL(255, 240, 0, 240), 138 [COLOR_YELLOW] = PIXEL(255, 240, 240, 0), 139 [COLOR_WHITE] = PIXEL(255, 240, 240, 240), 140 141 [COLOR_BLACK + 8] = PIXEL(255, 0, 0, 0), 142 [COLOR_BLUE + 8] = PIXEL(255, 0, 0, 255), 143 [COLOR_GREEN + 8] = PIXEL(255, 0, 255, 0), 144 [COLOR_CYAN + 8] = PIXEL(255, 0, 255, 255), 145 [COLOR_RED + 8] = PIXEL(255, 255, 0, 0), 146 [COLOR_MAGENTA + 8] = PIXEL(255, 255, 0, 255), 147 [COLOR_YELLOW + 8] = PIXEL(255, 255, 255, 0), 148 [COLOR_WHITE + 8] = PIXEL(255, 255, 255, 255), 149 }; 150 151 static inline void attrs_rgb(char_attrs_t attrs, pixel_t *bgcolor, pixel_t *fgcolor) 152 { 153 switch (attrs.type) { 180 static pixel_t termui_color_to_pixel(termui_color_t c) 181 { 182 uint8_t r, g, b; 183 termui_color_to_rgb(c, &r, &g, &b); 184 return PIXEL(255, r, g, b); 185 } 186 187 static termui_color_t termui_color_from_pixel(pixel_t pixel) 188 { 189 return termui_color_from_rgb(RED(pixel), GREEN(pixel), BLUE(pixel)); 190 } 191 192 static termui_cell_t charfield_to_termui_cell(terminal_t *term, const charfield_t *cf) 193 { 194 termui_cell_t cell = { }; 195 196 cell.glyph_idx = fb_font_glyph(cf->ch, NULL); 197 198 switch (cf->attrs.type) { 154 199 case CHAR_ATTR_STYLE: 155 switch ( attrs.val.style) {200 switch (cf->attrs.val.style) { 156 201 case STYLE_NORMAL: 157 *bgcolor = color_table[COLOR_WHITE];158 *fgcolor = color_table[COLOR_BLACK];202 cell.bgcolor = term->default_bgcolor; 203 cell.fgcolor = term->default_fgcolor; 159 204 break; 160 205 case STYLE_EMPHASIS: 161 *bgcolor = color_table[COLOR_WHITE];162 *fgcolor = color_table[COLOR_RED];206 cell.bgcolor = term->emphasis_bgcolor; 207 cell.fgcolor = term->emphasis_fgcolor; 163 208 break; 164 209 case STYLE_INVERTED: 165 *bgcolor = color_table[COLOR_BLACK]; 166 *fgcolor = color_table[COLOR_WHITE]; 210 cell.bgcolor = term->default_bgcolor; 211 cell.fgcolor = term->default_fgcolor; 212 cell.inverted = 1; 167 213 break; 168 214 case STYLE_SELECTED: 169 *bgcolor = color_table[COLOR_RED];170 *fgcolor = color_table[COLOR_WHITE];215 cell.bgcolor = term->selection_bgcolor; 216 cell.fgcolor = term->selection_fgcolor; 171 217 break; 172 218 } 173 219 break; 220 174 221 case CHAR_ATTR_INDEX: 175 *bgcolor = color_table[(attrs.val.index.bgcolor & 7) | 176 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)]; 177 *fgcolor = color_table[(attrs.val.index.fgcolor & 7) | 178 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)]; 222 char_attr_index_t index = cf->attrs.val.index; 223 224 int bright = (index.attr & CATTR_BRIGHT) ? COLOR_BRIGHT : 0; 225 pixel_t bgcolor = _basic_colors[index.bgcolor]; 226 pixel_t fgcolor = _basic_colors[index.fgcolor | bright]; 227 cell.bgcolor = termui_color_from_pixel(bgcolor); 228 cell.fgcolor = termui_color_from_pixel(fgcolor); 229 230 if (index.attr & CATTR_BLINK) 231 cell.blink = 1; 232 179 233 break; 234 180 235 case CHAR_ATTR_RGB: 181 *bgcolor = 0xff000000 | attrs.val.rgb.bgcolor;182 *fgcolor = 0xff000000 | attrs.val.rgb.fgcolor;236 cell.bgcolor = termui_color_from_pixel(cf->attrs.val.rgb.bgcolor); 237 cell.fgcolor = termui_color_from_pixel(cf->attrs.val.rgb.fgcolor); 183 238 break; 184 239 } 240 241 return cell; 185 242 } 186 243 … … 200 257 } 201 258 202 static void term_update_char(terminal_t *term, pixelmap_t *pixelmap, 203 sysarg_t sx, sysarg_t sy, sysarg_t col, sysarg_t row) 204 { 205 charfield_t *field = 206 chargrid_charfield_at(term->backbuf, col, row); 207 208 bool inverted = chargrid_cursor_at(term->backbuf, col, row); 209 210 sysarg_t bx = sx + (col * FONT_WIDTH); 211 sysarg_t by = sy + (row * FONT_SCANLINES); 212 213 pixel_t bgcolor = 0; 214 pixel_t fgcolor = 0; 215 216 if (inverted) 217 attrs_rgb(field->attrs, &fgcolor, &bgcolor); 218 else 219 attrs_rgb(field->attrs, &bgcolor, &fgcolor); 220 221 // FIXME: Glyph type should be actually uint32_t 222 // for full UTF-32 coverage. 223 224 uint16_t glyph = fb_font_glyph(field->ch, NULL); 259 static void term_draw_cell(terminal_t *term, pixelmap_t *pixelmap, int col, int row, const termui_cell_t *cell) 260 { 261 termui_color_t bg = cell->bgcolor; 262 if (bg == TERMUI_COLOR_DEFAULT) 263 bg = term->default_bgcolor; 264 265 termui_color_t fg = cell->fgcolor; 266 if (fg == TERMUI_COLOR_DEFAULT) 267 fg = term->default_fgcolor; 268 269 pixel_t bgcolor = termui_color_to_pixel(bg); 270 pixel_t fgcolor = termui_color_to_pixel(fg); 271 272 int bx = col * FONT_WIDTH; 273 int by = row * FONT_SCANLINES; 274 275 // TODO: support bold/italic/underline/strike/blink styling 276 277 if (cell->inverted ^ cell->cursor) { 278 pixel_t tmp = bgcolor; 279 bgcolor = fgcolor; 280 fgcolor = tmp; 281 } 282 283 uint32_t glyph = cell->glyph_idx; 284 assert(glyph < FONT_GLYPHS); 285 286 if (glyph == 0) 287 glyph = fb_font_glyph(U' ', NULL); 225 288 226 289 for (unsigned int y = 0; y < FONT_SCANLINES; y++) { … … 234 297 } 235 298 } 299 236 300 term_update_region(term, bx, by, FONT_WIDTH, FONT_SCANLINES); 237 301 } 238 302 239 static bool term_update_scroll(terminal_t *term, pixelmap_t *pixelmap, 240 sysarg_t sx, sysarg_t sy) 241 { 242 sysarg_t top_row = chargrid_get_top_row(term->frontbuf); 243 244 if (term->top_row == top_row) { 245 return false; 246 } 247 248 term->top_row = top_row; 249 250 for (sysarg_t row = 0; row < term->rows; row++) { 251 for (sysarg_t col = 0; col < term->cols; col++) { 252 charfield_t *front_field = 253 chargrid_charfield_at(term->frontbuf, col, row); 254 charfield_t *back_field = 255 chargrid_charfield_at(term->backbuf, col, row); 256 bool update = false; 257 258 if (front_field->ch != back_field->ch) { 259 back_field->ch = front_field->ch; 260 update = true; 261 } 262 263 if (!attrs_same(front_field->attrs, back_field->attrs)) { 264 back_field->attrs = front_field->attrs; 265 update = true; 266 } 267 268 front_field->flags &= ~CHAR_FLAG_DIRTY; 269 270 if (update) { 271 term_update_char(term, pixelmap, sx, sy, col, row); 272 } 273 } 274 } 275 276 return true; 277 } 278 279 static bool term_update_cursor(terminal_t *term, pixelmap_t *pixelmap, 280 sysarg_t sx, sysarg_t sy) 281 { 282 bool update = false; 283 284 sysarg_t front_col; 285 sysarg_t front_row; 286 chargrid_get_cursor(term->frontbuf, &front_col, &front_row); 287 288 sysarg_t back_col; 289 sysarg_t back_row; 290 chargrid_get_cursor(term->backbuf, &back_col, &back_row); 291 292 bool front_visibility = 293 chargrid_get_cursor_visibility(term->frontbuf) && 294 term->is_focused; 295 bool back_visibility = 296 chargrid_get_cursor_visibility(term->backbuf); 297 298 if (front_visibility != back_visibility) { 299 chargrid_set_cursor_visibility(term->backbuf, 300 front_visibility); 301 term_update_char(term, pixelmap, sx, sy, back_col, back_row); 302 update = true; 303 } 304 305 if ((front_col != back_col) || (front_row != back_row)) { 306 chargrid_set_cursor(term->backbuf, front_col, front_row); 307 term_update_char(term, pixelmap, sx, sy, back_col, back_row); 308 term_update_char(term, pixelmap, sx, sy, front_col, front_row); 309 update = true; 310 } 311 312 return update; 313 } 314 315 static void term_update(terminal_t *term) 316 { 317 pixelmap_t pixelmap; 303 static void term_render(terminal_t *term) 304 { 305 (void) gfx_bitmap_render(term->bmp, &term->update, &term->off); 306 307 term->update.p0.x = 0; 308 term->update.p0.y = 0; 309 term->update.p1.x = 0; 310 term->update.p1.y = 0; 311 } 312 313 static void termui_refresh_cb(void *userdata) 314 { 315 terminal_t *term = userdata; 316 317 termui_force_viewport_update(term->termui, 0, termui_get_rows(term->termui)); 318 } 319 320 static void termui_scroll_cb(void *userdata, int delta) 321 { 322 (void) delta; 323 324 // Until we have support for hardware accelerated scrolling, just redraw everything. 325 termui_refresh_cb(userdata); 326 } 327 328 static pixelmap_t term_get_pixelmap(terminal_t *term) 329 { 330 pixelmap_t pixelmap = { }; 318 331 gfx_bitmap_alloc_t alloc; 319 gfx_coord2_t pos; 320 errno_t rc; 321 322 rc = gfx_bitmap_get_alloc(term->bmp, &alloc); 323 if (rc != EOK) { 324 return; 325 } 326 327 fibril_mutex_lock(&term->mtx); 332 333 errno_t rc = gfx_bitmap_get_alloc(term->bmp, &alloc); 334 if (rc != EOK) 335 return pixelmap; 336 328 337 pixelmap.width = term->w; 329 338 pixelmap.height = term->h; 330 339 pixelmap.data = alloc.pixels; 331 332 bool update = false; 333 sysarg_t sx = 0/*term->widget.hpos*/; 334 sysarg_t sy = 0/*term->widget.vpos*/; 335 336 if (term_update_scroll(term, &pixelmap, sx, sy)) { 337 update = true; 338 } else { 339 for (sysarg_t y = 0; y < term->rows; y++) { 340 for (sysarg_t x = 0; x < term->cols; x++) { 341 charfield_t *front_field = 342 chargrid_charfield_at(term->frontbuf, x, y); 343 charfield_t *back_field = 344 chargrid_charfield_at(term->backbuf, x, y); 345 bool update = false; 346 347 if ((front_field->flags & CHAR_FLAG_DIRTY) == 348 CHAR_FLAG_DIRTY) { 349 if (front_field->ch != back_field->ch) { 350 back_field->ch = front_field->ch; 351 update = true; 352 } 353 354 if (!attrs_same(front_field->attrs, 355 back_field->attrs)) { 356 back_field->attrs = front_field->attrs; 357 update = true; 358 } 359 360 front_field->flags &= ~CHAR_FLAG_DIRTY; 361 } 362 363 if (update) { 364 term_update_char(term, &pixelmap, sx, sy, x, y); 365 update = true; 366 } 367 } 368 } 369 } 370 371 if (term_update_cursor(term, &pixelmap, sx, sy)) 372 update = true; 373 374 if (update) { 375 pos.x = 4; 376 pos.y = 26; 377 (void) gfx_bitmap_render(term->bmp, &term->update, &pos); 378 379 term->update.p0.x = 0; 380 term->update.p0.y = 0; 381 term->update.p1.x = 0; 382 term->update.p1.y = 0; 383 } 384 385 fibril_mutex_unlock(&term->mtx); 386 } 387 388 static void term_repaint(terminal_t *term) 389 { 390 pixelmap_t pixelmap; 391 gfx_bitmap_alloc_t alloc; 392 errno_t rc; 393 394 rc = gfx_bitmap_get_alloc(term->bmp, &alloc); 395 if (rc != EOK) { 396 printf("Error getting bitmap allocation info.\n"); 340 return pixelmap; 341 } 342 343 static void term_clear_bitmap(terminal_t *term, pixel_t color) 344 { 345 pixelmap_t pixelmap = term_get_pixelmap(term); 346 if (pixelmap.data == NULL) 397 347 return; 398 } 399 400 fibril_mutex_lock(&term->mtx); 401 402 pixelmap.width = term->w; 403 pixelmap.height = term->h; 404 pixelmap.data = alloc.pixels; 405 406 sysarg_t sx = 0; 407 sysarg_t sy = 0; 408 409 if (!term_update_scroll(term, &pixelmap, sx, sy)) { 410 for (sysarg_t y = 0; y < term->rows; y++) { 411 for (sysarg_t x = 0; x < term->cols; x++) { 412 charfield_t *front_field = 413 chargrid_charfield_at(term->frontbuf, x, y); 414 charfield_t *back_field = 415 chargrid_charfield_at(term->backbuf, x, y); 416 417 back_field->ch = front_field->ch; 418 back_field->attrs = front_field->attrs; 419 front_field->flags &= ~CHAR_FLAG_DIRTY; 420 421 term_update_char(term, &pixelmap, sx, sy, x, y); 422 } 423 } 424 } 425 426 term_update_cursor(term, &pixelmap, sx, sy); 427 428 fibril_mutex_unlock(&term->mtx); 348 349 sysarg_t pixels = pixelmap.height * pixelmap.width; 350 for (sysarg_t i = 0; i < pixels; i++) 351 pixelmap.data[i] = color; 352 353 term_update_region(term, 0, 0, pixelmap.width, pixelmap.height); 354 } 355 356 static void termui_update_cb(void *userdata, int col, int row, const termui_cell_t *cell, int len) 357 { 358 terminal_t *term = userdata; 359 360 pixelmap_t pixelmap = term_get_pixelmap(term); 361 if (pixelmap.data == NULL) 362 return; 363 364 for (int i = 0; i < len; i++) 365 term_draw_cell(term, &pixelmap, col + i, row, &cell[i]); 429 366 } 430 367 … … 466 403 if (pos < size) { 467 404 link_t *link = prodcons_consume(&term->input_pc); 468 cons_event_t *event = list_get_instance(link, cons_event_t, link); 405 terminal_event_t *qevent = list_get_instance(link, 406 terminal_event_t, link); 407 cons_event_t *event = &qevent->ev; 469 408 470 409 /* Accept key presses of printable chars only. */ … … 480 419 } 481 420 482 free( event);421 free(qevent); 483 422 } 484 423 } … … 490 429 static void term_write_char(terminal_t *term, wchar_t ch) 491 430 { 492 sysarg_t updated = 0;493 494 fibril_mutex_lock(&term->mtx);495 496 431 switch (ch) { 497 case '\n':498 updated = chargrid_newline(term->frontbuf);432 case L'\n': 433 termui_put_crlf(term->termui); 499 434 break; 500 case '\r': 435 case L'\r': 436 termui_put_cr(term->termui); 501 437 break; 502 case '\t':503 updated = chargrid_tabstop(term->frontbuf, 8);438 case L'\t': 439 termui_put_tab(term->termui); 504 440 break; 505 case '\b':506 updated = chargrid_backspace(term->frontbuf);441 case L'\b': 442 termui_put_backspace(term->termui); 507 443 break; 508 444 default: 509 updated = chargrid_putuchar(term->frontbuf, ch, true); 510 } 511 512 fibril_mutex_unlock(&term->mtx); 513 514 if (updated > 1) 515 term_update(term); 445 // TODO: For some languages, we might need support for combining 446 // characters. Currently, we assume every unicode code point is 447 // an individual printed character, which is not always the case. 448 termui_put_glyph(term->termui, fb_font_glyph(ch, NULL), 1); 449 break; 450 } 516 451 } 517 452 … … 519 454 { 520 455 terminal_t *term = srv_to_terminal(srv); 456 457 fibril_mutex_lock(&term->mtx); 521 458 522 459 size_t off = 0; … … 524 461 term_write_char(term, str_decode(data, &off, size)); 525 462 463 fibril_mutex_unlock(&term->mtx); 464 465 term_render(term); 466 gfx_update(term->gc); 526 467 *nwritten = size; 468 527 469 return EOK; 528 470 } … … 532 474 terminal_t *term = srv_to_terminal(srv); 533 475 534 term_update(term); 476 term_render(term); 477 gfx_update(term->gc); 535 478 } 536 479 … … 540 483 541 484 fibril_mutex_lock(&term->mtx); 542 chargrid_clear(term->frontbuf); 543 fibril_mutex_unlock(&term->mtx); 544 545 term_update(term); 485 termui_clear_screen(term->termui); 486 fibril_mutex_unlock(&term->mtx); 487 488 term_render(term); 489 gfx_update(term->gc); 546 490 } 547 491 … … 551 495 552 496 fibril_mutex_lock(&term->mtx); 553 chargrid_set_cursor(term->frontbuf, col, row); 554 fibril_mutex_unlock(&term->mtx); 555 556 term_update(term); 497 termui_set_pos(term->termui, col, row); 498 fibril_mutex_unlock(&term->mtx); 499 500 term_render(term); 501 gfx_update(term->gc); 557 502 } 558 503 … … 562 507 563 508 fibril_mutex_lock(&term->mtx); 564 chargrid_get_cursor(term->frontbuf, col, row); 565 fibril_mutex_unlock(&term->mtx); 509 int irow, icol; 510 termui_get_pos(term->termui, &icol, &irow); 511 fibril_mutex_unlock(&term->mtx); 512 513 *col = icol; 514 *row = irow; 566 515 567 516 return EOK; … … 573 522 574 523 fibril_mutex_lock(&term->mtx); 575 *cols = term ->cols;576 *rows = term ->rows;524 *cols = termui_get_cols(term->termui); 525 *rows = termui_get_rows(term->termui); 577 526 fibril_mutex_unlock(&term->mtx); 578 527 … … 592 541 terminal_t *term = srv_to_terminal(srv); 593 542 594 fibril_mutex_lock(&term->mtx); 595 chargrid_set_style(term->frontbuf, style); 543 termui_cell_t cellstyle = { }; 544 545 switch (style) { 546 case STYLE_NORMAL: 547 cellstyle.bgcolor = term->default_bgcolor; 548 cellstyle.fgcolor = term->default_fgcolor; 549 break; 550 case STYLE_EMPHASIS: 551 cellstyle.bgcolor = term->emphasis_bgcolor; 552 cellstyle.fgcolor = term->emphasis_fgcolor; 553 break; 554 case STYLE_INVERTED: 555 cellstyle.bgcolor = term->default_bgcolor; 556 cellstyle.fgcolor = term->default_fgcolor; 557 cellstyle.inverted = 1; 558 break; 559 case STYLE_SELECTED: 560 cellstyle.bgcolor = term->selection_bgcolor; 561 cellstyle.fgcolor = term->selection_fgcolor; 562 break; 563 } 564 565 fibril_mutex_lock(&term->mtx); 566 termui_set_style(term->termui, cellstyle); 596 567 fibril_mutex_unlock(&term->mtx); 597 568 } … … 602 573 terminal_t *term = srv_to_terminal(srv); 603 574 604 fibril_mutex_lock(&term->mtx); 605 chargrid_set_color(term->frontbuf, bgcolor, fgcolor, attr); 575 int bright = (attr & CATTR_BRIGHT) ? COLOR_BRIGHT : 0; 576 577 termui_cell_t cellstyle = { }; 578 cellstyle.bgcolor = termui_color_from_pixel(_basic_colors[bgcolor]); 579 cellstyle.fgcolor = termui_color_from_pixel(_basic_colors[fgcolor | bright]); 580 581 if (attr & CATTR_BLINK) 582 cellstyle.blink = 1; 583 584 fibril_mutex_lock(&term->mtx); 585 termui_set_style(term->termui, cellstyle); 606 586 fibril_mutex_unlock(&term->mtx); 607 587 } … … 611 591 { 612 592 terminal_t *term = srv_to_terminal(srv); 613 614 fibril_mutex_lock(&term->mtx); 615 chargrid_set_rgb_color(term->frontbuf, bgcolor, fgcolor); 593 termui_cell_t cellstyle = { 594 .bgcolor = termui_color_from_pixel(bgcolor), 595 .fgcolor = termui_color_from_pixel(fgcolor), 596 }; 597 598 fibril_mutex_lock(&term->mtx); 599 termui_set_style(term->termui, cellstyle); 616 600 fibril_mutex_unlock(&term->mtx); 617 601 } … … 622 606 623 607 fibril_mutex_lock(&term->mtx); 624 chargrid_set_cursor_visibility(term->frontbuf, visible); 625 fibril_mutex_unlock(&term->mtx); 626 627 term_update(term); 608 termui_set_cursor_visibility(term->termui, visible); 609 fibril_mutex_unlock(&term->mtx); 610 611 term_render(term); 612 gfx_update(term->gc); 613 } 614 615 static errno_t term_set_caption(con_srv_t *srv, const char *caption) 616 { 617 terminal_t *term = srv_to_terminal(srv); 618 const char *cap; 619 620 fibril_mutex_lock(&term->mtx); 621 622 if (str_size(caption) > 0) 623 cap = caption; 624 else 625 cap = "Terminal"; 626 627 ui_window_set_caption(term->window, cap); 628 fibril_mutex_unlock(&term->mtx); 629 630 term_render(term); 631 gfx_update(term->gc); 632 return EOK; 628 633 } 629 634 … … 632 637 terminal_t *term = srv_to_terminal(srv); 633 638 link_t *link = prodcons_consume(&term->input_pc); 634 cons_event_t *ev = list_get_instance(link, cons_event_t, link);635 636 *event = *ev;639 terminal_event_t *ev = list_get_instance(link, terminal_event_t, link); 640 641 *event = ev->ev; 637 642 free(ev); 638 643 return EOK; 639 644 } 640 645 641 static void deinit_terminal(terminal_t *term) 646 /** Create shared buffer for efficient rendering. 647 * 648 * @param srv Console server 649 * @param cols Number of columns in buffer 650 * @param rows Number of rows in buffer 651 * @param rbuf Place to store pointer to new sharable buffer 652 * 653 * @return EOK on sucess or an error code 654 */ 655 static errno_t term_map(con_srv_t *srv, sysarg_t cols, sysarg_t rows, 656 charfield_t **rbuf) 657 { 658 terminal_t *term = srv_to_terminal(srv); 659 void *buf; 660 661 fibril_mutex_lock(&term->mtx); 662 663 if (term->ubuf != NULL) { 664 fibril_mutex_unlock(&term->mtx); 665 return EBUSY; 666 } 667 668 buf = as_area_create(AS_AREA_ANY, cols * rows * sizeof(charfield_t), 669 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED); 670 if (buf == AS_MAP_FAILED) { 671 fibril_mutex_unlock(&term->mtx); 672 return ENOMEM; 673 } 674 675 term->ucols = cols; 676 term->urows = rows; 677 term->ubuf = buf; 678 679 /* Scroll back to active screen. */ 680 termui_history_scroll(term->termui, INT_MAX); 681 682 fibril_mutex_unlock(&term->mtx); 683 684 *rbuf = buf; 685 return EOK; 686 } 687 688 /** Delete shared buffer. 689 * 690 * @param srv Console server 691 */ 692 static void term_unmap(con_srv_t *srv) 693 { 694 terminal_t *term = srv_to_terminal(srv); 695 void *buf; 696 697 fibril_mutex_lock(&term->mtx); 698 699 buf = term->ubuf; 700 term->ubuf = NULL; 701 702 termui_wipe_screen(term->termui, 0); 703 704 fibril_mutex_unlock(&term->mtx); 705 706 /* Update terminal */ 707 term_render(term); 708 gfx_update(term->gc); 709 710 if (buf != NULL) 711 as_area_destroy(buf); 712 } 713 714 /** Update area of terminal from shared buffer. 715 * 716 * @param srv Console server 717 * @param c0 Column coordinate of top-left corner (inclusive) 718 * @param r0 Row coordinate of top-left corner (inclusive) 719 * @param c1 Column coordinate of bottom-right corner (exclusive) 720 * @param r1 Row coordinate of bottom-right corner (exclusive) 721 */ 722 static void term_buf_update(con_srv_t *srv, sysarg_t c0, sysarg_t r0, 723 sysarg_t c1, sysarg_t r1) 724 { 725 terminal_t *term = srv_to_terminal(srv); 726 727 fibril_mutex_lock(&term->mtx); 728 729 if (term->ubuf == NULL) { 730 fibril_mutex_unlock(&term->mtx); 731 return; 732 } 733 734 /* Make sure we have meaningful coordinates, within bounds */ 735 c1 = min(c1, term->ucols); 736 c1 = min(c1, (sysarg_t) termui_get_cols(term->termui)); 737 r1 = min(r1, term->urows); 738 r1 = min(r1, (sysarg_t) termui_get_rows(term->termui)); 739 740 if (c0 >= c1 || r0 >= r1) { 741 fibril_mutex_unlock(&term->mtx); 742 return; 743 } 744 745 /* Update front buffer from user buffer */ 746 747 for (sysarg_t row = r0; row < r1; row++) { 748 termui_cell_t *cells = termui_get_active_row(term->termui, row); 749 750 for (sysarg_t col = c0; col < c1; col++) { 751 cells[col] = charfield_to_termui_cell(term, &term->ubuf[row * term->ucols + col]); 752 } 753 754 termui_update_cb(term, c0, row, &cells[c0], c1 - c0); 755 } 756 757 fibril_mutex_unlock(&term->mtx); 758 759 /* Update terminal */ 760 term_render(term); 761 gfx_update(term->gc); 762 } 763 764 static errno_t terminal_window_resize(terminal_t *term) 765 { 766 gfx_rect_t rect; 767 ui_window_get_app_rect(term->window, &rect); 768 769 int width = rect.p1.x - rect.p0.x; 770 int height = rect.p1.y - rect.p0.y; 771 772 if (!term->gc) 773 term->gc = ui_window_get_gc(term->window); 774 else 775 assert(term->gc == ui_window_get_gc(term->window)); 776 777 if (!term->ui_res) 778 term->ui_res = ui_window_get_res(term->window); 779 else 780 assert(term->ui_res == ui_window_get_res(term->window)); 781 782 gfx_bitmap_t *new_bmp; 783 gfx_bitmap_params_t params; 784 gfx_bitmap_params_init(¶ms); 785 params.rect.p0.x = 0; 786 params.rect.p0.y = 0; 787 params.rect.p1.x = width; 788 params.rect.p1.y = height; 789 790 errno_t rc = gfx_bitmap_create(term->gc, ¶ms, NULL, &new_bmp); 791 if (rc != EOK) { 792 fprintf(stderr, "Error allocating new screen bitmap: %s\n", str_error(rc)); 793 return rc; 794 } 795 796 if (term->bmp) { 797 rc = gfx_bitmap_destroy(term->bmp); 798 if (rc != EOK) 799 fprintf(stderr, "Error deallocating old screen bitmap: %s\n", str_error(rc)); 800 } 801 802 term->bmp = new_bmp; 803 term->w = width; 804 term->h = height; 805 806 term_clear_bitmap(term, termui_color_to_pixel(term->default_bgcolor)); 807 808 return EOK; 809 } 810 811 void terminal_destroy(terminal_t *term) 642 812 { 643 813 list_remove(&term->link); 644 814 645 if (term->frontbuf) 646 chargrid_destroy(term->frontbuf); 647 648 if (term->backbuf) 649 chargrid_destroy(term->backbuf); 650 } 651 652 void terminal_destroy(terminal_t *term) 653 { 654 deinit_terminal(term); 815 termui_destroy(term->termui); 816 817 if (term->ubuf) 818 as_area_destroy(term->ubuf); 819 820 ui_destroy(term->ui); 655 821 free(term); 656 822 } … … 659 825 { 660 826 /* Got key press/release event */ 661 cons_event_t *event =662 ( cons_event_t *) malloc(sizeof(cons_event_t));827 terminal_event_t *event = 828 (terminal_event_t *) malloc(sizeof(terminal_event_t)); 663 829 if (event == NULL) 664 830 return; 665 831 666 *event= *ev;832 event->ev = *ev; 667 833 link_initialize(&event->link); 668 834 … … 675 841 terminal_t *term = (terminal_t *) arg; 676 842 677 (void) term; 678 679 // XXX This is not really a clean way of terminating 680 exit(0); 843 ui_quit(term->ui); 681 844 } 682 845 683 846 /** Handle window focus event. */ 684 static void terminal_focus_event(ui_window_t *window, void *arg) 847 static void terminal_focus_event(ui_window_t *window, void *arg, 848 unsigned nfocus) 685 849 { 686 850 terminal_t *term = (terminal_t *) arg; 687 851 852 (void)nfocus; 688 853 term->is_focused = true; 689 term_update(term); 854 term_render(term); 855 gfx_update(term->gc); 856 } 857 858 static void terminal_resize_handler(ui_window_t *window, void *arg) 859 { 860 terminal_t *term = (terminal_t *) arg; 861 862 fibril_mutex_lock(&term->mtx); 863 864 errno_t rc = terminal_window_resize(term); 865 if (rc == EOK) { 866 (void) termui_resize(term->termui, term->w / FONT_WIDTH, term->h / FONT_SCANLINES, SCROLLBACK_MAX_LINES); 867 termui_refresh_cb(term); 868 term_render(term); 869 gfx_update(term->gc); 870 871 cons_event_t event = { .type = CEV_RESIZE }; 872 terminal_queue_cons_event(term, &event); 873 } 874 875 fibril_mutex_unlock(&term->mtx); 876 } 877 878 static void terminal_resize_event(ui_window_t *window, void *arg) 879 { 880 ui_window_def_resize(window); 881 terminal_resize_handler(window, arg); 882 } 883 884 static void terminal_maximize_event(ui_window_t *window, void *arg) 885 { 886 ui_window_def_maximize(window); 887 terminal_resize_handler(window, arg); 888 } 889 890 static void terminal_unmaximize_event(ui_window_t *window, void *arg) 891 { 892 ui_window_def_unmaximize(window); 893 terminal_resize_handler(window, arg); 690 894 } 691 895 … … 700 904 event.ev.key = *kbd_event; 701 905 702 terminal_queue_cons_event(term, &event); 906 const int PAGE_ROWS = (termui_get_rows(term->termui) * 2) / 3; 907 908 fibril_mutex_lock(&term->mtx); 909 910 if (!term->ubuf && kbd_event->type == KEY_PRESS && 911 (kbd_event->key == KC_PAGE_UP || kbd_event->key == KC_PAGE_DOWN)) { 912 913 termui_history_scroll(term->termui, 914 (kbd_event->key == KC_PAGE_UP) ? -PAGE_ROWS : PAGE_ROWS); 915 916 term_render(term); 917 gfx_update(term->gc); 918 } else { 919 terminal_queue_cons_event(term, &event); 920 } 921 922 fibril_mutex_unlock(&term->mtx); 703 923 } 704 924 … … 709 929 terminal_t *term = (terminal_t *) arg; 710 930 711 sysarg_t sx = -term->off.x; 712 sysarg_t sy = -term->off.y; 713 714 if (event->type == POS_PRESS) { 715 cevent.type = CEV_POS; 716 cevent.ev.pos.type = event->type; 717 cevent.ev.pos.pos_id = event->pos_id; 718 cevent.ev.pos.btn_num = event->btn_num; 719 720 cevent.ev.pos.hpos = (event->hpos - sx) / FONT_WIDTH; 721 cevent.ev.pos.vpos = (event->vpos - sy) / FONT_SCANLINES; 931 switch (event->type) { 932 case POS_UPDATE: 933 return; 934 935 case POS_PRESS: 936 case POS_RELEASE: 937 case POS_DCLICK: 938 } 939 940 /* Ignore mouse events when we're in scrollback mode. */ 941 if (termui_scrollback_is_active(term->termui)) 942 return; 943 944 sysarg_t sx = term->off.x; 945 sysarg_t sy = term->off.y; 946 947 if (event->hpos < sx || event->vpos < sy) 948 return; 949 950 cevent.type = CEV_POS; 951 cevent.ev.pos.type = event->type; 952 cevent.ev.pos.pos_id = event->pos_id; 953 cevent.ev.pos.btn_num = event->btn_num; 954 955 cevent.ev.pos.hpos = (event->hpos - sx) / FONT_WIDTH; 956 cevent.ev.pos.vpos = (event->vpos - sy) / FONT_SCANLINES; 957 958 /* Filter out events outside the terminal area. */ 959 int cols = termui_get_cols(term->termui); 960 int rows = termui_get_rows(term->termui); 961 962 if (cevent.ev.pos.hpos < (sysarg_t) cols && cevent.ev.pos.vpos < (sysarg_t) rows) 722 963 terminal_queue_cons_event(term, &cevent); 723 }724 964 } 725 965 726 966 /** Handle window unfocus event. */ 727 static void terminal_unfocus_event(ui_window_t *window, void *arg) 967 static void terminal_unfocus_event(ui_window_t *window, void *arg, 968 unsigned nfocus) 728 969 { 729 970 terminal_t *term = (terminal_t *) arg; 730 971 731 term->is_focused = false; 732 term_update(term); 972 if (nfocus == 0) { 973 term->is_focused = false; 974 term_render(term); 975 gfx_update(term->gc); 976 } 733 977 } 734 978 … … 750 994 751 995 if (!atomic_flag_test_and_set(&term->refcnt)) 752 chargrid_set_cursor_visibility(term->frontbuf, true);996 termui_set_cursor_visibility(term->termui, true); 753 997 754 998 con_conn(icall, &term->srvs); 755 999 } 756 1000 1001 static errno_t term_init_window(terminal_t *term, const char *display_spec, 1002 gfx_coord_t width, gfx_coord_t height, 1003 gfx_coord_t min_width, gfx_coord_t min_height, 1004 terminal_flags_t flags) 1005 { 1006 gfx_rect_t min_rect = { { 0, 0 }, { min_width, min_height } }; 1007 gfx_rect_t wmin_rect; 1008 gfx_rect_t wrect; 1009 1010 errno_t rc = ui_create(display_spec, &term->ui); 1011 if (rc != EOK) { 1012 printf("Error creating UI on %s.\n", display_spec); 1013 return rc; 1014 } 1015 1016 ui_wnd_params_t wparams; 1017 ui_wnd_params_init(&wparams); 1018 wparams.caption = "Terminal"; 1019 wparams.style |= ui_wds_maximize_btn | ui_wds_resizable; 1020 1021 if ((flags & tf_topleft) != 0) 1022 wparams.placement = ui_wnd_place_top_left; 1023 1024 if (ui_is_fullscreen(term->ui)) { 1025 wparams.placement = ui_wnd_place_full_screen; 1026 wparams.style &= ~ui_wds_decorated; 1027 } 1028 1029 /* Compute wrect such that application area corresponds to rect. */ 1030 ui_wdecor_rect_from_app(term->ui, wparams.style, &min_rect, &wrect); 1031 gfx_rect_rtranslate(&wrect.p0, &wrect, &wmin_rect); 1032 wparams.min_size = wmin_rect.p1; 1033 1034 gfx_rect_t rect = { { 0, 0 }, { width, height } }; 1035 ui_wdecor_rect_from_app(term->ui, wparams.style, &rect, &rect); 1036 term->off.x = -rect.p0.x; 1037 term->off.y = -rect.p0.y; 1038 printf("off=%d,%d\n", term->off.x, term->off.y); 1039 gfx_rect_translate(&term->off, &rect, &wparams.rect); 1040 printf("wparams.rect=%d,%d,%d,%d\n", 1041 wparams.rect.p0.x, 1042 wparams.rect.p1.x, 1043 wparams.rect.p0.y, 1044 wparams.rect.p1.y); 1045 1046 rc = ui_window_create(term->ui, &wparams, &term->window); 1047 if (rc != EOK) 1048 return rc; 1049 1050 ui_window_set_cb(term->window, &terminal_window_cb, (void *) term); 1051 return terminal_window_resize(term); 1052 } 1053 757 1054 errno_t terminal_create(const char *display_spec, sysarg_t width, 758 sysarg_t height, terminal_flags_t flags, terminal_t **rterm) 759 { 760 terminal_t *term; 761 gfx_bitmap_params_t params; 762 ui_wnd_params_t wparams; 763 gfx_rect_t rect; 764 gfx_coord2_t off; 765 gfx_rect_t wrect; 1055 sysarg_t height, terminal_flags_t flags, const char *command, 1056 terminal_t **rterm) 1057 { 766 1058 errno_t rc; 767 1059 768 term = calloc(1, sizeof(terminal_t));1060 terminal_t *term = calloc(1, sizeof(terminal_t)); 769 1061 if (term == NULL) { 770 1062 printf("Out of memory.\n"); … … 779 1071 term->char_remains_len = 0; 780 1072 781 term->w = width; 782 term->h = height; 783 784 term->cols = width / FONT_WIDTH; 785 term->rows = height / FONT_SCANLINES; 786 787 term->frontbuf = NULL; 788 term->backbuf = NULL; 789 790 term->frontbuf = chargrid_create(term->cols, term->rows, 791 CHARGRID_FLAG_NONE); 792 if (!term->frontbuf) { 793 printf("Error creating front buffer.\n"); 1073 term->default_bgcolor = termui_color_from_pixel(_basic_colors[COLOR_WHITE | COLOR_BRIGHT]); 1074 term->default_fgcolor = termui_color_from_pixel(_basic_colors[COLOR_BLACK]); 1075 1076 term->emphasis_bgcolor = termui_color_from_pixel(_basic_colors[COLOR_WHITE | COLOR_BRIGHT]); 1077 term->emphasis_fgcolor = termui_color_from_pixel(_basic_colors[COLOR_RED | COLOR_BRIGHT]); 1078 1079 term->selection_bgcolor = termui_color_from_pixel(_basic_colors[COLOR_RED | COLOR_BRIGHT]); 1080 term->selection_fgcolor = termui_color_from_pixel(_basic_colors[COLOR_WHITE | COLOR_BRIGHT]); 1081 1082 rc = term_init_window(term, display_spec, width, height, 1083 MIN_WINDOW_COLS * FONT_WIDTH, MIN_WINDOW_ROWS * FONT_SCANLINES, flags); 1084 if (rc != EOK) { 1085 printf("Error creating window (%s).\n", str_error(rc)); 1086 goto error; 1087 } 1088 1089 term->termui = termui_create(term->w / FONT_WIDTH, 1090 term->h / FONT_SCANLINES, SCROLLBACK_MAX_LINES); 1091 if (!term->termui) { 1092 printf("Error creating terminal UI.\n"); 794 1093 rc = ENOMEM; 795 1094 goto error; 796 1095 } 797 1096 798 term->backbuf = chargrid_create(term->cols, term->rows, 799 CHARGRID_FLAG_NONE); 800 if (!term->backbuf) { 801 printf("Error creating back buffer.\n"); 802 rc = ENOMEM; 803 goto error; 804 } 805 806 rect.p0.x = 0; 807 rect.p0.y = 0; 808 rect.p1.x = width; 809 rect.p1.y = height; 810 811 ui_wnd_params_init(&wparams); 812 wparams.caption = "Terminal"; 813 if ((flags & tf_topleft) != 0) 814 wparams.placement = ui_wnd_place_top_left; 815 816 /* 817 * Compute window rectangle such that application area corresponds 818 * to rect 819 */ 820 ui_wdecor_rect_from_app(wparams.style, &rect, &wrect); 821 off = wrect.p0; 822 gfx_rect_rtranslate(&off, &wrect, &wparams.rect); 823 824 term->off = off; 825 826 rc = ui_create(display_spec, &term->ui); 827 if (rc != EOK) { 828 printf("Error creating UI on %s.\n", display_spec); 829 goto error; 830 } 831 832 rc = ui_window_create(term->ui, &wparams, &term->window); 833 if (rc != EOK) { 834 printf("Error creating window.\n"); 835 goto error; 836 } 837 838 term->gc = ui_window_get_gc(term->window); 839 term->ui_res = ui_window_get_res(term->window); 840 841 ui_window_set_cb(term->window, &terminal_window_cb, (void *) term); 842 843 gfx_bitmap_params_init(¶ms); 844 params.rect.p0.x = 0; 845 params.rect.p0.y = 0; 846 params.rect.p1.x = width; 847 params.rect.p1.y = height; 848 849 rc = gfx_bitmap_create(term->gc, ¶ms, NULL, &term->bmp); 850 if (rc != EOK) { 851 printf("Error allocating screen bitmap.\n"); 852 goto error; 853 } 854 855 chargrid_clear(term->frontbuf); 856 chargrid_clear(term->backbuf); 857 term->top_row = 0; 1097 termui_set_refresh_cb(term->termui, termui_refresh_cb, term); 1098 termui_set_scroll_cb(term->termui, termui_scroll_cb, term); 1099 termui_set_update_cb(term->termui, termui_update_cb, term); 858 1100 859 1101 async_set_fallback_port_handler(term_connection, NULL); … … 862 1104 term->srvs.sarg = term; 863 1105 864 rc = loc_server_register(NAME );1106 rc = loc_server_register(NAME, &term->srv); 865 1107 if (rc != EOK) { 866 1108 printf("Error registering server.\n"); … … 873 1115 task_get_id()); 874 1116 875 rc = loc_service_register( vc, &term->dsid);1117 rc = loc_service_register(term->srv, vc, &term->dsid); 876 1118 if (rc != EOK) { 877 1119 printf("Error registering service.\n"); … … 881 1123 882 1124 list_append(&term->link, &terms); 883 getterm(vc, "/app/bdsh"); 1125 rc = getterm(&term->wait, vc, command); 1126 if (rc != EOK) 1127 goto error; 1128 1129 term->wfid = fibril_create(terminal_wait_fibril, term); 1130 if (term->wfid == 0) 1131 goto error; 1132 1133 fibril_add_ready(term->wfid); 884 1134 885 1135 term->is_focused = true; 886 1136 887 term->update.p0.x = 0; 888 term->update.p0.y = 0; 889 term->update.p1.x = 0; 890 term->update.p1.y = 0; 891 892 term_repaint(term); 1137 termui_refresh_cb(term); 893 1138 894 1139 *rterm = term; 895 1140 return EOK; 896 1141 error: 1142 if (term->dsid != 0) 1143 loc_service_unregister(term->srv, term->dsid); 1144 if (term->srv != NULL) 1145 loc_server_unregister(term->srv); 897 1146 if (term->window != NULL) 898 1147 ui_window_destroy(term->window); 899 1148 if (term->ui != NULL) 900 1149 ui_destroy(term->ui); 901 if (term->frontbuf != NULL) 902 chargrid_destroy(term->frontbuf); 903 if (term->backbuf != NULL) 904 chargrid_destroy(term->backbuf); 1150 if (term->termui != NULL) 1151 termui_destroy(term->termui); 905 1152 free(term); 906 1153 return rc; 907 1154 } 908 1155 1156 static errno_t terminal_wait_fibril(void *arg) 1157 { 1158 terminal_t *term = (terminal_t *)arg; 1159 task_exit_t texit; 1160 int retval; 1161 1162 /* 1163 * XXX There is no way to break the sleep if the task does not 1164 * exit. 1165 */ 1166 (void) task_wait(&term->wait, &texit, &retval); 1167 ui_quit(term->ui); 1168 return EOK; 1169 } 1170 909 1171 /** @} 910 1172 */
Note:
See TracChangeset
for help on using the changeset viewer.