Changeset 7bf29e5 in mainline for uspace/app
- Timestamp:
- 2025-01-09T11:29:38Z (16 months ago)
- Children:
- a5c2960e
- Parents:
- bc3d695 (diff), 4e1221c (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. - Location:
- uspace/app
- Files:
-
- 6 added
- 14 edited
- 2 moved
-
gfxdemo/gfxdemo.c (modified) (9 diffs)
-
hello/hello.h (modified) (2 diffs)
-
init/init.c (modified) (6 diffs)
-
init/meson.build (modified) (2 diffs)
-
meson.build (modified) (1 diff)
-
shutdown-dlg/doc/doxygroups.h (added)
-
shutdown-dlg/meson.build (added)
-
shutdown-dlg/shutdown-dlg.c (added)
-
shutdown-dlg/shutdown-dlg.h (added)
-
shutdown/doc/doxygroups.h (added)
-
shutdown/meson.build (moved) (moved from uspace/srv/net/nconfsrv/meson.build ) (2 diffs)
-
shutdown/shutdown.c (added)
-
shutdown/shutdown.h (moved) (moved from abi/include/abi/proc/uarg.h ) (2 diffs)
-
sysinst/sysinst.c (modified) (1 diff)
-
terminal/meson.build (modified) (1 diff)
-
terminal/terminal.c (modified) (38 diffs)
-
terminal/terminal.h (modified) (4 diffs)
-
tester/print/print2.c (modified) (1 diff)
-
tetris/screen.c (modified) (7 diffs)
-
tetris/screen.h (modified) (1 diff)
-
tetris/tetris.c (modified) (1 diff)
-
uidemo/uidemo.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/gfxdemo/gfxdemo.c
rbc3d695 r7bf29e5 78 78 static gfx_coord_t vpad; 79 79 static console_ctrl_t *con = NULL; 80 static bool textmode; 80 81 static ui_t *ui; 81 82 82 83 /** Determine if we are running in text mode. 83 84 * 84 * @param w Screen width85 * @param h Screen height86 85 * @return @c true iff we are running in text mode 87 86 */ 88 static bool demo_is_text(gfx_coord_t w, gfx_coord_t h) 89 { 90 // XXX Need a proper way to determine text mode 91 return w <= 80; 87 static bool demo_is_text(void) 88 { 89 return textmode; 92 90 } 93 91 … … 181 179 182 180 /* XXX Crude way of detecting text mode */ 183 if ( w < 256) {181 if (demo_is_text()) { 184 182 /* Create dummy font for text mode */ 185 183 rc = gfx_typeface_create(gc, &tface); … … 270 268 271 269 if (font != NULL) { 272 if (demo_is_text( w, h)) {270 if (demo_is_text()) { 273 271 rc = gfx_color_new_ega(0x1e, &color); 274 272 if (rc != EOK) … … 719 717 gfx_color_delete(color); 720 718 721 if (demo_is_text( w, h)) {719 if (demo_is_text()) { 722 720 rc = gfx_color_new_ega(0x1f, &color); 723 721 if (rc != EOK) … … 807 805 808 806 for (i = 0; i < 8; i++) { 809 if (demo_is_text( w, h)) {807 if (demo_is_text()) { 810 808 rc = gfx_color_new_ega(i != 0 ? i : 0x10, &color); 811 809 if (rc != EOK) … … 884 882 gfx_color_delete(color); 885 883 886 if (demo_is_text( w, h)) {884 if (demo_is_text()) { 887 885 rc = gfx_color_new_ega(0x1f, &color); 888 886 if (rc != EOK) … … 1093 1091 1094 1092 gc = console_gc_get_ctx(cgc); 1093 1094 /* Currently console is always text. */ 1095 textmode = true; 1095 1096 1096 1097 rc = demo_loop(gc, cols, rows); … … 1192 1193 task_retval(0); 1193 1194 1195 textmode = ui_is_textmode(ui); 1196 1194 1197 args.gc = gc; 1195 1198 args.dims = dims; … … 1252 1255 1253 1256 task_retval(0); 1257 1258 /* FIXME Assuming display service is not text mode. */ 1259 textmode = false; 1254 1260 1255 1261 rc = demo_loop(gc, 400, 300); -
uspace/app/hello/hello.h
rbc3d695 r7bf29e5 1 1 /* 2 * Copyright (c) 202 0Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 37 37 #define HELLO_H 38 38 39 #include <display.h>40 39 #include <ui/fixed.h> 41 40 #include <ui/label.h> -
uspace/app/init/init.c
rbc3d695 r7bf29e5 35 35 */ 36 36 37 #include <fibril.h>38 #include <futil.h>39 37 #include <stdio.h> 40 38 #include <stdarg.h> … … 48 46 #include <loc.h> 49 47 #include <str_error.h> 50 #include <config.h>51 48 #include <io/logctl.h> 52 49 #include <vfs/vfs.h> 53 #include <vol.h>54 50 #include "untar.h" 55 51 #include "init.h" … … 61 57 #define ROOT_MOUNT_POINT "/" 62 58 63 #define LOCFS_FS_TYPE "locfs"64 #define LOCFS_MOUNT_POINT "/loc"65 66 #define TMPFS_FS_TYPE "tmpfs"67 #define TMPFS_MOUNT_POINT "/tmp"68 69 #define SRV_CONSOLE "/srv/hid/console"70 #define APP_GETTERM "/app/getterm"71 72 #define SRV_DISPLAY "/srv/hid/display"73 74 #define HID_INPUT "hid/input"75 #define HID_OUTPUT "hid/output"76 77 59 #define srv_start(path, ...) \ 78 60 srv_startl(path, path, ##__VA_ARGS__, NULL) 79 80 static const char *sys_dirs[] = {81 "/w/cfg",82 "/w/data",83 NULL,84 };85 61 86 62 /** Print banner */ … … 174 150 } 175 151 176 /** Mount locfs file system177 *178 * The operation blocks until the locfs file system179 * server is ready for mounting.180 *181 * @return True on success.182 * @return False on failure.183 *184 */185 static bool mount_locfs(void)186 {187 errno_t rc = vfs_mount_path(LOCFS_MOUNT_POINT, LOCFS_FS_TYPE, "", "",188 IPC_FLAG_BLOCKING, 0);189 return mount_report("Location service file system", LOCFS_MOUNT_POINT,190 LOCFS_FS_TYPE, NULL, rc);191 }192 193 152 static errno_t srv_startl(const char *path, ...) 194 153 { … … 253 212 } 254 213 255 static errno_t console(const char *isvc, const char *osvc)256 {257 /* Wait for the input service to be ready */258 service_id_t service_id;259 errno_t rc = loc_service_get_id(isvc, &service_id, IPC_FLAG_BLOCKING);260 if (rc != EOK) {261 printf("%s: Error waiting on %s (%s)\n", NAME, isvc,262 str_error(rc));263 return rc;264 }265 266 /* Wait for the output service to be ready */267 rc = loc_service_get_id(osvc, &service_id, IPC_FLAG_BLOCKING);268 if (rc != EOK) {269 printf("%s: Error waiting on %s (%s)\n", NAME, osvc,270 str_error(rc));271 return rc;272 }273 274 return srv_start(SRV_CONSOLE, isvc, osvc);275 }276 277 #ifdef CONFIG_WINSYS278 279 static errno_t display_server(void)280 {281 return srv_start(SRV_DISPLAY);282 }283 284 static int app_start(const char *app, const char *arg)285 {286 printf("%s: Spawning %s\n", NAME, app);287 288 task_id_t id;289 task_wait_t wait;290 errno_t rc = task_spawnl(&id, &wait, app, app, arg, NULL);291 if (rc != EOK) {292 oom_check(rc, app);293 printf("%s: Error spawning %s (%s)\n", NAME, app,294 str_error(rc));295 return -1;296 }297 298 task_exit_t texit;299 int retval;300 rc = task_wait(&wait, &texit, &retval);301 if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {302 printf("%s: Error retrieving retval from %s (%s)\n", NAME,303 app, str_error(rc));304 return rc;305 }306 307 return retval;308 }309 310 #endif311 312 static void getterm(const char *svc, const char *app, bool msg)313 {314 if (msg) {315 printf("%s: Spawning %s %s %s --msg --wait -- %s\n", NAME,316 APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);317 318 errno_t rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,319 LOCFS_MOUNT_POINT, "--msg", "--wait", "--", app, NULL);320 if (rc != EOK) {321 oom_check(rc, APP_GETTERM);322 printf("%s: Error spawning %s %s %s --msg --wait -- %s\n",323 NAME, APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);324 }325 } else {326 printf("%s: Spawning %s %s %s --wait -- %s\n", NAME,327 APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);328 329 errno_t rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,330 LOCFS_MOUNT_POINT, "--wait", "--", app, NULL);331 if (rc != EOK) {332 oom_check(rc, APP_GETTERM);333 printf("%s: Error spawning %s %s %s --wait -- %s\n",334 NAME, APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);335 }336 }337 }338 339 static bool mount_tmpfs(void)340 {341 errno_t rc = vfs_mount_path(TMPFS_MOUNT_POINT, TMPFS_FS_TYPE, "", "", 0, 0);342 return mount_report("Temporary file system", TMPFS_MOUNT_POINT,343 TMPFS_FS_TYPE, NULL, rc);344 }345 346 /** Init system volume.347 *348 * See if system volume is configured. If so, try to wait for it to become349 * available. If not, create basic directories for live image omde.350 */351 static errno_t init_sysvol(void)352 {353 vol_t *vol = NULL;354 vol_info_t vinfo;355 volume_id_t *volume_ids = NULL;356 service_id_t *part_ids = NULL;357 vol_part_info_t pinfo;358 size_t nvols;359 size_t nparts;360 bool sv_mounted;361 size_t i;362 errno_t rc;363 bool found_cfg;364 const char **cp;365 366 rc = vol_create(&vol);367 if (rc != EOK) {368 printf("Error contacting volume service.\n");369 goto error;370 }371 372 rc = vol_get_volumes(vol, &volume_ids, &nvols);373 if (rc != EOK) {374 printf("Error getting list of volumes.\n");375 goto error;376 }377 378 /* XXX This could be handled more efficiently by volsrv itself */379 found_cfg = false;380 for (i = 0; i < nvols; i++) {381 rc = vol_info(vol, volume_ids[i], &vinfo);382 if (rc != EOK) {383 printf("Error getting volume information.\n");384 rc = EIO;385 goto error;386 }387 388 if (str_cmp(vinfo.path, "/w") == 0) {389 found_cfg = true;390 break;391 }392 }393 394 free(volume_ids);395 volume_ids = NULL;396 397 if (!found_cfg) {398 /* Prepare directory structure for live image mode */399 printf("%s: Creating live image directory structure.\n", NAME);400 cp = sys_dirs;401 while (*cp != NULL) {402 rc = vfs_link_path(*cp, KIND_DIRECTORY, NULL);403 if (rc != EOK) {404 printf("%s: Error creating directory '%s'.\n",405 NAME, *cp);406 goto error;407 }408 409 ++cp;410 }411 412 /* Copy initial configuration files */413 rc = futil_rcopy_contents("/cfg", "/w/cfg");414 if (rc != EOK)415 goto error;416 } else {417 printf("%s: System volume is configured.\n", NAME);418 419 /* Wait until system volume is mounted */420 sv_mounted = false;421 422 while (true) {423 rc = vol_get_parts(vol, &part_ids, &nparts);424 if (rc != EOK) {425 printf("Error getting list of volumes.\n");426 goto error;427 }428 429 for (i = 0; i < nparts; i++) {430 rc = vol_part_info(vol, part_ids[i], &pinfo);431 if (rc != EOK) {432 printf("Error getting partition "433 "information.\n");434 rc = EIO;435 goto error;436 }437 438 if (str_cmp(pinfo.cur_mp, "/w") == 0) {439 sv_mounted = true;440 break;441 }442 }443 444 if (sv_mounted)445 break;446 447 free(part_ids);448 part_ids = NULL;449 450 fibril_sleep(1);451 printf("Sleeping(1) for system volume.\n");452 }453 }454 455 vol_destroy(vol);456 return EOK;457 error:458 vol_destroy(vol);459 if (volume_ids != NULL)460 free(volume_ids);461 if (part_ids != NULL)462 free(part_ids);463 464 return rc;465 }466 467 214 int main(int argc, char *argv[]) 468 215 { 469 errno_t rc;470 471 216 info_print(); 472 217 … … 476 221 } 477 222 478 /* Make sure file systems are running. */ 479 if (str_cmp(STRING(RDFMT), "tmpfs") != 0) 480 srv_start("/srv/fs/tmpfs"); 481 if (str_cmp(STRING(RDFMT), "exfat") != 0) 482 srv_start("/srv/fs/exfat"); 483 if (str_cmp(STRING(RDFMT), "fat") != 0) 484 srv_start("/srv/fs/fat"); 485 srv_start("/srv/fs/cdfs"); 486 srv_start("/srv/fs/mfs"); 487 488 srv_start("/srv/klog"); 489 srv_start("/srv/fs/locfs"); 490 491 if (!mount_locfs()) { 492 printf("%s: Exiting\n", NAME); 493 return 2; 494 } 495 496 mount_tmpfs(); 497 498 srv_start("/srv/devman"); 499 srv_start("/srv/hid/s3c24xx_uart"); 500 srv_start("/srv/hid/s3c24xx_ts"); 501 502 srv_start("/srv/bd/vbd"); 503 srv_start("/srv/bd/hr"); 504 srv_start("/srv/volsrv"); 505 506 init_sysvol(); 507 508 srv_start("/srv/taskmon"); 509 510 srv_start("/srv/net/loopip"); 511 srv_start("/srv/net/ethip"); 512 srv_start("/srv/net/inetsrv"); 513 srv_start("/srv/net/tcp"); 514 srv_start("/srv/net/udp"); 515 srv_start("/srv/net/dnsrsrv"); 516 srv_start("/srv/net/dhcp"); 517 srv_start("/srv/net/nconfsrv"); 518 519 srv_start("/srv/clipboard"); 520 srv_start("/srv/hid/remcons"); 521 522 srv_start("/srv/hid/input", HID_INPUT); 523 srv_start("/srv/hid/output", HID_OUTPUT); 524 srv_start("/srv/audio/hound"); 525 526 #ifdef CONFIG_WINSYS 527 if (!config_key_exists("console")) { 528 rc = display_server(); 529 if (rc == EOK) { 530 app_start("/app/taskbar", NULL); 531 app_start("/app/terminal", "-topleft"); 532 } 533 } 534 #endif 535 rc = console(HID_INPUT, HID_OUTPUT); 536 if (rc == EOK) { 537 getterm("term/vc0", "/app/bdsh", true); 538 getterm("term/vc1", "/app/bdsh", false); 539 getterm("term/vc2", "/app/bdsh", false); 540 getterm("term/vc3", "/app/bdsh", false); 541 getterm("term/vc4", "/app/bdsh", false); 542 getterm("term/vc5", "/app/bdsh", false); 543 } 544 223 /* System server takes over once root is mounted */ 224 srv_start("/srv/system"); 545 225 return 0; 546 226 } -
uspace/app/init/meson.build
rbc3d695 r7bf29e5 1 1 # 2 # Copyright (c) 2024 Jiri Svoboda 2 3 # Copyright (c) 2005 Martin Decky 3 4 # Copyright (c) 2007 Jakub Jermar … … 28 29 # 29 30 30 deps = [ 'block', ' futil', 'untar' ]31 deps = [ 'block', 'untar' ] 31 32 link_args += '-static' 32 33 src = files('init.c', 'untar.c') -
uspace/app/meson.build
rbc3d695 r7bf29e5 79 79 'redir', 80 80 'sbi', 81 'shutdown', 82 'shutdown-dlg', 81 83 'sportdmp', 82 84 'stats', -
uspace/app/shutdown/meson.build
rbc3d695 r7bf29e5 1 1 # 2 # Copyright (c) 202 1Jiri Svoboda2 # Copyright (c) 2024 Jiri Svoboda 3 3 # All rights reserved. 4 4 # … … 27 27 # 28 28 29 deps = [ ' inet' ]30 src = files(' iplink.c', 'nconfsrv.c')29 deps = [ 'clui', 'system' ] 30 src = files('shutdown.c') -
uspace/app/shutdown/shutdown.h
rbc3d695 r7bf29e5 1 1 /* 2 * Copyright (c) 20 06 Jakub Jermar2 * Copyright (c) 2024 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup abi_generic29 /** @addtogroup shutdown 30 30 * @{ 31 31 */ 32 /** @file 32 /** 33 * @file Shut the system down 33 34 */ 34 35 35 #ifndef _ABI_PROC_UARG_H_36 #define _ABI_PROC_UARG_H_36 #ifndef SHUTDOWN_H 37 #define SHUTDOWN_H 37 38 38 #include < stddef.h>39 #include < _bits/native.h>39 #include <fibril_synch.h> 40 #include <stdbool.h> 40 41 41 typedef void uspace_thread_function_t(void *); 42 /** Shutdown action */ 43 typedef enum { 44 sd_poweroff = 1, 45 sd_cancel 46 } sd_action_t; 42 47 43 /** Structure passed to uinit kernel thread as argument. */ 44 typedef struct uspace_arg { 45 uspace_addr_t uspace_entry; 46 uspace_addr_t uspace_stack; 47 size_t uspace_stack_size; 48 49 uspace_ptr_uspace_thread_function_t uspace_thread_function; 50 uspace_addr_t uspace_thread_arg; 51 52 uspace_ptr_struct_uspace_arg uspace_uarg; 53 } uspace_arg_t; 48 /** Shutdown state */ 49 typedef struct { 50 fibril_mutex_t lock; 51 fibril_condvar_t cv; 52 bool stopped; 53 bool failed; 54 } shutdown_t; 54 55 55 56 #endif -
uspace/app/sysinst/sysinst.c
rbc3d695 r7bf29e5 279 279 } 280 280 281 rv = asprintf(&path, "%s%s", rdpath, "/cfg/ volsrv.sif");281 rv = asprintf(&path, "%s%s", rdpath, "/cfg/initvol.sif"); 282 282 if (rv < 0) { 283 283 rc = ENOMEM; -
uspace/app/terminal/meson.build
rbc3d695 r7bf29e5 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
rbc3d695 r7bf29e5 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> … … 69 70 70 71 #define TERM_CAPS \ 71 (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 72 78 73 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 }; 74 102 75 103 static errno_t term_open(con_srvs_t *, con_srv_t *); … … 119 147 static void terminal_close_event(ui_window_t *, void *); 120 148 static void terminal_focus_event(ui_window_t *, void *, unsigned); 149 static void terminal_resize_event(ui_window_t *, void *); 121 150 static void terminal_kbd_event(ui_window_t *, void *, kbd_event_t *); 122 151 static void terminal_pos_event(ui_window_t *, void *, pos_event_t *); 123 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 *); 124 155 125 156 static ui_window_cb_t terminal_window_cb = { 126 157 .close = terminal_close_event, 127 158 .focus = terminal_focus_event, 159 .resize = terminal_resize_event, 128 160 .kbd = terminal_kbd_event, 129 161 .pos = terminal_pos_event, 130 .unfocus = terminal_unfocus_event 162 .unfocus = terminal_unfocus_event, 163 .maximize = terminal_maximize_event, 164 .unmaximize = terminal_unmaximize_event, 131 165 }; 132 166 … … 144 178 } 145 179 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) { 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) { 169 199 case CHAR_ATTR_STYLE: 170 switch ( attrs.val.style) {200 switch (cf->attrs.val.style) { 171 201 case STYLE_NORMAL: 172 *bgcolor = color_table[COLOR_WHITE + 8];173 *fgcolor = color_table[COLOR_BLACK];202 cell.bgcolor = term->default_bgcolor; 203 cell.fgcolor = term->default_fgcolor; 174 204 break; 175 205 case STYLE_EMPHASIS: 176 *bgcolor = color_table[COLOR_WHITE + 8];177 *fgcolor = color_table[COLOR_RED + 8];206 cell.bgcolor = term->emphasis_bgcolor; 207 cell.fgcolor = term->emphasis_fgcolor; 178 208 break; 179 209 case STYLE_INVERTED: 180 *bgcolor = color_table[COLOR_BLACK]; 181 *fgcolor = color_table[COLOR_WHITE + 8]; 210 cell.bgcolor = term->default_bgcolor; 211 cell.fgcolor = term->default_fgcolor; 212 cell.inverted = 1; 182 213 break; 183 214 case STYLE_SELECTED: 184 *bgcolor = color_table[COLOR_RED + 8];185 *fgcolor = color_table[COLOR_WHITE + 8];215 cell.bgcolor = term->selection_bgcolor; 216 cell.fgcolor = term->selection_fgcolor; 186 217 break; 187 218 } 188 219 break; 220 189 221 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)]; 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 193 233 break; 234 194 235 case CHAR_ATTR_RGB: 195 *bgcolor = 0xff000000 | attrs.val.rgb.bgcolor;196 *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); 197 238 break; 198 239 } 240 241 return cell; 199 242 } 200 243 … … 214 257 } 215 258 216 static void term_update_char(terminal_t *term, pixelmap_t *pixelmap, 217 sysarg_t sx, sysarg_t sy, 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 = sx + (col * FONT_WIDTH); 225 sysarg_t by = sy + (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); 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); 239 288 240 289 for (unsigned int y = 0; y < FONT_SCANLINES; y++) { … … 248 297 } 249 298 } 299 250 300 term_update_region(term, bx, by, FONT_WIDTH, FONT_SCANLINES); 251 301 } 252 302 253 static bool term_update_scroll(terminal_t *term, pixelmap_t *pixelmap, 254 sysarg_t sx, sysarg_t sy) 255 { 256 sysarg_t top_row = chargrid_get_top_row(term->frontbuf); 257 258 if (term->top_row == top_row) { 259 return false; 260 } 261 262 term->top_row = top_row; 263 264 for (sysarg_t row = 0; row < term->rows; row++) { 265 for (sysarg_t col = 0; col < term->cols; col++) { 266 charfield_t *front_field = 267 chargrid_charfield_at(term->frontbuf, col, row); 268 charfield_t *back_field = 269 chargrid_charfield_at(term->backbuf, col, row); 270 bool update = false; 271 272 if (front_field->ch != back_field->ch) { 273 back_field->ch = front_field->ch; 274 update = true; 275 } 276 277 if (!attrs_same(front_field->attrs, back_field->attrs)) { 278 back_field->attrs = front_field->attrs; 279 update = true; 280 } 281 282 front_field->flags &= ~CHAR_FLAG_DIRTY; 283 284 if (update) { 285 term_update_char(term, pixelmap, sx, sy, col, row); 286 } 287 } 288 } 289 290 return true; 291 } 292 293 static bool term_update_cursor(terminal_t *term, pixelmap_t *pixelmap, 294 sysarg_t sx, sysarg_t sy) 295 { 296 bool update = false; 297 298 sysarg_t front_col; 299 sysarg_t front_row; 300 chargrid_get_cursor(term->frontbuf, &front_col, &front_row); 301 302 sysarg_t back_col; 303 sysarg_t back_row; 304 chargrid_get_cursor(term->backbuf, &back_col, &back_row); 305 306 bool front_visibility = 307 chargrid_get_cursor_visibility(term->frontbuf) && 308 term->is_focused; 309 bool back_visibility = 310 chargrid_get_cursor_visibility(term->backbuf); 311 312 if (front_visibility != back_visibility) { 313 chargrid_set_cursor_visibility(term->backbuf, 314 front_visibility); 315 term_update_char(term, pixelmap, sx, sy, back_col, back_row); 316 update = true; 317 } 318 319 if ((front_col != back_col) || (front_row != back_row)) { 320 chargrid_set_cursor(term->backbuf, front_col, front_row); 321 term_update_char(term, pixelmap, sx, sy, back_col, back_row); 322 term_update_char(term, pixelmap, sx, sy, front_col, front_row); 323 update = true; 324 } 325 326 return update; 327 } 328 329 static void term_update(terminal_t *term) 330 { 331 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 = { }; 332 331 gfx_bitmap_alloc_t alloc; 333 gfx_coord2_t pos; 334 errno_t rc; 335 336 rc = gfx_bitmap_get_alloc(term->bmp, &alloc); 337 if (rc != EOK) { 338 return; 339 } 340 341 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 342 337 pixelmap.width = term->w; 343 338 pixelmap.height = term->h; 344 339 pixelmap.data = alloc.pixels; 345 346 bool update = false; 347 sysarg_t sx = 0; 348 sysarg_t sy = 0; 349 350 if (term_update_scroll(term, &pixelmap, sx, sy)) { 351 update = true; 352 } else { 353 for (sysarg_t y = 0; y < term->rows; y++) { 354 for (sysarg_t x = 0; x < term->cols; x++) { 355 charfield_t *front_field = 356 chargrid_charfield_at(term->frontbuf, x, y); 357 charfield_t *back_field = 358 chargrid_charfield_at(term->backbuf, x, y); 359 bool cupdate = false; 360 361 if ((front_field->flags & CHAR_FLAG_DIRTY) == 362 CHAR_FLAG_DIRTY) { 363 if (front_field->ch != back_field->ch) { 364 back_field->ch = front_field->ch; 365 cupdate = true; 366 } 367 368 if (!attrs_same(front_field->attrs, 369 back_field->attrs)) { 370 back_field->attrs = front_field->attrs; 371 cupdate = true; 372 } 373 374 front_field->flags &= ~CHAR_FLAG_DIRTY; 375 } 376 377 if (cupdate) { 378 term_update_char(term, &pixelmap, sx, sy, x, y); 379 update = true; 380 } 381 } 382 } 383 } 384 385 if (term_update_cursor(term, &pixelmap, sx, sy)) 386 update = true; 387 388 if (update) { 389 pos.x = 4; 390 pos.y = 26; 391 (void) gfx_bitmap_render(term->bmp, &term->update, &pos); 392 393 term->update.p0.x = 0; 394 term->update.p0.y = 0; 395 term->update.p1.x = 0; 396 term->update.p1.y = 0; 397 } 398 399 fibril_mutex_unlock(&term->mtx); 400 } 401 402 static void term_repaint(terminal_t *term) 403 { 404 pixelmap_t pixelmap; 405 gfx_bitmap_alloc_t alloc; 406 errno_t rc; 407 408 rc = gfx_bitmap_get_alloc(term->bmp, &alloc); 409 if (rc != EOK) { 410 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) 411 347 return; 412 } 413 414 fibril_mutex_lock(&term->mtx); 415 416 pixelmap.width = term->w; 417 pixelmap.height = term->h; 418 pixelmap.data = alloc.pixels; 419 420 sysarg_t sx = 0; 421 sysarg_t sy = 0; 422 423 if (!term_update_scroll(term, &pixelmap, sx, sy)) { 424 for (sysarg_t y = 0; y < term->rows; y++) { 425 for (sysarg_t x = 0; x < term->cols; x++) { 426 charfield_t *front_field = 427 chargrid_charfield_at(term->frontbuf, x, y); 428 charfield_t *back_field = 429 chargrid_charfield_at(term->backbuf, x, y); 430 431 back_field->ch = front_field->ch; 432 back_field->attrs = front_field->attrs; 433 front_field->flags &= ~CHAR_FLAG_DIRTY; 434 435 term_update_char(term, &pixelmap, sx, sy, x, y); 436 } 437 } 438 } 439 440 term_update_cursor(term, &pixelmap, sx, sy); 441 442 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]); 443 366 } 444 367 … … 480 403 if (pos < size) { 481 404 link_t *link = prodcons_consume(&term->input_pc); 482 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; 483 408 484 409 /* Accept key presses of printable chars only. */ … … 494 419 } 495 420 496 free( event);421 free(qevent); 497 422 } 498 423 } … … 504 429 static void term_write_char(terminal_t *term, wchar_t ch) 505 430 { 506 sysarg_t updated = 0;507 508 fibril_mutex_lock(&term->mtx);509 510 431 switch (ch) { 511 case '\n':512 updated = chargrid_newline(term->frontbuf);432 case L'\n': 433 termui_put_crlf(term->termui); 513 434 break; 514 case '\r': 435 case L'\r': 436 termui_put_cr(term->termui); 515 437 break; 516 case '\t':517 updated = chargrid_tabstop(term->frontbuf, 8);438 case L'\t': 439 termui_put_tab(term->termui); 518 440 break; 519 case '\b':520 updated = chargrid_backspace(term->frontbuf);441 case L'\b': 442 termui_put_backspace(term->termui); 521 443 break; 522 444 default: 523 updated = chargrid_putuchar(term->frontbuf, ch, true); 524 } 525 526 fibril_mutex_unlock(&term->mtx); 527 528 if (updated > 1) 529 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 } 530 451 } 531 452 … … 533 454 { 534 455 terminal_t *term = srv_to_terminal(srv); 456 457 fibril_mutex_lock(&term->mtx); 535 458 536 459 size_t off = 0; … … 538 461 term_write_char(term, str_decode(data, &off, size)); 539 462 463 fibril_mutex_unlock(&term->mtx); 464 465 term_render(term); 540 466 gfx_update(term->gc); 541 467 *nwritten = size; 468 542 469 return EOK; 543 470 } … … 547 474 terminal_t *term = srv_to_terminal(srv); 548 475 549 term_ update(term);476 term_render(term); 550 477 gfx_update(term->gc); 551 478 } … … 556 483 557 484 fibril_mutex_lock(&term->mtx); 558 chargrid_clear(term->frontbuf);559 fibril_mutex_unlock(&term->mtx); 560 561 term_ update(term);485 termui_clear_screen(term->termui); 486 fibril_mutex_unlock(&term->mtx); 487 488 term_render(term); 562 489 gfx_update(term->gc); 563 490 } … … 568 495 569 496 fibril_mutex_lock(&term->mtx); 570 chargrid_set_cursor(term->frontbuf, col, row);571 fibril_mutex_unlock(&term->mtx); 572 573 term_ update(term);497 termui_set_pos(term->termui, col, row); 498 fibril_mutex_unlock(&term->mtx); 499 500 term_render(term); 574 501 gfx_update(term->gc); 575 502 } … … 580 507 581 508 fibril_mutex_lock(&term->mtx); 582 chargrid_get_cursor(term->frontbuf, col, row); 583 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; 584 515 585 516 return EOK; … … 591 522 592 523 fibril_mutex_lock(&term->mtx); 593 *cols = term ->cols;594 *rows = term ->rows;524 *cols = termui_get_cols(term->termui); 525 *rows = termui_get_rows(term->termui); 595 526 fibril_mutex_unlock(&term->mtx); 596 527 … … 610 541 terminal_t *term = srv_to_terminal(srv); 611 542 612 fibril_mutex_lock(&term->mtx); 613 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); 614 567 fibril_mutex_unlock(&term->mtx); 615 568 } … … 620 573 terminal_t *term = srv_to_terminal(srv); 621 574 622 fibril_mutex_lock(&term->mtx); 623 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); 624 586 fibril_mutex_unlock(&term->mtx); 625 587 } … … 629 591 { 630 592 terminal_t *term = srv_to_terminal(srv); 631 632 fibril_mutex_lock(&term->mtx); 633 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); 634 600 fibril_mutex_unlock(&term->mtx); 635 601 } … … 640 606 641 607 fibril_mutex_lock(&term->mtx); 642 chargrid_set_cursor_visibility(term->frontbuf, visible);643 fibril_mutex_unlock(&term->mtx); 644 645 term_ update(term);608 termui_set_cursor_visibility(term->termui, visible); 609 fibril_mutex_unlock(&term->mtx); 610 611 term_render(term); 646 612 gfx_update(term->gc); 647 613 } … … 662 628 fibril_mutex_unlock(&term->mtx); 663 629 664 term_ update(term);630 term_render(term); 665 631 gfx_update(term->gc); 666 632 return EOK; … … 671 637 terminal_t *term = srv_to_terminal(srv); 672 638 link_t *link = prodcons_consume(&term->input_pc); 673 cons_event_t *ev = list_get_instance(link, cons_event_t, link);674 675 *event = *ev;639 terminal_event_t *ev = list_get_instance(link, terminal_event_t, link); 640 641 *event = ev->ev; 676 642 free(ev); 677 643 return EOK; … … 710 676 term->urows = rows; 711 677 term->ubuf = buf; 678 679 /* Scroll back to active screen. */ 680 termui_history_scroll(term->termui, INT_MAX); 681 712 682 fibril_mutex_unlock(&term->mtx); 713 683 … … 730 700 term->ubuf = NULL; 731 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 732 710 if (buf != NULL) 733 711 as_area_destroy(buf); 734 735 fibril_mutex_unlock(&term->mtx);736 712 } 737 713 … … 748 724 { 749 725 terminal_t *term = srv_to_terminal(srv); 750 charfield_t *ch;751 sysarg_t col, row;752 726 753 727 fibril_mutex_lock(&term->mtx); … … 759 733 760 734 /* Make sure we have meaningful coordinates, within bounds */ 761 762 if (c1 > term->ucols)763 c1 = term->ucols;764 if (c1 > term->cols)765 c1 = term->cols; 766 if (c0 >= c1 ) {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) { 767 741 fibril_mutex_unlock(&term->mtx); 768 742 return; 769 743 } 770 if (r1 > term->urows)771 r1 = term->urows;772 if (r1 > term->rows)773 r1 = term->rows;774 if (r0 >= r1) {775 fibril_mutex_unlock(&term->mtx);776 return;777 }778 744 779 745 /* Update front buffer from user buffer */ 780 746 781 for (row = r0; row < r1; row++) { 782 for (col = c0; col < c1; col++) { 783 ch = chargrid_charfield_at(term->frontbuf, col, row); 784 *ch = term->ubuf[row * term->ucols + col]; 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]); 785 752 } 753 754 termui_update_cb(term, c0, row, &cells[c0], c1 - c0); 786 755 } 787 756 … … 789 758 790 759 /* Update terminal */ 791 term_ update(term);760 term_render(term); 792 761 gfx_update(term->gc); 793 762 } 794 763 795 static void deinit_terminal(terminal_t *term) 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) 796 812 { 797 813 list_remove(&term->link); 798 814 799 if (term->frontbuf) 800 chargrid_destroy(term->frontbuf); 801 802 if (term->backbuf) 803 chargrid_destroy(term->backbuf); 804 } 805 806 void terminal_destroy(terminal_t *term) 807 { 808 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); 809 821 free(term); 810 822 } … … 813 825 { 814 826 /* Got key press/release event */ 815 cons_event_t *event =816 ( cons_event_t *) malloc(sizeof(cons_event_t));827 terminal_event_t *event = 828 (terminal_event_t *) malloc(sizeof(terminal_event_t)); 817 829 if (event == NULL) 818 830 return; 819 831 820 *event= *ev;832 event->ev = *ev; 821 833 link_initialize(&event->link); 822 834 … … 840 852 (void)nfocus; 841 853 term->is_focused = true; 842 term_ update(term);854 term_render(term); 843 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); 844 894 } 845 895 … … 854 904 event.ev.key = *kbd_event; 855 905 856 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); 857 923 } 858 924 … … 863 929 terminal_t *term = (terminal_t *) arg; 864 930 865 sysarg_t sx = -term->off.x; 866 sysarg_t sy = -term->off.y; 867 868 if (event->type == POS_PRESS || event->type == POS_RELEASE || 869 event->type == POS_DCLICK) { 870 cevent.type = CEV_POS; 871 cevent.ev.pos.type = event->type; 872 cevent.ev.pos.pos_id = event->pos_id; 873 cevent.ev.pos.btn_num = event->btn_num; 874 875 cevent.ev.pos.hpos = (event->hpos - sx) / FONT_WIDTH; 876 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) 877 963 terminal_queue_cons_event(term, &cevent); 878 }879 964 } 880 965 … … 887 972 if (nfocus == 0) { 888 973 term->is_focused = false; 889 term_ update(term);974 term_render(term); 890 975 gfx_update(term->gc); 891 976 } … … 909 994 910 995 if (!atomic_flag_test_and_set(&term->refcnt)) 911 chargrid_set_cursor_visibility(term->frontbuf, true);996 termui_set_cursor_visibility(term->termui, true); 912 997 913 998 con_conn(icall, &term->srvs); 999 } 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); 914 1052 } 915 1053 … … 918 1056 terminal_t **rterm) 919 1057 { 920 terminal_t *term;921 gfx_bitmap_params_t params;922 ui_wnd_params_t wparams;923 gfx_rect_t rect;924 gfx_coord2_t off;925 gfx_rect_t wrect;926 1058 errno_t rc; 927 1059 928 term = calloc(1, sizeof(terminal_t));1060 terminal_t *term = calloc(1, sizeof(terminal_t)); 929 1061 if (term == NULL) { 930 1062 printf("Out of memory.\n"); … … 939 1071 term->char_remains_len = 0; 940 1072 941 term->w = width; 942 term->h = height; 943 944 term->cols = width / FONT_WIDTH; 945 term->rows = height / FONT_SCANLINES; 946 947 term->frontbuf = NULL; 948 term->backbuf = NULL; 949 950 term->frontbuf = chargrid_create(term->cols, term->rows, 951 CHARGRID_FLAG_NONE); 952 if (!term->frontbuf) { 953 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"); 954 1093 rc = ENOMEM; 955 1094 goto error; 956 1095 } 957 1096 958 term->backbuf = chargrid_create(term->cols, term->rows, 959 CHARGRID_FLAG_NONE); 960 if (!term->backbuf) { 961 printf("Error creating back buffer.\n"); 962 rc = ENOMEM; 963 goto error; 964 } 965 966 rect.p0.x = 0; 967 rect.p0.y = 0; 968 rect.p1.x = width; 969 rect.p1.y = height; 970 971 ui_wnd_params_init(&wparams); 972 wparams.caption = "Terminal"; 973 if ((flags & tf_topleft) != 0) 974 wparams.placement = ui_wnd_place_top_left; 975 976 rc = ui_create(display_spec, &term->ui); 977 if (rc != EOK) { 978 printf("Error creating UI on %s.\n", display_spec); 979 goto error; 980 } 981 982 /* 983 * Compute window rectangle such that application area corresponds 984 * to rect 985 */ 986 ui_wdecor_rect_from_app(term->ui, wparams.style, &rect, &wrect); 987 off = wrect.p0; 988 gfx_rect_rtranslate(&off, &wrect, &wparams.rect); 989 990 term->off = off; 991 992 rc = ui_window_create(term->ui, &wparams, &term->window); 993 if (rc != EOK) { 994 printf("Error creating window.\n"); 995 goto error; 996 } 997 998 term->gc = ui_window_get_gc(term->window); 999 term->ui_res = ui_window_get_res(term->window); 1000 1001 ui_window_set_cb(term->window, &terminal_window_cb, (void *) term); 1002 1003 gfx_bitmap_params_init(¶ms); 1004 params.rect.p0.x = 0; 1005 params.rect.p0.y = 0; 1006 params.rect.p1.x = width; 1007 params.rect.p1.y = height; 1008 1009 rc = gfx_bitmap_create(term->gc, ¶ms, NULL, &term->bmp); 1010 if (rc != EOK) { 1011 printf("Error allocating screen bitmap.\n"); 1012 goto error; 1013 } 1014 1015 chargrid_clear(term->frontbuf); 1016 chargrid_clear(term->backbuf); 1017 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); 1018 1100 1019 1101 async_set_fallback_port_handler(term_connection, NULL); … … 1053 1135 term->is_focused = true; 1054 1136 1055 term->update.p0.x = 0; 1056 term->update.p0.y = 0; 1057 term->update.p1.x = 0; 1058 term->update.p1.y = 0; 1059 1060 term_repaint(term); 1137 termui_refresh_cb(term); 1061 1138 1062 1139 *rterm = term; … … 1071 1148 if (term->ui != NULL) 1072 1149 ui_destroy(term->ui); 1073 if (term->frontbuf != NULL) 1074 chargrid_destroy(term->frontbuf); 1075 if (term->backbuf != NULL) 1076 chargrid_destroy(term->backbuf); 1150 if (term->termui != NULL) 1151 termui_destroy(term->termui); 1077 1152 free(term); 1078 1153 return rc; -
uspace/app/terminal/terminal.h
rbc3d695 r7bf29e5 1 1 /* 2 * Copyright (c) 202 3Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * Copyright (c) 2012 Petr Koupy 4 4 * All rights reserved. … … 45 45 #include <gfx/context.h> 46 46 #include <gfx/coord.h> 47 #include <io/chargrid.h>48 47 #include <io/con_srv.h> 48 #include <io/cons_event.h> 49 49 #include <loc.h> 50 50 #include <stdatomic.h> 51 51 #include <str.h> 52 52 #include <task.h> 53 #include <termui.h> 53 54 #include <ui/ui.h> 54 55 #include <ui/window.h> … … 81 82 size_t char_remains_len; 82 83 83 sysarg_t cols; 84 sysarg_t rows; 85 chargrid_t *frontbuf; 86 chargrid_t *backbuf; 87 sysarg_t top_row; 84 termui_t *termui; 85 86 termui_color_t default_bgcolor; 87 termui_color_t default_fgcolor; 88 termui_color_t emphasis_bgcolor; 89 termui_color_t emphasis_fgcolor; 90 termui_color_t selection_bgcolor; 91 termui_color_t selection_fgcolor; 88 92 89 93 sysarg_t ucols; … … 99 103 } terminal_t; 100 104 105 /** Terminal event */ 106 typedef struct { 107 /** Link to list of events */ 108 link_t link; 109 /** Console event */ 110 cons_event_t ev; 111 } terminal_event_t; 112 101 113 extern errno_t terminal_create(const char *, sysarg_t, sysarg_t, 102 114 terminal_flags_t, const char *, terminal_t **); -
uspace/app/tester/print/print2.c
rbc3d695 r7bf29e5 62 62 TPRINTF("Real output: [%td] [%tu] [%tx] [%ti] [%to]\n\n", d, neg_d, neg_d, d, neg_d); 63 63 64 TPRINTF("Testing printf(\"%%lf\", 768.0):\n"); 65 TPRINTF("Expected output: [768.000000]\n"); 66 TPRINTF("Real output: [%lf]\n", 768.0); 67 64 68 return NULL; 65 69 } -
uspace/app/tetris/screen.c
rbc3d695 r7bf29e5 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2011 Martin Decky 3 4 * All rights reserved. … … 79 80 static usec_t timeleft = 0; 80 81 82 bool size_changed; 81 83 console_ctrl_t *console; 82 84 … … 142 144 console_cursor_visibility(console, 0); 143 145 resume_normal(); 144 scr_ clear();146 scr_set(); 145 147 } 146 148 … … 169 171 } 170 172 173 if ((ccap & CONSOLE_CAP_CURSORCTL) == 0) { 174 stop("Your screen does not support cursor control.\n"); 175 return; 176 } 171 177 *rgb = ((ccap & CONSOLE_CAP_RGB) == CONSOLE_CAP_RGB); 172 178 *color = ((ccap & CONSOLE_CAP_INDEXED) == CONSOLE_CAP_INDEXED); … … 194 200 195 201 snprintf(smallscr, sizeof(smallscr), 196 "the screen is too small (must be at least %dx%d) ",202 "the screen is too small (must be at least %dx%d)\n", 197 203 MINROWS, MINCOLS); 198 204 stop(smallscr); … … 217 223 218 224 fprintf(stderr, "aborting: %s", why); 219 abort();225 exit(1); 220 226 } 221 227 … … 410 416 exit(1); 411 417 418 if (event.type == CEV_RESIZE) 419 size_changed = true; 420 412 421 if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS) 413 422 c = event.ev.key.c; -
uspace/app/tetris/screen.h
rbc3d695 r7bf29e5 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
rbc3d695 r7bf29e5 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/app/uidemo/uidemo.c
rbc3d695 r7bf29e5 1 1 /* 2 * Copyright (c) 202 3Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 108 108 static void uidemo_file_load(ui_menu_entry_t *, void *); 109 109 static void uidemo_file_message(ui_menu_entry_t *, void *); 110 static void uidemo_file_confirmation(ui_menu_entry_t *, void *); 110 111 static void uidemo_file_exit(ui_menu_entry_t *, void *); 111 112 static void uidemo_edit_modify(ui_menu_entry_t *, void *); … … 340 341 } 341 342 342 /** Display a message window .343 /** Display a message window with OK button. 343 344 * 344 345 * @param demo UI demo … … 405 406 mdparams.caption = "Message For You"; 406 407 mdparams.text = "Hello, world!"; 408 409 rc = ui_msg_dialog_create(demo->ui, &mdparams, &dialog); 410 if (rc != EOK) { 411 printf("Error creating message dialog.\n"); 412 return; 413 } 414 415 ui_msg_dialog_set_cb(dialog, &msg_dialog_cb, &demo); 416 } 417 418 /** File / Confirmation menu entry selected. 419 * 420 * @param mentry Menu entry 421 * @param arg Argument (demo) 422 */ 423 static void uidemo_file_confirmation(ui_menu_entry_t *mentry, void *arg) 424 { 425 ui_demo_t *demo = (ui_demo_t *) arg; 426 ui_msg_dialog_params_t mdparams; 427 ui_msg_dialog_t *dialog; 428 errno_t rc; 429 430 ui_msg_dialog_params_init(&mdparams); 431 mdparams.caption = "Confirmation"; 432 mdparams.text = "This will not actually do anything. Proceed?"; 433 mdparams.choice = umdc_ok_cancel; 407 434 408 435 rc = ui_msg_dialog_create(demo->ui, &mdparams, &dialog); … … 741 768 } 742 769 770 /* Only allow making the window larger */ 771 gfx_rect_dims(¶ms.rect, ¶ms.min_size); 772 743 773 rc = ui_window_create(ui, ¶ms, &window); 744 774 if (rc != EOK) { … … 778 808 779 809 ui_menu_entry_set_cb(mmsg, uidemo_file_message, (void *) &demo); 810 811 rc = ui_menu_entry_create(demo.mfile, "~C~onfirmation", "", &mmsg); 812 if (rc != EOK) { 813 printf("Error creating menu.\n"); 814 return rc; 815 } 816 817 ui_menu_entry_set_cb(mmsg, uidemo_file_confirmation, (void *) &demo); 780 818 781 819 rc = ui_menu_entry_create(demo.mfile, "~L~oad", "", &mload);
Note:
See TracChangeset
for help on using the changeset viewer.
