source: mainline/uspace/app/nav/nav.c@ 1ec732a

Last change on this file since 1ec732a was 1ec732a, checked in by Jiri Svoboda <jiri@…>, 3 weeks ago

Verify file - navigator operation and command-line utility.

  • Property mode set to 100644
File size: 18.4 KB
RevLine 
[748c8bd]1/*
[accdf882]2 * Copyright (c) 2025 Jiri Svoboda
[748c8bd]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup nav
30 * @{
31 */
32/** @file Navigator.
33 *
34 * HelenOS file manager.
35 */
36
[c111da2]37#include <fibril.h>
[bb4d0b5]38#include <fmgt.h>
[748c8bd]39#include <gfx/coord.h>
40#include <stdio.h>
[5d466a1]41#include <stdlib.h>
[748c8bd]42#include <str.h>
[bb4d0b5]43#include <str_error.h>
[accdf882]44#include <task.h>
[748c8bd]45#include <ui/fixed.h>
[54ddb59]46#include <ui/filelist.h>
[748c8bd]47#include <ui/resource.h>
48#include <ui/ui.h>
49#include <ui/window.h>
[bb4d0b5]50#include "dlg/ioerrdlg.h"
[5d466a1]51#include "menu.h"
[f9c4c433]52#include "newfile.h"
[748c8bd]53#include "nav.h"
[b36ebb42]54#include "panel.h"
[1ec732a]55#include "verify.h"
[748c8bd]56
[accdf882]57#define EDITOR_CMD "/app/edit"
58
[748c8bd]59static void wnd_close(ui_window_t *, void *);
[9f7e9bb]60static void wnd_kbd(ui_window_t *, void *, kbd_event_t *);
[748c8bd]61
62static ui_window_cb_t window_cb = {
[9f7e9bb]63 .close = wnd_close,
64 .kbd = wnd_kbd
[748c8bd]65};
66
[f9c4c433]67static void navigator_file_new_file(void *);
[f59212cc]68static void navigator_file_open(void *);
[accdf882]69static void navigator_file_edit(void *);
[1ec732a]70static void navigator_file_verify(void *);
[f59212cc]71static void navigator_file_exit(void *);
72
73static nav_menu_cb_t navigator_menu_cb = {
[f9c4c433]74 .file_new_file = navigator_file_new_file,
[f59212cc]75 .file_open = navigator_file_open,
[accdf882]76 .file_edit = navigator_file_edit,
[1ec732a]77 .file_verify = navigator_file_verify,
[f59212cc]78 .file_exit = navigator_file_exit
79};
80
[39ab17c]81static void navigator_panel_activate_req(void *, panel_t *);
[b336bfd8]82static void navigator_panel_file_open(void *, panel_t *, const char *);
[39ab17c]83
84static panel_cb_t navigator_panel_cb = {
[b336bfd8]85 .activate_req = navigator_panel_activate_req,
86 .file_open = navigator_panel_file_open
[39ab17c]87};
88
[c3db721]89static void navigator_progress_babort(progress_dlg_t *, void *);
90static void navigator_progress_close(progress_dlg_t *, void *);
91
92progress_dlg_cb_t navigator_progress_cb = {
93 .babort = navigator_progress_babort,
94 .close = navigator_progress_close
95};
96
[bb4d0b5]97static void navigator_io_err_abort(io_err_dlg_t *, void *);
98static void navigator_io_err_retry(io_err_dlg_t *, void *);
99static void navigator_io_err_close(io_err_dlg_t *, void *);
100
101static io_err_dlg_cb_t navigator_io_err_dlg_cb = {
102 .babort = navigator_io_err_abort,
103 .bretry = navigator_io_err_retry,
104 .close = navigator_io_err_close
105};
106
[748c8bd]107/** Window close button was clicked.
108 *
109 * @param window Window
110 * @param arg Argument (navigator)
111 */
112static void wnd_close(ui_window_t *window, void *arg)
113{
114 navigator_t *navigator = (navigator_t *) arg;
115
116 ui_quit(navigator->ui);
117}
118
[9f7e9bb]119/** Window keyboard event handler.
120 *
121 * @param window Window
122 * @param arg Argument (navigator)
123 * @param event Keyboard event
124 */
125static void wnd_kbd(ui_window_t *window, void *arg, kbd_event_t *event)
126{
127 navigator_t *navigator = (navigator_t *) arg;
128
129 if (event->type == KEY_PRESS &&
130 ((event->mods & KM_ALT) == 0) &&
131 ((event->mods & KM_SHIFT) == 0) &&
132 (event->mods & KM_CTRL) != 0) {
[692c7f40]133 switch (event->key) {
[f9c4c433]134 case KC_M:
135 navigator_new_file_dlg(navigator);
136 break;
[accdf882]137 case KC_E:
138 navigator_file_edit((void *)navigator);
139 break;
[1ec732a]140 case KC_V:
141 navigator_file_verify((void *)navigator);
142 break;
[692c7f40]143 case KC_Q:
[9f7e9bb]144 ui_quit(navigator->ui);
[692c7f40]145 break;
146 default:
147 break;
148 }
149 }
150
151 if (event->type == KEY_PRESS &&
152 ((event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0)) {
153 switch (event->key) {
154 case KC_TAB:
155 navigator_switch_panel(navigator);
156 break;
157 default:
158 break;
159 }
[9f7e9bb]160 }
161
162 ui_window_def_kbd(window, event);
163}
164
[5d466a1]165/** Create navigator.
166 *
167 * @param display_spec Display specification
168 * @param rnavigator Place to store pointer to new navigator
169 * @return EOK on success or ane error code
170 */
[6aa85c1]171errno_t navigator_create(const char *display_spec,
[5d466a1]172 navigator_t **rnavigator)
[748c8bd]173{
[5d466a1]174 navigator_t *navigator;
[748c8bd]175 ui_wnd_params_t params;
[b36ebb42]176 gfx_rect_t rect;
[8edec53]177 gfx_rect_t arect;
178 gfx_coord_t pw;
[b36ebb42]179 unsigned i;
[748c8bd]180 errno_t rc;
181
[5d466a1]182 navigator = calloc(1, sizeof(navigator_t));
183 if (navigator == NULL)
184 return ENOMEM;
185
186 rc = ui_create(display_spec, &navigator->ui);
[748c8bd]187 if (rc != EOK) {
188 printf("Error creating UI on display %s.\n", display_spec);
[5d466a1]189 goto error;
[748c8bd]190 }
191
192 ui_wnd_params_init(&params);
193 params.caption = "Navigator";
[5d466a1]194 params.style &= ~ui_wds_decorated;
195 params.placement = ui_wnd_place_full_screen;
[748c8bd]196
[5d466a1]197 rc = ui_window_create(navigator->ui, &params, &navigator->window);
[748c8bd]198 if (rc != EOK) {
199 printf("Error creating window.\n");
[5d466a1]200 goto error;
[748c8bd]201 }
202
[5d466a1]203 ui_window_set_cb(navigator->window, &window_cb, (void *) navigator);
[8edec53]204 ui_window_get_app_rect(navigator->window, &arect);
[748c8bd]205
[5d466a1]206 rc = ui_fixed_create(&navigator->fixed);
[748c8bd]207 if (rc != EOK) {
208 printf("Error creating fixed layout.\n");
[5d466a1]209 goto error;
[748c8bd]210 }
211
[5d466a1]212 ui_window_add(navigator->window, ui_fixed_ctl(navigator->fixed));
[748c8bd]213
[6aa85c1]214 rc = nav_menu_create(navigator->window, &navigator->menu);
[5d466a1]215 if (rc != EOK)
216 goto error;
[748c8bd]217
[f59212cc]218 nav_menu_set_cb(navigator->menu, &navigator_menu_cb,
219 (void *)navigator);
220
[6aa85c1]221 rc = ui_fixed_add(navigator->fixed, nav_menu_ctl(navigator->menu));
222 if (rc != EOK) {
223 printf("Error adding control to layout.\n");
224 return rc;
225 }
226
[8edec53]227 /* Panel width */
228 pw = (arect.p1.x - arect.p0.x) / 2;
229
[b36ebb42]230 for (i = 0; i < 2; i++) {
[692c7f40]231 rc = panel_create(navigator->window, i == 0,
232 &navigator->panel[i]);
[b36ebb42]233 if (rc != EOK)
234 goto error;
235
[8edec53]236 rect.p0.x = arect.p0.x + pw * i;
237 rect.p0.y = arect.p0.y + 1;
238 rect.p1.x = arect.p0.x + pw * (i + 1);
239 rect.p1.y = arect.p1.y - 1;
[b36ebb42]240 panel_set_rect(navigator->panel[i], &rect);
241
[39ab17c]242 panel_set_cb(navigator->panel[i], &navigator_panel_cb,
243 navigator);
244
[b36ebb42]245 rc = ui_fixed_add(navigator->fixed,
246 panel_ctl(navigator->panel[i]));
247 if (rc != EOK) {
248 printf("Error adding control to layout.\n");
[0e80e40]249 goto error;
250 }
251
252 rc = panel_read_dir(navigator->panel[i], ".");
253 if (rc != EOK) {
254 printf("Error reading directory.\n");
255 goto error;
[b36ebb42]256 }
257 }
258
[5d466a1]259 rc = ui_window_paint(navigator->window);
[748c8bd]260 if (rc != EOK) {
[5d466a1]261 printf("Error painting window.\n");
262 goto error;
[748c8bd]263 }
264
[bb4d0b5]265 fibril_mutex_initialize(&navigator->io_err_act_lock);
266 fibril_condvar_initialize(&navigator->io_err_act_cv);
267 navigator->io_err_act_sel = false;
268
[5d466a1]269 *rnavigator = navigator;
270 return EOK;
271error:
272 navigator_destroy(navigator);
273 return rc;
274}
[748c8bd]275
[6aa85c1]276void navigator_destroy(navigator_t *navigator)
[5d466a1]277{
[b36ebb42]278 unsigned i;
279
280 for (i = 0; i < 2; i++) {
[1aa8c86]281 if (navigator->panel[i] != NULL) {
282 ui_fixed_remove(navigator->fixed,
283 panel_ctl(navigator->panel[i]));
284 panel_destroy(navigator->panel[i]);
285 }
[b36ebb42]286 }
287
[1aa8c86]288 if (navigator->menu != NULL) {
289 ui_fixed_remove(navigator->fixed, nav_menu_ctl(navigator->menu));
[5d466a1]290 nav_menu_destroy(navigator->menu);
[1aa8c86]291 }
292
[5d466a1]293 if (navigator->window != NULL)
294 ui_window_destroy(navigator->window);
295 if (navigator->ui != NULL)
296 ui_destroy(navigator->ui);
297 free(navigator);
298}
299
300/** Run navigator on the specified display. */
[6aa85c1]301errno_t navigator_run(const char *display_spec)
[5d466a1]302{
303 navigator_t *navigator;
304 errno_t rc;
[748c8bd]305
[5d466a1]306 rc = navigator_create(display_spec, &navigator);
307 if (rc != EOK)
308 return rc;
[748c8bd]309
[5d466a1]310 ui_run(navigator->ui);
[748c8bd]311
[5d466a1]312 navigator_destroy(navigator);
[748c8bd]313 return EOK;
314}
315
[692c7f40]316/** Get the currently active navigator panel.
317 *
318 * @param navigator Navigator
319 * @return Currently active panel
320 */
321panel_t *navigator_get_active_panel(navigator_t *navigator)
322{
323 int i;
324
325 for (i = 0; i < navigator_panels; i++) {
326 if (panel_is_active(navigator->panel[i]))
327 return navigator->panel[i];
328 }
329
330 /* This should not happen */
331 assert(false);
332 return NULL;
333}
334
335/** Switch to another navigator panel.
336 *
337 * Changes the currently active navigator panel to the next panel.
338 *
339 * @param navigator Navigator
340 */
341void navigator_switch_panel(navigator_t *navigator)
342{
[4fcc2de]343 errno_t rc;
344
[692c7f40]345 if (panel_is_active(navigator->panel[0])) {
[4fcc2de]346 rc = panel_activate(navigator->panel[1]);
347 if (rc != EOK)
348 return;
[692c7f40]349 panel_deactivate(navigator->panel[0]);
350 } else {
[4fcc2de]351 rc = panel_activate(navigator->panel[0]);
352 if (rc != EOK)
353 return;
[692c7f40]354 panel_deactivate(navigator->panel[1]);
355 }
356}
357
[f9c4c433]358/** Refresh navigator panels.
359 *
360 * This needs to be called when the disk/directory contents might have
361 * changed.
362 *
363 * @param navigator Navigator
364 */
365void navigator_refresh_panels(navigator_t *navigator)
366{
367 errno_t rc;
368 unsigned i;
369
370 /* First refresh inactive panel. */
371
372 for (i = 0; i < 2; i++) {
373 if (!panel_is_active(navigator->panel[i])) {
374 rc = panel_refresh(navigator->panel[i]);
375 if (rc != EOK)
376 return;
377 }
378 }
379
380 /*
381 * Refresh active panel last so that working directory is left
382 * to that of the active panel.
383 */
384
385 for (i = 0; i < 2; i++) {
386 if (panel_is_active(navigator->panel[i])) {
387 rc = panel_refresh(navigator->panel[i]);
388 if (rc != EOK)
389 return;
390 }
391 }
392}
393
394/** File / New File menu entry selected */
395static void navigator_file_new_file(void *arg)
396{
397 navigator_t *navigator = (navigator_t *)arg;
398
399 navigator_new_file_dlg(navigator);
400}
401
[f59212cc]402/** File / Open menu entry selected */
403static void navigator_file_open(void *arg)
404{
405 navigator_t *navigator = (navigator_t *)arg;
406 panel_t *panel;
407
408 panel = navigator_get_active_panel(navigator);
[54ddb59]409 ui_file_list_open(panel->flist, ui_file_list_get_cursor(panel->flist));
[f59212cc]410}
411
[accdf882]412/** Open file in text editor.
413 *
[b336bfd8]414 * @param navigator Navigator
[accdf882]415 * @param fname File name
416 *
417 * @return EOK on success or an error code
418 */
419static errno_t navigator_edit_file(navigator_t *navigator, const char *fname)
420{
421 task_id_t id;
422 task_wait_t wait;
423 task_exit_t texit;
424 int retval;
425 errno_t rc;
426
427 /* Free up and clean console for the child task. */
428 rc = ui_suspend(navigator->ui);
429 if (rc != EOK)
430 return rc;
431
432 rc = task_spawnl(&id, &wait, EDITOR_CMD, EDITOR_CMD, fname, NULL);
433 if (rc != EOK)
434 goto error;
435
436 rc = task_wait(&wait, &texit, &retval);
437 if ((rc != EOK) || (texit != TASK_EXIT_NORMAL))
438 goto error;
439
440 /* Resume UI operation */
441 rc = ui_resume(navigator->ui);
442 if (rc != EOK)
443 return rc;
444
[32ae27bb]445 navigator_refresh_panels(navigator);
[accdf882]446 (void) ui_paint(navigator->ui);
447 return EOK;
448error:
449 (void) ui_resume(navigator->ui);
450 (void) ui_paint(navigator->ui);
451 return rc;
452}
453
[b336bfd8]454/** Execute file entry.
455 *
456 * @param navigator Navigator
457 * @param fname File name
458 *
459 * @return EOK on success or an error code
460 */
461static errno_t navigator_exec_file(navigator_t *navigator, const char *fname)
462{
463 task_id_t id;
464 task_wait_t wait;
465 task_exit_t texit;
466 int retval;
467 errno_t rc;
468
469 /* Free up and clean console for the child task. */
470 rc = ui_suspend(navigator->ui);
471 if (rc != EOK)
472 return rc;
473
474 rc = task_spawnl(&id, &wait, fname, fname, NULL);
475 if (rc != EOK)
476 goto error;
477
478 rc = task_wait(&wait, &texit, &retval);
479 if ((rc != EOK) || (texit != TASK_EXIT_NORMAL))
480 goto error;
481
482 /* Resume UI operation */
483 rc = ui_resume(navigator->ui);
484 if (rc != EOK)
485 return rc;
486
[32ae27bb]487 navigator_refresh_panels(navigator);
488
[b336bfd8]489 (void) ui_paint(navigator->ui);
490 return EOK;
491error:
492 (void) ui_resume(navigator->ui);
493 (void) ui_paint(navigator->ui);
494 return rc;
495}
496
497/** Open panel file entry.
498 *
499 * Perform Open action on a file entry (based on extension).
500 *
501 * @param navigator Navigator
502 * @param fname File name
503 *
504 * @return EOK on success or an error code
505 */
506static errno_t navigator_open_file(navigator_t *navigator, const char *fname)
507{
508 const char *ext;
509
510 ext = str_rchr(fname, '.');
511 if (ext != NULL) {
512 if (str_casecmp(ext, ".txt") == 0)
513 return navigator_edit_file(navigator, fname);
514 }
515
516 return navigator_exec_file(navigator, fname);
517}
518
[accdf882]519/** File / Edit menu entry selected */
520static void navigator_file_edit(void *arg)
521{
522 navigator_t *navigator = (navigator_t *)arg;
523 ui_file_list_entry_t *entry;
524 ui_file_list_entry_attr_t attr;
525 panel_t *panel;
526
527 panel = navigator_get_active_panel(navigator);
528 entry = ui_file_list_get_cursor(panel->flist);
529 ui_file_list_entry_get_attr(entry, &attr);
530
531 (void)navigator_edit_file(navigator, attr.name);
532}
533
[1ec732a]534/** File / Verify menu entry selected */
535static void navigator_file_verify(void *arg)
536{
537 navigator_t *navigator = (navigator_t *)arg;
538
539 ui_file_list_entry_t *entry;
540 ui_file_list_entry_attr_t attr;
541 fmgt_flist_t *flist;
542 panel_t *panel;
543 errno_t rc;
544
545 panel = navigator_get_active_panel(navigator);
546 entry = ui_file_list_get_cursor(panel->flist);
547 ui_file_list_entry_get_attr(entry, &attr);
548
549 rc = fmgt_flist_create(&flist);
550 if (rc != EOK)
551 return;
552
553 rc = fmgt_flist_append(flist, attr.name);
554 if (rc != EOK) {
555 fmgt_flist_destroy(flist);
556 return;
557 }
558
559 /* flist ownership transferred */
560 navigator_verify_dlg(navigator, flist);
561}
562
[f59212cc]563/** File / Exit menu entry selected */
564static void navigator_file_exit(void *arg)
565{
566 navigator_t *navigator = (navigator_t *)arg;
567
568 ui_quit(navigator->ui);
569}
570
[39ab17c]571/** Panel callback requesting panel activation.
572 *
573 * @param arg Argument (navigator_t *)
574 * @param panel Panel
575 */
576void navigator_panel_activate_req(void *arg, panel_t *panel)
577{
578 navigator_t *navigator = (navigator_t *)arg;
579
580 if (!panel_is_active(panel))
581 navigator_switch_panel(navigator);
582}
583
[b336bfd8]584/** Panel callback requesting file open.
585 *
586 * @param arg Argument (navigator_t *)
587 * @param panel Panel
588 * @param fname File name
589 */
590void navigator_panel_file_open(void *arg, panel_t *panel, const char *fname)
591{
592 navigator_t *navigator = (navigator_t *)arg;
593
594 (void)panel;
595 navigator_open_file(navigator, fname);
596}
597
[c111da2]598/** Wrapper fibril function for worker function.
599 *
600 * This is the main fibril function for the worker fibril. It executes
601 * the worker function, then clears worker FID to indicate the worker
602 * is finished.
603 *
604 * @param arg Argument (navigator_worker_job_t *)
605 * @return EOK
606 */
607static errno_t navigator_worker_func(void *arg)
608{
609 navigator_worker_job_t *job = (navigator_worker_job_t *)arg;
610
611 job->wfunc(job->arg);
612 job->navigator->worker_fid = 0;
613 free(job);
614 return EOK;
615}
616
617/** Start long-time work in a worker fibril.
618 *
619 * Actions which can take time (file operations) cannot block the main UI
620 * fibril. This function will start an action in the worker fibril, i.e.,
621 * in the background. At the same time the caller should create a modal
622 * progress dialog that will be shown until the work is completed.
623 *
624 * (Only a single worker can execute at any given time).
625 *
626 * @param nav Navigator
627 * @param wfunc Worker main function
628 * @param arg Argument to worker function
629 *
630 * @return EOK on success or an error code
631 */
632errno_t navigator_worker_start(navigator_t *nav, void (*wfunc)(void *),
633 void *arg)
634{
635 navigator_worker_job_t *job;
636
637 if (nav->worker_fid != 0)
638 return EBUSY;
639
640 job = calloc(1, sizeof(navigator_worker_job_t));
641 if (job == NULL)
642 return ENOMEM;
643
644 job->navigator = nav;
645 job->wfunc = wfunc;
646 job->arg = arg;
647
648 nav->worker_fid = fibril_create(navigator_worker_func, (void *)job);
649 if (nav->worker_fid == 0) {
650 free(job);
651 return ENOMEM;
652 }
653
654 fibril_add_ready(nav->worker_fid);
655 return EOK;
656}
657
[c3db721]658/** Abort button pressed in progress dialog.
659 *
660 * @param dlg Progress dialog
661 * @param arg Argument (navigator_t *)
662 */
663static void navigator_progress_babort(progress_dlg_t *dlg, void *arg)
664{
665 navigator_t *nav = (navigator_t *)arg;
666
667 (void)dlg;
668 nav->abort_op = true;
669}
670
671/** Progress dialog closed,
672 *
673 * @param dlg Progress dialog
674 * @param arg Argument (navigator_t *)
675 */
676static void navigator_progress_close(progress_dlg_t *dlg, void *arg)
677{
678 navigator_t *nav = (navigator_t *)arg;
679
680 (void)dlg;
681 nav->abort_op = true;
682}
683
[bb4d0b5]684/** Called by fmgt to query for I/O error recovery action.
685 *
686 * @param arg Argument (navigator_t *)
687 * @param err I/O error report
688 * @return Recovery action to take.
689 */
690fmgt_error_action_t navigator_io_error_query(void *arg, fmgt_io_error_t *err)
691{
692 navigator_t *nav = (navigator_t *)arg;
693 io_err_dlg_t *dlg;
694 io_err_dlg_params_t params;
695 fmgt_error_action_t err_act;
696 char *text1;
697 errno_t rc;
698 int rv;
699
700 io_err_dlg_params_init(&params);
701 rv = asprintf(&text1, err->optype == fmgt_io_write ?
702 "Error writing file %s." : "Error reading file %s.",
703 err->fname);
704 if (rv < 0)
705 return fmgt_er_abort;
706
707 params.text1 = text1;
708 params.text2 = str_error(err->rc);
709
710 ui_lock(nav->ui);
711 rc = io_err_dlg_create(nav->ui, &params, &dlg);
712 if (rc != EOK) {
713 ui_unlock(nav->ui);
714 free(text1);
715 return fmgt_er_abort;
716 }
717
718 io_err_dlg_set_cb(dlg, &navigator_io_err_dlg_cb, (void *)nav);
719
720 ui_unlock(nav->ui);
721 free(text1);
722
723 fibril_mutex_lock(&nav->io_err_act_lock);
724
725 while (!nav->io_err_act_sel) {
726 fibril_condvar_wait(&nav->io_err_act_cv,
727 &nav->io_err_act_lock);
728 }
729
730 err_act = nav->io_err_act;
731 nav->io_err_act_sel = false;
732 fibril_mutex_unlock(&nav->io_err_act_lock);
733
734 return err_act;
735}
736
737/** I/O error dialog abort button was pressed.
738 *
739 * @param dlg I/O error dialog
740 * @param arg Argument (navigator_t *)
741 */
742static void navigator_io_err_abort(io_err_dlg_t *dlg, void *arg)
743{
744 navigator_t *nav = (navigator_t *)arg;
745
746 io_err_dlg_destroy(dlg);
747
748 fibril_mutex_lock(&nav->io_err_act_lock);
749 nav->io_err_act = fmgt_er_abort;
750 nav->io_err_act_sel = true;
751 fibril_condvar_signal(&nav->io_err_act_cv);
752 fibril_mutex_unlock(&nav->io_err_act_lock);
753}
754
755/** I/O error dialog retry button was pressed.
756 *
757 * @param dlg I/O error dialog
758 * @param arg Argument (navigator_t *)
759 */
760static void navigator_io_err_retry(io_err_dlg_t *dlg, void *arg)
761{
762 navigator_t *nav = (navigator_t *)arg;
763
764 io_err_dlg_destroy(dlg);
765
766 fibril_mutex_lock(&nav->io_err_act_lock);
767 nav->io_err_act = fmgt_er_retry;
768 nav->io_err_act_sel = true;
769 fibril_condvar_signal(&nav->io_err_act_cv);
770 fibril_mutex_unlock(&nav->io_err_act_lock);
771}
772
773/** I/O error dialog closure requested.
774 *
775 * @param dlg I/O error dialog
776 * @param arg Argument (navigator_t *)
777 */
778static void navigator_io_err_close(io_err_dlg_t *dlg, void *arg)
779{
780 navigator_t *nav = (navigator_t *)arg;
781
782 io_err_dlg_destroy(dlg);
783
784 fibril_mutex_lock(&nav->io_err_act_lock);
785 nav->io_err_act = fmgt_er_abort;
786 nav->io_err_act_sel = true;
787 fibril_condvar_signal(&nav->io_err_act_cv);
788 fibril_mutex_unlock(&nav->io_err_act_lock);
789}
790
[748c8bd]791/** @}
792 */
Note: See TracBrowser for help on using the repository browser.