Changes in / [9e7e1dc:0b44848] in mainline


Ignore:
Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • common/adt/bitmap.c

    r9e7e1dc r0b44848  
    2727 */
    2828
    29 /** @addtogroup kernel_generic_adt
     29/** @addtogroup libc
    3030 * @{
    3131 */
     
    4343#include <assert.h>
    4444#include <macros.h>
    45 #include <typedefs.h>
    4645
    4746#define ALL_ONES    0xff
  • common/include/adt/bitmap.h

    r9e7e1dc r0b44848  
    2727 */
    2828
    29 /** @addtogroup kernel_generic_adt
     29/** @addtogroup libc
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef KERN_BITMAP_H_
    36 #define KERN_BITMAP_H_
     35#ifndef _LIBC_BITMAP_H_
     36#define _LIBC_BITMAP_H_
    3737
    3838#include <stddef.h>
  • uspace/app/tester/meson.build

    r9e7e1dc r0b44848  
    11#
    2 # Copyright (c) 2023 Jiri Svoboda
     2# Copyright (c) 2025 Jiri Svoboda
    33# Copyright (c) 2005 Martin Decky
    44# Copyright (c) 2007 Jakub Jermar
     
    3333        'tester.c',
    3434        'util.c',
     35        'thread/deadlock.c',
    3536        'thread/thread1.c',
    3637        'thread/setjmp1.c',
  • uspace/app/tester/tester.c

    r9e7e1dc r0b44848  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2006 Ondrej Palkovsky
    34 * Copyright (c) 2007 Martin Decky
     
    4950
    5051test_t tests[] = {
     52#include "thread/deadlock.def"
    5153#include "thread/thread1.def"
    5254#include "thread/setjmp1.def"
  • uspace/app/tester/tester.h

    r9e7e1dc r0b44848  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2007 Martin Decky
    34 * All rights reserved.
     
    7980} test_t;
    8081
     82extern const char *test_deadlock(void);
    8183extern const char *test_thread1(void);
    8284extern const char *test_setjmp1(void);
  • uspace/app/uidemo/uidemo.c

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    108108static void uidemo_file_load(ui_menu_entry_t *, void *);
    109109static void uidemo_file_message(ui_menu_entry_t *, void *);
     110static void uidemo_file_confirmation(ui_menu_entry_t *, void *);
    110111static void uidemo_file_exit(ui_menu_entry_t *, void *);
    111112static void uidemo_edit_modify(ui_menu_entry_t *, void *);
     
    340341}
    341342
    342 /** Display a message window.
     343/** Display a message window with OK button.
    343344 *
    344345 * @param demo UI demo
     
    405406        mdparams.caption = "Message For You";
    406407        mdparams.text = "Hello, world!";
     408
     409        rc = ui_msg_dialog_create(demo->ui, &mdparams, &dialog);
     410        if (rc != EOK) {
     411                printf("Error creating message dialog.\n");
     412                return;
     413        }
     414
     415        ui_msg_dialog_set_cb(dialog, &msg_dialog_cb, &demo);
     416}
     417
     418/** File / Confirmation menu entry selected.
     419 *
     420 * @param mentry Menu entry
     421 * @param arg Argument (demo)
     422 */
     423static void uidemo_file_confirmation(ui_menu_entry_t *mentry, void *arg)
     424{
     425        ui_demo_t *demo = (ui_demo_t *) arg;
     426        ui_msg_dialog_params_t mdparams;
     427        ui_msg_dialog_t *dialog;
     428        errno_t rc;
     429
     430        ui_msg_dialog_params_init(&mdparams);
     431        mdparams.caption = "Confirmation";
     432        mdparams.text = "This will not actually do anything. Proceed?";
     433        mdparams.choice = umdc_ok_cancel;
    407434
    408435        rc = ui_msg_dialog_create(demo->ui, &mdparams, &dialog);
     
    782809        ui_menu_entry_set_cb(mmsg, uidemo_file_message, (void *) &demo);
    783810
     811        rc = ui_menu_entry_create(demo.mfile, "~C~onfirmation", "", &mmsg);
     812        if (rc != EOK) {
     813                printf("Error creating menu.\n");
     814                return rc;
     815        }
     816
     817        ui_menu_entry_set_cb(mmsg, uidemo_file_confirmation, (void *) &demo);
     818
    784819        rc = ui_menu_entry_create(demo.mfile, "~L~oad", "", &mload);
    785820        if (rc != EOK) {
  • uspace/lib/c/generic/thread/fibril_synch.c

    r9e7e1dc r0b44848  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2009 Jakub Jermar
    34 * All rights reserved.
     
    112113#define AWAITER_INIT { .fid = fibril_get_id() }
    113114
    114 static void print_deadlock(fibril_owner_info_t *oi)
     115/** Print deadlock message nad blocking chain.
     116 *
     117 * @param oi Owner info for the resource being acquired
     118 * @param f Fibril that is trying to acquire the resource
     119 */
     120static void print_deadlock(fibril_owner_info_t *oi, fibril_t *f)
    115121{
    116122        // FIXME: Print to stderr.
    117 
    118         fibril_t *f = (fibril_t *) fibril_get_id();
    119123
    120124        if (deadlocked) {
     
    143147}
    144148
    145 static void check_fibril_for_deadlock(fibril_owner_info_t *oi, fibril_t *fib)
    146 {
     149/** Check whether fibril trying to acquire a resource will cause deadlock.
     150 *
     151 * @param wanted_oi Owner info for the primitive that the fibril wants
     152 * @param fib Fibril that wants to aquire the primitive
     153 */
     154static void check_fibril_for_deadlock(fibril_owner_info_t *wanted_oi,
     155    fibril_t *fib)
     156{
     157        fibril_owner_info_t *oi;
     158
    147159        futex_assert_is_locked(&fibril_synch_futex);
    148160
     161        oi = wanted_oi;
    149162        while (oi && oi->owned_by) {
    150163                if (oi->owned_by == fib) {
    151164                        futex_unlock(&fibril_synch_futex);
    152                         print_deadlock(oi);
     165                        print_deadlock(wanted_oi, fib);
    153166                        abort();
    154167                }
     
    157170}
    158171
     172/** Check whether trying to acquire a resource will cause deadlock.
     173 *
     174 * @param oi Owner info for the primitive that the current fibril wants
     175 */
    159176static void check_for_deadlock(fibril_owner_info_t *oi)
    160177{
  • uspace/lib/c/meson.build

    r9e7e1dc r0b44848  
    5959
    6060src += files(
     61        'common/adt/bitmap.c',
    6162        'common/adt/checksum.c',
    6263        'common/adt/circ_buf.c',
  • uspace/lib/display/include/display.h

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4848extern errno_t display_open(const char *, display_t **);
    4949extern void display_close(display_t *);
     50extern void display_lock(display_t *);
     51extern void display_unlock(display_t *);
    5052extern errno_t display_get_info(display_t *, display_info_t *);
    5153
  • uspace/lib/display/src/display.c

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    138138}
    139139
     140/*
     141 * Lock display.
     142 *
     143 * While display is locked, display event handlers will not be called.
     144 *
     145 * @param display Display
     146 */
     147void display_lock(display_t *display)
     148{
     149        fibril_mutex_lock(&display->lock);
     150}
     151
     152/*
     153 * Unlock display.
     154 *
     155 * @param display Display
     156 */
     157void display_unlock(display_t *display)
     158{
     159        fibril_mutex_unlock(&display->lock);
     160}
     161
    140162/** Initialize window parameters structure.
    141163 *
     
    700722        display_wnd_ev_t event;
    701723
     724        display_lock(display);
     725
    702726        while (true) {
    703                 fibril_mutex_lock(&display->lock);
    704 
    705727                if (display->sess != NULL)
    706728                        rc = display_get_event(display, &window, &event);
    707729                else
    708730                        rc = ENOENT;
    709 
    710                 fibril_mutex_unlock(&display->lock);
    711731
    712732                if (rc != EOK)
     
    752772        }
    753773
     774        display_unlock(display);
    754775        async_answer_0(icall, EOK);
    755776}
  • uspace/lib/ui/include/types/ui/msgdialog.h

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4545typedef struct ui_msg_dialog ui_msg_dialog_t;
    4646
     47enum {
     48        /** Maximum number of buttons in message dialog. */
     49        ui_msg_dialog_maxbtn = 2
     50};
     51
     52/** Which choices the user can select from. */
     53typedef enum {
     54        /** OK (the default) */
     55        umdc_ok,
     56        /** OK, Cancel */
     57        umdc_ok_cancel
     58} ui_msg_dialog_choice_t;
     59
    4760/** Message dialog parameters */
    4861typedef struct {
     
    5164        /** Message text */
    5265        const char *text;
     66        /** The choice that the user is given */
     67        ui_msg_dialog_choice_t choice;
    5368} ui_msg_dialog_params_t;
    5469
  • uspace/lib/ui/private/msgdialog.h

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#define _UI_PRIVATE_MSGDIALOG_H
    3939
     40#include <types/ui/msgdialog.h>
     41#include <ui/pbutton.h>
     42#include <ui/window.h>
     43
    4044/** Actual structure of message dialog.
    4145 *
     
    4549        /** Dialog window */
    4650        struct ui_window *window;
    47         /** OK button */
    48         struct ui_pbutton *bok;
     51        /** Buttons */
     52        struct ui_pbutton *btn[ui_msg_dialog_maxbtn];
    4953        /** Message dialog callbacks */
    5054        struct ui_msg_dialog_cb *cb;
  • uspace/lib/ui/src/filedialog.c

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    396396 *
    397397 * @param window Window
    398  * @param arg Argument (ui_prompt_dialog_t *)
     398 * @param arg Argument (ui_file_dialog_t *)
    399399 * @param event Keyboard event
    400400 */
     
    427427                }
    428428        }
    429 
    430429}
    431430
  • uspace/lib/ui/src/msgdialog.c

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4747
    4848static void ui_msg_dialog_wnd_close(ui_window_t *, void *);
     49static void ui_msg_dialog_wnd_kbd(ui_window_t *, void *, kbd_event_t *);
    4950
    5051ui_window_cb_t ui_msg_dialog_wnd_cb = {
    51         .close = ui_msg_dialog_wnd_close
     52        .close = ui_msg_dialog_wnd_close,
     53        .kbd = ui_msg_dialog_wnd_kbd
    5254};
    5355
     
    5658ui_pbutton_cb_t ui_msg_dialog_btn_cb = {
    5759        .clicked = ui_msg_dialog_btn_clicked
     60};
     61
     62static const char *ui_msg_dialog_captions[][ui_msg_dialog_maxbtn + 1] = {
     63        [umdc_ok] = { "OK", NULL },
     64        [umdc_ok_cancel] = { "OK", "Cancel", NULL }
    5865};
    5966
     
    8693        ui_fixed_t *fixed = NULL;
    8794        ui_label_t *label = NULL;
    88         ui_pbutton_t *bok = NULL;
     95        ui_pbutton_t *btn[ui_msg_dialog_maxbtn];
     96        const char **cp;
     97        unsigned i, nb;
    8998        gfx_rect_t rect;
     99        gfx_coord_t bw, bpad, btnsw, bp0x;
    90100        ui_resource_t *ui_res;
     101
     102        for (i = 0; i < ui_msg_dialog_maxbtn; i++)
     103                btn[i] = NULL;
    91104
    92105        dialog = calloc(1, sizeof(ui_msg_dialog_t));
     
    103116                wparams.rect.p0.x = 0;
    104117                wparams.rect.p0.y = 0;
    105                 wparams.rect.p1.x = 40;
     118                wparams.rect.p1.x = 60;
    106119                wparams.rect.p1.y = 7;
    107120        } else {
    108121                wparams.rect.p0.x = 0;
    109122                wparams.rect.p0.y = 0;
    110                 wparams.rect.p1.x = 200;
     123                wparams.rect.p1.x = 400;
    111124                wparams.rect.p1.y = 110;
    112125        }
     
    132145                rect.p0.x = 3;
    133146                rect.p0.y = 2;
    134                 rect.p1.x = 17;
     147                rect.p1.x = 57;
    135148                rect.p1.y = 3;
    136149        } else {
    137150                rect.p0.x = 10;
    138151                rect.p0.y = 35;
    139                 rect.p1.x = 190;
     152                rect.p1.x = 390;
    140153                rect.p1.y = 50;
    141154        }
     
    150163        label = NULL;
    151164
    152         rc = ui_pbutton_create(ui_res, "OK", &bok);
    153         if (rc != EOK)
    154                 goto error;
    155 
    156         ui_pbutton_set_cb(bok, &ui_msg_dialog_btn_cb, dialog);
    157 
    158         /* FIXME: Auto layout */
     165        i = 0;
     166        assert(params->choice == umdc_ok || params->choice == umdc_ok_cancel);
     167        cp = ui_msg_dialog_captions[params->choice];
     168
     169        while (*cp != NULL) {
     170                rc = ui_pbutton_create(ui_res, *cp, &btn[i]);
     171                if (rc != EOK)
     172                        goto error;
     173
     174                ui_pbutton_set_cb(btn[i], &ui_msg_dialog_btn_cb, dialog);
     175                ++cp;
     176                ++i;
     177        }
     178
     179        nb = i;
     180
    159181        if (ui_is_textmode(ui)) {
    160                 rect.p0.x = 8;
    161                 rect.p0.y = 4;
    162                 rect.p1.x = 12;
    163                 rect.p1.y = 5;
     182                bw = 12;
     183                bpad = 2;
    164184        } else {
    165                 rect.p0.x = 55;
    166                 rect.p0.y = 60;
    167                 rect.p1.x = 145;
    168                 rect.p1.y = 88;
    169         }
    170 
    171         ui_pbutton_set_rect(bok, &rect);
    172 
    173         ui_pbutton_set_default(bok, true);
    174 
    175         rc = ui_fixed_add(fixed, ui_pbutton_ctl(bok));
    176         if (rc != EOK)
    177                 goto error;
    178 
    179         dialog->bok = bok;
    180         bok = NULL;
     185                bw = 90;
     186                bpad = 10;
     187        }
     188
     189        btnsw = (nb - 1) * (bw + bpad) + bw;
     190        bp0x = (wparams.rect.p0.x + wparams.rect.p1.x - btnsw) / 2;
     191
     192        for (i = 0; i < nb; i++) {
     193                /* FIXME: Auto layout */
     194                if (ui_is_textmode(ui)) {
     195                        rect.p0.x = bp0x + i * (bw + bpad);
     196                        rect.p0.y = 4;
     197                        rect.p1.x = bp0x + bw + i * (bw + bpad);
     198                        rect.p1.y = 5;
     199                } else {
     200                        rect.p0.x = bp0x + i * (bw + bpad);
     201                        rect.p0.y = 60;
     202                        rect.p1.x = bp0x + bw + i * (bw + bpad);
     203                        rect.p1.y = 88;
     204                }
     205
     206                ui_pbutton_set_rect(btn[i], &rect);
     207
     208                rc = ui_fixed_add(fixed, ui_pbutton_ctl(btn[i]));
     209                if (rc != EOK)
     210                        goto error;
     211        }
     212
     213        ui_pbutton_set_default(btn[0], true);
     214
     215        for (i = 0; i < ui_msg_dialog_maxbtn; i++) {
     216                dialog->btn[i] = btn[i];
     217                btn[i] = NULL;
     218        }
    181219
    182220        ui_window_add(window, ui_fixed_ctl(fixed));
     
    191229        return EOK;
    192230error:
    193         if (bok != NULL)
    194                 ui_pbutton_destroy(bok);
     231        for (i = 0; i < ui_msg_dialog_maxbtn; i++) {
     232                if (btn[i] != NULL)
     233                        ui_pbutton_destroy(btn[i]);
     234        }
    195235        if (label != NULL)
    196236                ui_label_destroy(label);
     
    243283}
    244284
     285/** Message dialog window keyboard event handler.
     286 *
     287 * @param window Window
     288 * @param arg Argument (ui_msg_dialog_t *)
     289 * @param event Keyboard event
     290 */
     291static void ui_msg_dialog_wnd_kbd(ui_window_t *window, void *arg,
     292    kbd_event_t *event)
     293{
     294        ui_msg_dialog_t *dialog = (ui_msg_dialog_t *) arg;
     295        ui_evclaim_t claim;
     296
     297        claim = ui_window_def_kbd(window, event);
     298        if (claim == ui_claimed)
     299                return;
     300
     301        if (event->type == KEY_PRESS &&
     302            (event->mods & (KM_CTRL | KM_SHIFT | KM_ALT)) == 0) {
     303                if (event->key == KC_ENTER) {
     304                        /* OK / default button */
     305                        if (dialog->cb != NULL && dialog->cb->button != NULL) {
     306                                dialog->cb->button(dialog, dialog->arg, 0);
     307                                return;
     308                        }
     309                } else if (event->key == KC_ESCAPE) {
     310                        /* Cancel */
     311                        if (dialog->cb != NULL && dialog->cb->close != NULL) {
     312                                dialog->cb->close(dialog, dialog->arg);
     313                                return;
     314                        }
     315                }
     316        }
     317
     318}
     319
    245320/** Message dialog button click handler.
    246321 *
     
    251326{
    252327        ui_msg_dialog_t *dialog = (ui_msg_dialog_t *) arg;
    253 
    254         if (dialog->cb != NULL && dialog->cb->button != NULL)
    255                 dialog->cb->button(dialog, dialog->arg, 0);
     328        unsigned i;
     329
     330        if (dialog->cb != NULL && dialog->cb->button != NULL) {
     331                for (i = 0; i < ui_msg_dialog_maxbtn; i++) {
     332                        if (dialog->btn[i] == pbutton)
     333                                dialog->cb->button(dialog, dialog->arg, i);
     334                }
     335        }
    256336}
    257337
  • uspace/lib/ui/src/ui.c

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    568568void ui_lock(ui_t *ui)
    569569{
     570        if (ui->display != NULL)
     571                display_lock(ui->display);
    570572        fibril_mutex_lock(&ui->lock);
    571573}
     
    582584{
    583585        fibril_mutex_unlock(&ui->lock);
     586        if (ui->display != NULL)
     587                display_unlock(ui->display);
    584588}
    585589
  • uspace/lib/ui/src/window.c

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    978978        ui_t *ui = window->ui;
    979979
    980         ui_lock(ui);
     980        fibril_mutex_lock(&ui->lock);
    981981        ui_window_send_close(window);
    982         ui_unlock(ui);
     982        fibril_mutex_unlock(&ui->lock);
    983983}
    984984
     
    989989        ui_t *ui = window->ui;
    990990
    991         ui_lock(ui);
     991        fibril_mutex_lock(&ui->lock);
    992992        (void)nfocus;
    993993
     
    998998
    999999        ui_window_send_focus(window, nfocus);
    1000         ui_unlock(ui);
     1000        fibril_mutex_unlock(&ui->lock);
    10011001}
    10021002
     
    10071007        ui_t *ui = window->ui;
    10081008
    1009         ui_lock(ui);
     1009        fibril_mutex_lock(&ui->lock);
    10101010        ui_window_send_kbd(window, kbd_event);
    1011         ui_unlock(ui);
     1011        fibril_mutex_unlock(&ui->lock);
    10121012}
    10131013
     
    10231023                return;
    10241024
    1025         ui_lock(ui);
     1025        fibril_mutex_lock(&ui->lock);
    10261026
    10271027        claim = ui_wdecor_pos_event(window->wdecor, event);
    10281028        if (claim == ui_claimed) {
    1029                 ui_unlock(ui);
     1029                fibril_mutex_unlock(&ui->lock);
    10301030                return;
    10311031        }
    10321032
    10331033        ui_window_send_pos(window, event);
    1034         ui_unlock(ui);
     1034        fibril_mutex_unlock(&ui->lock);
    10351035}
    10361036
     
    10481048                return;
    10491049
    1050         ui_lock(ui);
     1050        fibril_mutex_lock(&ui->lock);
    10511051        (void) ui_window_resize(window, rect);
    10521052        ui_window_send_resize(window);
    1053         ui_unlock(ui);
     1053        fibril_mutex_unlock(&ui->lock);
    10541054}
    10551055
     
    10601060        ui_t *ui = window->ui;
    10611061
    1062         ui_lock(ui);
     1062        fibril_mutex_lock(&ui->lock);
    10631063
    10641064        if (window->wdecor != NULL && nfocus == 0) {
     
    10681068
    10691069        ui_window_send_unfocus(window, nfocus);
    1070         ui_unlock(ui);
     1070        fibril_mutex_unlock(&ui->lock);
    10711071}
    10721072
  • uspace/lib/ui/test/msgdialog.c

    r9e7e1dc r0b44848  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    9292        ui_msg_dialog_params_t params;
    9393        ui_msg_dialog_t *dialog = NULL;
     94        unsigned i;
    9495        test_cb_resp_t resp;
    9596
     
    100101        params.caption = "Message";
    101102        params.text = "Hello";
     103        params.choice = umdc_ok_cancel;
    102104
    103105        rc = ui_msg_dialog_create(ui, &params, &dialog);
     
    106108
    107109        /* Button callback with no callbacks set */
    108         ui_pbutton_clicked(dialog->bok);
     110        ui_pbutton_clicked(dialog->btn[0]);
    109111
    110112        /* Button callback with callback not implemented */
    111113        ui_msg_dialog_set_cb(dialog, &dummy_msg_dialog_cb, NULL);
    112         ui_pbutton_clicked(dialog->bok);
     114        ui_pbutton_clicked(dialog->btn[0]);
    113115
    114         /* Button callback with real callback set */
    115         resp.button = false;
    116         resp.bnum = 123;
    117         ui_msg_dialog_set_cb(dialog, &test_msg_dialog_cb, &resp);
    118         ui_pbutton_clicked(dialog->bok);
    119         PCUT_ASSERT_TRUE(resp.button);
    120         PCUT_ASSERT_INT_EQUALS(0, resp.bnum);
     116        for (i = 0; i < 2; i++) {
     117                /* Button callback with real callback set */
     118                resp.button = false;
     119                resp.bnum = 123;
     120                ui_msg_dialog_set_cb(dialog, &test_msg_dialog_cb, &resp);
     121                ui_pbutton_clicked(dialog->btn[i]);
     122                PCUT_ASSERT_TRUE(resp.button);
     123                PCUT_ASSERT_INT_EQUALS(i, resp.bnum);
     124        }
    121125
    122126        ui_msg_dialog_destroy(dialog);
Note: See TracChangeset for help on using the changeset viewer.