Changeset ebb1489 in mainline for uspace/app


Ignore:
Timestamp:
2024-10-13T08:23:40Z (18 months ago)
Author:
GitHub <noreply@…>
Parents:
2a0c827c (diff), b3b79981 (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.
git-author:
boba-buba <120932204+boba-buba@…> (2024-10-13 08:23:40)
git-committer:
GitHub <noreply@…> (2024-10-13 08:23:40)
Message:

Merge branch 'HelenOS:master' into topic/packet-capture

Location:
uspace/app
Files:
2 added
2 deleted
36 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/help/help.c

    r2a0c827c rebb1489  
    154154            "This is but a small glimpse of what you can do with HelenOS. "
    155155            "To learn more please point your browser to the HelenOS User's "
    156             "Guide: http://trac.helenos.org/wiki/UsersGuide\n\n",
     156            "Guide: https://www.helenos.org/wiki/UsersGuide\n\n",
    157157            ALIGN_LEFT);
    158158}
  • uspace/app/blkdump/blkdump.c

    r2a0c827c rebb1489  
    11/*
     2 * Copyright (c) 2024 Jiri Svoboda
    23 * Copyright (c) 2011 Martin Sucha
    3  * Copyright (c) 2013 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    150150        }
    151151
    152         rc = block_init(service_id, 2048);
     152        rc = block_init(service_id);
    153153        if (rc != EOK)  {
    154154                printf(NAME ": Error initializing libblock.\n");
  • uspace/app/dltest/dltest.c

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2016 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    571571#ifdef DLTEST_LINKED
    572572
     573/** Test if we can read the correct value of a public pointer variable.
     574 *
     575 * dl_public_ptr_var is initialized in libdltest to point to dl_public_var.
     576 * This is done using a relocation. The main program (unless compiled with
     577 * PIC or PIE) will contain a copy of dl_public_ptr_var. This needs
     578 * to be copied using a COPY relocation. The relocations in the main
     579 * program need to be processed after the relocations in the shared
     580 * libraries (so that we copy the correct value).
     581 */
     582static bool test_public_ptr_var(void)
     583{
     584        int *ptr;
     585
     586        printf("Read dl_public_ptr_var directly...\n");
     587        ptr = dl_public_ptr_var;
     588
     589        if (ptr != &dl_public_var) {
     590                printf("FAILED\n");
     591                return false;
     592        }
     593
     594        printf("Passed\n");
     595        return true;
     596}
     597
    573598/** Test directly calling function that returns a constant */
    574599static bool test_lnk_dl_get_constant(void)
     
    920945
    921946#ifndef STATIC_EXE
     947
    922948        if (!test_dlfcn_dl_get_private_fib_var())
    923949                return 1;
     
    9741000
    9751001        if (!test_lnk_read_public_uvar())
     1002                return 1;
     1003
     1004        if (!test_public_ptr_var())
    9761005                return 1;
    9771006
  • uspace/app/download/main.c

    r2a0c827c rebb1489  
    6161        fprintf(stderr, "  to redirect the output, e.g.\n");
    6262        fprintf(stderr, "\n");
    63         fprintf(stderr, "    download http://helenos.org/ | to helenos.html\n\n");
     63        fprintf(stderr, "    download http://test-ipv4.helenos.org/ | to test.html\n\n");
    6464}
    6565
  • uspace/app/edit/edit.c

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * Copyright (c) 2012 Martin Sucha
    44 * All rights reserved.
     
    177177static void pos_handle(pos_event_t *ev);
    178178
     179static errno_t file_new(void);
     180static void file_open(void);
     181static errno_t file_open_file(const char *fname);
    179182static errno_t file_save(char const *fname);
    180183static void file_save_as(void);
    181 static errno_t file_insert(char *fname);
     184static errno_t file_insert(const char *fname);
    182185static errno_t file_save_range(char const *fname, spt_t const *spos,
    183186    spt_t const *epos);
     
    238241
    239242static void edit_wnd_close(ui_window_t *, void *);
     243static void edit_wnd_focus(ui_window_t *, void *, unsigned);
    240244static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
     245static void edit_wnd_unfocus(ui_window_t *, void *, unsigned);
    241246
    242247static ui_window_cb_t edit_window_cb = {
    243248        .close = edit_wnd_close,
    244         .kbd = edit_wnd_kbd_event
     249        .focus = edit_wnd_focus,
     250        .kbd = edit_wnd_kbd_event,
     251        .unfocus = edit_wnd_unfocus
    245252};
    246253
     254static void edit_menubar_activate(ui_menu_bar_t *, void *);
     255static void edit_menubar_deactivate(ui_menu_bar_t *, void *);
     256
     257static ui_menu_bar_cb_t edit_menubar_cb = {
     258        .activate = edit_menubar_activate,
     259        .deactivate = edit_menubar_deactivate
     260};
     261
     262static void edit_file_new(ui_menu_entry_t *, void *);
     263static void edit_file_open(ui_menu_entry_t *, void *);
    247264static void edit_file_save(ui_menu_entry_t *, void *);
    248265static void edit_file_save_as(ui_menu_entry_t *, void *);
     
    269286};
    270287
     288static void open_dialog_bok(ui_file_dialog_t *, void *, const char *);
     289static void open_dialog_bcancel(ui_file_dialog_t *, void *);
     290static void open_dialog_close(ui_file_dialog_t *, void *);
     291
     292static ui_file_dialog_cb_t open_dialog_cb = {
     293        .bok = open_dialog_bok,
     294        .bcancel = open_dialog_bcancel,
     295        .close = open_dialog_close
     296};
     297
    271298static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *);
    272299static void save_as_dialog_bcancel(ui_file_dialog_t *, void *);
     
    301328int main(int argc, char *argv[])
    302329{
    303         bool new_file;
    304330        errno_t rc;
    305331
     
    307333        pane.sh_column = 1;
    308334
    309         /* Start with an empty sheet. */
    310         rc = sheet_create(&doc.sh);
    311         if (rc != EOK) {
    312                 printf("Out of memory.\n");
    313                 return -1;
    314         }
    315 
    316         /* Place caret at the beginning of file. */
    317         spt_t sof;
    318         pt_get_sof(&sof);
    319         sheet_place_tag(doc.sh, &sof, &pane.caret_pos);
    320         pane.ideal_column = 1;
     335        /* Create UI */
     336        rc = edit_ui_create(&edit);
     337        if (rc != EOK)
     338                return 1;
    321339
    322340        if (argc == 2) {
    323341                doc.file_name = str_dup(argv[1]);
     342                rc = file_open_file(argv[1]);
     343                if (rc != EOK) {
     344                        status_display("File not found. Starting empty file.");
     345                        rc = file_new();
     346                }
    324347        } else if (argc > 1) {
    325348                printf("Invalid arguments.\n");
    326349                return -2;
    327350        } else {
    328                 doc.file_name = NULL;
    329         }
    330 
    331         new_file = false;
    332 
    333         if (doc.file_name == NULL || file_insert(doc.file_name) != EOK)
    334                 new_file = true;
    335 
    336         /* Place selection start tag. */
    337         sheet_place_tag(doc.sh, &sof, &pane.sel_start);
    338 
    339         /* Move to beginning of file. */
    340         pt_get_sof(&sof);
    341 
    342         /* Create UI */
    343         rc = edit_ui_create(&edit);
    344         if (rc != EOK)
    345                 return 1;
    346 
    347         caret_move(sof, true, true);
     351                rc = file_new();
     352        }
    348353
    349354        /* Initial display */
     
    353358                return rc;
    354359        }
    355 
    356         pane_status_display(&pane);
    357         if (new_file && doc.file_name != NULL)
    358                 status_display("File not found. Starting empty file.");
    359         pane_caret_display(&pane);
    360         cursor_setvis(true);
    361360
    362361        ui_run(edit.ui);
     
    378377        ui_menu_t *mfile = NULL;
    379378        ui_menu_t *medit = NULL;
     379        ui_menu_entry_t *mnew = NULL;
     380        ui_menu_entry_t *mopen = NULL;
    380381        ui_menu_entry_t *msave = NULL;
    381382        ui_menu_entry_t *msaveas = NULL;
     
    431432        }
    432433
     434        ui_menu_bar_set_cb(edit->menubar, &edit_menubar_cb, (void *) edit);
     435
    433436        rc = ui_menu_dd_create(edit->menubar, "~F~ile", NULL, &mfile);
    434437        if (rc != EOK) {
     
    437440        }
    438441
     442        rc = ui_menu_entry_create(mfile, "~N~ew", "Ctrl-N", &mnew);
     443        if (rc != EOK) {
     444                printf("Error creating menu.\n");
     445                return rc;
     446        }
     447
     448        ui_menu_entry_set_cb(mnew, edit_file_new, (void *) edit);
     449
     450        rc = ui_menu_entry_create(mfile, "~O~pen", "Ctrl-O", &mopen);
     451        if (rc != EOK) {
     452                printf("Error creating menu.\n");
     453                return rc;
     454        }
     455
     456        ui_menu_entry_set_cb(mopen, edit_file_open, (void *) edit);
     457
    439458        rc = ui_menu_entry_create(mfile, "~S~ave", "Ctrl-S", &msave);
    440459        if (rc != EOK) {
     
    541560        ui_menu_entry_set_cb(mfindr, edit_search_reverse_find, (void *) edit);
    542561
    543         rc = ui_menu_entry_create(msearch, "Find ~N~ext", "Ctrl-N", &mfindn);
     562        rc = ui_menu_entry_create(msearch, "Find ~N~ext", "Ctrl-R", &mfindn);
    544563        if (rc != EOK) {
    545564                printf("Error creating menu.\n");
     
    727746                ui_quit(edit.ui);
    728747                break;
     748        case KC_N:
     749                file_new();
     750                break;
     751        case KC_O:
     752                file_open();
     753                break;
    729754        case KC_S:
    730755                if (doc.file_name != NULL)
     
    760785                search_prompt(false);
    761786                break;
    762         case KC_N:
     787        case KC_R:
    763788                search_repeat();
    764789                break;
     
    899924}
    900925
    901 /** Save the document. */
    902 static errno_t file_save(char const *fname)
    903 {
    904         spt_t sp, ep;
     926/** Create new document. */
     927static errno_t file_new(void)
     928{
    905929        errno_t rc;
    906 
    907         status_display("Saving...");
    908         pt_get_sof(&sp);
    909         pt_get_eof(&ep);
    910 
    911         rc = file_save_range(fname, &sp, &ep);
    912 
    913         switch (rc) {
    914         case EINVAL:
    915                 status_display("Error opening file!");
    916                 break;
    917         case EIO:
    918                 status_display("Error writing data!");
    919                 break;
    920         default:
    921                 status_display("File saved.");
    922                 break;
    923         }
    924 
    925         return rc;
    926 }
    927 
    928 /** Open Save As dialog. */
    929 static void file_save_as(void)
     930        sheet_t *sh;
     931
     932        /* Create empty sheet. */
     933        rc = sheet_create(&sh);
     934        if (rc != EOK) {
     935                printf("Out of memory.\n");
     936                return ENOMEM;
     937        }
     938
     939        if (doc.sh != NULL)
     940                sheet_destroy(doc.sh);
     941
     942        doc.sh = sh;
     943
     944        /* Place caret at the beginning of file. */
     945        spt_t sof;
     946        pt_get_sof(&sof);
     947        sheet_place_tag(doc.sh, &sof, &pane.caret_pos);
     948        pane.ideal_column = 1;
     949
     950        doc.file_name = NULL;
     951
     952        /* Place selection start tag. */
     953        sheet_place_tag(doc.sh, &sof, &pane.sel_start);
     954
     955        /* Move to beginning of file. */
     956        pt_get_sof(&sof);
     957
     958        caret_move(sof, true, true);
     959
     960        pane_status_display(&pane);
     961        pane_caret_display(&pane);
     962        pane_text_display(&pane);
     963        cursor_setvis(true);
     964
     965        return EOK;
     966}
     967
     968/** Open Open File dialog. */
     969static void file_open(void)
    930970{
    931971        const char *old_fname = (doc.file_name != NULL) ? doc.file_name : "";
     
    935975
    936976        ui_file_dialog_params_init(&fdparams);
     977        fdparams.caption = "Open File";
     978        fdparams.ifname = old_fname;
     979
     980        rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog);
     981        if (rc != EOK) {
     982                printf("Error creating message dialog.\n");
     983                return;
     984        }
     985
     986        ui_file_dialog_set_cb(dialog, &open_dialog_cb, &edit);
     987}
     988
     989/** Open exising document. */
     990static errno_t file_open_file(const char *fname)
     991{
     992        errno_t rc;
     993        sheet_t *sh;
     994        char *fn;
     995
     996        /* Create empty sheet. */
     997        rc = sheet_create(&sh);
     998        if (rc != EOK) {
     999                printf("Out of memory.\n");
     1000                return ENOMEM;
     1001        }
     1002
     1003        fn = str_dup(fname);
     1004        if (fn == NULL) {
     1005                sheet_destroy(sh);
     1006                return ENOMEM;
     1007        }
     1008
     1009        if (doc.sh != NULL)
     1010                sheet_destroy(doc.sh);
     1011
     1012        doc.sh = sh;
     1013
     1014        /* Place caret at the beginning of file. */
     1015        spt_t sof;
     1016        pt_get_sof(&sof);
     1017        sheet_place_tag(doc.sh, &sof, &pane.caret_pos);
     1018        pane.ideal_column = 1;
     1019
     1020        rc = file_insert(fname);
     1021        if (rc != EOK)
     1022                return rc;
     1023
     1024        doc.file_name = fn;
     1025
     1026        /* Place selection start tag. */
     1027        sheet_place_tag(doc.sh, &sof, &pane.sel_start);
     1028
     1029        /* Move to beginning of file. */
     1030        pt_get_sof(&sof);
     1031
     1032        caret_move(sof, true, true);
     1033
     1034        pane_status_display(&pane);
     1035        pane_caret_display(&pane);
     1036        pane_text_display(&pane);
     1037        cursor_setvis(true);
     1038
     1039        return EOK;
     1040}
     1041
     1042/** Save the document. */
     1043static errno_t file_save(char const *fname)
     1044{
     1045        spt_t sp, ep;
     1046        errno_t rc;
     1047
     1048        status_display("Saving...");
     1049        pt_get_sof(&sp);
     1050        pt_get_eof(&ep);
     1051
     1052        rc = file_save_range(fname, &sp, &ep);
     1053
     1054        switch (rc) {
     1055        case EINVAL:
     1056                status_display("Error opening file!");
     1057                break;
     1058        case EIO:
     1059                status_display("Error writing data!");
     1060                break;
     1061        default:
     1062                status_display("File saved.");
     1063                break;
     1064        }
     1065
     1066        return rc;
     1067}
     1068
     1069/** Open Save As dialog. */
     1070static void file_save_as(void)
     1071{
     1072        const char *old_fname = (doc.file_name != NULL) ? doc.file_name : "";
     1073        ui_file_dialog_params_t fdparams;
     1074        ui_file_dialog_t *dialog;
     1075        errno_t rc;
     1076
     1077        ui_file_dialog_params_init(&fdparams);
    9371078        fdparams.caption = "Save As";
    9381079        fdparams.ifname = old_fname;
     
    9521093 * of the caret.
    9531094 */
    954 static errno_t file_insert(char *fname)
     1095static errno_t file_insert(const char *fname)
    9551096{
    9561097        FILE *f;
     
    22212362}
    22222363
     2364/** Window focus event
     2365 *
     2366 * @param window Window
     2367 * @param arg Argument (edit_t *)
     2368 * @param focus Focus number
     2369 */
     2370static void edit_wnd_focus(ui_window_t *window, void *arg, unsigned focus)
     2371{
     2372        edit_t *edit = (edit_t *)arg;
     2373
     2374        (void)edit;
     2375        pane_caret_display(&pane);
     2376        cursor_setvis(true);
     2377}
     2378
    22232379/** Window keyboard event
    22242380 *
     
    22422398}
    22432399
     2400/** Window unfocus event
     2401 *
     2402 * @param window Window
     2403 * @param arg Argument (edit_t *)
     2404 * @param focus Focus number
     2405 */
     2406static void edit_wnd_unfocus(ui_window_t *window, void *arg, unsigned focus)
     2407{
     2408        edit_t *edit = (edit_t *) arg;
     2409
     2410        (void)edit;
     2411        cursor_setvis(false);
     2412}
     2413
     2414/** Menu bar activate event
     2415 *
     2416 * @param mbar Menu bar
     2417 * @param arg Argument (edit_t *)
     2418 */
     2419static void edit_menubar_activate(ui_menu_bar_t *mbar, void *arg)
     2420{
     2421        edit_t *edit = (edit_t *)arg;
     2422
     2423        (void)edit;
     2424        cursor_setvis(false);
     2425}
     2426
     2427/** Menu bar deactivate event
     2428 *
     2429 * @param mbar Menu bar
     2430 * @param arg Argument (edit_t *)
     2431 */
     2432static void edit_menubar_deactivate(ui_menu_bar_t *mbar, void *arg)
     2433{
     2434        edit_t *edit = (edit_t *)arg;
     2435
     2436        (void)edit;
     2437        pane_caret_display(&pane);
     2438        cursor_setvis(true);
     2439}
     2440
     2441/** File / New menu entry selected.
     2442 *
     2443 * @param mentry Menu entry
     2444 * @param arg Argument (edit_t *)
     2445 */
     2446static void edit_file_new(ui_menu_entry_t *mentry, void *arg)
     2447{
     2448        edit_t *edit = (edit_t *) arg;
     2449
     2450        (void)edit;
     2451        file_new();
     2452        (void) gfx_update(ui_window_get_gc(edit->window));
     2453}
     2454
     2455/** File / Open menu entry selected.
     2456 *
     2457 * @param mentry Menu entry
     2458 * @param arg Argument (edit_t *)
     2459 */
     2460static void edit_file_open(ui_menu_entry_t *mentry, void *arg)
     2461{
     2462        edit_t *edit = (edit_t *) arg;
     2463
     2464        (void)edit;
     2465        file_open();
     2466}
     2467
    22442468/** File / Save menu entry selected.
    22452469 *
     
    23972621}
    23982622
    2399 /** Save As dialog OK button press.
    2400  *
    2401  * @param dialog Save As dialog
     2623/** Open File dialog OK button press.
     2624 *
     2625 * @param dialog Open File dialog
    24022626 * @param arg Argument (ui_demo_t *)
    24032627 * @param fname File name
    24042628 */
    2405 static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg,
     2629static void open_dialog_bok(ui_file_dialog_t *dialog, void *arg,
    24062630    const char *fname)
    24072631{
    24082632        edit_t *edit = (edit_t *)arg;
    2409         gfx_context_t *gc = ui_window_get_gc(edit->window);
    24102633        char *cname;
    24112634        errno_t rc;
    24122635
     2636        (void)edit;
    24132637        ui_file_dialog_destroy(dialog);
    2414         // TODO Smarter cursor management
    2415         pane.rflags |= REDRAW_CARET;
    2416         (void) pane_update(&pane);
    2417         gfx_cursor_set_visible(gc, true);
    24182638
    24192639        cname = str_dup(fname);
     
    24232643        }
    24242644
     2645        rc = file_open_file(fname);
     2646        if (rc != EOK)
     2647                return;
     2648
     2649        if (doc.file_name != NULL)
     2650                free(doc.file_name);
     2651        doc.file_name = cname;
     2652
     2653        (void) gfx_update(ui_window_get_gc(edit->window));
     2654}
     2655
     2656/** Open File dialog cancel button press.
     2657 *
     2658 * @param dialog File dialog
     2659 * @param arg Argument (ui_demo_t *)
     2660 */
     2661static void open_dialog_bcancel(ui_file_dialog_t *dialog, void *arg)
     2662{
     2663        edit_t *edit = (edit_t *)arg;
     2664
     2665        (void)edit;
     2666        ui_file_dialog_destroy(dialog);
     2667}
     2668
     2669/** Open File dialog close request.
     2670 *
     2671 * @param dialog File dialog
     2672 * @param arg Argument (ui_demo_t *)
     2673 */
     2674static void open_dialog_close(ui_file_dialog_t *dialog, void *arg)
     2675{
     2676        edit_t *edit = (edit_t *)arg;
     2677
     2678        (void)edit;
     2679        ui_file_dialog_destroy(dialog);
     2680}
     2681
     2682/** Save As dialog OK button press.
     2683 *
     2684 * @param dialog Save As dialog
     2685 * @param arg Argument (ui_demo_t *)
     2686 * @param fname File name
     2687 */
     2688static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg,
     2689    const char *fname)
     2690{
     2691        edit_t *edit = (edit_t *)arg;
     2692        char *cname;
     2693        errno_t rc;
     2694
     2695        (void)edit;
     2696        ui_file_dialog_destroy(dialog);
     2697
     2698        cname = str_dup(fname);
     2699        if (cname == NULL) {
     2700                printf("Out of memory.\n");
     2701                return;
     2702        }
     2703
    24252704        rc = file_save(fname);
    24262705        if (rc != EOK)
     
    24412720{
    24422721        edit_t *edit = (edit_t *)arg;
    2443         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2444 
     2722
     2723        (void)edit;
    24452724        ui_file_dialog_destroy(dialog);
    2446         // TODO Smarter cursor management
    2447         pane.rflags |= REDRAW_CARET;
    2448         (void) pane_update(&pane);
    2449         gfx_cursor_set_visible(gc, true);
    24502725}
    24512726
     
    24582733{
    24592734        edit_t *edit = (edit_t *)arg;
    2460         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2461 
     2735
     2736        (void)edit;
    24622737        ui_file_dialog_destroy(dialog);
    2463         // TODO Smarter cursor management
    2464         pane.rflags |= REDRAW_CARET;
    2465         (void) pane_update(&pane);
    2466         gfx_cursor_set_visible(gc, true);
    24672738}
    24682739
     
    24772748{
    24782749        edit_t *edit = (edit_t *) arg;
    2479         gfx_context_t *gc = ui_window_get_gc(edit->window);
    24802750        char *endptr;
    24812751        int line;
     
    24892759
    24902760        caret_move_absolute(line, pane.ideal_column, dir_before, false);
    2491         // TODO Smarter cursor management
     2761        (void)edit;
    24922762        (void) pane_update(&pane);
    2493         gfx_cursor_set_visible(gc, true);
    2494         (void) gfx_update(gc);
    24952763}
    24962764
     
    25032771{
    25042772        edit_t *edit = (edit_t *) arg;
    2505         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2506 
     2773
     2774        (void)edit;
    25072775        ui_prompt_dialog_destroy(dialog);
    2508         // TODO Smarter cursor management
    2509         pane.rflags |= REDRAW_CARET;
    2510         (void) pane_update(&pane);
    2511         gfx_cursor_set_visible(gc, true);
    25122776}
    25132777
     
    25202784{
    25212785        edit_t *edit = (edit_t *) arg;
    2522         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2523 
     2786
     2787        (void)edit;
    25242788        ui_prompt_dialog_destroy(dialog);
    2525         // TODO Smarter cursor management
    2526         pane.rflags |= REDRAW_CARET;
    2527         (void) pane_update(&pane);
    2528         gfx_cursor_set_visible(gc, true);
    25292789}
    25302790
     
    25392799{
    25402800        edit_t *edit = (edit_t *) arg;
    2541         gfx_context_t *gc = ui_window_get_gc(edit->window);
    25422801        char *pattern;
    25432802        bool reverse;
    25442803
     2804        (void)edit;
    25452805        ui_prompt_dialog_destroy(dialog);
    25462806
     
    25592819        search(pattern, reverse);
    25602820
    2561         // TODO Smarter cursor management
    25622821        (void) pane_update(&pane);
    2563         gfx_cursor_set_visible(gc, true);
    2564         (void) gfx_update(gc);
    25652822}
    25662823
     
    25732830{
    25742831        edit_t *edit = (edit_t *) arg;
    2575         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2576 
     2832
     2833        (void)edit;
    25772834        ui_prompt_dialog_destroy(dialog);
    2578         // TODO Smarter cursor management
    2579         pane.rflags |= REDRAW_CARET;
    2580         (void) pane_update(&pane);
    2581         gfx_cursor_set_visible(gc, true);
    25822835}
    25832836
     
    25902843{
    25912844        edit_t *edit = (edit_t *) arg;
    2592         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2593 
     2845
     2846        (void)edit;
    25942847        ui_prompt_dialog_destroy(dialog);
    2595         // TODO Smarter cursor management
    2596         pane.rflags |= REDRAW_CARET;
    2597         (void) pane_update(&pane);
    2598         gfx_cursor_set_visible(gc, true);
    25992848}
    26002849
  • uspace/app/edit/sheet.c

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    9090}
    9191
     92/** Destroy sheet. */
     93void sheet_destroy(sheet_t *sh)
     94{
     95        free(sh->data);
     96        free(sh);
     97}
     98
    9299/** Insert text into sheet.
    93100 *
  • uspace/app/edit/sheet.h

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    9191
    9292extern errno_t sheet_create(sheet_t **);
     93extern void sheet_destroy(sheet_t *);
    9394extern errno_t sheet_insert(sheet_t *, spt_t *, enum dir_spec, char *);
    9495extern errno_t sheet_delete(sheet_t *, spt_t *, spt_t *);
  • uspace/app/getterm/welcome.c

    r2a0c827c rebb1489  
    4141{
    4242        printf("Welcome to HelenOS!\n");
    43         printf("http://www.helenos.org/\n\n");
     43        printf("https://www.helenos.org/\n\n");
    4444        printf("Type 'help' [Enter] to see a few survival tips.\n\n");
    4545}
  • uspace/app/gfxdemo/gfxdemo.c

    r2a0c827c rebb1489  
    7878static gfx_coord_t vpad;
    7979static console_ctrl_t *con = NULL;
     80static bool textmode;
    8081static ui_t *ui;
    8182
    8283/** Determine if we are running in text mode.
    8384 *
    84  * @param w Screen width
    85  * @param h Screen height
    8685 * @return @c true iff we are running in text mode
    8786 */
    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;
     87static bool demo_is_text(void)
     88{
     89        return textmode;
    9290}
    9391
     
    181179
    182180        /* XXX Crude way of detecting text mode */
    183         if (w < 256) {
     181        if (demo_is_text()) {
    184182                /* Create dummy font for text mode */
    185183                rc = gfx_typeface_create(gc, &tface);
     
    270268
    271269        if (font != NULL) {
    272                 if (demo_is_text(w, h)) {
     270                if (demo_is_text()) {
    273271                        rc = gfx_color_new_ega(0x1e, &color);
    274272                        if (rc != EOK)
     
    719717        gfx_color_delete(color);
    720718
    721         if (demo_is_text(w, h)) {
     719        if (demo_is_text()) {
    722720                rc = gfx_color_new_ega(0x1f, &color);
    723721                if (rc != EOK)
     
    807805
    808806        for (i = 0; i < 8; i++) {
    809                 if (demo_is_text(w, h)) {
     807                if (demo_is_text()) {
    810808                        rc = gfx_color_new_ega(i != 0 ? i : 0x10, &color);
    811809                        if (rc != EOK)
     
    884882                gfx_color_delete(color);
    885883
    886                 if (demo_is_text(w, h)) {
     884                if (demo_is_text()) {
    887885                        rc = gfx_color_new_ega(0x1f, &color);
    888886                        if (rc != EOK)
     
    10931091
    10941092        gc = console_gc_get_ctx(cgc);
     1093
     1094        /* Currently console is always text. */
     1095        textmode = true;
    10951096
    10961097        rc = demo_loop(gc, cols, rows);
     
    11921193                task_retval(0);
    11931194
     1195        textmode = ui_is_textmode(ui);
     1196
    11941197        args.gc = gc;
    11951198        args.dims = dims;
     
    12521255
    12531256        task_retval(0);
     1257
     1258        /* FIXME Assuming display service is not text mode. */
     1259        textmode = false;
    12541260
    12551261        rc = demo_loop(gc, 400, 300);
  • uspace/app/hbench/benchlist.c

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * Copyright (c) 2018 Vojtech Horky
    44 * All rights reserved.
     
    4242        &benchmark_fibril_mutex,
    4343        &benchmark_file_read,
     44        &benchmark_rand_read,
     45        &benchmark_seq_read,
    4446        &benchmark_malloc1,
    4547        &benchmark_malloc2,
  • uspace/app/hbench/hbench.h

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * Copyright (c) 2019 Vojtech Horky
    44 * All rights reserved.
     
    135135extern benchmark_t benchmark_fibril_mutex;
    136136extern benchmark_t benchmark_file_read;
     137extern benchmark_t benchmark_rand_read;
     138extern benchmark_t benchmark_seq_read;
    137139extern benchmark_t benchmark_malloc1;
    138140extern benchmark_t benchmark_malloc2;
  • uspace/app/hbench/meson.build

    r2a0c827c rebb1489  
    11#
    2 # Copyright (c) 2023 Jiri Svoboda
     2# Copyright (c) 2024 Jiri Svoboda
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 deps = [ 'math', 'ipctest' ]
     29deps = [ 'block', 'math', 'ipctest' ]
    3030src = files(
    3131        'benchlist.c',
     
    3434        'main.c',
    3535        'utils.c',
     36        'disk/randread.c',
     37        'disk/seqread.c',
    3638        'fs/dirread.c',
    3739        'fs/fileread.c',
  • uspace/app/init/init.c

    r2a0c827c rebb1489  
    11/*
     2 * Copyright (c) 2024 Jiri Svoboda
    23 * Copyright (c) 2005 Martin Decky
    34 * All rights reserved.
     
    3536
    3637#include <fibril.h>
     38#include <futil.h>
    3739#include <stdio.h>
    3840#include <stdarg.h>
     
    7880static const char *sys_dirs[] = {
    7981        "/w/cfg",
    80         "/w/data"
     82        "/w/data",
     83        NULL,
    8184};
    8285
     
    351354        vol_info_t vinfo;
    352355        volume_id_t *volume_ids = NULL;
     356        service_id_t *part_ids = NULL;
     357        vol_part_info_t pinfo;
    353358        size_t nvols;
     359        size_t nparts;
     360        bool sv_mounted;
    354361        size_t i;
    355362        errno_t rc;
     
    385392        }
    386393
    387         vol_destroy(vol);
    388394        free(volume_ids);
     395        volume_ids = NULL;
    389396
    390397        if (!found_cfg) {
     
    397404                                printf("%s: Error creating directory '%s'.\n",
    398405                                    NAME, *cp);
    399                                 return rc;
     406                                goto error;
    400407                        }
    401408
    402409                        ++cp;
    403410                }
     411
     412                /* Copy initial configuration files */
     413                rc = futil_rcopy_contents("/cfg", "/w/cfg");
     414                if (rc != EOK)
     415                        goto error;
    404416        } else {
    405417                printf("%s: System volume is configured.\n", NAME);
    406         }
    407 
     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);
    408456        return EOK;
    409457error:
     
    411459        if (volume_ids != NULL)
    412460                free(volume_ids);
     461        if (part_ids != NULL)
     462                free(part_ids);
    413463
    414464        return rc;
     
    438488        srv_start("/srv/klog");
    439489        srv_start("/srv/fs/locfs");
    440         srv_start("/srv/taskmon");
    441490
    442491        if (!mount_locfs()) {
     
    454503        srv_start("/srv/volsrv");
    455504
     505        init_sysvol();
     506
     507        srv_start("/srv/taskmon");
     508
    456509        srv_start("/srv/net/loopip");
    457510        srv_start("/srv/net/ethip");
     511        srv_start("/srv/net/dhcp");
    458512        srv_start("/srv/net/inetsrv");
    459513        srv_start("/srv/net/tcp");
    460514        srv_start("/srv/net/udp");
    461515        srv_start("/srv/net/dnsrsrv");
    462         srv_start("/srv/net/dhcp");
    463         srv_start("/srv/net/nconfsrv");
    464516
    465517        srv_start("/srv/clipboard");
     
    469521        srv_start("/srv/hid/output", HID_OUTPUT);
    470522        srv_start("/srv/audio/hound");
    471 
    472         init_sysvol();
    473523
    474524#ifdef CONFIG_WINSYS
  • uspace/app/init/meson.build

    r2a0c827c rebb1489  
    2828#
    2929
    30 deps = [ 'untar', 'block' ]
     30deps = [ 'block', 'futil', 'untar' ]
    3131link_args += '-static'
    3232src = files('init.c', 'untar.c')
  • uspace/app/init/untar.c

    r2a0c827c rebb1489  
    11/*
     2 * Copyright (c) 2024 Jiri Svoboda
    23 * Copyright (c) 2018 Martin Decky
    34 * All rights reserved.
     
    5960                return ret;
    6061
    61         ret = block_init(state->sid, 4096);
     62        ret = block_init(state->sid);
    6263        if (ret != EOK)
    6364                return ret;
  • uspace/app/meson.build

    r2a0c827c rebb1489  
    3434        'blkdump',
    3535        'calculator',
    36         'contacts',
    3736        'corecfg',
    3837        'cpptest',
  • uspace/app/mkexfat/mkexfat.c

    r2a0c827c rebb1489  
    11/*
     2 * Copyright (c) 2024 Jiri Svoboda
    23 * Copyright (c) 2012 Maurizio Lombardi
    34 * All rights reserved.
     
    858859        }
    859860
    860         rc = block_init(service_id, 2048);
     861        rc = block_init(service_id);
    861862        if (rc != EOK) {
    862863                printf(NAME ": Error initializing libblock.\n");
  • uspace/app/mkfat/mkfat.c

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2010 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6666        default_fat_count               = 2,
    6767        default_reserved_clusters       = 2,
    68         default_media_descriptor        = 0xF8 /**< fixed disk */
     68        default_media_descriptor        = 0xF8 /**< fixed disk */,
     69        fat32_root_cluster              = 2
    6970};
    7071
     
    198199        }
    199200
    200         rc = block_init(service_id, 2048);
     201        rc = block_init(service_id);
    201202        if (rc != EOK)  {
    202203                printf(NAME ": Error initializing libblock.\n");
     
    313314        cfg->reserved_sectors = 1 + cfg->addt_res_sectors;
    314315
    315         /* Only correct for FAT12/16 (FAT32 has root dir stored in clusters */
     316        /* Only correct for FAT12/16 (FAT32 has root dir stored in clusters) */
    316317        rd_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
    317318            cfg->sector_size);
     
    434435        }
    435436
     437        if (cfg->fat_type == FAT32) {
     438                /* Root dir is stored in cluster fat32_root_cluster */
     439                addr += fat32_root_cluster * cfg->sectors_per_cluster;
     440        }
     441
    436442        /* Root directory */
    437443        printf("Writing root directory.\n");
     
    529535                bs->fat32.ebs = 0x29;
    530536                bs->fat32.id = host2uint32_t_be(vsn);
    531                 bs->fat32.root_cluster = 2;
     537                bs->fat32.root_cluster = fat32_root_cluster;
    532538
    533539                (void) fat_label_encode(&bs->fat32.label, bs_label);
  • uspace/app/mkmfs/mkmfs.c

    r2a0c827c rebb1489  
    11/*
     2 * Copyright (c) 2024 Jiri Svoboda
    23 * Copyright (c) 2011 Maurizio Lombardi
    34 * All rights reserved.
     
    211212        }
    212213
    213         rc = block_init(service_id, 2048);
     214        rc = block_init(service_id);
    214215        if (rc != EOK)  {
    215216                printf(NAME ": Error initializing libblock.\n");
  • uspace/app/pkg/pkg.c

    r2a0c827c rebb1489  
    116116        pkg_name = argv[2];
    117117
    118         ret = asprintf(&src_uri, "http://ci.helenos.org/latest/" STRING(UARCH)
     118        ret = asprintf(&src_uri, "http://ci-ipv4.helenos.org/latest/" STRING(UARCH)
    119119            "/%s-for-helenos-" STRING(UARCH) ".tar.gz",
    120120            pkg_name);
  • uspace/app/sysinst/meson.build

    r2a0c827c rebb1489  
    2727#
    2828
    29 deps = [ 'block', 'fdisk', 'sif' ]
     29deps = [ 'block', 'fdisk', 'futil', 'sif' ]
    3030src = files(
    31         'futil.c',
    3231        'rdimg.c',
    3332        'sysinst.c',
  • uspace/app/sysinst/sysinst.c

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2018 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <errno.h>
    4242#include <fdisk.h>
     43#include <futil.h>
    4344#include <loc.h>
    4445#include <stdio.h>
     
    4950#include <vol.h>
    5051
    51 #include "futil.h"
    5252#include "grub.h"
    5353#include "rdimg.h"
     
    6262 * in Grub notation).
    6363 */
    64 #define DEFAULT_DEV "devices/\\hw\\sys\\00:01.0\\ata-c1\\d0"
     64#define DEFAULT_DEV_0 "devices/\\hw\\sys\\00:01.1\\c0d0"
     65#define DEFAULT_DEV_1 "devices/\\hw\\sys\\00:01.0\\ata1\\c0d0"
    6566//#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0"
    6667/** Volume label for the new file system */
     
    7980#define BOOT_BLOCK_IDX 0 /* MBR */
    8081
     82#define CFG_FILES_SRC "/cfg"
     83#define CFG_FILES_DEST MOUNT_POINT "/cfg"
     84
     85static const char *default_devs[] = {
     86        DEFAULT_DEV_0,
     87        DEFAULT_DEV_1,
     88        NULL
     89};
     90
    8191static const char *sys_dirs[] = {
    8292        "/cfg",
    83         "/data"
     93        "/data",
     94        NULL
    8495};
     96
     97/** Check the if the destination device exists.
     98 *
     99 * @param dev Disk device
     100 *
     101 * @return EOK on success or an error code
     102 */
     103static errno_t sysinst_check_dev(const char *dev)
     104{
     105        service_id_t sid;
     106        errno_t rc;
     107
     108        rc = loc_service_get_id(dev, &sid, 0);
     109        if (rc != EOK)
     110                return rc;
     111
     112        (void)sid;
     113        return EOK;
     114}
    85115
    86116/** Label the destination device.
     
    200230        path = NULL;
    201231
     232        /* Copy initial configuration files */
     233        rc = futil_rcopy_contents(CFG_FILES_SRC, CFG_FILES_DEST);
     234        if (rc != EOK)
     235                return rc;
     236
    202237        return EOK;
    203238error:
     
    244279        }
    245280
    246         rv = asprintf(&path, "%s%s", rdpath, "/cfg/volsrv.sif");
     281        rv = asprintf(&path, "%s%s", rdpath, "/cfg/initvol.sif");
    247282        if (rv < 0) {
    248283                rc = ENOMEM;
     
    271306                printf("Error creating system partition configuration.\n");
    272307                rc = EIO;
     308                goto error;
     309        }
     310
     311        rc = vol_volumes_sync(volumes);
     312        if (rc != EOK) {
     313                printf("Error saving volume confiuration.\n");
    273314                goto error;
    274315        }
     
    361402
    362403        printf("sysinst_copy_boot_blocks: block_init.\n");
    363         rc = block_init(sid, 512);
     404        rc = block_init(sid);
    364405        if (rc != EOK)
    365406                return rc;
     
    490531int main(int argc, char *argv[])
    491532{
    492         const char *dev = DEFAULT_DEV;
    493         return sysinst_install(dev);
     533        unsigned i;
     534        errno_t rc;
     535
     536        i = 0;
     537        while (default_devs[i] != NULL) {
     538                rc = sysinst_check_dev(default_devs[i]);
     539                if (rc == EOK)
     540                        break;
     541        }
     542
     543        if (default_devs[i] == NULL) {
     544                printf("Cannot determine installation device.\n");
     545                return 1;
     546        }
     547
     548        return sysinst_install(default_devs[i]);
    494549}
    495550
  • uspace/app/taskbar-cfg/main.c

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    7777                return 1;
    7878
    79         rc = taskbar_cfg_open(tbcfg, "/cfg/taskbar.sif");
     79        rc = taskbar_cfg_open(tbcfg, "/w/cfg/taskbar.sif");
    8080        if (rc != EOK)
    8181                return 1;
  • uspace/app/taskbar-cfg/smeedit.c

    r2a0c827c rebb1489  
    403403
    404404                startmenu_repaint(smee->startmenu);
     405                (void)tbarcfg_sync(smee->startmenu->tbarcfg->tbarcfg);
    405406                (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    406407        } else {
     
    418419                        return;
    419420
    420                 (void)smenu_entry_save(smee->smentry->entry);
     421                (void)tbarcfg_sync(smee->startmenu->tbarcfg->tbarcfg);
    421422                startmenu_entry_update(smee->smentry);
     423                (void)tbarcfg_sync(smee->startmenu->tbarcfg->tbarcfg);
    422424                (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    423425        }
  • uspace/app/taskbar-cfg/startmenu.c

    r2a0c827c rebb1489  
    515515
    516516        (void)smee;
     517        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    517518        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    518519}
     
    534535        (void)startmenu_insert(smenu, entry, &smentry);
    535536        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     537        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    536538        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    537539}
     
    620622        startmenu_t *smenu = (startmenu_t *)arg;
    621623        startmenu_entry_t *smentry;
    622         errno_t rc;
    623624
    624625        (void)pbutton;
     
    628629                return;
    629630
    630         rc = smenu_entry_destroy(smentry->entry);
    631         if (rc != EOK)
    632                 return;
    633 
     631        smenu_entry_destroy(smentry->entry);
    634632        ui_list_entry_delete(smentry->lentry);
    635633        free(smentry);
     634
    636635        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     636        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    637637        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    638638}
     
    673673        startmenu_t *smenu = (startmenu_t *)arg;
    674674        startmenu_entry_t *smentry;
    675         errno_t rc;
    676675
    677676        (void)pbutton;
     
    681680                return;
    682681
    683         rc = smenu_entry_move_up(smentry->entry);
    684         if (rc != EOK)
    685                 return;
    686 
     682        smenu_entry_move_up(smentry->entry);
    687683        ui_list_entry_move_up(smentry->lentry);
    688684
    689685        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     686        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    690687        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    691688}
     
    700697        startmenu_t *smenu = (startmenu_t *)arg;
    701698        startmenu_entry_t *smentry;
    702         errno_t rc;
    703699
    704700        (void)pbutton;
     
    708704                return;
    709705
    710         rc = smenu_entry_move_down(smentry->entry);
    711         if (rc != EOK)
    712                 return;
    713 
     706        smenu_entry_move_down(smentry->entry);
    714707        ui_list_entry_move_down(smentry->lentry);
    715708
    716709        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     710        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    717711        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    718712}
  • uspace/app/taskbar/taskbar.c

    r2a0c827c rebb1489  
    4848#include "wndlist.h"
    4949
    50 #define TASKBAR_CONFIG_FILE "/cfg/taskbar.sif"
     50#define TASKBAR_CONFIG_FILE "/w/cfg/taskbar.sif"
    5151
    5252static void taskbar_wnd_close(ui_window_t *, void *);
  • uspace/app/taskbar/taskbar.sif

    r2a0c827c rebb1489  
    1 [sif](){[entries](){[entry]([caption]=[~N~avigator][cmd]=[/app/nav][terminal]=[y]){}[entry]([caption]=[Text ~E~ditor][cmd]=[/app/edit][terminal]=[y]){}[entry]([caption]=[Co~m~mand Line][cmd]=[/app/bdsh][terminal]=[y]){}[entry]([caption]=[~C~alculator][cmd]=[/app/calculator -d %d][terminal]=[n]){}[entry]([caption]=[~I~mage Viewer][cmd]=[/app/viewer -d %d][terminal]=[n]){}[entry]([separator]=[y]){}[entry]([caption]=[~U~I Demo][cmd]=[/app/uidemo -d %d][terminal]=[n]){}[entry]([caption]=[~G~FX Demo][cmd]=[/app/gfxdemo -d %d ui][terminal]=[n]){}[entry]([caption]=[~B~arber Pole][cmd]=[/app/barber -d %d][terminal]=[n]){}[entry]([caption]=[~T~etris][cmd]=[/app/tetris][terminal]=[y]){}[entry]([separator]=[y]){}[entry]([caption]=[~D~isplay Configuration][cmd]=[/app/display-cfg -d %d][terminal]=[n]){}[entry]([caption]=[Ta~s~kbar Configuration][cmd]=[/app/taskbar-cfg -d %d][terminal]=[n]){}[entry]([separator]=[y]){}[entry]([caption]=[Tas~k~ Monitor (top)][cmd]=[/app/top][terminal]=[y]){}[entry]([caption]=[~F~disk Disk Editor][cmd]=[/app/fdisk][terminal]=[y]){}[entry]([separator]=[y]){}[entry]([caption]=[~A~bout HelenOS][cmd]=[/app/aboutos -d %d][terminal]=[n]){}}}
     1<sif>
     2<entries>
     3<entry caption="~N~avigator" cmd="/app/nav" terminal="y">
     4</entry>
     5<entry caption="Text ~E~ditor" cmd="/app/edit" terminal="y">
     6</entry>
     7<entry caption="Co~m~mand Line" cmd="/app/bdsh" terminal="y">
     8</entry>
     9<entry caption="~C~alculator" cmd="/app/calculator -d %d" terminal="n">
     10</entry>
     11<entry caption="~I~mage Viewer" cmd="/app/viewer -d %d" terminal="n">
     12</entry>
     13<entry separator="y">
     14</entry>
     15<entry caption="~U~I Demo" cmd="/app/uidemo -d %d" terminal="n">
     16</entry>
     17<entry caption="~G~FX Demo" cmd="/app/gfxdemo -d %d ui" terminal="n">
     18</entry>
     19<entry caption="~B~arber Pole" cmd="/app/barber -d %d" terminal="n">
     20</entry>
     21<entry caption="~T~etris" cmd="/app/tetris" terminal="y">
     22</entry>
     23<entry separator="y">
     24</entry>
     25<entry caption="~D~isplay Configuration" cmd="/app/display-cfg -d %d" terminal="n">
     26</entry>
     27<entry caption="Ta~s~kbar Configuration" cmd="/app/taskbar-cfg -d %d" terminal="n">
     28</entry>
     29<entry separator="y">
     30</entry>
     31<entry caption="Tas~k~ Monitor (top)" cmd="/app/top" terminal="y">
     32</entry>
     33<entry caption="~F~disk Disk Editor" cmd="/app/fdisk" terminal="y">
     34</entry>
     35<entry separator="y">
     36</entry>
     37<entry caption="~A~bout HelenOS" cmd="/app/aboutos -d %d" terminal="n">
     38</entry>
     39</entries>
     40</sif>
  • uspace/app/terminal/meson.build

    r2a0c827c rebb1489  
    2727#
    2828
    29 deps = [ 'fbfont', 'display', 'ui' ]
     29deps = [ 'fbfont', 'display', 'ui', 'termui' ]
    3030src = files(
    3131        'main.c',
  • uspace/app/terminal/terminal.c

    r2a0c827c rebb1489  
    4040#include <errno.h>
    4141#include <fbfont/font-8x16.h>
    42 #include <io/chargrid.h>
    4342#include <fibril.h>
    4443#include <gfx/bitmap.h>
     
    4948#include <io/console.h>
    5049#include <io/pixelmap.h>
    51 #include <task.h>
     50#include <macros.h>
    5251#include <stdarg.h>
    5352#include <stdio.h>
    5453#include <stdlib.h>
     54#include <str_error.h>
    5555#include <str.h>
     56#include <task.h>
    5657#include <ui/resource.h>
    5758#include <ui/ui.h>
     
    6970
    7071#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
    7278
    7379static LIST_INITIALIZE(terms);
     80
     81#define COLOR_BRIGHT 8
     82
     83static 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};
    74102
    75103static errno_t term_open(con_srvs_t *, con_srv_t *);
     
    119147static void terminal_close_event(ui_window_t *, void *);
    120148static void terminal_focus_event(ui_window_t *, void *, unsigned);
     149static void terminal_resize_event(ui_window_t *, void *);
    121150static void terminal_kbd_event(ui_window_t *, void *, kbd_event_t *);
    122151static void terminal_pos_event(ui_window_t *, void *, pos_event_t *);
    123152static void terminal_unfocus_event(ui_window_t *, void *, unsigned);
     153static void terminal_maximize_event(ui_window_t *, void *);
     154static void terminal_unmaximize_event(ui_window_t *, void *);
    124155
    125156static ui_window_cb_t terminal_window_cb = {
    126157        .close = terminal_close_event,
    127158        .focus = terminal_focus_event,
     159        .resize = terminal_resize_event,
    128160        .kbd = terminal_kbd_event,
    129161        .pos = terminal_pos_event,
    130         .unfocus = terminal_unfocus_event
     162        .unfocus = terminal_unfocus_event,
     163        .maximize = terminal_maximize_event,
     164        .unmaximize = terminal_unmaximize_event,
    131165};
    132166
     
    144178}
    145179
    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) {
     180static 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
     187static 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
     192static 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) {
    169199        case CHAR_ATTR_STYLE:
    170                 switch (attrs.val.style) {
     200                switch (cf->attrs.val.style) {
    171201                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;
    174204                        break;
    175205                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;
    178208                        break;
    179209                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;
    182213                        break;
    183214                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;
    186217                        break;
    187218                }
    188219                break;
     220
    189221        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
    193233                break;
     234
    194235        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);
    197238                break;
    198239        }
     240
     241        return cell;
    199242}
    200243
     
    214257}
    215258
    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);
     259static 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);
    239288
    240289        for (unsigned int y = 0; y < FONT_SCANLINES; y++) {
     
    248297                }
    249298        }
     299
    250300        term_update_region(term, bx, by, FONT_WIDTH, FONT_SCANLINES);
    251301}
    252302
    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;
     303static 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
     313static 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
     320static 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
     328static pixelmap_t term_get_pixelmap(terminal_t *term)
     329{
     330        pixelmap_t pixelmap = { };
    332331        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
    342337        pixelmap.width = term->w;
    343338        pixelmap.height = term->h;
    344339        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
     343static void term_clear_bitmap(terminal_t *term, pixel_t color)
     344{
     345        pixelmap_t pixelmap = term_get_pixelmap(term);
     346        if (pixelmap.data == NULL)
    411347                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
     356static 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]);
    443366}
    444367
     
    480403                if (pos < size) {
    481404                        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;
    483408
    484409                        /* Accept key presses of printable chars only. */
     
    494419                        }
    495420
    496                         free(event);
     421                        free(qevent);
    497422                }
    498423        }
     
    504429static void term_write_char(terminal_t *term, wchar_t ch)
    505430{
    506         sysarg_t updated = 0;
    507 
    508         fibril_mutex_lock(&term->mtx);
    509 
    510431        switch (ch) {
    511         case '\n':
    512                 updated = chargrid_newline(term->frontbuf);
     432        case L'\n':
     433                termui_put_crlf(term->termui);
    513434                break;
    514         case '\r':
     435        case L'\r':
     436                termui_put_cr(term->termui);
    515437                break;
    516         case '\t':
    517                 updated = chargrid_tabstop(term->frontbuf, 8);
     438        case L'\t':
     439                termui_put_tab(term->termui);
    518440                break;
    519         case '\b':
    520                 updated = chargrid_backspace(term->frontbuf);
     441        case L'\b':
     442                termui_put_backspace(term->termui);
    521443                break;
    522444        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        }
    530451}
    531452
     
    533454{
    534455        terminal_t *term = srv_to_terminal(srv);
     456
     457        fibril_mutex_lock(&term->mtx);
    535458
    536459        size_t off = 0;
     
    538461                term_write_char(term, str_decode(data, &off, size));
    539462
     463        fibril_mutex_unlock(&term->mtx);
     464
     465        term_render(term);
    540466        gfx_update(term->gc);
    541467        *nwritten = size;
     468
    542469        return EOK;
    543470}
     
    547474        terminal_t *term = srv_to_terminal(srv);
    548475
    549         term_update(term);
     476        term_render(term);
    550477        gfx_update(term->gc);
    551478}
     
    556483
    557484        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);
    562489        gfx_update(term->gc);
    563490}
     
    568495
    569496        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);
    574501        gfx_update(term->gc);
    575502}
     
    580507
    581508        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;
    584515
    585516        return EOK;
     
    591522
    592523        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);
    595526        fibril_mutex_unlock(&term->mtx);
    596527
     
    610541        terminal_t *term = srv_to_terminal(srv);
    611542
    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);
    614567        fibril_mutex_unlock(&term->mtx);
    615568}
     
    620573        terminal_t *term = srv_to_terminal(srv);
    621574
    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);
    624586        fibril_mutex_unlock(&term->mtx);
    625587}
     
    629591{
    630592        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);
    634600        fibril_mutex_unlock(&term->mtx);
    635601}
     
    640606
    641607        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);
    646612        gfx_update(term->gc);
    647613}
     
    662628        fibril_mutex_unlock(&term->mtx);
    663629
    664         term_update(term);
     630        term_render(term);
    665631        gfx_update(term->gc);
    666632        return EOK;
     
    671637        terminal_t *term = srv_to_terminal(srv);
    672638        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;
    676642        free(ev);
    677643        return EOK;
     
    710676        term->urows = rows;
    711677        term->ubuf = buf;
     678
     679        /* Scroll back to active screen. */
     680        termui_history_scroll(term->termui, INT_MAX);
     681
    712682        fibril_mutex_unlock(&term->mtx);
    713683
     
    730700        term->ubuf = NULL;
    731701
     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
    732710        if (buf != NULL)
    733711                as_area_destroy(buf);
    734 
    735         fibril_mutex_unlock(&term->mtx);
    736712}
    737713
     
    748724{
    749725        terminal_t *term = srv_to_terminal(srv);
    750         charfield_t *ch;
    751         sysarg_t col, row;
    752726
    753727        fibril_mutex_lock(&term->mtx);
     
    759733
    760734        /* 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) {
    767741                fibril_mutex_unlock(&term->mtx);
    768742                return;
    769743        }
    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         }
    778744
    779745        /* Update front buffer from user buffer */
    780746
    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]);
    785752                }
     753
     754                termui_update_cb(term, c0, row, &cells[c0], c1 - c0);
    786755        }
    787756
     
    789758
    790759        /* Update terminal */
    791         term_update(term);
     760        term_render(term);
    792761        gfx_update(term->gc);
    793762}
    794763
    795 static void deinit_terminal(terminal_t *term)
     764static 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(&params);
     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, &params, 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
     811void terminal_destroy(terminal_t *term)
    796812{
    797813        list_remove(&term->link);
    798814
    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);
    809821        free(term);
    810822}
     
    813825{
    814826        /* 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));
    817829        if (event == NULL)
    818830                return;
    819831
    820         *event = *ev;
     832        event->ev = *ev;
    821833        link_initialize(&event->link);
    822834
     
    840852        (void)nfocus;
    841853        term->is_focused = true;
    842         term_update(term);
     854        term_render(term);
    843855        gfx_update(term->gc);
     856}
     857
     858static 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
     878static 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
     884static 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
     890static void terminal_unmaximize_event(ui_window_t *window, void *arg)
     891{
     892        ui_window_def_unmaximize(window);
     893        terminal_resize_handler(window, arg);
    844894}
    845895
     
    854904        event.ev.key = *kbd_event;
    855905
    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);
    857923}
    858924
     
    863929        terminal_t *term = (terminal_t *) arg;
    864930
    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)
    877963                terminal_queue_cons_event(term, &cevent);
    878         }
    879964}
    880965
     
    887972        if (nfocus == 0) {
    888973                term->is_focused = false;
    889                 term_update(term);
     974                term_render(term);
    890975                gfx_update(term->gc);
    891976        }
     
    909994
    910995        if (!atomic_flag_test_and_set(&term->refcnt))
    911                 chargrid_set_cursor_visibility(term->frontbuf, true);
     996                termui_set_cursor_visibility(term->termui, true);
    912997
    913998        con_conn(icall, &term->srvs);
     999}
     1000
     1001static 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);
    9141052}
    9151053
     
    9181056    terminal_t **rterm)
    9191057{
    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;
    9261058        errno_t rc;
    9271059
    928         term = calloc(1, sizeof(terminal_t));
     1060        terminal_t *term = calloc(1, sizeof(terminal_t));
    9291061        if (term == NULL) {
    9301062                printf("Out of memory.\n");
     
    9391071        term->char_remains_len = 0;
    9401072
    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");
    9541093                rc = ENOMEM;
    9551094                goto error;
    9561095        }
    9571096
    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(&params);
    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, &params, 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);
    10181100
    10191101        async_set_fallback_port_handler(term_connection, NULL);
     
    10531135        term->is_focused = true;
    10541136
    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);
    10611138
    10621139        *rterm = term;
     
    10711148        if (term->ui != NULL)
    10721149                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);
    10771152        free(term);
    10781153        return rc;
  • uspace/app/terminal/terminal.h

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * Copyright (c) 2012 Petr Koupy
    44 * All rights reserved.
     
    4545#include <gfx/context.h>
    4646#include <gfx/coord.h>
    47 #include <io/chargrid.h>
    4847#include <io/con_srv.h>
     48#include <io/cons_event.h>
    4949#include <loc.h>
    5050#include <stdatomic.h>
    5151#include <str.h>
    5252#include <task.h>
     53#include <termui.h>
    5354#include <ui/ui.h>
    5455#include <ui/window.h>
     
    8182        size_t char_remains_len;
    8283
    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;
    8892
    8993        sysarg_t ucols;
     
    99103} terminal_t;
    100104
     105/** Terminal event */
     106typedef struct {
     107        /** Link to list of events */
     108        link_t link;
     109        /** Console event */
     110        cons_event_t ev;
     111} terminal_event_t;
     112
    101113extern errno_t terminal_create(const char *, sysarg_t, sysarg_t,
    102114    terminal_flags_t, const char *, terminal_t **);
  • uspace/app/tester/print/print2.c

    r2a0c827c rebb1489  
    6262        TPRINTF("Real output:     [%td] [%tu] [%tx] [%ti] [%to]\n\n", d, neg_d, neg_d, d, neg_d);
    6363
     64        TPRINTF("Testing printf(\"%%lf\", 768.0):\n");
     65        TPRINTF("Expected output: [768.000000]\n");
     66        TPRINTF("Real output:     [%lf]\n", 768.0);
     67
    6468        return NULL;
    6569}
  • uspace/app/tetris/screen.c

    r2a0c827c rebb1489  
    11/*
     2 * Copyright (c) 2024 Jiri Svoboda
    23 * Copyright (c) 2011 Martin Decky
    34 * All rights reserved.
     
    7980static usec_t timeleft = 0;
    8081
     82bool size_changed;
    8183console_ctrl_t *console;
    8284
     
    142144        console_cursor_visibility(console, 0);
    143145        resume_normal();
    144         scr_clear();
     146        scr_set();
    145147}
    146148
     
    169171        }
    170172
     173        if ((ccap & CONSOLE_CAP_CURSORCTL) == 0) {
     174                stop("Your screen does not support cursor control.\n");
     175                return;
     176        }
    171177        *rgb = ((ccap & CONSOLE_CAP_RGB) == CONSOLE_CAP_RGB);
    172178        *color = ((ccap & CONSOLE_CAP_INDEXED) == CONSOLE_CAP_INDEXED);
     
    194200
    195201                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",
    197203                    MINROWS, MINCOLS);
    198204                stop(smallscr);
     
    217223
    218224        fprintf(stderr, "aborting: %s", why);
    219         abort();
     225        exit(1);
    220226}
    221227
     
    410416                        exit(1);
    411417
     418                if (event.type == CEV_RESIZE)
     419                        size_changed = true;
     420
    412421                if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
    413422                        c = event.ev.key.c;
  • uspace/app/tetris/screen.h

    r2a0c827c rebb1489  
    6767extern console_ctrl_t *console;
    6868extern winsize_t winsize;
     69extern bool size_changed;
    6970
    7071extern void moveto(sysarg_t r, sysarg_t c);
  • uspace/app/tetris/tetris.c

    r2a0c827c rebb1489  
    330330
    331331                while (true) {
     332                        if (size_changed) {
     333                                size_changed = false;
     334                                scr_set();
     335                                scr_msg(key_msg, 1);
     336                        }
     337
    332338                        place(curshape, pos, 1);
    333339                        scr_update();
  • uspace/app/uidemo/uidemo.c

    r2a0c827c rebb1489  
    741741        }
    742742
     743        /* Only allow making the window larger */
     744        gfx_rect_dims(&params.rect, &params.min_size);
     745
    743746        rc = ui_window_create(ui, &params, &window);
    744747        if (rc != EOK) {
  • uspace/app/viewer/viewer.c

    r2a0c827c rebb1489  
    517517        if (viewer != NULL && viewer->imgs != NULL) {
    518518                for (u = 0; u < viewer->imgs_count; u++) {
    519                         if (viewer->imgs[i] != NULL)
    520                                 free(viewer->imgs[i]);
     519                        if (viewer->imgs[u] != NULL)
     520                                free(viewer->imgs[u]);
    521521                }
    522522                free(viewer->imgs);
Note: See TracChangeset for help on using the changeset viewer.