Changes in uspace/app/nav/nav.c [13277e3:b336bfd8] in mainline
- File:
-
- 1 edited
-
uspace/app/nav/nav.c (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/nav/nav.c
r13277e3 rb336bfd8 1 1 /* 2 * Copyright (c) 202 6Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 35 35 */ 36 36 37 #include <fibril.h>38 #include <fmgt.h>39 37 #include <gfx/coord.h> 40 38 #include <stdio.h> 41 39 #include <stdlib.h> 42 40 #include <str.h> 43 #include <str_error.h>44 41 #include <task.h> 45 42 #include <ui/fixed.h> … … 48 45 #include <ui/ui.h> 49 46 #include <ui/window.h> 50 51 #include "copy.h"52 #include "delete.h"53 #include "dlg/existsdlg.h"54 #include "dlg/ioerrdlg.h"55 47 #include "menu.h" 56 #include "move.h"57 #include "newdir.h"58 #include "newfile.h"59 48 #include "nav.h" 60 49 #include "panel.h" 61 #include "rename.h"62 #include "verify.h"63 50 64 51 #define EDITOR_CMD "/app/edit" 65 52 66 static void wnd_resize(ui_window_t *, void *);67 53 static void wnd_close(ui_window_t *, void *); 68 54 static void wnd_kbd(ui_window_t *, void *, kbd_event_t *); 69 55 70 56 static ui_window_cb_t window_cb = { 71 .resize = wnd_resize,72 57 .close = wnd_close, 73 58 .kbd = wnd_kbd 74 59 }; 75 60 76 static void navigator_file_new_file(void *);77 static void navigator_file_new_dir(void *);78 61 static void navigator_file_open(void *); 79 62 static void navigator_file_edit(void *); 80 static void navigator_file_verify(void *);81 static void navigator_file_copy(void *);82 static void navigator_file_rename(void *);83 static void navigator_file_move(void *);84 static void navigator_file_delete(void *);85 63 static void navigator_file_exit(void *); 86 64 87 65 static nav_menu_cb_t navigator_menu_cb = { 88 .file_new_file = navigator_file_new_file,89 .file_new_dir = navigator_file_new_dir,90 66 .file_open = navigator_file_open, 91 67 .file_edit = navigator_file_edit, 92 .file_verify = navigator_file_verify,93 .file_copy = navigator_file_copy,94 .file_rename = navigator_file_rename,95 .file_move = navigator_file_move,96 .file_delete = navigator_file_delete,97 68 .file_exit = navigator_file_exit 98 69 }; 99 70 100 static void navigator_panel_rect(navigator_t *, unsigned, gfx_rect_t *);101 71 static void navigator_panel_activate_req(void *, panel_t *); 102 72 static void navigator_panel_file_open(void *, panel_t *, const char *); … … 106 76 .file_open = navigator_panel_file_open 107 77 }; 108 109 static void navigator_progress_babort(progress_dlg_t *, void *);110 static void navigator_progress_close(progress_dlg_t *, void *);111 112 progress_dlg_cb_t navigator_progress_cb = {113 .babort = navigator_progress_babort,114 .close = navigator_progress_close115 };116 117 static void navigator_io_err_abort(io_err_dlg_t *, void *);118 static void navigator_io_err_retry(io_err_dlg_t *, void *);119 static void navigator_io_err_close(io_err_dlg_t *, void *);120 121 static io_err_dlg_cb_t navigator_io_err_dlg_cb = {122 .babort = navigator_io_err_abort,123 .bretry = navigator_io_err_retry,124 .close = navigator_io_err_close125 };126 127 static void navigator_exists_overwrite(exists_dlg_t *, void *);128 static void navigator_exists_skip(exists_dlg_t *, void *);129 static void navigator_exists_abort(exists_dlg_t *, void *);130 static void navigator_exists_close(exists_dlg_t *, void *);131 132 static exists_dlg_cb_t navigator_exists_dlg_cb = {133 .boverwrite = navigator_exists_overwrite,134 .bskip = navigator_exists_skip,135 .babort = navigator_exists_abort,136 .close = navigator_exists_close137 };138 139 /** Window size has changed.140 *141 * @param window Window142 * @param arg Argument (navigator)143 */144 static void wnd_resize(ui_window_t *window, void *arg)145 {146 navigator_t *navigator = (navigator_t *) arg;147 unsigned i;148 gfx_rect_t rect;149 150 nav_menu_resize(navigator->menu);151 152 for (i = 0; i < navigator_panels; i++) {153 navigator_panel_rect(navigator, i, &rect);154 panel_set_rect(navigator->panel[i], &rect);155 }156 }157 78 158 79 /** Window close button was clicked. … … 183 104 (event->mods & KM_CTRL) != 0) { 184 105 switch (event->key) { 185 case KC_M:186 navigator_new_file_dlg(navigator);187 break;188 case KC_N:189 navigator_new_dir_dlg(navigator);190 break;191 106 case KC_E: 192 107 navigator_file_edit((void *)navigator); 193 break;194 case KC_V:195 navigator_file_verify((void *)navigator);196 break;197 case KC_C:198 navigator_file_copy((void *)navigator);199 break;200 case KC_X:201 navigator_file_move((void *)navigator);202 break;203 case KC_D:204 navigator_file_delete((void *)navigator);205 break;206 case KC_R:207 navigator_file_rename((void *)navigator);208 108 break; 209 109 case KC_Q: … … 229 129 } 230 130 231 /** Compute size of panel rectangle.232 *233 * @param navigator Navigator234 * @param i Panel index (0 .. navigator_panels -1)235 * @param rect Place to store rectangle.236 */237 static void navigator_panel_rect(navigator_t *navigator, unsigned i,238 gfx_rect_t *rect)239 {240 gfx_rect_t arect;241 gfx_coord_t pw;242 243 ui_window_get_app_rect(navigator->window, &arect);244 245 /* Panel width */246 pw = (arect.p1.x - arect.p0.x) / navigator_panels;247 248 rect->p0.x = arect.p0.x + pw * i;249 rect->p0.y = arect.p0.y + 1;250 rect->p1.x = arect.p0.x + pw * (i + 1);251 rect->p1.y = arect.p1.y - 1;252 }253 254 131 /** Create navigator. 255 132 * … … 265 142 gfx_rect_t rect; 266 143 gfx_rect_t arect; 144 gfx_coord_t pw; 267 145 unsigned i; 268 146 errno_t rc; … … 286 164 if (rc != EOK) { 287 165 printf("Error creating window.\n"); 288 289 166 goto error; 290 167 } … … 314 191 } 315 192 316 /* Create panels. */ 317 for (i = 0; i < navigator_panels; i++) { 193 /* Panel width */ 194 pw = (arect.p1.x - arect.p0.x) / 2; 195 196 for (i = 0; i < 2; i++) { 318 197 rc = panel_create(navigator->window, i == 0, 319 198 &navigator->panel[i]); … … 321 200 goto error; 322 201 323 navigator_panel_rect(navigator, i, &rect); 202 rect.p0.x = arect.p0.x + pw * i; 203 rect.p0.y = arect.p0.y + 1; 204 rect.p1.x = arect.p0.x + pw * (i + 1); 205 rect.p1.y = arect.p1.y - 1; 324 206 panel_set_rect(navigator->panel[i], &rect); 325 207 … … 347 229 } 348 230 349 fibril_mutex_initialize(&navigator->io_err_act_lock);350 fibril_condvar_initialize(&navigator->io_err_act_cv);351 navigator->io_err_act_sel = false;352 353 fibril_mutex_initialize(&navigator->exists_act_lock);354 fibril_condvar_initialize(&navigator->exists_act_cv);355 navigator->exists_act_sel = false;356 357 231 *rnavigator = navigator; 358 232 return EOK; … … 366 240 unsigned i; 367 241 368 for (i = 0; i < navigator_panels; i++) {242 for (i = 0; i < 2; i++) { 369 243 if (navigator->panel[i] != NULL) { 370 244 ui_fixed_remove(navigator->fixed, … … 413 287 for (i = 0; i < navigator_panels; i++) { 414 288 if (panel_is_active(navigator->panel[i])) 415 return navigator->panel[i];416 }417 418 /* This should not happen */419 assert(false);420 return NULL;421 }422 423 /** Get the currently inactive navigator panel.424 *425 * @param navigator Navigator426 * @return Currently inactive panel427 */428 panel_t *navigator_get_inactive_panel(navigator_t *navigator)429 {430 int i;431 432 for (i = 0; i < navigator_panels; i++) {433 if (!panel_is_active(navigator->panel[i]))434 289 return navigator->panel[i]; 435 290 } … … 463 318 } 464 319 465 /** Refresh navigator panels.466 *467 * This needs to be called when the disk/directory contents might have468 * changed.469 *470 * @param navigator Navigator471 */472 void navigator_refresh_panels(navigator_t *navigator)473 {474 errno_t rc;475 unsigned i;476 477 /* First refresh inactive panel. */478 479 for (i = 0; i < navigator_panels; i++) {480 if (!panel_is_active(navigator->panel[i])) {481 rc = panel_refresh(navigator->panel[i]);482 if (rc != EOK)483 return;484 }485 }486 487 /*488 * Refresh active panel last so that working directory is left489 * to that of the active panel.490 */491 492 for (i = 0; i < navigator_panels; i++) {493 if (panel_is_active(navigator->panel[i])) {494 rc = panel_refresh(navigator->panel[i]);495 if (rc != EOK)496 return;497 }498 }499 }500 501 /** File / New File menu entry selected */502 static void navigator_file_new_file(void *arg)503 {504 navigator_t *navigator = (navigator_t *)arg;505 506 navigator_new_file_dlg(navigator);507 }508 509 /** File / New Directory menu entry selected */510 static void navigator_file_new_dir(void *arg)511 {512 navigator_t *navigator = (navigator_t *)arg;513 514 navigator_new_dir_dlg(navigator);515 }516 517 320 /** File / Open menu entry selected */ 518 321 static void navigator_file_open(void *arg) … … 558 361 return rc; 559 362 560 navigator_refresh_panels(navigator);561 363 (void) ui_paint(navigator->ui); 562 364 return EOK; … … 600 402 return rc; 601 403 602 navigator_refresh_panels(navigator);603 604 404 (void) ui_paint(navigator->ui); 605 405 return EOK; … … 647 447 } 648 448 649 /** File / Verify menu entry selected */650 static void navigator_file_verify(void *arg)651 {652 navigator_t *navigator = (navigator_t *)arg;653 654 ui_file_list_entry_t *entry;655 ui_file_list_entry_attr_t attr;656 fmgt_flist_t *flist;657 panel_t *panel;658 errno_t rc;659 660 panel = navigator_get_active_panel(navigator);661 entry = ui_file_list_get_cursor(panel->flist);662 ui_file_list_entry_get_attr(entry, &attr);663 664 rc = fmgt_flist_create(&flist);665 if (rc != EOK)666 return;667 668 rc = fmgt_flist_append(flist, attr.name);669 if (rc != EOK) {670 fmgt_flist_destroy(flist);671 return;672 }673 674 /* flist ownership transferred */675 navigator_verify_dlg(navigator, flist);676 }677 678 /** File / Copy menu entry selected */679 static void navigator_file_copy(void *arg)680 {681 navigator_t *navigator = (navigator_t *)arg;682 683 ui_file_list_entry_t *entry;684 ui_file_list_entry_attr_t attr;685 fmgt_flist_t *flist;686 panel_t *panel;687 errno_t rc;688 689 panel = navigator_get_active_panel(navigator);690 entry = ui_file_list_get_cursor(panel->flist);691 ui_file_list_entry_get_attr(entry, &attr);692 693 rc = fmgt_flist_create(&flist);694 if (rc != EOK)695 return;696 697 rc = fmgt_flist_append(flist, attr.name);698 if (rc != EOK) {699 fmgt_flist_destroy(flist);700 return;701 }702 703 /* flist ownership transferred */704 navigator_copy_dlg(navigator, flist);705 }706 707 /** File / Move menu entry selected */708 static void navigator_file_move(void *arg)709 {710 navigator_t *navigator = (navigator_t *)arg;711 712 ui_file_list_entry_t *entry;713 ui_file_list_entry_attr_t attr;714 fmgt_flist_t *flist;715 panel_t *panel;716 errno_t rc;717 718 panel = navigator_get_active_panel(navigator);719 entry = ui_file_list_get_cursor(panel->flist);720 ui_file_list_entry_get_attr(entry, &attr);721 722 rc = fmgt_flist_create(&flist);723 if (rc != EOK)724 return;725 726 rc = fmgt_flist_append(flist, attr.name);727 if (rc != EOK) {728 fmgt_flist_destroy(flist);729 return;730 }731 732 /* flist ownership transferred */733 navigator_move_dlg(navigator, flist);734 }735 736 /** File / Delete menu entry selected */737 static void navigator_file_delete(void *arg)738 {739 navigator_t *navigator = (navigator_t *)arg;740 741 ui_file_list_entry_t *entry;742 ui_file_list_entry_attr_t attr;743 fmgt_flist_t *flist;744 panel_t *panel;745 errno_t rc;746 747 panel = navigator_get_active_panel(navigator);748 entry = ui_file_list_get_cursor(panel->flist);749 ui_file_list_entry_get_attr(entry, &attr);750 751 rc = fmgt_flist_create(&flist);752 if (rc != EOK)753 return;754 755 rc = fmgt_flist_append(flist, attr.name);756 if (rc != EOK) {757 fmgt_flist_destroy(flist);758 return;759 }760 761 /* flist ownership transferred */762 navigator_delete_dlg(navigator, flist);763 }764 765 /** File / Rename menu entry selected */766 static void navigator_file_rename(void *arg)767 {768 navigator_t *navigator = (navigator_t *)arg;769 770 ui_file_list_entry_t *entry;771 ui_file_list_entry_attr_t attr;772 panel_t *panel;773 774 panel = navigator_get_active_panel(navigator);775 entry = ui_file_list_get_cursor(panel->flist);776 ui_file_list_entry_get_attr(entry, &attr);777 778 /* flist ownership transferred */779 navigator_rename_dlg(navigator, attr.name);780 }781 782 449 /** File / Exit menu entry selected */ 783 450 static void navigator_file_exit(void *arg) … … 815 482 } 816 483 817 /** Wrapper fibril function for worker function.818 *819 * This is the main fibril function for the worker fibril. It executes820 * the worker function, then clears worker FID to indicate the worker821 * is finished.822 *823 * @param arg Argument (navigator_worker_job_t *)824 * @return EOK825 */826 static errno_t navigator_worker_func(void *arg)827 {828 navigator_worker_job_t *job = (navigator_worker_job_t *)arg;829 830 job->wfunc(job->arg);831 job->navigator->worker_fid = 0;832 free(job);833 return EOK;834 }835 836 /** Start long-time work in a worker fibril.837 *838 * Actions which can take time (file operations) cannot block the main UI839 * fibril. This function will start an action in the worker fibril, i.e.,840 * in the background. At the same time the caller should create a modal841 * progress dialog that will be shown until the work is completed.842 *843 * (Only a single worker can execute at any given time).844 *845 * @param nav Navigator846 * @param wfunc Worker main function847 * @param arg Argument to worker function848 *849 * @return EOK on success or an error code850 */851 errno_t navigator_worker_start(navigator_t *nav, void (*wfunc)(void *),852 void *arg)853 {854 navigator_worker_job_t *job;855 856 if (nav->worker_fid != 0)857 return EBUSY;858 859 job = calloc(1, sizeof(navigator_worker_job_t));860 if (job == NULL)861 return ENOMEM;862 863 job->navigator = nav;864 job->wfunc = wfunc;865 job->arg = arg;866 867 nav->worker_fid = fibril_create(navigator_worker_func, (void *)job);868 if (nav->worker_fid == 0) {869 free(job);870 return ENOMEM;871 }872 873 fibril_add_ready(nav->worker_fid);874 return EOK;875 }876 877 /** Abort button pressed in progress dialog.878 *879 * @param dlg Progress dialog880 * @param arg Argument (navigator_t *)881 */882 static void navigator_progress_babort(progress_dlg_t *dlg, void *arg)883 {884 navigator_t *nav = (navigator_t *)arg;885 886 (void)dlg;887 nav->abort_op = true;888 }889 890 /** Progress dialog closed,891 *892 * @param dlg Progress dialog893 * @param arg Argument (navigator_t *)894 */895 static void navigator_progress_close(progress_dlg_t *dlg, void *arg)896 {897 navigator_t *nav = (navigator_t *)arg;898 899 (void)dlg;900 nav->abort_op = true;901 }902 903 /** Called by fmgt to query for I/O error recovery action.904 *905 * @param arg Argument (navigator_t *)906 * @param err I/O error report907 * @return Recovery action to take.908 */909 fmgt_error_action_t navigator_io_error_query(void *arg, fmgt_io_error_t *err)910 {911 navigator_t *nav = (navigator_t *)arg;912 io_err_dlg_t *dlg;913 io_err_dlg_params_t params;914 fmgt_error_action_t err_act;915 char *text1;916 const char *fmt = NULL;917 errno_t rc;918 int rv;919 920 switch (err->optype) {921 case fmgt_io_write:922 fmt = "Error reading file %s.";923 break;924 case fmgt_io_read:925 fmt = "Error writing file %s.";926 break;927 case fmgt_io_open:928 fmt = "Error opening %s.";929 break;930 case fmgt_io_create:931 fmt = "Error creating %s.";932 break;933 case fmgt_io_delete:934 fmt = "Error deleting %s.";935 break;936 case fmgt_io_rename:937 fmt = "Error renaming %s.";938 break;939 }940 941 io_err_dlg_params_init(¶ms);942 rv = asprintf(&text1, fmt, err->fname);943 if (rv < 0)944 return fmgt_er_abort;945 946 params.text1 = text1;947 params.text2 = str_error(err->rc);948 949 ui_lock(nav->ui);950 rc = io_err_dlg_create(nav->ui, ¶ms, &dlg);951 if (rc != EOK) {952 ui_unlock(nav->ui);953 free(text1);954 return fmgt_er_abort;955 }956 957 io_err_dlg_set_cb(dlg, &navigator_io_err_dlg_cb, (void *)nav);958 959 ui_unlock(nav->ui);960 free(text1);961 962 fibril_mutex_lock(&nav->io_err_act_lock);963 964 while (!nav->io_err_act_sel) {965 fibril_condvar_wait(&nav->io_err_act_cv,966 &nav->io_err_act_lock);967 }968 969 err_act = nav->io_err_act;970 nav->io_err_act_sel = false;971 fibril_mutex_unlock(&nav->io_err_act_lock);972 973 return err_act;974 }975 976 /** I/O error dialog abort button was pressed.977 *978 * @param dlg I/O error dialog979 * @param arg Argument (navigator_t *)980 */981 static void navigator_io_err_abort(io_err_dlg_t *dlg, void *arg)982 {983 navigator_t *nav = (navigator_t *)arg;984 985 io_err_dlg_destroy(dlg);986 987 fibril_mutex_lock(&nav->io_err_act_lock);988 nav->io_err_act = fmgt_er_abort;989 nav->io_err_act_sel = true;990 fibril_condvar_signal(&nav->io_err_act_cv);991 fibril_mutex_unlock(&nav->io_err_act_lock);992 }993 994 /** I/O error dialog retry button was pressed.995 *996 * @param dlg I/O error dialog997 * @param arg Argument (navigator_t *)998 */999 static void navigator_io_err_retry(io_err_dlg_t *dlg, void *arg)1000 {1001 navigator_t *nav = (navigator_t *)arg;1002 1003 io_err_dlg_destroy(dlg);1004 1005 fibril_mutex_lock(&nav->io_err_act_lock);1006 nav->io_err_act = fmgt_er_retry;1007 nav->io_err_act_sel = true;1008 fibril_condvar_signal(&nav->io_err_act_cv);1009 fibril_mutex_unlock(&nav->io_err_act_lock);1010 }1011 1012 /** I/O error dialog closure requested.1013 *1014 * @param dlg I/O error dialog1015 * @param arg Argument (navigator_t *)1016 */1017 static void navigator_io_err_close(io_err_dlg_t *dlg, void *arg)1018 {1019 navigator_t *nav = (navigator_t *)arg;1020 1021 io_err_dlg_destroy(dlg);1022 1023 fibril_mutex_lock(&nav->io_err_act_lock);1024 nav->io_err_act = fmgt_er_abort;1025 nav->io_err_act_sel = true;1026 fibril_condvar_signal(&nav->io_err_act_cv);1027 fibril_mutex_unlock(&nav->io_err_act_lock);1028 }1029 1030 /** Called by fmgt to query for file/directory exists recovery action.1031 *1032 * @param arg Argument (navigator_t *)1033 * @param exists File/directory exists report1034 * @return Recovery action to take.1035 */1036 fmgt_exists_action_t navigator_exists_query(void *arg, fmgt_exists_t *exists)1037 {1038 navigator_t *nav = (navigator_t *)arg;1039 exists_dlg_t *dlg;1040 exists_dlg_params_t params;1041 fmgt_exists_action_t exists_act;1042 char *text1;1043 errno_t rc;1044 int rv;1045 1046 exists_dlg_params_init(¶ms);1047 rv = asprintf(&text1, "File %s exists.", exists->fname);1048 if (rv < 0)1049 return fmgt_exr_abort;1050 1051 params.text1 = text1;1052 1053 ui_lock(nav->ui);1054 rc = exists_dlg_create(nav->ui, ¶ms, &dlg);1055 if (rc != EOK) {1056 ui_unlock(nav->ui);1057 free(text1);1058 return fmgt_exr_abort;1059 }1060 1061 exists_dlg_set_cb(dlg, &navigator_exists_dlg_cb, (void *)nav);1062 1063 ui_unlock(nav->ui);1064 free(text1);1065 1066 fibril_mutex_lock(&nav->exists_act_lock);1067 1068 while (!nav->exists_act_sel) {1069 fibril_condvar_wait(&nav->exists_act_cv,1070 &nav->exists_act_lock);1071 }1072 1073 exists_act = nav->exists_act;1074 nav->exists_act_sel = false;1075 fibril_mutex_unlock(&nav->exists_act_lock);1076 1077 return exists_act;1078 }1079 1080 /** File/directory exists dialog overwrite button was pressed.1081 *1082 * @param dlg File/directory exists dialog1083 * @param arg Argument (navigator_t *)1084 */1085 static void navigator_exists_overwrite(exists_dlg_t *dlg, void *arg)1086 {1087 navigator_t *nav = (navigator_t *)arg;1088 1089 exists_dlg_destroy(dlg);1090 1091 fibril_mutex_lock(&nav->exists_act_lock);1092 nav->exists_act = fmgt_exr_overwrite;1093 nav->exists_act_sel = true;1094 fibril_condvar_signal(&nav->exists_act_cv);1095 fibril_mutex_unlock(&nav->exists_act_lock);1096 }1097 1098 /** File/directory exists dialog skip button was pressed.1099 *1100 * @param dlg File/directory exists dialog1101 * @param arg Argument (navigator_t *)1102 */1103 static void navigator_exists_skip(exists_dlg_t *dlg, void *arg)1104 {1105 navigator_t *nav = (navigator_t *)arg;1106 1107 exists_dlg_destroy(dlg);1108 1109 fibril_mutex_lock(&nav->exists_act_lock);1110 nav->exists_act = fmgt_exr_skip;1111 nav->exists_act_sel = true;1112 fibril_condvar_signal(&nav->exists_act_cv);1113 fibril_mutex_unlock(&nav->exists_act_lock);1114 }1115 1116 /** File/directory exists dialog abort button was pressed.1117 *1118 * @param dlg File/directory exists dialog1119 * @param arg Argument (navigator_t *)1120 */1121 static void navigator_exists_abort(exists_dlg_t *dlg, void *arg)1122 {1123 navigator_t *nav = (navigator_t *)arg;1124 1125 exists_dlg_destroy(dlg);1126 1127 fibril_mutex_lock(&nav->exists_act_lock);1128 nav->exists_act = fmgt_exr_abort;1129 nav->exists_act_sel = true;1130 fibril_condvar_signal(&nav->exists_act_cv);1131 fibril_mutex_unlock(&nav->exists_act_lock);1132 }1133 1134 /** File/directory exists dialog closure requested.1135 *1136 * @param dlg File/directory exists dialog1137 * @param arg Argument (navigator_t *)1138 */1139 static void navigator_exists_close(exists_dlg_t *dlg, void *arg)1140 {1141 navigator_t *nav = (navigator_t *)arg;1142 1143 exists_dlg_destroy(dlg);1144 1145 fibril_mutex_lock(&nav->exists_act_lock);1146 nav->exists_act = fmgt_exr_abort;1147 nav->exists_act_sel = true;1148 fibril_condvar_signal(&nav->exists_act_cv);1149 fibril_mutex_unlock(&nav->exists_act_lock);1150 }1151 1152 484 /** @} 1153 485 */
Note:
See TracChangeset
for help on using the changeset viewer.
