Ignore:
File:
1 edited

Legend:

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

    rda15002 r3d588be  
    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 bool textmode;
     81static ui_t *ui;
     82
     83/** Determine if we are running in text mode.
     84 *
     85 * @return @c true iff we are running in text mode
     86 */
     87static bool demo_is_text(void)
     88{
     89        return textmode;
     90}
     91
     92/** Sleep until timeout or quit request.
     93 *
     94 * @param msec Number of microseconds to sleep for
     95 */
     96static void demo_msleep(unsigned msec)
     97{
     98        errno_t rc;
     99        usec_t usec;
     100        cons_event_t cevent;
     101
     102        if (ui != NULL)
     103                ui_unlock(ui);
     104        fibril_mutex_lock(&quit_lock);
     105        if (!quit) {
     106                if (con != NULL) {
     107                        usec = (usec_t)msec * 1000;
     108                        while (usec > 0 && !quit) {
     109                                rc = console_get_event_timeout(con, &cevent, &usec);
     110                                if (rc == EOK) {
     111                                        if (cevent.type == CEV_KEY) {
     112                                                fibril_mutex_unlock(&quit_lock);
     113                                                demo_kbd_event(&cevent.ev.key);
     114                                                fibril_mutex_lock(&quit_lock);
     115                                        }
     116                                }
     117                        }
     118                } else {
     119                        (void) fibril_condvar_wait_timeout(&quit_cv, &quit_lock,
     120                            (usec_t)msec * 1000);
     121                }
     122        }
     123        fibril_mutex_unlock(&quit_lock);
     124        if (ui != NULL)
     125                ui_lock(ui);
     126}
    74127
    75128/** Clear screen.
     
    126179
    127180        /* XXX Crude way of detecting text mode */
    128         if (w < 256) {
     181        if (demo_is_text()) {
    129182                /* Create dummy font for text mode */
    130183                rc = gfx_typeface_create(gc, &tface);
     
    215268
    216269        if (font != NULL) {
    217                 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
    218                 if (rc != EOK)
    219                         goto error;
     270                if (demo_is_text()) {
     271                        rc = gfx_color_new_ega(0x1e, &color);
     272                        if (rc != EOK)
     273                                goto error;
     274                } else {
     275                        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     276                        if (rc != EOK)
     277                                goto error;
     278                }
    220279
    221280                gfx_text_fmt_init(&fmt);
     281                fmt.font = font;
    222282                fmt.color = color;
    223283                fmt.halign = gfx_halign_center;
     
    225285
    226286                pos.x = w / 2;
    227                 pos.y = h - 1;
    228                 rc = gfx_puttext(font, &pos, &fmt, text);
     287                pos.y = h;
     288                rc = gfx_puttext(&pos, &fmt, text);
    229289                if (rc != EOK) {
    230290                        printf("Error rendering text.\n");
     
    297357                gfx_color_delete(color);
    298358
    299                 fibril_usleep(500 * 1000);
    300 
     359                demo_msleep(500);
    301360                if (quit)
    302361                        break;
     
    332391                for (j = 0; j < h; j++) {
    333392                        pixelmap_put_pixel(&pixelmap, i, j,
    334                             PIXEL(0, (i % 30) < 3 ? 255 : 0,
     393                            PIXEL(255, (i % 30) < 3 ? 255 : 0,
    335394                            (j % 30) < 3 ? 255 : 0, i / 2));
    336395                }
     
    368427                        k = i * i + j * j;
    369428                        pixelmap_put_pixel(&pixelmap, i, j,
    370                             PIXEL(0, k, k, k));
     429                            PIXEL(255, k, k, k));
    371430                }
    372431        }
     
    403462                        k = i * i + j * j;
    404463                        pixelmap_put_pixel(&pixelmap, i, j,
    405                             k < w * w / 2 ? PIXEL(0, 0, 255, 0) :
    406                             PIXEL(0, 255, 0, 255));
     464                            k < w * w / 2 ? PIXEL(255, 0, 255, 0) :
     465                            PIXEL(255, 255, 0, 255));
    407466                }
    408467        }
     
    459518                        if (rc != EOK)
    460519                                goto error;
    461                         fibril_usleep(250 * 1000);
    462 
     520
     521                        demo_msleep(250);
    463522                        if (quit)
    464523                                goto out;
     
    520579                }
    521580
    522                 fibril_usleep(500 * 1000);
    523 
     581                demo_msleep(500);
    524582                if (quit)
    525583                        break;
     
    561619        params.rect.p1.y = 40;
    562620        params.flags = bmpf_color_key;
    563         params.key_color = PIXEL(0, 255, 0, 255);
     621        params.key_color = PIXEL(255, 255, 0, 255);
    564622
    565623        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     
    581639                }
    582640
    583                 fibril_usleep(500 * 1000);
    584 
     641                demo_msleep(500);
    585642                if (quit)
    586643                        break;
     
    660717        gfx_color_delete(color);
    661718
    662         rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
    663         if (rc != EOK)
    664                 goto error;
     719        if (demo_is_text()) {
     720                rc = gfx_color_new_ega(0x1f, &color);
     721                if (rc != EOK)
     722                        goto error;
     723        } else {
     724                rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     725                if (rc != EOK)
     726                        goto error;
     727        }
    665728
    666729        gfx_text_fmt_init(&fmt);
     730        fmt.font = font;
    667731        fmt.color = color;
    668732
    669733        pos.x = rect.p0.x;
    670734        pos.y = rect.p0.y;
    671         rc = gfx_puttext(font, &pos, &fmt, "Top left");
     735        rc = gfx_puttext(&pos, &fmt, "Top left");
    672736        if (rc != EOK) {
    673737                printf("Error rendering text.\n");
     
    678742        pos.y = rect.p0.y;
    679743        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;
     744        rc = gfx_puttext(&pos, &fmt, "Top center");
     745        if (rc != EOK)
     746                goto error;
     747
     748        pos.x = rect.p1.x;
    685749        pos.y = rect.p0.y;
    686750        fmt.halign = gfx_halign_right;
    687         rc = gfx_puttext(font, &pos, &fmt, "Top right");
     751        rc = gfx_puttext(&pos, &fmt, "Top right");
    688752        if (rc != EOK)
    689753                goto error;
     
    694758        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    695759        fmt.halign = gfx_halign_left;
    696         rc = gfx_puttext(font, &pos, &fmt, "Center left");
     760        rc = gfx_puttext(&pos, &fmt, "Center left");
    697761        if (rc != EOK)
    698762                goto error;
     
    701765        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    702766        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;
     767        rc = gfx_puttext(&pos, &fmt, "Center");
     768        if (rc != EOK)
     769                goto error;
     770
     771        pos.x = rect.p1.x;
    708772        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    709773        fmt.halign = gfx_halign_right;
    710         rc = gfx_puttext(font, &pos, &fmt, "Center right");
     774        rc = gfx_puttext(&pos, &fmt, "Center right");
    711775        if (rc != EOK)
    712776                goto error;
     
    717781        pos.y = rect.p1.y - 1;
    718782        fmt.halign = gfx_halign_left;
    719         rc = gfx_puttext(font, &pos, &fmt, "Bottom left");
     783        rc = gfx_puttext(&pos, &fmt, "Bottom left");
    720784        if (rc != EOK)
    721785                goto error;
    722786
    723787        pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
    724         pos.y = rect.p1.y - 1;
     788        pos.y = rect.p1.y;
    725789        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;
     790        rc = gfx_puttext(&pos, &fmt, "Bottom center");
     791        if (rc != EOK)
     792                goto error;
     793
     794        pos.x = rect.p1.x;
     795        pos.y = rect.p1.y;
    732796        fmt.halign = gfx_halign_right;
    733         rc = gfx_puttext(font, &pos, &fmt, "Bottom right");
     797        rc = gfx_puttext(&pos, &fmt, "Bottom right");
    734798        if (rc != EOK)
    735799                goto error;
     
    738802
    739803        gfx_text_fmt_init(&fmt);
     804        fmt.font = font;
    740805
    741806        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;
     807                if (demo_is_text()) {
     808                        rc = gfx_color_new_ega(i != 0 ? i : 0x10, &color);
     809                        if (rc != EOK)
     810                                goto error;
     811                } else {
     812                        rc = gfx_color_new_rgb_i16((i & 4) ? 0xffff : 0,
     813                            (i & 2) ? 0xffff : 0, (i & 1) ? 0xffff : 0, &color);
     814                        if (rc != EOK)
     815                                goto error;
     816                }
    746817
    747818                fmt.color = color;
     819                fmt.underline = !fmt.underline;
    748820
    749821                pos.x = w / 20;
    750822                pos.y = (6 + i) * h / 15;
    751                 rc = gfx_puttext(font, &pos, &fmt, "The quick brown fox jumps over the lazy dog.");
     823                rc = gfx_puttext(&pos, &fmt, "The quick brown fox jumps over the lazy dog.");
    752824                if (rc != EOK)
    753825                        goto error;
     
    757829
    758830        for (i = 0; i < 10; i++) {
    759                 fibril_usleep(500 * 1000);
     831                demo_msleep(500);
     832                if (quit)
     833                        break;
     834        }
     835
     836        return EOK;
     837error:
     838        return rc;
     839}
     840
     841/** Run text abbreviation demo on a graphic context.
     842 *
     843 * @param gc Graphic context
     844 * @param w Width
     845 * @param h Height
     846 */
     847static errno_t demo_text_abbr(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
     848{
     849        gfx_color_t *color = NULL;
     850        gfx_rect_t rect;
     851        gfx_coord2_t pos;
     852        gfx_text_fmt_t fmt;
     853        int i;
     854        errno_t rc;
     855
     856        if (quit)
     857                return EOK;
     858
     859        rc = demo_begin(gc, w, h, "Text abbreviation");
     860        if (rc != EOK)
     861                goto error;
     862
     863        for (i = 0; i < 11; i++) {
     864
     865                rc = gfx_color_new_rgb_i16(0, 0, 0x8000, &color);
     866                if (rc != EOK)
     867                        goto error;
     868
     869                rc = gfx_set_color(gc, color);
     870                if (rc != EOK)
     871                        goto error;
     872
     873                rect.p0.x = w / 20;
     874                rect.p0.y = (2 + 2 * i) * h / 25;
     875                rect.p1.x = w - w / 20 - w * i / 12;
     876                rect.p1.y = (3 + 2 * i) * h / 25;
     877
     878                rc = gfx_fill_rect(gc, &rect);
     879                if (rc != EOK)
     880                        goto error;
     881
     882                gfx_color_delete(color);
     883
     884                if (demo_is_text()) {
     885                        rc = gfx_color_new_ega(0x1f, &color);
     886                        if (rc != EOK)
     887                                goto error;
     888                } else {
     889                        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff,
     890                            &color);
     891                        if (rc != EOK)
     892                                goto error;
     893                }
     894
     895                gfx_text_fmt_init(&fmt);
     896                fmt.font = font;
     897                fmt.color = color;
     898                fmt.abbreviate = true;
     899                fmt.width = rect.p1.x - rect.p0.x;
     900
     901                pos.x = rect.p0.x;
     902                pos.y = rect.p0.y;
     903                rc = gfx_puttext(&pos, &fmt,
     904                    "The quick brow fox jumps over the lazy dog!");
     905                if (rc != EOK) {
     906                        printf("Error rendering text.\n");
     907                        goto error;
     908                }
     909        }
     910
     911        for (i = 0; i < 10; i++) {
     912                demo_msleep(500);
    760913                if (quit)
    761914                        break;
     
    8541007                }
    8551008
    856                 fibril_usleep(500 * 1000);
    857 
     1009                demo_msleep(500);
    8581010                if (quit)
    8591011                        break;
     
    9021054                        goto error;
    9031055
     1056                rc = demo_text_abbr(gc, w, h);
     1057                if (rc != EOK)
     1058                        goto error;
     1059
    9041060                rc = demo_clip(gc, w, h);
    9051061                if (rc != EOK)
     
    9171073static errno_t demo_console(void)
    9181074{
    919         console_ctrl_t *con = NULL;
    9201075        console_gc_t *cgc = NULL;
    9211076        gfx_context_t *gc;
    922         errno_t rc;
    923 
    924         printf("Init console..\n");
     1077        sysarg_t cols, rows;
     1078        errno_t rc;
     1079
    9251080        con = console_init(stdin, stdout);
    9261081        if (con == NULL)
    9271082                return EIO;
    9281083
    929         printf("Create console GC\n");
     1084        rc = console_get_size(con, &cols, &rows);
     1085        if (rc != EOK)
     1086                return rc;
     1087
    9301088        rc = console_gc_create(con, stdout, &cgc);
    9311089        if (rc != EOK)
     
    9341092        gc = console_gc_get_ctx(cgc);
    9351093
    936         rc = demo_loop(gc, 80, 25);
     1094        /* Currently console is always text. */
     1095        textmode = true;
     1096
     1097        rc = demo_loop(gc, cols, rows);
    9371098        if (rc != EOK)
    9381099                return rc;
     
    9431104
    9441105        return EOK;
     1106}
     1107
     1108static errno_t demo_ui_fibril(void *arg)
     1109{
     1110        demo_ui_args_t *args = (demo_ui_args_t *)arg;
     1111        errno_t rc;
     1112
     1113        ui_lock(args->ui);
     1114        rc = demo_loop(args->gc, args->dims.x, args->dims.y);
     1115        ui_unlock(args->ui);
     1116        ui_quit(args->ui);
     1117        return rc;
    9451118}
    9461119
     
    9481121static errno_t demo_ui(const char *display_spec)
    9491122{
    950         ui_t *ui = NULL;
    9511123        ui_wnd_params_t params;
    9521124        ui_window_t *window = NULL;
     
    9551127        gfx_rect_t wrect;
    9561128        gfx_coord2_t off;
    957         errno_t rc;
    958 
    959         printf("Init UI..\n");
     1129        gfx_rect_t ui_rect;
     1130        gfx_coord2_t dims;
     1131        demo_ui_args_t args;
     1132        fid_t fid;
     1133        errno_t rc;
    9601134
    9611135        rc = ui_create(display_spec, &ui);
    9621136        if (rc != EOK) {
    9631137                printf("Error initializing UI (%s)\n", display_spec);
     1138                goto error;
     1139        }
     1140
     1141        rc = ui_get_rect(ui, &ui_rect);
     1142        if (rc != EOK) {
     1143                printf("Error getting display size.\n");
    9641144                goto error;
    9651145        }
     
    9731153        params.caption = "GFX Demo";
    9741154
     1155        /* Do not decorate the window in fullscreen mode */
     1156        if (ui_is_fullscreen(ui))
     1157                params.style &= ~ui_wds_decorated;
     1158
    9751159        /*
    9761160         * Compute window rectangle such that application area corresponds
    9771161         * to rect
    9781162         */
    979         ui_wdecor_rect_from_app(params.style, &rect, &wrect);
     1163        ui_wdecor_rect_from_app(ui, params.style, &rect, &wrect);
    9801164        off = wrect.p0;
    9811165        gfx_rect_rtranslate(&off, &wrect, &params.rect);
     1166
     1167        gfx_rect_dims(&ui_rect, &dims);
     1168
     1169        /* Make sure window is not larger than the entire screen */
     1170        if (params.rect.p1.x > dims.x)
     1171                params.rect.p1.x = dims.x;
     1172        if (params.rect.p1.y > dims.y)
     1173                params.rect.p1.y = dims.y;
    9821174
    9831175        rc = ui_window_create(ui, &params, &window);
     
    9951187        }
    9961188
    997         task_retval(0);
    998 
    999         rc = demo_loop(gc, rect.p1.x, rect.p1.y);
    1000         if (rc != EOK)
    1001                 goto error;
    1002 
     1189        ui_window_get_app_rect(window, &rect);
     1190        gfx_rect_dims(&rect, &dims);
     1191
     1192        if (!ui_is_fullscreen(ui))
     1193                task_retval(0);
     1194
     1195        textmode = ui_is_textmode(ui);
     1196
     1197        args.gc = gc;
     1198        args.dims = dims;
     1199        args.ui = ui;
     1200
     1201        fid = fibril_create(demo_ui_fibril, (void *)&args);
     1202        if (fid == 0) {
     1203                rc = ENOMEM;
     1204                goto error;
     1205        }
     1206
     1207        fibril_add_ready(fid);
     1208
     1209        ui_run(ui);
    10031210        ui_window_destroy(window);
    10041211        ui_destroy(ui);
     
    10221229        errno_t rc;
    10231230
    1024         printf("Init display..\n");
    1025 
    10261231        rc = display_open(display_svc, &display);
    10271232        if (rc != EOK) {
     
    10351240        params.rect.p1.x = 400;
    10361241        params.rect.p1.y = 300;
     1242        params.caption = "GFX Demo";
    10371243
    10381244        rc = display_window_create(display, &params, &wnd_cb, NULL, &window);
     
    10501256        task_retval(0);
    10511257
     1258        /* FIXME Assuming display service is not text mode. */
     1259        textmode = false;
     1260
    10521261        rc = demo_loop(gc, 400, 300);
    10531262        if (rc != EOK)
     
    10641273}
    10651274
     1275static void demo_quit(void)
     1276{
     1277        fibril_mutex_lock(&quit_lock);
     1278        quit = true;
     1279        fibril_mutex_unlock(&quit_lock);
     1280        fibril_condvar_broadcast(&quit_cv);
     1281}
     1282
    10661283static void wnd_close_event(void *arg)
    10671284{
    1068         printf("Close event\n");
    1069         quit = true;
     1285        demo_quit();
     1286}
     1287
     1288static void demo_kbd_event(kbd_event_t *event)
     1289{
     1290        if (event->type == KEY_PRESS) {
     1291                /* Ctrl-Q */
     1292                if ((event->mods & KM_CTRL) != 0 &&
     1293                    (event->mods & KM_ALT) == 0 &&
     1294                    (event->mods & KM_SHIFT) == 0 &&
     1295                    event->key == KC_Q) {
     1296                        demo_quit();
     1297                }
     1298
     1299                /* Escape */
     1300                if ((event->mods & KM_CTRL) == 0 &&
     1301                    (event->mods & KM_ALT) == 0 &&
     1302                    (event->mods & KM_SHIFT) == 0 &&
     1303                    event->key == KC_ESCAPE) {
     1304                        demo_quit();
     1305                }
     1306        }
    10701307}
    10711308
    10721309static void wnd_kbd_event(void *arg, kbd_event_t *event)
    10731310{
    1074         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1075         if (event->type == KEY_PRESS)
    1076                 quit = true;
     1311        (void)arg;
     1312        demo_kbd_event(event);
    10771313}
    10781314
    10791315static void uiwnd_close_event(ui_window_t *window, void *arg)
    10801316{
    1081         printf("Close event\n");
    1082         quit = true;
     1317        demo_quit();
    10831318}
    10841319
    10851320static void uiwnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
    10861321{
    1087         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1088         if (event->type == KEY_PRESS)
    1089                 quit = true;
     1322        (void)window;
     1323        (void)arg;
     1324        demo_kbd_event(event);
    10901325}
    10911326
     
    10991334        errno_t rc;
    11001335        const char *display_svc = DISPLAY_DEFAULT;
     1336        const char *ui_display_spec = UI_ANY_DEFAULT;
    11011337        int i;
    11021338
     
    11111347                        }
    11121348
    1113                         display_svc = argv[i++];
     1349                        display_svc = ui_display_spec = argv[i++];
    11141350                } else {
    11151351                        printf("Invalid option '%s'.\n", argv[i]);
     
    11281364                        return 1;
    11291365        } else if (str_cmp(argv[i], "ui") == 0) {
    1130                 rc = demo_ui(display_svc);
     1366                rc = demo_ui(ui_display_spec);
    11311367                if (rc != EOK)
    11321368                        return 1;
Note: See TracChangeset for help on using the changeset viewer.