Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/gfxdemo/gfxdemo.c

    rda15002 r0a411bbf  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5151#include <ui/window.h>
    5252#include <ui/wdecor.h>
     53#include "gfxdemo.h"
    5354
    5455static void wnd_close_event(void *);
     
    6869};
    6970
     71static void demo_kbd_event(kbd_event_t *);
     72
    7073static bool quit = false;
     74static FIBRIL_MUTEX_INITIALIZE(quit_lock);
     75static FIBRIL_CONDVAR_INITIALIZE(quit_cv);
    7176static gfx_typeface_t *tface;
    7277static gfx_font_t *font;
    7378static gfx_coord_t vpad;
     79static console_ctrl_t *con = NULL;
     80static ui_t *ui;
     81
     82/** Determine if we are running in text mode.
     83 *
     84 * @param w Screen width
     85 * @param h Screen height
     86 * @return @c true iff we are running in text mode
     87 */
     88static 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;
     92}
     93
     94/** Sleep until timeout or quit request.
     95 *
     96 * @param msec Number of microseconds to sleep for
     97 */
     98static void demo_msleep(unsigned msec)
     99{
     100        errno_t rc;
     101        usec_t usec;
     102        cons_event_t cevent;
     103
     104        if (ui != NULL)
     105                ui_unlock(ui);
     106        fibril_mutex_lock(&quit_lock);
     107        if (!quit) {
     108                if (con != NULL) {
     109                        usec = (usec_t)msec * 1000;
     110                        while (usec > 0 && !quit) {
     111                                rc = console_get_event_timeout(con, &cevent, &usec);
     112                                if (rc == EOK) {
     113                                        if (cevent.type == CEV_KEY) {
     114                                                fibril_mutex_unlock(&quit_lock);
     115                                                demo_kbd_event(&cevent.ev.key);
     116                                                fibril_mutex_lock(&quit_lock);
     117                                        }
     118                                }
     119                        }
     120                } else {
     121                        (void) fibril_condvar_wait_timeout(&quit_cv, &quit_lock,
     122                            (usec_t)msec * 1000);
     123                }
     124        }
     125        fibril_mutex_unlock(&quit_lock);
     126        if (ui != NULL)
     127                ui_lock(ui);
     128}
    74129
    75130/** Clear screen.
     
    215270
    216271        if (font != NULL) {
    217                 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
    218                 if (rc != EOK)
    219                         goto error;
     272                if (demo_is_text(w, h)) {
     273                        rc = gfx_color_new_ega(0x1e, &color);
     274                        if (rc != EOK)
     275                                goto error;
     276                } else {
     277                        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     278                        if (rc != EOK)
     279                                goto error;
     280                }
    220281
    221282                gfx_text_fmt_init(&fmt);
     283                fmt.font = font;
    222284                fmt.color = color;
    223285                fmt.halign = gfx_halign_center;
     
    225287
    226288                pos.x = w / 2;
    227                 pos.y = h - 1;
    228                 rc = gfx_puttext(font, &pos, &fmt, text);
     289                pos.y = h;
     290                rc = gfx_puttext(&pos, &fmt, text);
    229291                if (rc != EOK) {
    230292                        printf("Error rendering text.\n");
     
    297359                gfx_color_delete(color);
    298360
    299                 fibril_usleep(500 * 1000);
    300 
     361                demo_msleep(500);
    301362                if (quit)
    302363                        break;
     
    332393                for (j = 0; j < h; j++) {
    333394                        pixelmap_put_pixel(&pixelmap, i, j,
    334                             PIXEL(0, (i % 30) < 3 ? 255 : 0,
     395                            PIXEL(255, (i % 30) < 3 ? 255 : 0,
    335396                            (j % 30) < 3 ? 255 : 0, i / 2));
    336397                }
     
    368429                        k = i * i + j * j;
    369430                        pixelmap_put_pixel(&pixelmap, i, j,
    370                             PIXEL(0, k, k, k));
     431                            PIXEL(255, k, k, k));
    371432                }
    372433        }
     
    403464                        k = i * i + j * j;
    404465                        pixelmap_put_pixel(&pixelmap, i, j,
    405                             k < w * w / 2 ? PIXEL(0, 0, 255, 0) :
    406                             PIXEL(0, 255, 0, 255));
     466                            k < w * w / 2 ? PIXEL(255, 0, 255, 0) :
     467                            PIXEL(255, 255, 0, 255));
    407468                }
    408469        }
     
    459520                        if (rc != EOK)
    460521                                goto error;
    461                         fibril_usleep(250 * 1000);
    462 
     522
     523                        demo_msleep(250);
    463524                        if (quit)
    464525                                goto out;
     
    520581                }
    521582
    522                 fibril_usleep(500 * 1000);
    523 
     583                demo_msleep(500);
    524584                if (quit)
    525585                        break;
     
    561621        params.rect.p1.y = 40;
    562622        params.flags = bmpf_color_key;
    563         params.key_color = PIXEL(0, 255, 0, 255);
     623        params.key_color = PIXEL(255, 255, 0, 255);
    564624
    565625        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     
    581641                }
    582642
    583                 fibril_usleep(500 * 1000);
    584 
     643                demo_msleep(500);
    585644                if (quit)
    586645                        break;
     
    660719        gfx_color_delete(color);
    661720
    662         rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
    663         if (rc != EOK)
    664                 goto error;
     721        if (demo_is_text(w, h)) {
     722                rc = gfx_color_new_ega(0x1f, &color);
     723                if (rc != EOK)
     724                        goto error;
     725        } else {
     726                rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     727                if (rc != EOK)
     728                        goto error;
     729        }
    665730
    666731        gfx_text_fmt_init(&fmt);
     732        fmt.font = font;
    667733        fmt.color = color;
    668734
    669735        pos.x = rect.p0.x;
    670736        pos.y = rect.p0.y;
    671         rc = gfx_puttext(font, &pos, &fmt, "Top left");
     737        rc = gfx_puttext(&pos, &fmt, "Top left");
    672738        if (rc != EOK) {
    673739                printf("Error rendering text.\n");
     
    678744        pos.y = rect.p0.y;
    679745        fmt.halign = gfx_halign_center;
    680         rc = gfx_puttext(font, &pos, &fmt, "Top center");
    681         if (rc != EOK)
    682                 goto error;
    683 
    684         pos.x = rect.p1.x - 1;
     746        rc = gfx_puttext(&pos, &fmt, "Top center");
     747        if (rc != EOK)
     748                goto error;
     749
     750        pos.x = rect.p1.x;
    685751        pos.y = rect.p0.y;
    686752        fmt.halign = gfx_halign_right;
    687         rc = gfx_puttext(font, &pos, &fmt, "Top right");
     753        rc = gfx_puttext(&pos, &fmt, "Top right");
    688754        if (rc != EOK)
    689755                goto error;
     
    694760        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    695761        fmt.halign = gfx_halign_left;
    696         rc = gfx_puttext(font, &pos, &fmt, "Center left");
     762        rc = gfx_puttext(&pos, &fmt, "Center left");
    697763        if (rc != EOK)
    698764                goto error;
     
    701767        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    702768        fmt.halign = gfx_halign_center;
    703         rc = gfx_puttext(font, &pos, &fmt, "Center");
    704         if (rc != EOK)
    705                 goto error;
    706 
    707         pos.x = rect.p1.x - 1;
     769        rc = gfx_puttext(&pos, &fmt, "Center");
     770        if (rc != EOK)
     771                goto error;
     772
     773        pos.x = rect.p1.x;
    708774        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    709775        fmt.halign = gfx_halign_right;
    710         rc = gfx_puttext(font, &pos, &fmt, "Center right");
     776        rc = gfx_puttext(&pos, &fmt, "Center right");
    711777        if (rc != EOK)
    712778                goto error;
     
    717783        pos.y = rect.p1.y - 1;
    718784        fmt.halign = gfx_halign_left;
    719         rc = gfx_puttext(font, &pos, &fmt, "Bottom left");
     785        rc = gfx_puttext(&pos, &fmt, "Bottom left");
    720786        if (rc != EOK)
    721787                goto error;
    722788
    723789        pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
    724         pos.y = rect.p1.y - 1;
     790        pos.y = rect.p1.y;
    725791        fmt.halign = gfx_halign_center;
    726         rc = gfx_puttext(font, &pos, &fmt, "Bottom center");
    727         if (rc != EOK)
    728                 goto error;
    729 
    730         pos.x = rect.p1.x - 1;
    731         pos.y = rect.p1.y - 1;
     792        rc = gfx_puttext(&pos, &fmt, "Bottom center");
     793        if (rc != EOK)
     794                goto error;
     795
     796        pos.x = rect.p1.x;
     797        pos.y = rect.p1.y;
    732798        fmt.halign = gfx_halign_right;
    733         rc = gfx_puttext(font, &pos, &fmt, "Bottom right");
     799        rc = gfx_puttext(&pos, &fmt, "Bottom right");
    734800        if (rc != EOK)
    735801                goto error;
     
    738804
    739805        gfx_text_fmt_init(&fmt);
     806        fmt.font = font;
    740807
    741808        for (i = 0; i < 8; i++) {
    742                 rc = gfx_color_new_rgb_i16((i & 4) ? 0xffff : 0,
    743                     (i & 2) ? 0xffff : 0, (i & 1) ? 0xffff : 0, &color);
    744                 if (rc != EOK)
    745                         goto error;
     809                if (demo_is_text(w, h)) {
     810                        rc = gfx_color_new_ega(i != 0 ? i : 0x10, &color);
     811                        if (rc != EOK)
     812                                goto error;
     813                } else {
     814                        rc = gfx_color_new_rgb_i16((i & 4) ? 0xffff : 0,
     815                            (i & 2) ? 0xffff : 0, (i & 1) ? 0xffff : 0, &color);
     816                        if (rc != EOK)
     817                                goto error;
     818                }
    746819
    747820                fmt.color = color;
     821                fmt.underline = !fmt.underline;
    748822
    749823                pos.x = w / 20;
    750824                pos.y = (6 + i) * h / 15;
    751                 rc = gfx_puttext(font, &pos, &fmt, "The quick brown fox jumps over the lazy dog.");
     825                rc = gfx_puttext(&pos, &fmt, "The quick brown fox jumps over the lazy dog.");
    752826                if (rc != EOK)
    753827                        goto error;
     
    757831
    758832        for (i = 0; i < 10; i++) {
    759                 fibril_usleep(500 * 1000);
     833                demo_msleep(500);
     834                if (quit)
     835                        break;
     836        }
     837
     838        return EOK;
     839error:
     840        return rc;
     841}
     842
     843/** Run text abbreviation demo on a graphic context.
     844 *
     845 * @param gc Graphic context
     846 * @param w Width
     847 * @param h Height
     848 */
     849static errno_t demo_text_abbr(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
     850{
     851        gfx_color_t *color = NULL;
     852        gfx_rect_t rect;
     853        gfx_coord2_t pos;
     854        gfx_text_fmt_t fmt;
     855        int i;
     856        errno_t rc;
     857
     858        if (quit)
     859                return EOK;
     860
     861        rc = demo_begin(gc, w, h, "Text abbreviation");
     862        if (rc != EOK)
     863                goto error;
     864
     865        for (i = 0; i < 11; i++) {
     866
     867                rc = gfx_color_new_rgb_i16(0, 0, 0x8000, &color);
     868                if (rc != EOK)
     869                        goto error;
     870
     871                rc = gfx_set_color(gc, color);
     872                if (rc != EOK)
     873                        goto error;
     874
     875                rect.p0.x = w / 20;
     876                rect.p0.y = (2 + 2 * i) * h / 25;
     877                rect.p1.x = w - w / 20 - w * i / 12;
     878                rect.p1.y = (3 + 2 * i) * h / 25;
     879
     880                rc = gfx_fill_rect(gc, &rect);
     881                if (rc != EOK)
     882                        goto error;
     883
     884                gfx_color_delete(color);
     885
     886                if (demo_is_text(w, h)) {
     887                        rc = gfx_color_new_ega(0x1f, &color);
     888                        if (rc != EOK)
     889                                goto error;
     890                } else {
     891                        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff,
     892                            &color);
     893                        if (rc != EOK)
     894                                goto error;
     895                }
     896
     897                gfx_text_fmt_init(&fmt);
     898                fmt.font = font;
     899                fmt.color = color;
     900                fmt.abbreviate = true;
     901                fmt.width = rect.p1.x - rect.p0.x;
     902
     903                pos.x = rect.p0.x;
     904                pos.y = rect.p0.y;
     905                rc = gfx_puttext(&pos, &fmt,
     906                    "The quick brow fox jumps over the lazy dog!");
     907                if (rc != EOK) {
     908                        printf("Error rendering text.\n");
     909                        goto error;
     910                }
     911        }
     912
     913        for (i = 0; i < 10; i++) {
     914                demo_msleep(500);
    760915                if (quit)
    761916                        break;
     
    8541009                }
    8551010
    856                 fibril_usleep(500 * 1000);
    857 
     1011                demo_msleep(500);
    8581012                if (quit)
    8591013                        break;
     
    9021056                        goto error;
    9031057
     1058                rc = demo_text_abbr(gc, w, h);
     1059                if (rc != EOK)
     1060                        goto error;
     1061
    9041062                rc = demo_clip(gc, w, h);
    9051063                if (rc != EOK)
     
    9171075static errno_t demo_console(void)
    9181076{
    919         console_ctrl_t *con = NULL;
    9201077        console_gc_t *cgc = NULL;
    9211078        gfx_context_t *gc;
    922         errno_t rc;
    923 
    924         printf("Init console..\n");
     1079        sysarg_t cols, rows;
     1080        errno_t rc;
     1081
    9251082        con = console_init(stdin, stdout);
    9261083        if (con == NULL)
    9271084                return EIO;
    9281085
    929         printf("Create console GC\n");
     1086        rc = console_get_size(con, &cols, &rows);
     1087        if (rc != EOK)
     1088                return rc;
     1089
    9301090        rc = console_gc_create(con, stdout, &cgc);
    9311091        if (rc != EOK)
     
    9341094        gc = console_gc_get_ctx(cgc);
    9351095
    936         rc = demo_loop(gc, 80, 25);
     1096        rc = demo_loop(gc, cols, rows);
    9371097        if (rc != EOK)
    9381098                return rc;
     
    9431103
    9441104        return EOK;
     1105}
     1106
     1107static errno_t demo_ui_fibril(void *arg)
     1108{
     1109        demo_ui_args_t *args = (demo_ui_args_t *)arg;
     1110        errno_t rc;
     1111
     1112        ui_lock(args->ui);
     1113        rc = demo_loop(args->gc, args->dims.x, args->dims.y);
     1114        ui_unlock(args->ui);
     1115        ui_quit(args->ui);
     1116        return rc;
    9451117}
    9461118
     
    9481120static errno_t demo_ui(const char *display_spec)
    9491121{
    950         ui_t *ui = NULL;
    9511122        ui_wnd_params_t params;
    9521123        ui_window_t *window = NULL;
     
    9551126        gfx_rect_t wrect;
    9561127        gfx_coord2_t off;
    957         errno_t rc;
    958 
    959         printf("Init UI..\n");
     1128        gfx_rect_t ui_rect;
     1129        gfx_coord2_t dims;
     1130        demo_ui_args_t args;
     1131        fid_t fid;
     1132        errno_t rc;
    9601133
    9611134        rc = ui_create(display_spec, &ui);
    9621135        if (rc != EOK) {
    9631136                printf("Error initializing UI (%s)\n", display_spec);
     1137                goto error;
     1138        }
     1139
     1140        rc = ui_get_rect(ui, &ui_rect);
     1141        if (rc != EOK) {
     1142                printf("Error getting display size.\n");
    9641143                goto error;
    9651144        }
     
    9731152        params.caption = "GFX Demo";
    9741153
     1154        /* Do not decorate the window in fullscreen mode */
     1155        if (ui_is_fullscreen(ui))
     1156                params.style &= ~ui_wds_decorated;
     1157
    9751158        /*
    9761159         * Compute window rectangle such that application area corresponds
    9771160         * to rect
    9781161         */
    979         ui_wdecor_rect_from_app(params.style, &rect, &wrect);
     1162        ui_wdecor_rect_from_app(ui, params.style, &rect, &wrect);
    9801163        off = wrect.p0;
    9811164        gfx_rect_rtranslate(&off, &wrect, &params.rect);
     1165
     1166        gfx_rect_dims(&ui_rect, &dims);
     1167
     1168        /* Make sure window is not larger than the entire screen */
     1169        if (params.rect.p1.x > dims.x)
     1170                params.rect.p1.x = dims.x;
     1171        if (params.rect.p1.y > dims.y)
     1172                params.rect.p1.y = dims.y;
    9821173
    9831174        rc = ui_window_create(ui, &params, &window);
     
    9951186        }
    9961187
    997         task_retval(0);
    998 
    999         rc = demo_loop(gc, rect.p1.x, rect.p1.y);
    1000         if (rc != EOK)
    1001                 goto error;
    1002 
     1188        ui_window_get_app_rect(window, &rect);
     1189        gfx_rect_dims(&rect, &dims);
     1190
     1191        if (!ui_is_fullscreen(ui))
     1192                task_retval(0);
     1193
     1194        args.gc = gc;
     1195        args.dims = dims;
     1196        args.ui = ui;
     1197
     1198        fid = fibril_create(demo_ui_fibril, (void *)&args);
     1199        if (fid == 0) {
     1200                rc = ENOMEM;
     1201                goto error;
     1202        }
     1203
     1204        fibril_add_ready(fid);
     1205
     1206        ui_run(ui);
    10031207        ui_window_destroy(window);
    10041208        ui_destroy(ui);
     
    10221226        errno_t rc;
    10231227
    1024         printf("Init display..\n");
    1025 
    10261228        rc = display_open(display_svc, &display);
    10271229        if (rc != EOK) {
     
    10351237        params.rect.p1.x = 400;
    10361238        params.rect.p1.y = 300;
     1239        params.caption = "GFX Demo";
    10371240
    10381241        rc = display_window_create(display, &params, &wnd_cb, NULL, &window);
     
    10641267}
    10651268
     1269static void demo_quit(void)
     1270{
     1271        fibril_mutex_lock(&quit_lock);
     1272        quit = true;
     1273        fibril_mutex_unlock(&quit_lock);
     1274        fibril_condvar_broadcast(&quit_cv);
     1275}
     1276
    10661277static void wnd_close_event(void *arg)
    10671278{
    1068         printf("Close event\n");
    1069         quit = true;
     1279        demo_quit();
     1280}
     1281
     1282static void demo_kbd_event(kbd_event_t *event)
     1283{
     1284        if (event->type == KEY_PRESS) {
     1285                /* Ctrl-Q */
     1286                if ((event->mods & KM_CTRL) != 0 &&
     1287                    (event->mods & KM_ALT) == 0 &&
     1288                    (event->mods & KM_SHIFT) == 0 &&
     1289                    event->key == KC_Q) {
     1290                        demo_quit();
     1291                }
     1292
     1293                /* Escape */
     1294                if ((event->mods & KM_CTRL) == 0 &&
     1295                    (event->mods & KM_ALT) == 0 &&
     1296                    (event->mods & KM_SHIFT) == 0 &&
     1297                    event->key == KC_ESCAPE) {
     1298                        demo_quit();
     1299                }
     1300        }
    10701301}
    10711302
    10721303static void wnd_kbd_event(void *arg, kbd_event_t *event)
    10731304{
    1074         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1075         if (event->type == KEY_PRESS)
    1076                 quit = true;
     1305        (void)arg;
     1306        demo_kbd_event(event);
    10771307}
    10781308
    10791309static void uiwnd_close_event(ui_window_t *window, void *arg)
    10801310{
    1081         printf("Close event\n");
    1082         quit = true;
     1311        demo_quit();
    10831312}
    10841313
    10851314static void uiwnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
    10861315{
    1087         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1088         if (event->type == KEY_PRESS)
    1089                 quit = true;
     1316        (void)window;
     1317        (void)arg;
     1318        demo_kbd_event(event);
    10901319}
    10911320
     
    10991328        errno_t rc;
    11001329        const char *display_svc = DISPLAY_DEFAULT;
     1330        const char *ui_display_spec = UI_ANY_DEFAULT;
    11011331        int i;
    11021332
     
    11111341                        }
    11121342
    1113                         display_svc = argv[i++];
     1343                        display_svc = ui_display_spec = argv[i++];
    11141344                } else {
    11151345                        printf("Invalid option '%s'.\n", argv[i]);
     
    11281358                        return 1;
    11291359        } else if (str_cmp(argv[i], "ui") == 0) {
    1130                 rc = demo_ui(display_svc);
     1360                rc = demo_ui(ui_display_spec);
    11311361                if (rc != EOK)
    11321362                        return 1;
Note: See TracChangeset for help on using the changeset viewer.