Changeset 34aad53d in mainline for uspace/app/viewer/viewer.c


Ignore:
Timestamp:
2024-04-07T09:45:45Z (6 weeks ago)
Author:
Nataliia Korop <n.corop08@…>
Children:
c37c24c
Parents:
e4cc266 (diff), 522eecf (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge master to topic/packet-capture

File:
1 edited

Legend:

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

    re4cc266 r34aad53d  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2024 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>
    4243#include <ui/image.h>
    4344#include <ui/ui.h>
     
    5051typedef struct {
    5152        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;
    5266} viewer_t;
    5367
    54 static size_t imgs_count;
    55 static size_t imgs_current = 0;
    56 static char **imgs;
    57 
    58 static ui_window_t *window;
    59 static gfx_bitmap_t *bitmap = NULL;
    60 static ui_image_t *image = NULL;
    61 static gfx_context_t *window_gc;
    62 
    63 static gfx_rect_t img_rect;
    64 
    65 static bool img_load(gfx_context_t *gc, const char *, gfx_bitmap_t **,
     68static bool viewer_img_load(viewer_t *, const char *, gfx_bitmap_t **,
    6669    gfx_rect_t *);
    67 static bool img_setup(gfx_context_t *, gfx_bitmap_t *, gfx_rect_t *);
     70static bool viewer_img_setup(viewer_t *, gfx_bitmap_t *, gfx_rect_t *);
     71static errno_t viewer_window_create(viewer_t *);
     72static void viewer_window_destroy(viewer_t *);
    6873
    6974static void wnd_close(ui_window_t *, void *);
     
    7580};
    7681
     82static void file_dialog_bok(ui_file_dialog_t *, void *, const char *);
     83static void file_dialog_bcancel(ui_file_dialog_t *, void *);
     84static void file_dialog_close(ui_file_dialog_t *, void *);
     85
     86static 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
    7792/** Window close request
    7893 *
     
    87102}
    88103
    89 static void wnd_kbd_event(ui_window_t *window, void *arg,
    90     kbd_event_t *event)
     104/** Viewer unmodified key press.
     105 *
     106 * @param viewer Viewer
     107 * @param event Keyboard event
     108 */
     109static void viewer_kbd_event_unmod(viewer_t *viewer, kbd_event_t *event)
    91110{
    92111        bool update = false;
    93112
    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;
     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;
    100119                else
    101                         imgs_current++;
     120                        viewer->imgs_current++;
    102121
    103122                update = true;
    104123        }
    105124
    106         if ((event->type == KEY_PRESS) && (event->key == KC_PAGE_UP)) {
    107                 if (imgs_current == 0)
    108                         imgs_current = imgs_count - 1;
     125        if (event->key == KC_PAGE_UP) {
     126                if (viewer->imgs_current == 0)
     127                        viewer->imgs_current = viewer->imgs_count - 1;
    109128                else
    110                         imgs_current--;
     129                        viewer->imgs_current--;
    111130
    112131                update = true;
     
    117136                gfx_rect_t lrect;
    118137
    119                 if (!img_load(window_gc, imgs[imgs_current], &lbitmap, &lrect)) {
    120                         printf("Cannot load image \"%s\".\n", imgs[imgs_current]);
     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]);
    121142                        exit(4);
    122143                }
    123                 if (!img_setup(window_gc, lbitmap, &lrect)) {
    124                         printf("Cannot setup image \"%s\".\n", imgs[imgs_current]);
     144                if (!viewer_img_setup(viewer, lbitmap, &lrect)) {
     145                        printf("Cannot setup image \"%s\".\n",
     146                            viewer->imgs[viewer->imgs_current]);
    125147                        exit(6);
    126148                }
     
    128150}
    129151
    130 static bool img_load(gfx_context_t *gc, const char *fname,
     152/** Viewer ctrl-key key press.
     153 *
     154 * @param viewer Viewer
     155 * @param event Keyboard event
     156 */
     157static 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 */
     169static 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 */
     193static 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 */
     227static 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 */
     240static 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
     248static bool viewer_img_load(viewer_t *viewer, const char *fname,
    131249    gfx_bitmap_t **rbitmap, gfx_rect_t *rect)
    132250{
     
    159277        vfs_put(fd);
    160278
    161         rc = decode_tga(gc, tga, stat.size, rbitmap, rect);
     279        rc = decode_tga(viewer->window_gc, tga, stat.size, rbitmap, rect);
    162280        if (rc != EOK) {
    163281                free(tga);
     
    167285        free(tga);
    168286
    169         img_rect = *rect;
     287        viewer->img_rect = *rect;
    170288        return true;
    171289}
    172290
    173 static bool img_setup(gfx_context_t *gc, gfx_bitmap_t *bmp, gfx_rect_t *rect)
     291static bool viewer_img_setup(viewer_t *viewer, gfx_bitmap_t *bmp,
     292    gfx_rect_t *rect)
    174293{
    175294        gfx_rect_t arect;
     
    178297        errno_t rc;
    179298
    180         ui_res = ui_window_get_res(window);
    181 
    182         ui_window_get_app_rect(window, &arect);
     299        ui_res = ui_window_get_res(viewer->window);
     300
     301        ui_window_get_app_rect(viewer->window, &arect);
    183302
    184303        /* Center image on application area */
    185304        gfx_rect_ctr_on_rect(rect, &arect, &irect);
    186305
    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);
     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);
    191310        } else {
    192                 rc = ui_image_create(ui_res, bmp, rect, &image);
     311                rc = ui_image_create(ui_res, bmp, rect, &viewer->image);
    193312                if (rc != EOK) {
    194313                        gfx_bitmap_destroy(bmp);
     
    196315                }
    197316
    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;
     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;
    206325        return true;
    207326}
     
    214333}
    215334
    216 int main(int argc, char *argv[])
    217 {
    218         const char *display_spec = UI_DISPLAY_DEFAULT;
     335static errno_t viewer_window_create(viewer_t *viewer)
     336{
     337        ui_wnd_params_t params;
    219338        gfx_bitmap_t *lbitmap;
    220339        gfx_rect_t lrect;
    221         bool fullscreen = false;
    222         gfx_rect_t rect;
    223340        gfx_rect_t wrect;
    224341        gfx_coord2_t off;
    225         ui_t *ui;
    226         ui_wnd_params_t params;
    227         viewer_t viewer;
     342        gfx_rect_t rect;
    228343        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;
    280344
    281345        /*
     
    290354        params.rect.p1.y = 1;
    291355
    292         if (fullscreen) {
     356        if (viewer->fullscreen) {
    293357                params.style &= ~ui_wds_decorated;
    294358                params.placement = ui_wnd_place_full_screen;
    295359        }
    296360
    297         rc = ui_window_create(ui, &params, &window);
     361        rc = ui_window_create(viewer->ui, &params, &viewer->window);
    298362        if (rc != EOK) {
    299363                printf("Error creating window.\n");
    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;
     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;
    310376        }
    311377
     
    314380         * to rect
    315381         */
    316         ui_wdecor_rect_from_app(params.style, &lrect, &wrect);
     382        ui_wdecor_rect_from_app(viewer->ui, params.style, &lrect, &wrect);
    317383        off = wrect.p0;
    318384        gfx_rect_rtranslate(&off, &wrect, &rect);
    319385
    320         if (!fullscreen) {
    321                 rc = ui_window_resize(window, &rect);
     386        if (!viewer->fullscreen) {
     387                rc = ui_window_resize(viewer->window, &rect);
    322388                if (rc != EOK) {
    323389                        printf("Error resizing window.\n");
    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);
     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);
    334401        if (rc != EOK) {
    335402                printf("Error painting window.\n");
    336                 return 1;
     403                goto error;
     404        }
     405
     406        return EOK;
     407error:
     408        viewer_window_destroy(viewer);
     409        ui_quit(viewer->ui);
     410        return rc;
     411}
     412
     413static 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
     420int 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);
    337505        }
    338506
    339507        ui_run(ui);
    340508
     509        ui_window_destroy(viewer->window);
     510        ui_destroy(ui);
     511        free(viewer);
     512
    341513        return 0;
     514error:
     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;
    342531}
    343532
Note: See TracChangeset for help on using the changeset viewer.