Ignore:
File:
1 edited

Legend:

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

    r400a16d r0a411bbf  
    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 ui_t *ui;
    7481
    7582/** Determine if we are running in text mode.
     
    8390        // XXX Need a proper way to determine text mode
    8491        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);
    85128}
    86129
     
    238281
    239282                gfx_text_fmt_init(&fmt);
     283                fmt.font = font;
    240284                fmt.color = color;
    241285                fmt.halign = gfx_halign_center;
     
    243287
    244288                pos.x = w / 2;
    245                 pos.y = h - 1;
    246                 rc = gfx_puttext(font, &pos, &fmt, text);
     289                pos.y = h;
     290                rc = gfx_puttext(&pos, &fmt, text);
    247291                if (rc != EOK) {
    248292                        printf("Error rendering text.\n");
     
    315359                gfx_color_delete(color);
    316360
    317                 fibril_usleep(500 * 1000);
    318 
     361                demo_msleep(500);
    319362                if (quit)
    320363                        break;
     
    350393                for (j = 0; j < h; j++) {
    351394                        pixelmap_put_pixel(&pixelmap, i, j,
    352                             PIXEL(0, (i % 30) < 3 ? 255 : 0,
     395                            PIXEL(255, (i % 30) < 3 ? 255 : 0,
    353396                            (j % 30) < 3 ? 255 : 0, i / 2));
    354397                }
     
    386429                        k = i * i + j * j;
    387430                        pixelmap_put_pixel(&pixelmap, i, j,
    388                             PIXEL(0, k, k, k));
     431                            PIXEL(255, k, k, k));
    389432                }
    390433        }
     
    421464                        k = i * i + j * j;
    422465                        pixelmap_put_pixel(&pixelmap, i, j,
    423                             k < w * w / 2 ? PIXEL(0, 0, 255, 0) :
    424                             PIXEL(0, 255, 0, 255));
     466                            k < w * w / 2 ? PIXEL(255, 0, 255, 0) :
     467                            PIXEL(255, 255, 0, 255));
    425468                }
    426469        }
     
    477520                        if (rc != EOK)
    478521                                goto error;
    479                         fibril_usleep(250 * 1000);
    480 
     522
     523                        demo_msleep(250);
    481524                        if (quit)
    482525                                goto out;
     
    538581                }
    539582
    540                 fibril_usleep(500 * 1000);
    541 
     583                demo_msleep(500);
    542584                if (quit)
    543585                        break;
     
    579621        params.rect.p1.y = 40;
    580622        params.flags = bmpf_color_key;
    581         params.key_color = PIXEL(0, 255, 0, 255);
     623        params.key_color = PIXEL(255, 255, 0, 255);
    582624
    583625        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     
    599641                }
    600642
    601                 fibril_usleep(500 * 1000);
    602 
     643                demo_msleep(500);
    603644                if (quit)
    604645                        break;
     
    689730
    690731        gfx_text_fmt_init(&fmt);
     732        fmt.font = font;
    691733        fmt.color = color;
    692734
    693735        pos.x = rect.p0.x;
    694736        pos.y = rect.p0.y;
    695         rc = gfx_puttext(font, &pos, &fmt, "Top left");
     737        rc = gfx_puttext(&pos, &fmt, "Top left");
    696738        if (rc != EOK) {
    697739                printf("Error rendering text.\n");
     
    702744        pos.y = rect.p0.y;
    703745        fmt.halign = gfx_halign_center;
    704         rc = gfx_puttext(font, &pos, &fmt, "Top center");
     746        rc = gfx_puttext(&pos, &fmt, "Top center");
    705747        if (rc != EOK)
    706748                goto error;
     
    709751        pos.y = rect.p0.y;
    710752        fmt.halign = gfx_halign_right;
    711         rc = gfx_puttext(font, &pos, &fmt, "Top right");
     753        rc = gfx_puttext(&pos, &fmt, "Top right");
    712754        if (rc != EOK)
    713755                goto error;
     
    718760        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    719761        fmt.halign = gfx_halign_left;
    720         rc = gfx_puttext(font, &pos, &fmt, "Center left");
     762        rc = gfx_puttext(&pos, &fmt, "Center left");
    721763        if (rc != EOK)
    722764                goto error;
     
    725767        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    726768        fmt.halign = gfx_halign_center;
    727         rc = gfx_puttext(font, &pos, &fmt, "Center");
     769        rc = gfx_puttext(&pos, &fmt, "Center");
    728770        if (rc != EOK)
    729771                goto error;
     
    732774        pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
    733775        fmt.halign = gfx_halign_right;
    734         rc = gfx_puttext(font, &pos, &fmt, "Center right");
     776        rc = gfx_puttext(&pos, &fmt, "Center right");
    735777        if (rc != EOK)
    736778                goto error;
     
    741783        pos.y = rect.p1.y - 1;
    742784        fmt.halign = gfx_halign_left;
    743         rc = gfx_puttext(font, &pos, &fmt, "Bottom left");
     785        rc = gfx_puttext(&pos, &fmt, "Bottom left");
    744786        if (rc != EOK)
    745787                goto error;
     
    748790        pos.y = rect.p1.y;
    749791        fmt.halign = gfx_halign_center;
    750         rc = gfx_puttext(font, &pos, &fmt, "Bottom center");
     792        rc = gfx_puttext(&pos, &fmt, "Bottom center");
    751793        if (rc != EOK)
    752794                goto error;
     
    755797        pos.y = rect.p1.y;
    756798        fmt.halign = gfx_halign_right;
    757         rc = gfx_puttext(font, &pos, &fmt, "Bottom right");
     799        rc = gfx_puttext(&pos, &fmt, "Bottom right");
    758800        if (rc != EOK)
    759801                goto error;
     
    762804
    763805        gfx_text_fmt_init(&fmt);
     806        fmt.font = font;
    764807
    765808        for (i = 0; i < 8; i++) {
     
    776819
    777820                fmt.color = color;
     821                fmt.underline = !fmt.underline;
    778822
    779823                pos.x = w / 20;
    780824                pos.y = (6 + i) * h / 15;
    781                 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.");
    782826                if (rc != EOK)
    783827                        goto error;
     
    787831
    788832        for (i = 0; i < 10; i++) {
    789                 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);
    790915                if (quit)
    791916                        break;
     
    8841009                }
    8851010
    886                 fibril_usleep(500 * 1000);
    887 
     1011                demo_msleep(500);
    8881012                if (quit)
    8891013                        break;
     
    9321056                        goto error;
    9331057
     1058                rc = demo_text_abbr(gc, w, h);
     1059                if (rc != EOK)
     1060                        goto error;
     1061
    9341062                rc = demo_clip(gc, w, h);
    9351063                if (rc != EOK)
     
    9471075static errno_t demo_console(void)
    9481076{
    949         console_ctrl_t *con = NULL;
    9501077        console_gc_t *cgc = NULL;
    9511078        gfx_context_t *gc;
    952         errno_t rc;
    953 
    954         printf("Init console..\n");
     1079        sysarg_t cols, rows;
     1080        errno_t rc;
     1081
    9551082        con = console_init(stdin, stdout);
    9561083        if (con == NULL)
    9571084                return EIO;
    9581085
    959         printf("Create console GC\n");
     1086        rc = console_get_size(con, &cols, &rows);
     1087        if (rc != EOK)
     1088                return rc;
     1089
    9601090        rc = console_gc_create(con, stdout, &cgc);
    9611091        if (rc != EOK)
     
    9641094        gc = console_gc_get_ctx(cgc);
    9651095
    966         rc = demo_loop(gc, 80, 25);
     1096        rc = demo_loop(gc, cols, rows);
    9671097        if (rc != EOK)
    9681098                return rc;
     
    9731103
    9741104        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;
    9751117}
    9761118
     
    9781120static errno_t demo_ui(const char *display_spec)
    9791121{
    980         ui_t *ui = NULL;
    9811122        ui_wnd_params_t params;
    9821123        ui_window_t *window = NULL;
     
    9851126        gfx_rect_t wrect;
    9861127        gfx_coord2_t off;
    987         errno_t rc;
    988 
    989         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;
    9901133
    9911134        rc = ui_create(display_spec, &ui);
    9921135        if (rc != EOK) {
    9931136                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");
    9941143                goto error;
    9951144        }
     
    10031152        params.caption = "GFX Demo";
    10041153
     1154        /* Do not decorate the window in fullscreen mode */
     1155        if (ui_is_fullscreen(ui))
     1156                params.style &= ~ui_wds_decorated;
     1157
    10051158        /*
    10061159         * Compute window rectangle such that application area corresponds
    10071160         * to rect
    10081161         */
    1009         ui_wdecor_rect_from_app(params.style, &rect, &wrect);
     1162        ui_wdecor_rect_from_app(ui, params.style, &rect, &wrect);
    10101163        off = wrect.p0;
    10111164        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;
    10121173
    10131174        rc = ui_window_create(ui, &params, &window);
     
    10251186        }
    10261187
    1027         task_retval(0);
    1028 
    1029         rc = demo_loop(gc, rect.p1.x, rect.p1.y);
    1030         if (rc != EOK)
    1031                 goto error;
    1032 
     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);
    10331207        ui_window_destroy(window);
    10341208        ui_destroy(ui);
     
    10521226        errno_t rc;
    10531227
    1054         printf("Init display..\n");
    1055 
    10561228        rc = display_open(display_svc, &display);
    10571229        if (rc != EOK) {
     
    10651237        params.rect.p1.x = 400;
    10661238        params.rect.p1.y = 300;
     1239        params.caption = "GFX Demo";
    10671240
    10681241        rc = display_window_create(display, &params, &wnd_cb, NULL, &window);
     
    10941267}
    10951268
     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
    10961277static void wnd_close_event(void *arg)
    10971278{
    1098         printf("Close event\n");
    1099         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        }
    11001301}
    11011302
    11021303static void wnd_kbd_event(void *arg, kbd_event_t *event)
    11031304{
    1104         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1105         if (event->type == KEY_PRESS)
    1106                 quit = true;
     1305        (void)arg;
     1306        demo_kbd_event(event);
    11071307}
    11081308
    11091309static void uiwnd_close_event(ui_window_t *window, void *arg)
    11101310{
    1111         printf("Close event\n");
    1112         quit = true;
     1311        demo_quit();
    11131312}
    11141313
    11151314static void uiwnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
    11161315{
    1117         printf("Keyboard event type=%d key=%d\n", event->type, event->key);
    1118         if (event->type == KEY_PRESS)
    1119                 quit = true;
     1316        (void)window;
     1317        (void)arg;
     1318        demo_kbd_event(event);
    11201319}
    11211320
     
    11291328        errno_t rc;
    11301329        const char *display_svc = DISPLAY_DEFAULT;
     1330        const char *ui_display_spec = UI_ANY_DEFAULT;
    11311331        int i;
    11321332
     
    11411341                        }
    11421342
    1143                         display_svc = argv[i++];
     1343                        display_svc = ui_display_spec = argv[i++];
    11441344                } else {
    11451345                        printf("Invalid option '%s'.\n", argv[i]);
     
    11581358                        return 1;
    11591359        } else if (str_cmp(argv[i], "ui") == 0) {
    1160                 rc = demo_ui(display_svc);
     1360                rc = demo_ui(ui_display_spec);
    11611361                if (rc != EOK)
    11621362                        return 1;
Note: See TracChangeset for help on using the changeset viewer.