Ignore:
File:
1 edited

Legend:

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

    r400a16d r3d588be  
    11/*
    2  * Copyright (c) 2021 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;
    7482
    7583/** Determine if we are running in text mode.
    7684 *
    77  * @param w Screen width
    78  * @param h Screen height
    7985 * @return @c true iff we are running in text mode
    8086 */
    81 static bool demo_is_text(gfx_coord_t w, gfx_coord_t h)
    82 {
    83         // XXX Need a proper way to determine text mode
    84         return w <= 80;
     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);
    85126}
    86127
     
    138179
    139180        /* XXX Crude way of detecting text mode */
    140         if (w < 256) {
     181        if (demo_is_text()) {
    141182                /* Create dummy font for text mode */
    142183                rc = gfx_typeface_create(gc, &tface);
     
    227268
    228269        if (font != NULL) {
    229                 if (demo_is_text(w, h)) {
     270                if (demo_is_text()) {
    230271                        rc = gfx_color_new_ega(0x1e, &color);
    231272                        if (rc != EOK)
     
    238279
    239280                gfx_text_fmt_init(&fmt);
     281                fmt.font = font;
    240282                fmt.color = color;
    241283                fmt.halign = gfx_halign_center;
     
    243285
    244286                pos.x = w / 2;
    245                 pos.y = h - 1;
    246                 rc = gfx_puttext(font, &pos, &fmt, text);
     287                pos.y = h;
     288                rc = gfx_puttext(&pos, &fmt, text);
    247289                if (rc != EOK) {
    248290                        printf("Error rendering text.\n");
     
    315357                gfx_color_delete(color);
    316358
    317                 fibril_usleep(500 * 1000);
    318 
     359                demo_msleep(500);
    319360                if (quit)
    320361                        break;
     
    350391                for (j = 0; j < h; j++) {
    351392                        pixelmap_put_pixel(&pixelmap, i, j,
    352                             PIXEL(0, (i % 30) < 3 ? 255 : 0,
     393                            PIXEL(255, (i % 30) < 3 ? 255 : 0,
    353394                            (j % 30) < 3 ? 255 : 0, i / 2));
    354395                }
     
    386427                        k = i * i + j * j;
    387428                        pixelmap_put_pixel(&pixelmap, i, j,
    388                             PIXEL(0, k, k, k));
     429                            PIXEL(255, k, k, k));
    389430                }
    390431        }
     
    421462                        k = i * i + j * j;
    422463                        pixelmap_put_pixel(&pixelmap, i, j,
    423                             k < w * w / 2 ? PIXEL(0, 0, 255, 0) :
    424                             PIXEL(0, 255, 0, 255));
     464                            k < w * w / 2 ? PIXEL(255, 0, 255, 0) :
     465                            PIXEL(255, 255, 0, 255));
    425466                }
    426467        }
     
    477518                        if (rc != EOK)
    478519                                goto error;
    479                         fibril_usleep(250 * 1000);
    480 
     520
     521                        demo_msleep(250);
    481522                        if (quit)
    482523                                goto out;
     
    538579                }
    539580
    540                 fibril_usleep(500 * 1000);
    541 
     581                demo_msleep(500);
    542582                if (quit)
    543583                        break;
     
    579619        params.rect.p1.y = 40;
    580620        params.flags = bmpf_color_key;
    581         params.key_color = PIXEL(0, 255, 0, 255);
     621        params.key_color = PIXEL(255, 255, 0, 255);
    582622
    583623        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     
    599639                }
    600640
    601                 fibril_usleep(500 * 1000);
    602 
     641                demo_msleep(500);
    603642                if (quit)
    604643                        break;
     
    678717        gfx_color_delete(color);
    679718
    680         if (demo_is_text(w, h)) {
     719        if (demo_is_text()) {
    681720                rc = gfx_color_new_ega(0x1f, &color);
    682721                if (rc != EOK)
     
    689728
    690729        gfx_text_fmt_init(&fmt);
     730        fmt.font = font;
    691731        fmt.color = color;
    692732
    693733        pos.x = rect.p0.x;
    694734        pos.y = rect.p0.y;
    695         rc = gfx_puttext(font, &pos, &fmt, "Top left");
     735        rc = gfx_puttext(&pos, &fmt, "Top left");
    696736        if (rc != EOK) {
    697737                printf("Error rendering text.\n");
     
    702742        pos.y = rect.p0.y;
    703743        fmt.halign = gfx_halign_center;
    704         rc = gfx_puttext(font, &pos, &fmt, "Top center");
     744        rc = gfx_puttext(&pos, &fmt, "Top center");
    705745        if (rc != EOK)
    706746                goto error;
     
    709749        pos.y = rect.p0.y;
    710750        fmt.halign = gfx_halign_right;
    711         rc = gfx_puttext(font, &pos, &fmt, "Top right");
     751        rc = gfx_puttext(&pos, &fmt, "Top right");
    712752        if (rc != EOK)
    713753                goto error;
     
    718758        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    719759        fmt.halign = gfx_halign_left;
    720         rc = gfx_puttext(font, &pos, &fmt, "Center left");
     760        rc = gfx_puttext(&pos, &fmt, "Center left");
    721761        if (rc != EOK)
    722762                goto error;
     
    725765        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    726766        fmt.halign = gfx_halign_center;
    727         rc = gfx_puttext(font, &pos, &fmt, "Center");
     767        rc = gfx_puttext(&pos, &fmt, "Center");
    728768        if (rc != EOK)
    729769                goto error;
     
    732772        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    733773        fmt.halign = gfx_halign_right;
    734         rc = gfx_puttext(font, &pos, &fmt, "Center right");
     774        rc = gfx_puttext(&pos, &fmt, "Center right");
    735775        if (rc != EOK)
    736776                goto error;
     
    741781        pos.y = rect.p1.y - 1;
    742782        fmt.halign = gfx_halign_left;
    743         rc = gfx_puttext(font, &pos, &fmt, "Bottom left");
     783        rc = gfx_puttext(&pos, &fmt, "Bottom left");
    744784        if (rc != EOK)
    745785                goto error;
     
    748788        pos.y = rect.p1.y;
    749789        fmt.halign = gfx_halign_center;
    750         rc = gfx_puttext(font, &pos, &fmt, "Bottom center");
     790        rc = gfx_puttext(&pos, &fmt, "Bottom center");
    751791        if (rc != EOK)
    752792                goto error;
     
    755795        pos.y = rect.p1.y;
    756796        fmt.halign = gfx_halign_right;
    757         rc = gfx_puttext(font, &pos, &fmt, "Bottom right");
     797        rc = gfx_puttext(&pos, &fmt, "Bottom right");
    758798        if (rc != EOK)
    759799                goto error;
     
    762802
    763803        gfx_text_fmt_init(&fmt);
     804        fmt.font = font;
    764805
    765806        for (i = 0; i < 8; i++) {
    766                 if (demo_is_text(w, h)) {
     807                if (demo_is_text()) {
    767808                        rc = gfx_color_new_ega(i != 0 ? i : 0x10, &color);
    768809                        if (rc != EOK)
     
    776817
    777818                fmt.color = color;
     819                fmt.underline = !fmt.underline;
    778820
    779821                pos.x = w / 20;
    780822                pos.y = (6 + i) * h / 15;
    781                 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.");
    782824                if (rc != EOK)
    783825                        goto error;
     
    787829
    788830        for (i = 0; i < 10; i++) {
    789                 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);
    790913                if (quit)
    791914                        break;
     
    8841007                }
    8851008
    886                 fibril_usleep(500 * 1000);
    887 
     1009                demo_msleep(500);
    8881010                if (quit)
    8891011                        break;
     
    9321054                        goto error;
    9331055
     1056                rc = demo_text_abbr(gc, w, h);
     1057                if (rc != EOK)
     1058                        goto error;
     1059
    9341060                rc = demo_clip(gc, w, h);
    9351061                if (rc != EOK)
     
    9471073static errno_t demo_console(void)
    9481074{
    949         console_ctrl_t *con = NULL;
    9501075        console_gc_t *cgc = NULL;
    9511076        gfx_context_t *gc;
    952         errno_t rc;
    953 
    954         printf("Init console..\n");
     1077        sysarg_t cols, rows;
     1078        errno_t rc;
     1079
    9551080        con = console_init(stdin, stdout);
    9561081        if (con == NULL)
    9571082                return EIO;
    9581083
    959         printf("Create console GC\n");
     1084        rc = console_get_size(con, &cols, &rows);
     1085        if (rc != EOK)
     1086                return rc;
     1087
    9601088        rc = console_gc_create(con, stdout, &cgc);
    9611089        if (rc != EOK)
     
    9641092        gc = console_gc_get_ctx(cgc);
    9651093
    966         rc = demo_loop(gc, 80, 25);
     1094        /* Currently console is always text. */
     1095        textmode = true;
     1096
     1097        rc = demo_loop(gc, cols, rows);
    9671098        if (rc != EOK)
    9681099                return rc;
     
    9731104
    9741105        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;
    9751118}
    9761119
     
    9781121static errno_t demo_ui(const char *display_spec)
    9791122{
    980         ui_t *ui = NULL;
    9811123        ui_wnd_params_t params;
    9821124        ui_window_t *window = NULL;
     
    9851127        gfx_rect_t wrect;
    9861128        gfx_coord2_t off;
    987         errno_t rc;
    988 
    989         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;
    9901134
    9911135        rc = ui_create(display_spec, &ui);
    9921136        if (rc != EOK) {
    9931137                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");
    9941144                goto error;
    9951145        }
     
    10031153        params.caption = "GFX Demo";
    10041154
     1155        /* Do not decorate the window in fullscreen mode */
     1156        if (ui_is_fullscreen(ui))
     1157                params.style &= ~ui_wds_decorated;
     1158
    10051159        /*
    10061160         * Compute window rectangle such that application area corresponds
    10071161         * to rect
    10081162         */
    1009         ui_wdecor_rect_from_app(params.style, &rect, &wrect);
     1163        ui_wdecor_rect_from_app(ui, params.style, &rect, &wrect);
    10101164        off = wrect.p0;
    10111165        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;
    10121174
    10131175        rc = ui_window_create(ui, &params, &window);
     
    10251187        }
    10261188
    1027         task_retval(0);
    1028 
    1029         rc = demo_loop(gc, rect.p1.x, rect.p1.y);
    1030         if (rc != EOK)
    1031                 goto error;
    1032 
     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);
    10331210        ui_window_destroy(window);
    10341211        ui_destroy(ui);
     
    10521229        errno_t rc;
    10531230
    1054         printf("Init display..\n");
    1055 
    10561231        rc = display_open(display_svc, &display);
    10571232        if (rc != EOK) {
     
    10651240        params.rect.p1.x = 400;
    10661241        params.rect.p1.y = 300;
     1242        params.caption = "GFX Demo";
    10671243
    10681244        rc = display_window_create(display, &params, &wnd_cb, NULL, &window);
     
    10801256        task_retval(0);
    10811257
     1258        /* FIXME Assuming display service is not text mode. */
     1259        textmode = false;
     1260
    10821261        rc = demo_loop(gc, 400, 300);
    10831262        if (rc != EOK)
     
    10941273}
    10951274
     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
    10961283static void wnd_close_event(void *arg)
    10971284{
    1098         printf("Close event\n");
    1099         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        }
    11001307}
    11011308
    11021309static void wnd_kbd_event(void *arg, kbd_event_t *event)
    11031310{
    1104         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1105         if (event->type == KEY_PRESS)
    1106                 quit = true;
     1311        (void)arg;
     1312        demo_kbd_event(event);
    11071313}
    11081314
    11091315static void uiwnd_close_event(ui_window_t *window, void *arg)
    11101316{
    1111         printf("Close event\n");
    1112         quit = true;
     1317        demo_quit();
    11131318}
    11141319
    11151320static void uiwnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
    11161321{
    1117         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1118         if (event->type == KEY_PRESS)
    1119                 quit = true;
     1322        (void)window;
     1323        (void)arg;
     1324        demo_kbd_event(event);
    11201325}
    11211326
     
    11291334        errno_t rc;
    11301335        const char *display_svc = DISPLAY_DEFAULT;
     1336        const char *ui_display_spec = UI_ANY_DEFAULT;
    11311337        int i;
    11321338
     
    11411347                        }
    11421348
    1143                         display_svc = argv[i++];
     1349                        display_svc = ui_display_spec = argv[i++];
    11441350                } else {
    11451351                        printf("Invalid option '%s'.\n", argv[i]);
     
    11581364                        return 1;
    11591365        } else if (str_cmp(argv[i], "ui") == 0) {
    1160                 rc = demo_ui(display_svc);
     1366                rc = demo_ui(ui_display_spec);
    11611367                if (rc != EOK)
    11621368                        return 1;
Note: See TracChangeset for help on using the changeset viewer.