Ignore:
File:
1 edited

Legend:

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

    r2f11647f rf2b9ecf  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2020 Jiri Svoboda
    33 * Copyright (c) 2013 Martin Decky
    44 * All rights reserved.
     
    4040#include <stdlib.h>
    4141#include <str.h>
    42 #include <ui/filedialog.h>
    4342#include <ui/image.h>
    4443#include <ui/ui.h>
     
    5150typedef struct {
    5251        ui_t *ui;
    53 
    54         size_t imgs_count;
    55         size_t imgs_current;
    56         char **imgs;
    57 
    58         bool fullscreen;
    59         ui_window_t *window;
    60         gfx_bitmap_t *bitmap;
    61         ui_image_t *image;
    62         gfx_context_t *window_gc;
    63         ui_file_dialog_t *dialog;
    64 
    65         gfx_rect_t img_rect;
    6652} viewer_t;
    6753
    68 static bool viewer_img_load(viewer_t *, const char *, gfx_bitmap_t **,
     54static size_t imgs_count;
     55static size_t imgs_current = 0;
     56static char **imgs;
     57
     58static ui_window_t *window;
     59static gfx_bitmap_t *bitmap = NULL;
     60static ui_image_t *image = NULL;
     61static gfx_context_t *window_gc;
     62
     63static gfx_rect_t img_rect;
     64
     65static bool img_load(gfx_context_t *gc, const char *, gfx_bitmap_t **,
    6966    gfx_rect_t *);
    70 static bool viewer_img_setup(viewer_t *, gfx_bitmap_t *, gfx_rect_t *);
    71 static errno_t viewer_window_create(viewer_t *);
    72 static void viewer_window_destroy(viewer_t *);
     67static bool img_setup(gfx_context_t *, gfx_bitmap_t *, gfx_rect_t *);
    7368
    7469static void wnd_close(ui_window_t *, void *);
     
    8075};
    8176
    82 static void file_dialog_bok(ui_file_dialog_t *, void *, const char *);
    83 static void file_dialog_bcancel(ui_file_dialog_t *, void *);
    84 static void file_dialog_close(ui_file_dialog_t *, void *);
    85 
    86 static ui_file_dialog_cb_t file_dialog_cb = {
    87         .bok = file_dialog_bok,
    88         .bcancel = file_dialog_bcancel,
    89         .close = file_dialog_close
    90 };
    91 
    9277/** Window close request
    9378 *
     
    10287}
    10388
    104 /** Viewer unmodified key press.
    105  *
    106  * @param viewer Viewer
    107  * @param event Keyboard event
    108  */
    109 static void viewer_kbd_event_unmod(viewer_t *viewer, kbd_event_t *event)
     89static void wnd_kbd_event(ui_window_t *window, void *arg,
     90    kbd_event_t *event)
    11091{
    11192        bool update = false;
    11293
    113         if (event->key == KC_Q || event->key == KC_ESCAPE)
    114                 ui_quit(viewer->ui);
    115 
    116         if (event->key == KC_PAGE_DOWN) {
    117                 if (viewer->imgs_current == viewer->imgs_count - 1)
    118                         viewer->imgs_current = 0;
     94        if ((event->type == KEY_PRESS) && (event->c == 'q'))
     95                exit(0);
     96
     97        if ((event->type == KEY_PRESS) && (event->key == KC_PAGE_DOWN)) {
     98                if (imgs_current == imgs_count - 1)
     99                        imgs_current = 0;
    119100                else
    120                         viewer->imgs_current++;
     101                        imgs_current++;
    121102
    122103                update = true;
    123104        }
    124105
    125         if (event->key == KC_PAGE_UP) {
    126                 if (viewer->imgs_current == 0)
    127                         viewer->imgs_current = viewer->imgs_count - 1;
     106        if ((event->type == KEY_PRESS) && (event->key == KC_PAGE_UP)) {
     107                if (imgs_current == 0)
     108                        imgs_current = imgs_count - 1;
    128109                else
    129                         viewer->imgs_current--;
     110                        imgs_current--;
    130111
    131112                update = true;
     
    136117                gfx_rect_t lrect;
    137118
    138                 if (!viewer_img_load(viewer, viewer->imgs[viewer->imgs_current],
    139                     &lbitmap, &lrect)) {
    140                         printf("Cannot load image \"%s\".\n",
    141                             viewer->imgs[viewer->imgs_current]);
     119                if (!img_load(window_gc, imgs[imgs_current], &lbitmap, &lrect)) {
     120                        printf("Cannot load image \"%s\".\n", imgs[imgs_current]);
    142121                        exit(4);
    143122                }
    144                 if (!viewer_img_setup(viewer, lbitmap, &lrect)) {
    145                         printf("Cannot setup image \"%s\".\n",
    146                             viewer->imgs[viewer->imgs_current]);
     123                if (!img_setup(window_gc, lbitmap, &lrect)) {
     124                        printf("Cannot setup image \"%s\".\n", imgs[imgs_current]);
    147125                        exit(6);
    148126                }
     
    150128}
    151129
    152 /** Viewer ctrl-key key press.
    153  *
    154  * @param viewer Viewer
    155  * @param event Keyboard event
    156  */
    157 static void viewer_kbd_event_ctrl(viewer_t *viewer, kbd_event_t *event)
    158 {
    159         if (event->key == KC_Q)
    160                 ui_quit(viewer->ui);
    161 }
    162 
    163 /** Viewer window keyboard event.
    164  *
    165  * @param window UI window
    166  * @param arg Argument (viewer_t *)
    167  * @param event Keyboard event
    168  */
    169 static void wnd_kbd_event(ui_window_t *window, void *arg,
    170     kbd_event_t *event)
    171 {
    172         viewer_t *viewer = (viewer_t *)arg;
    173 
    174         if (event->type != KEY_PRESS)
    175                 return;
    176 
    177         if ((event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0)
    178                 viewer_kbd_event_unmod(viewer, event);
    179 
    180         if ((event->mods & KM_CTRL) != 0 &&
    181             (event->mods & (KM_ALT | KM_SHIFT)) == 0)
    182                 viewer_kbd_event_ctrl(viewer, event);
    183 
    184         ui_window_def_kbd(window, event);
    185 }
    186 
    187 /** File dialog OK button press.
    188  *
    189  * @param dialog File dialog
    190  * @param arg Argument (viewer_t *)
    191  * @param fname File name
    192  */
    193 static void file_dialog_bok(ui_file_dialog_t *dialog, void *arg,
    194     const char *fname)
    195 {
    196         viewer_t *viewer = (viewer_t *) arg;
    197         errno_t rc;
    198 
    199         viewer->imgs_count = 1;
    200         viewer->imgs = calloc(viewer->imgs_count, sizeof(char *));
    201         if (viewer->imgs == NULL) {
    202                 printf("Out of memory.\n");
    203                 ui_quit(viewer->ui);
    204                 return;
    205         }
    206 
    207         viewer->imgs[0] = str_dup(fname);
    208         if (viewer->imgs[0] == NULL) {
    209                 printf("Out of memory.\n");
    210                 ui_quit(viewer->ui);
    211                 return;
    212         }
    213 
    214         rc = viewer_window_create(viewer);
    215         if (rc != EOK)
    216                 ui_quit(viewer->ui);
    217 
    218         ui_file_dialog_destroy(dialog);
    219         viewer->dialog = NULL;
    220 }
    221 
    222 /** File dialog cancel button press.
    223  *
    224  * @param dialog File dialog
    225  * @param arg Argument (viewer_t *)
    226  */
    227 static void file_dialog_bcancel(ui_file_dialog_t *dialog, void *arg)
    228 {
    229         viewer_t *viewer = (viewer_t *) arg;
    230 
    231         ui_file_dialog_destroy(dialog);
    232         ui_quit(viewer->ui);
    233 }
    234 
    235 /** File dialog close request.
    236  *
    237  * @param dialog File dialog
    238  * @param arg Argument (viewer_t *)
    239  */
    240 static void file_dialog_close(ui_file_dialog_t *dialog, void *arg)
    241 {
    242         viewer_t *viewer = (viewer_t *) arg;
    243 
    244         ui_file_dialog_destroy(dialog);
    245         ui_quit(viewer->ui);
    246 }
    247 
    248 static bool viewer_img_load(viewer_t *viewer, const char *fname,
     130static bool img_load(gfx_context_t *gc, const char *fname,
    249131    gfx_bitmap_t **rbitmap, gfx_rect_t *rect)
    250132{
     
    277159        vfs_put(fd);
    278160
    279         rc = decode_tga(viewer->window_gc, tga, stat.size, rbitmap, rect);
     161        rc = decode_tga(gc, tga, stat.size, rbitmap, rect);
    280162        if (rc != EOK) {
    281163                free(tga);
     
    285167        free(tga);
    286168
    287         viewer->img_rect = *rect;
     169        img_rect = *rect;
    288170        return true;
    289171}
    290172
    291 static bool viewer_img_setup(viewer_t *viewer, gfx_bitmap_t *bmp,
    292     gfx_rect_t *rect)
     173static bool img_setup(gfx_context_t *gc, gfx_bitmap_t *bmp, gfx_rect_t *rect)
    293174{
    294175        gfx_rect_t arect;
     
    297178        errno_t rc;
    298179
    299         ui_res = ui_window_get_res(viewer->window);
    300 
    301         ui_window_get_app_rect(viewer->window, &arect);
     180        ui_res = ui_window_get_res(window);
     181
     182        ui_window_get_app_rect(window, &arect);
    302183
    303184        /* Center image on application area */
    304185        gfx_rect_ctr_on_rect(rect, &arect, &irect);
    305186
    306         if (viewer->image != NULL) {
    307                 ui_image_set_bmp(viewer->image, bmp, rect);
    308                 (void) ui_image_paint(viewer->image);
    309                 ui_image_set_rect(viewer->image, &irect);
     187        if (image != NULL) {
     188                ui_image_set_bmp(image, bmp, rect);
     189                (void) ui_image_paint(image);
     190                ui_image_set_rect(image, &irect);
    310191        } else {
    311                 rc = ui_image_create(ui_res, bmp, rect, &viewer->image);
     192                rc = ui_image_create(ui_res, bmp, rect, &image);
    312193                if (rc != EOK) {
    313194                        gfx_bitmap_destroy(bmp);
     
    315196                }
    316197
    317                 ui_image_set_rect(viewer->image, &irect);
    318                 ui_window_add(viewer->window, ui_image_ctl(viewer->image));
    319         }
    320 
    321         if (viewer->bitmap != NULL)
    322                 gfx_bitmap_destroy(viewer->bitmap);
    323 
    324         viewer->bitmap = bmp;
     198                ui_image_set_rect(image, &irect);
     199                ui_window_add(window, ui_image_ctl(image));
     200        }
     201
     202        if (bitmap != NULL)
     203                gfx_bitmap_destroy(bitmap);
     204
     205        bitmap = bmp;
    325206        return true;
    326207}
     
    333214}
    334215
    335 static errno_t viewer_window_create(viewer_t *viewer)
    336 {
    337         ui_wnd_params_t params;
     216int main(int argc, char *argv[])
     217{
     218        const char *display_spec = UI_DISPLAY_DEFAULT;
    338219        gfx_bitmap_t *lbitmap;
    339220        gfx_rect_t lrect;
     221        bool fullscreen = false;
     222        gfx_rect_t rect;
    340223        gfx_rect_t wrect;
    341224        gfx_coord2_t off;
    342         gfx_rect_t rect;
     225        ui_t *ui;
     226        ui_wnd_params_t params;
     227        viewer_t viewer;
    343228        errno_t rc;
     229        int i;
     230
     231        i = 1;
     232        while (i < argc && argv[i][0] == '-') {
     233                if (str_cmp(argv[i], "-d") == 0) {
     234                        ++i;
     235                        if (i >= argc) {
     236                                printf("Argument missing.\n");
     237                                print_syntax();
     238                                return 1;
     239                        }
     240
     241                        display_spec = argv[i++];
     242                } else if (str_cmp(argv[i], "-f") == 0) {
     243                        ++i;
     244                        fullscreen = true;
     245                } else {
     246                        printf("Invalid option '%s'.\n", argv[i]);
     247                        print_syntax();
     248                        return 1;
     249                }
     250        }
     251
     252        if (i >= argc) {
     253                printf("No image files specified.\n");
     254                print_syntax();
     255                return 1;
     256        }
     257
     258        imgs_count = argc - i;
     259        imgs = calloc(imgs_count, sizeof(char *));
     260        if (imgs == NULL) {
     261                printf("Out of memory.\n");
     262                return 1;
     263        }
     264
     265        for (int j = 0; j < argc - i; j++) {
     266                imgs[j] = str_dup(argv[i + j]);
     267                if (imgs[j] == NULL) {
     268                        printf("Out of memory.\n");
     269                        return 3;
     270                }
     271        }
     272
     273        rc = ui_create(display_spec, &ui);
     274        if (rc != EOK) {
     275                printf("Error creating UI on display %s.\n", display_spec);
     276                return 1;
     277        }
     278
     279        viewer.ui = ui;
    344280
    345281        /*
     
    354290        params.rect.p1.y = 1;
    355291
    356         if (viewer->fullscreen) {
     292        if (fullscreen) {
    357293                params.style &= ~ui_wds_decorated;
    358294                params.placement = ui_wnd_place_full_screen;
    359295        }
    360296
    361         rc = ui_window_create(viewer->ui, &params, &viewer->window);
     297        rc = ui_window_create(ui, &params, &window);
    362298        if (rc != EOK) {
    363299                printf("Error creating window.\n");
    364                 goto error;
    365         }
    366 
    367         viewer->window_gc = ui_window_get_gc(viewer->window);
    368 
    369         ui_window_set_cb(viewer->window, &window_cb, (void *)viewer);
    370 
    371         if (!viewer_img_load(viewer, viewer->imgs[viewer->imgs_current],
    372             &lbitmap, &lrect)) {
    373                 printf("Cannot load image \"%s\".\n",
    374                     viewer->imgs[viewer->imgs_current]);
    375                 goto error;
     300                return 1;
     301        }
     302
     303        window_gc = ui_window_get_gc(window);
     304
     305        ui_window_set_cb(window, &window_cb, (void *) &viewer);
     306
     307        if (!img_load(window_gc, imgs[imgs_current], &lbitmap, &lrect)) {
     308                printf("Cannot load image \"%s\".\n", imgs[imgs_current]);
     309                return 1;
    376310        }
    377311
     
    380314         * to rect
    381315         */
    382         ui_wdecor_rect_from_app(viewer->ui, params.style, &lrect, &wrect);
     316        ui_wdecor_rect_from_app(params.style, &lrect, &wrect);
    383317        off = wrect.p0;
    384318        gfx_rect_rtranslate(&off, &wrect, &rect);
    385319
    386         if (!viewer->fullscreen) {
    387                 rc = ui_window_resize(viewer->window, &rect);
     320        if (!fullscreen) {
     321                rc = ui_window_resize(window, &rect);
    388322                if (rc != EOK) {
    389323                        printf("Error resizing window.\n");
    390                         goto error;
    391                 }
    392         }
    393 
    394         if (!viewer_img_setup(viewer, lbitmap, &lrect)) {
    395                 printf("Cannot setup image \"%s\".\n",
    396                     viewer->imgs[viewer->imgs_current]);
    397                 goto error;
    398         }
    399 
    400         rc = ui_window_paint(viewer->window);
     324                        return 1;
     325                }
     326        }
     327
     328        if (!img_setup(window_gc, lbitmap, &lrect)) {
     329                printf("Cannot setup image \"%s\".\n", imgs[imgs_current]);
     330                return 1;
     331        }
     332
     333        rc = ui_window_paint(window);
    401334        if (rc != EOK) {
    402335                printf("Error painting window.\n");
    403                 goto error;
    404         }
    405 
    406         return EOK;
    407 error:
    408         viewer_window_destroy(viewer);
    409         ui_quit(viewer->ui);
    410         return rc;
    411 }
    412 
    413 static void viewer_window_destroy(viewer_t *viewer)
    414 {
    415         if (viewer->window != NULL)
    416                 ui_window_destroy(viewer->window);
    417         viewer->window = NULL;
    418 }
    419 
    420 int main(int argc, char *argv[])
    421 {
    422         const char *display_spec = UI_ANY_DEFAULT;
    423         ui_t *ui = NULL;
    424         viewer_t *viewer;
    425         errno_t rc;
    426         int i;
    427         unsigned u;
    428         ui_file_dialog_params_t fdparams;
    429 
    430         viewer = calloc(1, sizeof(viewer_t));
    431         if (viewer == NULL) {
    432                 printf("Out of memory.\n");
    433                 goto error;
    434         }
    435 
    436         i = 1;
    437         while (i < argc && argv[i][0] == '-') {
    438                 if (str_cmp(argv[i], "-d") == 0) {
    439                         ++i;
    440                         if (i >= argc) {
    441                                 printf("Argument missing.\n");
    442                                 print_syntax();
    443                                 goto error;
    444                         }
    445 
    446                         display_spec = argv[i++];
    447                 } else if (str_cmp(argv[i], "-f") == 0) {
    448                         ++i;
    449                         viewer->fullscreen = true;
    450                 } else {
    451                         printf("Invalid option '%s'.\n", argv[i]);
    452                         print_syntax();
    453                         goto error;
    454                 }
    455         }
    456 
    457         /* Images specified? */
    458         if (i < argc) {
    459                 viewer->imgs_count = argc - i;
    460                 viewer->imgs = calloc(viewer->imgs_count, sizeof(char *));
    461                 if (viewer->imgs == NULL) {
    462                         printf("Out of memory.\n");
    463                         goto error;
    464                 }
    465 
    466                 for (int j = 0; j < argc - i; j++) {
    467                         viewer->imgs[j] = str_dup(argv[i + j]);
    468                         if (viewer->imgs[j] == NULL) {
    469                                 printf("Out of memory.\n");
    470                                 goto error;
    471                         }
    472                 }
    473         }
    474 
    475         rc = ui_create(display_spec, &ui);
    476         if (rc != EOK) {
    477                 printf("Error creating UI on display %s.\n", display_spec);
    478                 goto error;
    479         }
    480 
    481         if (ui_is_fullscreen(ui))
    482                 viewer->fullscreen = true;
    483 
    484         viewer->ui = ui;
    485 
    486         if (viewer->imgs != NULL) {
    487                 /* We have images, create viewer window. */
    488                 rc = viewer_window_create(viewer);
    489                 if (rc != EOK)
    490                         goto error;
    491         } else {
    492                 /* No images specified, browse for one. */
    493                 ui_file_dialog_params_init(&fdparams);
    494                 fdparams.caption = "Open Image";
    495 
    496                 rc = ui_file_dialog_create(viewer->ui, &fdparams,
    497                     &viewer->dialog);
    498                 if (rc != EOK) {
    499                         printf("Error creating file dialog.\n");
    500                         goto error;
    501                 }
    502 
    503                 ui_file_dialog_set_cb(viewer->dialog, &file_dialog_cb,
    504                     (void *)viewer);
     336                return 1;
    505337        }
    506338
    507339        ui_run(ui);
    508340
    509         ui_window_destroy(viewer->window);
    510         ui_destroy(ui);
    511         free(viewer);
    512 
    513341        return 0;
    514 error:
    515         if (viewer != NULL && viewer->dialog != NULL)
    516                 ui_file_dialog_destroy(viewer->dialog);
    517         if (viewer != NULL && viewer->imgs != NULL) {
    518                 for (u = 0; u < viewer->imgs_count; u++) {
    519                         if (viewer->imgs[i] != NULL)
    520                                 free(viewer->imgs[i]);
    521                 }
    522                 free(viewer->imgs);
    523         }
    524         if (viewer != NULL)
    525                 viewer_window_destroy(viewer);
    526         if (ui != NULL)
    527                 ui_destroy(ui);
    528         if (viewer != NULL)
    529                 free(viewer);
    530         return 1;
    531342}
    532343
Note: See TracChangeset for help on using the changeset viewer.