Changeset 899bdfd in mainline
- Timestamp:
- 2024-09-12T13:14:20Z (3 months ago)
- Branches:
- master
- Children:
- 4c2339b
- Parents:
- dd50aa19
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-12 11:47:56)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-12 13:14:20)
- Location:
- uspace
- Files:
-
- 5 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/terminal/meson.build
rdd50aa19 r899bdfd 27 27 # 28 28 29 deps = [ 'fbfont', 'display', 'ui' ]29 deps = [ 'fbfont', 'display', 'ui', 'termui' ] 30 30 src = files( 31 31 'main.c', -
uspace/app/terminal/terminal.c
rdd50aa19 r899bdfd 40 40 #include <errno.h> 41 41 #include <fbfont/font-8x16.h> 42 #include <io/chargrid.h>43 42 #include <fibril.h> 44 43 #include <gfx/bitmap.h> … … 49 48 #include <io/console.h> 50 49 #include <io/pixelmap.h> 51 #include < task.h>50 #include <macros.h> 52 51 #include <stdarg.h> 53 52 #include <stdio.h> 54 53 #include <stdlib.h> 54 #include <str_error.h> 55 55 #include <str.h> 56 #include <task.h> 56 57 #include <ui/resource.h> 57 58 #include <ui/ui.h> … … 71 72 (CONSOLE_CAP_STYLE | CONSOLE_CAP_INDEXED | CONSOLE_CAP_RGB) 72 73 74 #define SCROLLBACK_MAX_LINES 1000 75 #define MIN_WINDOW_COLS 8 76 #define MIN_WINDOW_ROWS 4 77 73 78 static LIST_INITIALIZE(terms); 79 80 #define COLOR_BRIGHT 8 81 82 static const pixel_t _basic_colors[16] = { 83 [COLOR_BLACK] = PIXEL(255, 0, 0, 0), 84 [COLOR_RED] = PIXEL(255, 170, 0, 0), 85 [COLOR_GREEN] = PIXEL(255, 0, 170, 0), 86 [COLOR_YELLOW] = PIXEL(255, 170, 85, 0), 87 [COLOR_BLUE] = PIXEL(255, 0, 0, 170), 88 [COLOR_MAGENTA] = PIXEL(255, 170, 0, 170), 89 [COLOR_CYAN] = PIXEL(255, 0, 170, 170), 90 [COLOR_WHITE] = PIXEL(255, 170, 170, 170), 91 92 [COLOR_BLACK | COLOR_BRIGHT] = PIXEL(255, 85, 85, 85), 93 [COLOR_RED | COLOR_BRIGHT] = PIXEL(255, 255, 85, 85), 94 [COLOR_GREEN | COLOR_BRIGHT] = PIXEL(255, 85, 255, 85), 95 [COLOR_YELLOW | COLOR_BRIGHT] = PIXEL(255, 255, 255, 85), 96 [COLOR_BLUE | COLOR_BRIGHT] = PIXEL(255, 85, 85, 255), 97 [COLOR_MAGENTA | COLOR_BRIGHT] = PIXEL(255, 255, 85, 255), 98 [COLOR_CYAN | COLOR_BRIGHT] = PIXEL(255, 85, 255, 255), 99 [COLOR_WHITE | COLOR_BRIGHT] = PIXEL(255, 255, 255, 255), 100 }; 74 101 75 102 static errno_t term_open(con_srvs_t *, con_srv_t *); … … 119 146 static void terminal_close_event(ui_window_t *, void *); 120 147 static void terminal_focus_event(ui_window_t *, void *, unsigned); 148 static void terminal_resize_event(ui_window_t *, void *); 121 149 static void terminal_kbd_event(ui_window_t *, void *, kbd_event_t *); 122 150 static void terminal_pos_event(ui_window_t *, void *, pos_event_t *); 123 151 static void terminal_unfocus_event(ui_window_t *, void *, unsigned); 152 static void terminal_maximize_event(ui_window_t *, void *); 153 static void terminal_unmaximize_event(ui_window_t *, void *); 124 154 125 155 static ui_window_cb_t terminal_window_cb = { 126 156 .close = terminal_close_event, 127 157 .focus = terminal_focus_event, 158 .resize = terminal_resize_event, 128 159 .kbd = terminal_kbd_event, 129 160 .pos = terminal_pos_event, 130 .unfocus = terminal_unfocus_event 161 .unfocus = terminal_unfocus_event, 162 .maximize = terminal_maximize_event, 163 .unmaximize = terminal_unmaximize_event, 131 164 }; 132 165 … … 144 177 } 145 178 146 static pixel_t color_table[16] = { 147 [COLOR_BLACK] = PIXEL(255, 0, 0, 0), 148 [COLOR_BLUE] = PIXEL(255, 0, 0, 170), 149 [COLOR_GREEN] = PIXEL(255, 0, 170, 0), 150 [COLOR_CYAN] = PIXEL(255, 0, 170, 170), 151 [COLOR_RED] = PIXEL(255, 170, 0, 0), 152 [COLOR_MAGENTA] = PIXEL(255, 170, 0, 170), 153 [COLOR_YELLOW] = PIXEL(255, 170, 85, 0), 154 [COLOR_WHITE] = PIXEL(255, 170, 170, 170), 155 156 [COLOR_BLACK + 8] = PIXEL(255, 85, 85, 85), 157 [COLOR_BLUE + 8] = PIXEL(255, 85, 85, 255), 158 [COLOR_GREEN + 8] = PIXEL(255, 85, 255, 85), 159 [COLOR_CYAN + 8] = PIXEL(255, 85, 255, 255), 160 [COLOR_RED + 8] = PIXEL(255, 255, 85, 85), 161 [COLOR_MAGENTA + 8] = PIXEL(255, 255, 85, 255), 162 [COLOR_YELLOW + 8] = PIXEL(255, 255, 255, 85), 163 [COLOR_WHITE + 8] = PIXEL(255, 255, 255, 255), 164 }; 165 166 static inline void attrs_rgb(char_attrs_t attrs, pixel_t *bgcolor, pixel_t *fgcolor) 167 { 168 switch (attrs.type) { 179 static pixel_t termui_color_to_pixel(termui_color_t c) 180 { 181 uint8_t r, g, b; 182 termui_color_to_rgb(c, &r, &g, &b); 183 return PIXEL(255, r, g, b); 184 } 185 186 static termui_color_t termui_color_from_pixel(pixel_t pixel) 187 { 188 return termui_color_from_rgb(RED(pixel), GREEN(pixel), BLUE(pixel)); 189 } 190 191 static termui_cell_t charfield_to_termui_cell(terminal_t *term, const charfield_t *cf) 192 { 193 termui_cell_t cell = { }; 194 195 cell.glyph_idx = fb_font_glyph(cf->ch, NULL); 196 197 switch (cf->attrs.type) { 169 198 case CHAR_ATTR_STYLE: 170 switch ( attrs.val.style) {199 switch (cf->attrs.val.style) { 171 200 case STYLE_NORMAL: 172 *bgcolor = color_table[COLOR_WHITE + 8];173 *fgcolor = color_table[COLOR_BLACK];201 cell.bgcolor = term->default_bgcolor; 202 cell.fgcolor = term->default_fgcolor; 174 203 break; 175 204 case STYLE_EMPHASIS: 176 *bgcolor = color_table[COLOR_WHITE + 8];177 *fgcolor = color_table[COLOR_RED + 8];205 cell.bgcolor = term->emphasis_bgcolor; 206 cell.fgcolor = term->emphasis_fgcolor; 178 207 break; 179 208 case STYLE_INVERTED: 180 *bgcolor = color_table[COLOR_BLACK]; 181 *fgcolor = color_table[COLOR_WHITE + 8]; 209 cell.bgcolor = term->default_bgcolor; 210 cell.fgcolor = term->default_fgcolor; 211 cell.inverted = 1; 182 212 break; 183 213 case STYLE_SELECTED: 184 *bgcolor = color_table[COLOR_RED + 8];185 *fgcolor = color_table[COLOR_WHITE + 8];214 cell.bgcolor = term->selection_bgcolor; 215 cell.fgcolor = term->selection_fgcolor; 186 216 break; 187 217 } 188 218 break; 219 189 220 case CHAR_ATTR_INDEX: 190 *bgcolor = color_table[(attrs.val.index.bgcolor & 7)]; 191 *fgcolor = color_table[(attrs.val.index.fgcolor & 7) | 192 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)]; 221 char_attr_index_t index = cf->attrs.val.index; 222 223 int bright = (index.attr & CATTR_BRIGHT) ? COLOR_BRIGHT : 0; 224 pixel_t bgcolor = _basic_colors[index.bgcolor | bright]; 225 pixel_t fgcolor = _basic_colors[index.fgcolor | bright]; 226 cell.bgcolor = termui_color_from_pixel(bgcolor); 227 cell.fgcolor = termui_color_from_pixel(fgcolor); 228 229 if (index.attr & CATTR_BLINK) 230 cell.blink = 1; 231 193 232 break; 233 194 234 case CHAR_ATTR_RGB: 195 *bgcolor = 0xff000000 | attrs.val.rgb.bgcolor;196 *fgcolor = 0xff000000 | attrs.val.rgb.fgcolor;235 cell.bgcolor = termui_color_from_pixel(cf->attrs.val.rgb.bgcolor); 236 cell.fgcolor = termui_color_from_pixel(cf->attrs.val.rgb.fgcolor); 197 237 break; 198 238 } 239 240 return cell; 199 241 } 200 242 … … 214 256 } 215 257 216 static void term_update_char(terminal_t *term, pixelmap_t *pixelmap, 217 sysarg_t col, sysarg_t row) 218 { 219 charfield_t *field = 220 chargrid_charfield_at(term->backbuf, col, row); 221 222 bool inverted = chargrid_cursor_at(term->backbuf, col, row); 223 224 sysarg_t bx = col * FONT_WIDTH; 225 sysarg_t by = row * FONT_SCANLINES; 226 227 pixel_t bgcolor = 0; 228 pixel_t fgcolor = 0; 229 230 if (inverted) 231 attrs_rgb(field->attrs, &fgcolor, &bgcolor); 232 else 233 attrs_rgb(field->attrs, &bgcolor, &fgcolor); 234 235 // FIXME: Glyph type should be actually uint32_t 236 // for full UTF-32 coverage. 237 238 uint16_t glyph = fb_font_glyph(field->ch, NULL); 258 static void term_draw_cell(terminal_t *term, pixelmap_t *pixelmap, int col, int row, const termui_cell_t *cell) 259 { 260 termui_color_t bg = cell->bgcolor; 261 if (bg == TERMUI_COLOR_DEFAULT) 262 bg = term->default_bgcolor; 263 264 termui_color_t fg = cell->fgcolor; 265 if (fg == TERMUI_COLOR_DEFAULT) 266 fg = term->default_fgcolor; 267 268 pixel_t bgcolor = termui_color_to_pixel(bg); 269 pixel_t fgcolor = termui_color_to_pixel(fg); 270 271 int bx = col * FONT_WIDTH; 272 int by = row * FONT_SCANLINES; 273 274 // TODO: support bold/italic/underline/strike/blink styling 275 276 if (cell->inverted ^ cell->cursor) { 277 pixel_t tmp = bgcolor; 278 bgcolor = fgcolor; 279 fgcolor = tmp; 280 } 281 282 uint32_t glyph = cell->glyph_idx; 283 assert(glyph < FONT_GLYPHS); 284 285 if (glyph == 0) 286 glyph = fb_font_glyph(U' ', NULL); 239 287 240 288 for (unsigned int y = 0; y < FONT_SCANLINES; y++) { … … 248 296 } 249 297 } 298 250 299 term_update_region(term, bx, by, FONT_WIDTH, FONT_SCANLINES); 251 300 } 252 301 253 static bool term_update_scroll(terminal_t *term, pixelmap_t *pixelmap) 254 { 255 sysarg_t top_row = chargrid_get_top_row(term->frontbuf); 256 257 if (term->top_row == top_row) { 258 return false; 259 } 260 261 term->top_row = top_row; 262 263 for (sysarg_t row = 0; row < term->rows; row++) { 264 for (sysarg_t col = 0; col < term->cols; col++) { 265 charfield_t *front_field = 266 chargrid_charfield_at(term->frontbuf, col, row); 267 charfield_t *back_field = 268 chargrid_charfield_at(term->backbuf, col, row); 269 bool update = false; 270 271 if (front_field->ch != back_field->ch) { 272 back_field->ch = front_field->ch; 273 update = true; 274 } 275 276 if (!attrs_same(front_field->attrs, back_field->attrs)) { 277 back_field->attrs = front_field->attrs; 278 update = true; 279 } 280 281 front_field->flags &= ~CHAR_FLAG_DIRTY; 282 283 if (update) { 284 term_update_char(term, pixelmap, col, row); 285 } 286 } 287 } 288 289 return true; 290 } 291 292 static bool term_update_cursor(terminal_t *term, pixelmap_t *pixelmap) 293 { 294 bool update = false; 295 296 sysarg_t front_col; 297 sysarg_t front_row; 298 chargrid_get_cursor(term->frontbuf, &front_col, &front_row); 299 300 sysarg_t back_col; 301 sysarg_t back_row; 302 chargrid_get_cursor(term->backbuf, &back_col, &back_row); 303 304 bool front_visibility = 305 chargrid_get_cursor_visibility(term->frontbuf) && 306 term->is_focused; 307 bool back_visibility = 308 chargrid_get_cursor_visibility(term->backbuf); 309 310 if (front_visibility != back_visibility) { 311 chargrid_set_cursor_visibility(term->backbuf, 312 front_visibility); 313 term_update_char(term, pixelmap, back_col, back_row); 314 update = true; 315 } 316 317 if ((front_col != back_col) || (front_row != back_row)) { 318 chargrid_set_cursor(term->backbuf, front_col, front_row); 319 term_update_char(term, pixelmap, back_col, back_row); 320 term_update_char(term, pixelmap, front_col, front_row); 321 update = true; 322 } 323 324 return update; 325 } 326 327 static void term_update(terminal_t *term) 328 { 329 pixelmap_t pixelmap; 302 static void term_render(terminal_t *term) 303 { 304 gfx_coord2_t pos = { .x = 4, .y = 26 }; 305 (void) gfx_bitmap_render(term->bmp, &term->update, &pos); 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 = { }; 330 331 gfx_bitmap_alloc_t alloc; 331 gfx_coord2_t pos; 332 errno_t rc; 333 334 rc = gfx_bitmap_get_alloc(term->bmp, &alloc); 335 if (rc != EOK) { 336 return; 337 } 338 339 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 340 337 pixelmap.width = term->w; 341 338 pixelmap.height = term->h; 342 339 pixelmap.data = alloc.pixels; 343 344 bool update = false; 345 346 if (term_update_scroll(term, &pixelmap)) { 347 update = true; 348 } else { 349 for (sysarg_t y = 0; y < term->rows; y++) { 350 for (sysarg_t x = 0; x < term->cols; x++) { 351 charfield_t *front_field = 352 chargrid_charfield_at(term->frontbuf, x, y); 353 charfield_t *back_field = 354 chargrid_charfield_at(term->backbuf, x, y); 355 bool cupdate = false; 356 357 if ((front_field->flags & CHAR_FLAG_DIRTY) == 358 CHAR_FLAG_DIRTY) { 359 if (front_field->ch != back_field->ch) { 360 back_field->ch = front_field->ch; 361 cupdate = true; 362 } 363 364 if (!attrs_same(front_field->attrs, 365 back_field->attrs)) { 366 back_field->attrs = front_field->attrs; 367 cupdate = true; 368 } 369 370 front_field->flags &= ~CHAR_FLAG_DIRTY; 371 } 372 373 if (cupdate) { 374 term_update_char(term, &pixelmap, x, y); 375 update = true; 376 } 377 } 378 } 379 } 380 381 if (term_update_cursor(term, &pixelmap)) 382 update = true; 383 384 if (update) { 385 pos.x = 4; 386 pos.y = 26; 387 (void) gfx_bitmap_render(term->bmp, &term->update, &pos); 388 389 term->update.p0.x = 0; 390 term->update.p0.y = 0; 391 term->update.p1.x = 0; 392 term->update.p1.y = 0; 393 } 394 395 fibril_mutex_unlock(&term->mtx); 396 } 397 398 static void term_repaint(terminal_t *term) 399 { 400 pixelmap_t pixelmap; 401 gfx_bitmap_alloc_t alloc; 402 errno_t rc; 403 404 rc = gfx_bitmap_get_alloc(term->bmp, &alloc); 405 if (rc != EOK) { 406 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) 407 347 return; 408 } 409 410 fibril_mutex_lock(&term->mtx); 411 412 pixelmap.width = term->w; 413 pixelmap.height = term->h; 414 pixelmap.data = alloc.pixels; 415 416 if (!term_update_scroll(term, &pixelmap)) { 417 for (sysarg_t y = 0; y < term->rows; y++) { 418 for (sysarg_t x = 0; x < term->cols; x++) { 419 charfield_t *front_field = 420 chargrid_charfield_at(term->frontbuf, x, y); 421 charfield_t *back_field = 422 chargrid_charfield_at(term->backbuf, x, y); 423 424 back_field->ch = front_field->ch; 425 back_field->attrs = front_field->attrs; 426 front_field->flags &= ~CHAR_FLAG_DIRTY; 427 428 term_update_char(term, &pixelmap, x, y); 429 } 430 } 431 } 432 433 term_update_cursor(term, &pixelmap); 434 435 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]); 436 366 } 437 367 … … 497 427 static void term_write_char(terminal_t *term, wchar_t ch) 498 428 { 499 sysarg_t updated = 0;500 501 fibril_mutex_lock(&term->mtx);502 503 429 switch (ch) { 504 case '\n':505 updated = chargrid_newline(term->frontbuf);430 case L'\n': 431 termui_put_crlf(term->termui); 506 432 break; 507 case '\r': 433 case L'\r': 434 termui_put_cr(term->termui); 508 435 break; 509 case '\t':510 updated = chargrid_tabstop(term->frontbuf, 8);436 case L'\t': 437 termui_put_tab(term->termui); 511 438 break; 512 case '\b':513 updated = chargrid_backspace(term->frontbuf);439 case L'\b': 440 termui_put_backspace(term->termui); 514 441 break; 515 442 default: 516 updated = chargrid_putuchar(term->frontbuf, ch, true); 517 } 518 519 fibril_mutex_unlock(&term->mtx); 520 521 if (updated > 1) 522 term_update(term); 443 // TODO: For some languages, we might need support for combining 444 // characters. Currently, we assume every unicode code point is 445 // an individual printed character, which is not always the case. 446 termui_put_glyph(term->termui, fb_font_glyph(ch, NULL), 1); 447 break; 448 } 523 449 } 524 450 … … 526 452 { 527 453 terminal_t *term = srv_to_terminal(srv); 454 455 fibril_mutex_lock(&term->mtx); 528 456 529 457 size_t off = 0; … … 531 459 term_write_char(term, str_decode(data, &off, size)); 532 460 461 fibril_mutex_unlock(&term->mtx); 462 463 term_render(term); 533 464 gfx_update(term->gc); 534 465 *nwritten = size; 466 535 467 return EOK; 536 468 } … … 540 472 terminal_t *term = srv_to_terminal(srv); 541 473 542 term_ update(term);474 term_render(term); 543 475 gfx_update(term->gc); 544 476 } … … 549 481 550 482 fibril_mutex_lock(&term->mtx); 551 chargrid_clear(term->frontbuf);552 fibril_mutex_unlock(&term->mtx); 553 554 term_ update(term);483 termui_clear_screen(term->termui); 484 fibril_mutex_unlock(&term->mtx); 485 486 term_render(term); 555 487 gfx_update(term->gc); 556 488 } … … 561 493 562 494 fibril_mutex_lock(&term->mtx); 563 chargrid_set_cursor(term->frontbuf, col, row);564 fibril_mutex_unlock(&term->mtx); 565 566 term_ update(term);495 termui_set_pos(term->termui, col, row); 496 fibril_mutex_unlock(&term->mtx); 497 498 term_render(term); 567 499 gfx_update(term->gc); 568 500 } … … 573 505 574 506 fibril_mutex_lock(&term->mtx); 575 chargrid_get_cursor(term->frontbuf, col, row); 576 fibril_mutex_unlock(&term->mtx); 507 int irow, icol; 508 termui_get_pos(term->termui, &icol, &irow); 509 fibril_mutex_unlock(&term->mtx); 510 511 *col = icol; 512 *row = irow; 577 513 578 514 return EOK; … … 584 520 585 521 fibril_mutex_lock(&term->mtx); 586 *cols = term ->cols;587 *rows = term ->rows;522 *cols = termui_get_cols(term->termui); 523 *rows = termui_get_rows(term->termui); 588 524 fibril_mutex_unlock(&term->mtx); 589 525 … … 603 539 terminal_t *term = srv_to_terminal(srv); 604 540 605 fibril_mutex_lock(&term->mtx); 606 chargrid_set_style(term->frontbuf, style); 541 termui_cell_t cellstyle = { }; 542 543 switch (style) { 544 case STYLE_NORMAL: 545 cellstyle.bgcolor = term->default_bgcolor; 546 cellstyle.fgcolor = term->default_fgcolor; 547 break; 548 case STYLE_EMPHASIS: 549 cellstyle.bgcolor = term->emphasis_bgcolor; 550 cellstyle.fgcolor = term->emphasis_fgcolor; 551 break; 552 case STYLE_INVERTED: 553 cellstyle.bgcolor = term->default_bgcolor; 554 cellstyle.fgcolor = term->default_fgcolor; 555 cellstyle.inverted = 1; 556 break; 557 case STYLE_SELECTED: 558 cellstyle.bgcolor = term->selection_bgcolor; 559 cellstyle.fgcolor = term->selection_fgcolor; 560 break; 561 } 562 563 fibril_mutex_lock(&term->mtx); 564 termui_set_style(term->termui, cellstyle); 607 565 fibril_mutex_unlock(&term->mtx); 608 566 } … … 613 571 terminal_t *term = srv_to_terminal(srv); 614 572 615 fibril_mutex_lock(&term->mtx); 616 chargrid_set_color(term->frontbuf, bgcolor, fgcolor, attr); 573 int bright = (attr & CATTR_BRIGHT) ? COLOR_BRIGHT : 0; 574 575 termui_cell_t cellstyle = { }; 576 cellstyle.bgcolor = termui_color_from_pixel(_basic_colors[bgcolor | bright]); 577 cellstyle.fgcolor = termui_color_from_pixel(_basic_colors[fgcolor | bright]); 578 579 if (attr & CATTR_BLINK) 580 cellstyle.blink = 1; 581 582 fibril_mutex_lock(&term->mtx); 583 termui_set_style(term->termui, cellstyle); 617 584 fibril_mutex_unlock(&term->mtx); 618 585 } … … 622 589 { 623 590 terminal_t *term = srv_to_terminal(srv); 624 625 fibril_mutex_lock(&term->mtx); 626 chargrid_set_rgb_color(term->frontbuf, bgcolor, fgcolor); 591 termui_cell_t cellstyle = { 592 .bgcolor = termui_color_from_pixel(bgcolor), 593 .fgcolor = termui_color_from_pixel(fgcolor), 594 }; 595 596 fibril_mutex_lock(&term->mtx); 597 termui_set_style(term->termui, cellstyle); 627 598 fibril_mutex_unlock(&term->mtx); 628 599 } … … 633 604 634 605 fibril_mutex_lock(&term->mtx); 635 chargrid_set_cursor_visibility(term->frontbuf, visible);636 fibril_mutex_unlock(&term->mtx); 637 638 term_ update(term);606 termui_set_cursor_visibility(term->termui, visible); 607 fibril_mutex_unlock(&term->mtx); 608 609 term_render(term); 639 610 gfx_update(term->gc); 640 611 } … … 655 626 fibril_mutex_unlock(&term->mtx); 656 627 657 term_ update(term);628 term_render(term); 658 629 gfx_update(term->gc); 659 630 return EOK; … … 703 674 term->urows = rows; 704 675 term->ubuf = buf; 676 677 /* Scroll back to active screen. */ 678 termui_history_scroll(term->termui, INT_MAX); 679 705 680 fibril_mutex_unlock(&term->mtx); 706 681 … … 723 698 term->ubuf = NULL; 724 699 700 termui_wipe_screen(term->termui, 0); 701 702 fibril_mutex_unlock(&term->mtx); 703 704 /* Update terminal */ 705 term_render(term); 706 gfx_update(term->gc); 707 725 708 if (buf != NULL) 726 709 as_area_destroy(buf); 727 728 fibril_mutex_unlock(&term->mtx);729 710 } 730 711 … … 741 722 { 742 723 terminal_t *term = srv_to_terminal(srv); 743 charfield_t *ch;744 sysarg_t col, row;745 724 746 725 fibril_mutex_lock(&term->mtx); … … 752 731 753 732 /* Make sure we have meaningful coordinates, within bounds */ 754 755 if (c1 > term->ucols)756 c1 = term->ucols;757 if (c1 > term->cols)758 c1 = term->cols; 759 if (c0 >= c1 ) {733 c1 = min(c1, term->ucols); 734 c1 = min(c1, (sysarg_t) termui_get_cols(term->termui)); 735 r1 = min(r1, term->urows); 736 r1 = min(r1, (sysarg_t) termui_get_rows(term->termui)); 737 738 if (c0 >= c1 || r0 >= r1) { 760 739 fibril_mutex_unlock(&term->mtx); 761 740 return; 762 741 } 763 if (r1 > term->urows)764 r1 = term->urows;765 if (r1 > term->rows)766 r1 = term->rows;767 if (r0 >= r1) {768 fibril_mutex_unlock(&term->mtx);769 return;770 }771 742 772 743 /* Update front buffer from user buffer */ 773 744 774 for (row = r0; row < r1; row++) { 775 for (col = c0; col < c1; col++) { 776 ch = chargrid_charfield_at(term->frontbuf, col, row); 777 *ch = term->ubuf[row * term->ucols + col]; 745 for (sysarg_t row = r0; row < r1; row++) { 746 termui_cell_t *cells = termui_get_active_row(term->termui, row); 747 748 for (sysarg_t col = c0; col < c1; col++) { 749 cells[col] = charfield_to_termui_cell(term, &term->ubuf[row * term->ucols + col]); 778 750 } 751 752 termui_update_cb(term, c0, row, &cells[c0], c1 - c0); 779 753 } 780 754 … … 782 756 783 757 /* Update terminal */ 784 term_ update(term);758 term_render(term); 785 759 gfx_update(term->gc); 786 760 } 787 761 788 static void deinit_terminal(terminal_t *term) 762 static errno_t terminal_window_resize(terminal_t *term) 763 { 764 gfx_rect_t rect; 765 ui_window_get_app_rect(term->window, &rect); 766 767 int width = rect.p1.x - rect.p0.x; 768 int height = rect.p1.y - rect.p0.y; 769 770 if (!term->gc) 771 term->gc = ui_window_get_gc(term->window); 772 else 773 assert(term->gc == ui_window_get_gc(term->window)); 774 775 if (!term->ui_res) 776 term->ui_res = ui_window_get_res(term->window); 777 else 778 assert(term->ui_res == ui_window_get_res(term->window)); 779 780 gfx_bitmap_t *new_bmp; 781 gfx_bitmap_params_t params; 782 gfx_bitmap_params_init(¶ms); 783 params.rect.p0.x = 0; 784 params.rect.p0.y = 0; 785 params.rect.p1.x = width; 786 params.rect.p1.y = height; 787 788 errno_t rc = gfx_bitmap_create(term->gc, ¶ms, NULL, &new_bmp); 789 if (rc != EOK) { 790 fprintf(stderr, "Error allocating new screen bitmap: %s\n", str_error(rc)); 791 return rc; 792 } 793 794 if (term->bmp) { 795 rc = gfx_bitmap_destroy(term->bmp); 796 if (rc != EOK) 797 fprintf(stderr, "Error deallocating old screen bitmap: %s\n", str_error(rc)); 798 } 799 800 term->bmp = new_bmp; 801 term->w = width; 802 term->h = height; 803 804 term_clear_bitmap(term, termui_color_to_pixel(term->default_bgcolor)); 805 806 return EOK; 807 } 808 809 void terminal_destroy(terminal_t *term) 789 810 { 790 811 list_remove(&term->link); 791 812 792 if (term->frontbuf) 793 chargrid_destroy(term->frontbuf); 794 795 if (term->backbuf) 796 chargrid_destroy(term->backbuf); 797 } 798 799 void terminal_destroy(terminal_t *term) 800 { 801 deinit_terminal(term); 813 termui_destroy(term->termui); 814 815 if (term->ubuf) 816 as_area_destroy(term->ubuf); 817 802 818 free(term); 803 819 } … … 833 849 (void)nfocus; 834 850 term->is_focused = true; 835 term_ update(term);851 term_render(term); 836 852 gfx_update(term->gc); 853 } 854 855 static void terminal_resize_handler(ui_window_t *window, void *arg) 856 { 857 terminal_t *term = (terminal_t *) arg; 858 859 fibril_mutex_lock(&term->mtx); 860 861 errno_t rc = terminal_window_resize(term); 862 if (rc == EOK) { 863 (void) termui_resize(term->termui, term->w / FONT_WIDTH, term->h / FONT_SCANLINES, SCROLLBACK_MAX_LINES); 864 termui_refresh_cb(term); 865 term_render(term); 866 gfx_update(term->gc); 867 868 cons_event_t event = { .type = CEV_RESIZE }; 869 terminal_queue_cons_event(term, &event); 870 } 871 872 fibril_mutex_unlock(&term->mtx); 873 } 874 875 static void terminal_resize_event(ui_window_t *window, void *arg) 876 { 877 ui_window_def_resize(window); 878 terminal_resize_handler(window, arg); 879 } 880 881 static void terminal_maximize_event(ui_window_t *window, void *arg) 882 { 883 ui_window_def_maximize(window); 884 terminal_resize_handler(window, arg); 885 } 886 887 static void terminal_unmaximize_event(ui_window_t *window, void *arg) 888 { 889 ui_window_def_unmaximize(window); 890 terminal_resize_handler(window, arg); 837 891 } 838 892 … … 847 901 event.ev.key = *kbd_event; 848 902 849 terminal_queue_cons_event(term, &event); 903 const int PAGE_ROWS = (termui_get_rows(term->termui) * 2) / 3; 904 905 fibril_mutex_lock(&term->mtx); 906 907 if (!term->ubuf && kbd_event->type == KEY_PRESS && 908 (kbd_event->key == KC_PAGE_UP || kbd_event->key == KC_PAGE_DOWN)) { 909 910 termui_history_scroll(term->termui, 911 (kbd_event->key == KC_PAGE_UP) ? -PAGE_ROWS : PAGE_ROWS); 912 913 term_render(term); 914 gfx_update(term->gc); 915 } else { 916 terminal_queue_cons_event(term, &event); 917 } 918 919 fibril_mutex_unlock(&term->mtx); 850 920 } 851 921 … … 856 926 terminal_t *term = (terminal_t *) arg; 857 927 928 switch (event->type) { 929 case POS_UPDATE: 930 return; 931 932 case POS_PRESS: 933 case POS_RELEASE: 934 case POS_DCLICK: 935 } 936 937 /* Ignore mouse events when we're in scrollback mode. */ 938 if (termui_scrollback_is_active(term->termui)) 939 return; 940 858 941 sysarg_t sx = -term->off.x; 859 942 sysarg_t sy = -term->off.y; 860 943 861 if (event->type == POS_PRESS || event->type == POS_RELEASE || 862 event->type == POS_DCLICK) { 863 cevent.type = CEV_POS; 864 cevent.ev.pos.type = event->type; 865 cevent.ev.pos.pos_id = event->pos_id; 866 cevent.ev.pos.btn_num = event->btn_num; 867 868 cevent.ev.pos.hpos = (event->hpos - sx) / FONT_WIDTH; 869 cevent.ev.pos.vpos = (event->vpos - sy) / FONT_SCANLINES; 944 if (event->hpos < sx || event->vpos < sy) 945 return; 946 947 cevent.type = CEV_POS; 948 cevent.ev.pos.type = event->type; 949 cevent.ev.pos.pos_id = event->pos_id; 950 cevent.ev.pos.btn_num = event->btn_num; 951 952 cevent.ev.pos.hpos = (event->hpos - sx) / FONT_WIDTH; 953 cevent.ev.pos.vpos = (event->vpos - sy) / FONT_SCANLINES; 954 955 /* Filter out events outside the terminal area. */ 956 int cols = termui_get_cols(term->termui); 957 int rows = termui_get_rows(term->termui); 958 959 if (cevent.ev.pos.hpos < (sysarg_t) cols && cevent.ev.pos.vpos < (sysarg_t) rows) 870 960 terminal_queue_cons_event(term, &cevent); 871 }872 961 } 873 962 … … 880 969 if (nfocus == 0) { 881 970 term->is_focused = false; 882 term_ update(term);971 term_render(term); 883 972 gfx_update(term->gc); 884 973 } … … 902 991 903 992 if (!atomic_flag_test_and_set(&term->refcnt)) 904 chargrid_set_cursor_visibility(term->frontbuf, true);993 termui_set_cursor_visibility(term->termui, true); 905 994 906 995 con_conn(icall, &term->srvs); 996 } 997 998 static errno_t term_init_window(terminal_t *term, const char *display_spec, 999 gfx_coord_t width, gfx_coord_t height, 1000 gfx_coord_t min_width, gfx_coord_t min_height, 1001 terminal_flags_t flags) 1002 { 1003 gfx_rect_t min_rect = { { 0, 0 }, { min_width, min_height } }; 1004 1005 ui_wnd_params_t wparams; 1006 ui_wnd_params_init(&wparams); 1007 wparams.caption = "Terminal"; 1008 wparams.style |= ui_wds_maximize_btn | ui_wds_resizable; 1009 if ((flags & tf_topleft) != 0) 1010 wparams.placement = ui_wnd_place_top_left; 1011 1012 errno_t rc = ui_create(display_spec, &term->ui); 1013 if (rc != EOK) { 1014 printf("Error creating UI on %s.\n", display_spec); 1015 return rc; 1016 } 1017 1018 /* Compute wrect such that application area corresponds to rect. */ 1019 gfx_rect_t wrect; 1020 ui_wdecor_rect_from_app(term->ui, wparams.style, &min_rect, &wrect); 1021 gfx_rect_rtranslate(&wrect.p0, &wrect, &wparams.rect); 1022 1023 rc = ui_window_create(term->ui, &wparams, &term->window); 1024 if (rc != EOK) 1025 return rc; 1026 1027 gfx_rect_t rect = { { 0, 0 }, { width, height } }; 1028 ui_wdecor_rect_from_app(term->ui, wparams.style, &rect, &rect); 1029 term->off = rect.p0; 1030 gfx_rect_rtranslate(&term->off, &rect, &wrect); 1031 1032 ui_window_resize(term->window, &wrect); 1033 ui_window_set_cb(term->window, &terminal_window_cb, (void *) term); 1034 1035 return terminal_window_resize(term); 907 1036 } 908 1037 … … 911 1040 terminal_t **rterm) 912 1041 { 913 terminal_t *term; 914 gfx_bitmap_params_t params; 915 ui_wnd_params_t wparams; 916 gfx_rect_t rect; 917 gfx_coord2_t off; 918 gfx_rect_t wrect; 1042 printf("terminal_create(%zu, %zu)\n", width, height); 1043 919 1044 errno_t rc; 920 1045 921 term = calloc(1, sizeof(terminal_t));1046 terminal_t *term = calloc(1, sizeof(terminal_t)); 922 1047 if (term == NULL) { 923 1048 printf("Out of memory.\n"); … … 932 1057 term->char_remains_len = 0; 933 1058 934 term-> w = width;935 term-> h = height;936 937 term-> cols = width / FONT_WIDTH;938 term-> rows = height / FONT_SCANLINES;939 940 term-> frontbuf = NULL;941 term-> backbuf = NULL;942 943 term-> frontbuf = chargrid_create(term->cols, term->rows,944 CHARGRID_FLAG_NONE);945 if (!term-> frontbuf) {946 printf("Error creating front buffer.\n");1059 term->default_bgcolor = termui_color_from_pixel(_basic_colors[COLOR_WHITE | COLOR_BRIGHT]); 1060 term->default_fgcolor = termui_color_from_pixel(_basic_colors[COLOR_BLACK]); 1061 1062 term->emphasis_bgcolor = termui_color_from_pixel(_basic_colors[COLOR_WHITE | COLOR_BRIGHT]); 1063 term->emphasis_fgcolor = termui_color_from_pixel(_basic_colors[COLOR_RED | COLOR_BRIGHT]); 1064 1065 term->selection_bgcolor = termui_color_from_pixel(_basic_colors[COLOR_RED | COLOR_BRIGHT]); 1066 term->selection_fgcolor = termui_color_from_pixel(_basic_colors[COLOR_WHITE | COLOR_BRIGHT]); 1067 1068 term->termui = termui_create(width / FONT_WIDTH, height / FONT_SCANLINES, 1069 SCROLLBACK_MAX_LINES); 1070 if (!term->termui) { 1071 printf("Error creating terminal UI.\n"); 947 1072 rc = ENOMEM; 948 1073 goto error; 949 1074 } 950 1075 951 term->backbuf = chargrid_create(term->cols, term->rows, 952 CHARGRID_FLAG_NONE); 953 if (!term->backbuf) { 954 printf("Error creating back buffer.\n"); 955 rc = ENOMEM; 1076 termui_set_refresh_cb(term->termui, termui_refresh_cb, term); 1077 termui_set_scroll_cb(term->termui, termui_scroll_cb, term); 1078 termui_set_update_cb(term->termui, termui_update_cb, term); 1079 1080 rc = term_init_window(term, display_spec, width, height, 1081 MIN_WINDOW_COLS * FONT_WIDTH, MIN_WINDOW_ROWS * FONT_SCANLINES, flags); 1082 if (rc != EOK) { 1083 printf("Error creating window (%s).\n", str_error(rc)); 956 1084 goto error; 957 1085 } 958 959 rect.p0.x = 0;960 rect.p0.y = 0;961 rect.p1.x = width;962 rect.p1.y = height;963 964 ui_wnd_params_init(&wparams);965 wparams.caption = "Terminal";966 if ((flags & tf_topleft) != 0)967 wparams.placement = ui_wnd_place_top_left;968 969 rc = ui_create(display_spec, &term->ui);970 if (rc != EOK) {971 printf("Error creating UI on %s.\n", display_spec);972 goto error;973 }974 975 /*976 * Compute window rectangle such that application area corresponds977 * to rect978 */979 ui_wdecor_rect_from_app(term->ui, wparams.style, &rect, &wrect);980 off = wrect.p0;981 gfx_rect_rtranslate(&off, &wrect, &wparams.rect);982 983 term->off = off;984 985 rc = ui_window_create(term->ui, &wparams, &term->window);986 if (rc != EOK) {987 printf("Error creating window.\n");988 goto error;989 }990 991 term->gc = ui_window_get_gc(term->window);992 term->ui_res = ui_window_get_res(term->window);993 994 ui_window_set_cb(term->window, &terminal_window_cb, (void *) term);995 996 gfx_bitmap_params_init(¶ms);997 params.rect.p0.x = 0;998 params.rect.p0.y = 0;999 params.rect.p1.x = width;1000 params.rect.p1.y = height;1001 1002 rc = gfx_bitmap_create(term->gc, ¶ms, NULL, &term->bmp);1003 if (rc != EOK) {1004 printf("Error allocating screen bitmap.\n");1005 goto error;1006 }1007 1008 chargrid_clear(term->frontbuf);1009 chargrid_clear(term->backbuf);1010 term->top_row = 0;1011 1086 1012 1087 async_set_fallback_port_handler(term_connection, NULL); … … 1046 1121 term->is_focused = true; 1047 1122 1048 term->update.p0.x = 0; 1049 term->update.p0.y = 0; 1050 term->update.p1.x = 0; 1051 term->update.p1.y = 0; 1052 1053 term_repaint(term); 1123 termui_refresh_cb(term); 1054 1124 1055 1125 *rterm = term; … … 1064 1134 if (term->ui != NULL) 1065 1135 ui_destroy(term->ui); 1066 if (term->frontbuf != NULL) 1067 chargrid_destroy(term->frontbuf); 1068 if (term->backbuf != NULL) 1069 chargrid_destroy(term->backbuf); 1136 if (term->termui != NULL) 1137 termui_destroy(term->termui); 1070 1138 free(term); 1071 1139 return rc; -
uspace/app/terminal/terminal.h
rdd50aa19 r899bdfd 45 45 #include <gfx/context.h> 46 46 #include <gfx/coord.h> 47 #include <io/chargrid.h>48 47 #include <io/con_srv.h> 49 48 #include <loc.h> … … 51 50 #include <str.h> 52 51 #include <task.h> 52 #include <termui.h> 53 53 #include <ui/ui.h> 54 54 #include <ui/window.h> … … 81 81 size_t char_remains_len; 82 82 83 sysarg_t cols; 84 sysarg_t rows; 85 chargrid_t *frontbuf; 86 chargrid_t *backbuf; 87 sysarg_t top_row; 83 termui_t *termui; 84 85 termui_color_t default_bgcolor; 86 termui_color_t default_fgcolor; 87 termui_color_t emphasis_bgcolor; 88 termui_color_t emphasis_fgcolor; 89 termui_color_t selection_bgcolor; 90 termui_color_t selection_fgcolor; 88 91 89 92 sysarg_t ucols; -
uspace/app/tetris/screen.c
rdd50aa19 r899bdfd 79 79 static usec_t timeleft = 0; 80 80 81 bool size_changed; 81 82 console_ctrl_t *console; 82 83 … … 217 218 218 219 fprintf(stderr, "aborting: %s", why); 219 abort();220 exit(1); 220 221 } 221 222 … … 410 411 exit(1); 411 412 413 if (event.type == CEV_RESIZE) 414 size_changed = true; 415 412 416 if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS) 413 417 c = event.ev.key.c; -
uspace/app/tetris/screen.h
rdd50aa19 r899bdfd 67 67 extern console_ctrl_t *console; 68 68 extern winsize_t winsize; 69 extern bool size_changed; 69 70 70 71 extern void moveto(sysarg_t r, sysarg_t c); -
uspace/app/tetris/tetris.c
rdd50aa19 r899bdfd 330 330 331 331 while (true) { 332 if (size_changed) { 333 size_changed = false; 334 scr_set(); 335 scr_msg(key_msg, 1); 336 } 337 332 338 place(curshape, pos, 1); 333 339 scr_update(); -
uspace/lib/clui/src/tinput.c
rdd50aa19 r899bdfd 113 113 static void tinput_display_tail(tinput_t *ti, size_t start, size_t pad) 114 114 { 115 char32_t *dbuf = malloc((INPUT_MAX_SIZE + 1) * sizeof(char32_t)); 116 if (!dbuf) 117 return; 118 115 char32_t stash; 119 116 size_t sa; 120 117 size_t sb; 121 118 tinput_sel_get_bounds(ti, &sa, &sb); 119 assert(sa <= sb); 122 120 123 121 tinput_console_set_lpos(ti, ti->text_coord + start); 124 122 console_set_style(ti->console, STYLE_NORMAL); 125 123 126 size_t p = start; 127 if (p < sa) { 128 memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(char32_t)); 129 dbuf[sa - p] = '\0'; 130 printf("%ls", dbuf); 131 p = sa; 132 } 133 134 if (p < sb) { 124 sa = max(start, sa); 125 sb = max(start, sb); 126 127 if (start < sa) { 128 stash = ti->buffer[sa]; 129 ti->buffer[sa] = L'\0'; 130 printf("%ls", &ti->buffer[start]); 131 ti->buffer[sa] = stash; 132 } 133 134 if (sa < sb) { 135 135 console_flush(ti->console); 136 136 console_set_style(ti->console, STYLE_SELECTED); 137 137 138 memcpy(dbuf, ti->buffer + p, 139 (sb - p) * sizeof(char32_t)); 140 dbuf[sb - p] = '\0'; 141 printf("%ls", dbuf); 142 p = sb; 143 } 138 stash = ti->buffer[sb]; 139 ti->buffer[sb] = L'\0'; 140 printf("%ls", &ti->buffer[sa]); 141 ti->buffer[sb] = stash; 142 143 console_flush(ti->console); 144 console_set_style(ti->console, STYLE_NORMAL); 145 } 146 147 if (sb < ti->nc) { 148 ti->buffer[ti->nc] = L'\0'; 149 printf("%ls", &ti->buffer[sb]); 150 } 151 152 for (; pad > 0; pad--) 153 putuchar(' '); 144 154 145 155 console_flush(ti->console); 146 console_set_style(ti->console, STYLE_NORMAL);147 148 if (p < ti->nc) {149 memcpy(dbuf, ti->buffer + p,150 (ti->nc - p) * sizeof(char32_t));151 dbuf[ti->nc - p] = '\0';152 printf("%ls", dbuf);153 }154 155 for (p = 0; p < pad; p++)156 putuchar(' ');157 158 console_flush(ti->console);159 160 free(dbuf);161 156 } 162 157 … … 218 213 tinput_display_prompt(ti); 219 214 220 /* The screen might have scrolled after pri ting the prompt */215 /* The screen might have scrolled after printing the prompt */ 221 216 tinput_update_origin_coord(ti, ti->prompt_coord + str_width(ti->prompt)); 222 217 … … 237 232 return; 238 233 239 unsigned new_width = LIN_TO_COL(ti, ti->text_coord) + ti->nc + 1; 240 if (new_width % ti->con_cols == 0) { 241 /* Advancing to new line. */ 242 sysarg_t new_height = (new_width / ti->con_cols) + 1; 243 if (new_height >= ti->con_rows) { 244 /* Disallow text longer than 1 page for now. */ 245 return; 246 } 247 } 234 /* Disallow text longer than 1 page for now. */ 235 unsigned prompt_len = ti->text_coord - ti->prompt_coord; 236 if (prompt_len + ti->nc + 1 >= ti->con_cols * ti->con_rows) 237 return; 248 238 249 239 size_t i; … … 881 871 } 882 872 873 static errno_t tinput_resize(tinput_t *ti) 874 { 875 assert(ti->prompt_coord % ti->con_cols == 0); 876 877 errno_t rc = console_get_size(ti->console, &ti->con_cols, &ti->con_rows); 878 if (rc != EOK) 879 return rc; 880 881 sysarg_t col, row; 882 rc = console_get_pos(ti->console, &col, &row); 883 if (rc != EOK) 884 return rc; 885 886 assert(ti->prompt_coord <= ti->text_coord); 887 unsigned prompt_len = ti->text_coord - ti->prompt_coord; 888 889 size_t new_caret_coord = row * ti->con_cols + col; 890 891 if (prompt_len <= new_caret_coord && ti->pos <= new_caret_coord - prompt_len) { 892 ti->text_coord = new_caret_coord - ti->pos; 893 ti->prompt_coord = ti->text_coord - prompt_len; 894 895 unsigned prompt_col = ti->prompt_coord % ti->con_cols; 896 if (prompt_col != 0) { 897 /* 898 * Prompt doesn't seem to start at column 0, which means 899 * the console didn't reflow the line like we expected it to. 900 * Change offsets a bit to recover. 901 */ 902 fprintf(stderr, "Unexpected prompt position after resize.\n"); 903 ti->prompt_coord -= prompt_col; 904 ti->text_coord -= prompt_col; 905 906 console_cursor_visibility(ti->console, false); 907 tinput_display_prompt(ti); 908 tinput_display_tail(ti, 0, prompt_col); 909 tinput_position_caret(ti); 910 console_cursor_visibility(ti->console, true); 911 } 912 913 assert(ti->prompt_coord % ti->con_cols == 0); 914 } else { 915 /* 916 * Overflown screen. 917 * We will just trim the buffer and rewrite everything. 918 */ 919 console_clear(ti->console); 920 921 ti->nc = min(ti->nc, ti->con_cols * ti->con_rows - prompt_len - 1); 922 ti->pos = min(ti->pos, ti->nc); 923 ti->sel_start = min(ti->sel_start, ti->nc); 924 925 ti->prompt_coord = 0; 926 ti->text_coord = prompt_len; 927 928 console_cursor_visibility(ti->console, false); 929 tinput_display_prompt(ti); 930 tinput_display_tail(ti, 0, 0); 931 tinput_position_caret(ti); 932 console_cursor_visibility(ti->console, true); 933 } 934 935 assert(ti->nc + ti->text_coord < ti->con_cols * ti->con_rows); 936 937 return EOK; 938 } 939 883 940 /** Read in one line of input with initial text provided. 884 941 * … … 927 984 tinput_pos(ti, &ev.ev.pos); 928 985 break; 986 case CEV_RESIZE: 987 tinput_resize(ti); 988 break; 929 989 } 930 990 } -
uspace/lib/console/include/io/cons_event.h
rdd50aa19 r899bdfd 44 44 CEV_KEY, 45 45 /** Position event */ 46 CEV_POS 46 CEV_POS, 47 /** Resize event */ 48 CEV_RESIZE, 47 49 } cons_event_type_t; 48 50 -
uspace/lib/console/src/con_srv.c
rdd50aa19 r899bdfd 53 53 ipc_set_arg4(icall, event->ev.key.mods); 54 54 ipc_set_arg5(icall, event->ev.key.c); 55 break;55 return EOK; 56 56 case CEV_POS: 57 57 ipc_set_arg2(icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff)); … … 59 59 ipc_set_arg4(icall, event->ev.pos.hpos); 60 60 ipc_set_arg5(icall, event->ev.pos.vpos); 61 break; 62 default: 63 return EIO; 64 } 65 66 return EOK; 61 return EOK; 62 case CEV_RESIZE: 63 ipc_set_arg2(icall, 0); 64 ipc_set_arg3(icall, 0); 65 ipc_set_arg4(icall, 0); 66 ipc_set_arg5(icall, 0); 67 return EOK; 68 } 69 70 return EIO; 67 71 } 68 72 -
uspace/lib/console/src/console.c
rdd50aa19 r899bdfd 193 193 event->ev.key.mods = ipc_get_arg4(call); 194 194 event->ev.key.c = ipc_get_arg5(call); 195 break;195 return EOK; 196 196 case CEV_POS: 197 197 event->ev.pos.pos_id = ipc_get_arg2(call) >> 16; … … 200 200 event->ev.pos.hpos = ipc_get_arg4(call); 201 201 event->ev.pos.vpos = ipc_get_arg5(call); 202 break;203 default:204 return E IO;205 } 206 207 return E OK;202 return EOK; 203 case CEV_RESIZE: 204 return EOK; 205 } 206 207 return EIO; 208 208 } 209 209 -
uspace/lib/meson.build
rdd50aa19 r899bdfd 91 91 'sif', 92 92 'tbarcfg', 93 'termui', 93 94 'trackmod', 94 95 'untar', -
uspace/lib/ui/src/ui.c
rdd50aa19 r899bdfd 357 357 358 358 break; 359 case CEV_RESIZE: 360 ui_lock(ui); 361 ui_window_send_resize(awnd); 362 ui_unlock(ui); 363 break; 359 364 } 360 365 }
Note:
See TracChangeset
for help on using the changeset viewer.