@@ -76,18 +76,17 @@ bool cg_switch_mode(arg_t a) | |||||
{ | { | ||||
if (mode == MODE_IMAGE) { | if (mode == MODE_IMAGE) { | ||||
if (tns.thumbs == NULL) | if (tns.thumbs == NULL) | ||||
tns_init(&tns, filecnt, &win); | |||||
tns_init(&tns, filecnt, &win, &fileidx); | |||||
img_close(&img, false); | img_close(&img, false); | ||||
reset_timeout(reset_cursor); | reset_timeout(reset_cursor); | ||||
if (img.ss.on) { | if (img.ss.on) { | ||||
img.ss.on = false; | img.ss.on = false; | ||||
reset_timeout(slideshow); | reset_timeout(slideshow); | ||||
} | } | ||||
tns.sel = fileidx; | |||||
tns.dirty = true; | tns.dirty = true; | ||||
mode = MODE_THUMB; | mode = MODE_THUMB; | ||||
} else { | } else { | ||||
load_image(tns.sel); | |||||
load_image(fileidx); | |||||
mode = MODE_IMAGE; | mode = MODE_IMAGE; | ||||
} | } | ||||
return true; | return true; | ||||
@@ -130,11 +129,9 @@ bool cg_reload_image(arg_t a) | |||||
load_image(fileidx); | load_image(fileidx); | ||||
} else { | } else { | ||||
win_set_cursor(&win, CURSOR_WATCH); | win_set_cursor(&win, CURSOR_WATCH); | ||||
if (!tns_load(&tns, tns.sel, &files[tns.sel], true, false)) { | |||||
remove_file(tns.sel, false); | |||||
if (!tns_load(&tns, fileidx, &files[fileidx], true, false)) { | |||||
remove_file(fileidx, false); | |||||
tns.dirty = true; | tns.dirty = true; | ||||
if (tns.sel >= tns.cnt) | |||||
tns.sel = tns.cnt - 1; | |||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
@@ -146,11 +143,9 @@ bool cg_remove_image(arg_t a) | |||||
remove_file(fileidx, true); | remove_file(fileidx, true); | ||||
load_image(fileidx >= filecnt ? filecnt - 1 : fileidx); | load_image(fileidx >= filecnt ? filecnt - 1 : fileidx); | ||||
return true; | return true; | ||||
} else if (tns.sel < tns.cnt) { | |||||
remove_file(tns.sel, true); | |||||
} else if (fileidx < tns.cnt) { | |||||
remove_file(fileidx, true); | |||||
tns.dirty = true; | tns.dirty = true; | ||||
if (tns.sel >= tns.cnt) | |||||
tns.sel = tns.cnt - 1; | |||||
return true; | return true; | ||||
} else { | } else { | ||||
return false; | return false; | ||||
@@ -162,8 +157,8 @@ bool cg_first(arg_t a) | |||||
if (mode == MODE_IMAGE && fileidx != 0) { | if (mode == MODE_IMAGE && fileidx != 0) { | ||||
load_image(0); | load_image(0); | ||||
return true; | return true; | ||||
} else if (mode == MODE_THUMB && tns.sel != 0) { | |||||
tns.sel = 0; | |||||
} else if (mode == MODE_THUMB && fileidx != 0) { | |||||
fileidx = 0; | |||||
tns.dirty = true; | tns.dirty = true; | ||||
return true; | return true; | ||||
} else { | } else { | ||||
@@ -178,8 +173,8 @@ bool cg_n_or_last(arg_t a) | |||||
if (mode == MODE_IMAGE && fileidx != n) { | if (mode == MODE_IMAGE && fileidx != n) { | ||||
load_image(n); | load_image(n); | ||||
return true; | return true; | ||||
} else if (mode == MODE_THUMB && tns.sel != n) { | |||||
tns.sel = n; | |||||
} else if (mode == MODE_THUMB && fileidx != n) { | |||||
fileidx = n; | |||||
tns.dirty = true; | tns.dirty = true; | ||||
return true; | return true; | ||||
} else { | } else { | ||||
@@ -199,11 +194,9 @@ bool cg_scroll_screen(arg_t a) | |||||
bool cg_toggle_image_mark(arg_t a) | bool cg_toggle_image_mark(arg_t a) | ||||
{ | { | ||||
int sel = mode == MODE_IMAGE ? fileidx : tns.sel; | |||||
files[sel].marked = !files[sel].marked; | |||||
files[fileidx].marked = !files[fileidx].marked; | |||||
if (mode == MODE_THUMB) | if (mode == MODE_THUMB) | ||||
tns_mark(&tns, sel, files[sel].marked); | |||||
tns_mark(&tns, fileidx, files[fileidx].marked); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -221,26 +214,23 @@ bool cg_reverse_marks(arg_t a) | |||||
bool cg_navigate_marked(arg_t a) | bool cg_navigate_marked(arg_t a) | ||||
{ | { | ||||
long n = (long) a; | long n = (long) a; | ||||
int d, i, cnt, sel, new; | |||||
int d, i; | |||||
int cnt = mode == MODE_IMAGE ? filecnt : tns.cnt, new = fileidx; | |||||
if (mode == MODE_IMAGE) | |||||
cnt = filecnt, sel = new = fileidx; | |||||
else | |||||
cnt = tns.cnt, sel = new = tns.sel; | |||||
if (prefix > 0) | if (prefix > 0) | ||||
n *= prefix; | n *= prefix; | ||||
d = n > 0 ? 1 : -1; | d = n > 0 ? 1 : -1; | ||||
for (i = sel + d; n != 0 && i >= 0 && i < cnt; i += d) { | |||||
for (i = fileidx + d; n != 0 && i >= 0 && i < cnt; i += d) { | |||||
if (files[i].marked) { | if (files[i].marked) { | ||||
n -= d; | n -= d; | ||||
new = i; | new = i; | ||||
} | } | ||||
} | } | ||||
if (new != sel) { | |||||
if (new != fileidx) { | |||||
if (mode == MODE_IMAGE) { | if (mode == MODE_IMAGE) { | ||||
load_image(new); | load_image(new); | ||||
} else { | } else { | ||||
tns.sel = new; | |||||
fileidx = new; | |||||
tns.dirty = true; | tns.dirty = true; | ||||
} | } | ||||
return true; | return true; | ||||
@@ -462,7 +452,7 @@ bool ct_move_sel(arg_t a) | |||||
bool ct_reload_all(arg_t a) | bool ct_reload_all(arg_t a) | ||||
{ | { | ||||
tns_free(&tns); | tns_free(&tns); | ||||
tns_init(&tns, filecnt, &win); | |||||
tns_init(&tns, filecnt, &win, &fileidx); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -184,6 +184,8 @@ void remove_file(int n, bool manual) | |||||
filecnt--; | filecnt--; | ||||
if (n < tns.cnt) | if (n < tns.cnt) | ||||
tns.cnt--; | tns.cnt--; | ||||
if (mode == MODE_THUMB && fileidx >= tns.cnt) | |||||
fileidx = tns.cnt - 1; | |||||
if (n < alternate) | if (n < alternate) | ||||
alternate--; | alternate--; | ||||
} | } | ||||
@@ -340,7 +342,6 @@ void load_image(int new) | |||||
void update_info(void) | void update_info(void) | ||||
{ | { | ||||
int sel; | |||||
unsigned int i, fn, fw, n; | unsigned int i, fn, fw, n; | ||||
unsigned int llen = sizeof(win.bar.l), rlen = sizeof(win.bar.r); | unsigned int llen = sizeof(win.bar.l), rlen = sizeof(win.bar.r); | ||||
char *lt = win.bar.l, *rt = win.bar.r, title[TITLE_LEN]; | char *lt = win.bar.l, *rt = win.bar.r, title[TITLE_LEN]; | ||||
@@ -348,23 +349,22 @@ void update_info(void) | |||||
bool ow_info; | bool ow_info; | ||||
for (fw = 0, i = filecnt; i > 0; fw++, i /= 10); | for (fw = 0, i = filecnt; i > 0; fw++, i /= 10); | ||||
sel = mode == MODE_IMAGE ? fileidx : tns.sel; | |||||
/* update window title */ | /* update window title */ | ||||
if (mode == MODE_THUMB) { | if (mode == MODE_THUMB) { | ||||
win_set_title(&win, "sxiv"); | win_set_title(&win, "sxiv"); | ||||
} else { | } else { | ||||
snprintf(title, sizeof(title), "sxiv - %s", files[sel].name); | |||||
snprintf(title, sizeof(title), "sxiv - %s", files[fileidx].name); | |||||
win_set_title(&win, title); | win_set_title(&win, title); | ||||
} | } | ||||
/* update bar contents */ | /* update bar contents */ | ||||
if (win.bar.h == 0) | if (win.bar.h == 0) | ||||
return; | return; | ||||
mark = files[sel].marked ? "* " : ""; | |||||
mark = files[fileidx].marked ? "* " : ""; | |||||
if (mode == MODE_THUMB) { | if (mode == MODE_THUMB) { | ||||
if (tns.loadnext >= filecnt) { | if (tns.loadnext >= filecnt) { | ||||
n = snprintf(rt, rlen, "%s%0*d/%d", mark, fw, sel + 1, filecnt); | |||||
n = snprintf(rt, rlen, "%s%0*d/%d", mark, fw, fileidx + 1, filecnt); | |||||
ow_info = true; | ow_info = true; | ||||
} else { | } else { | ||||
snprintf(lt, llen, "Loading... %0*d/%d", fw, tns.loadnext, filecnt); | snprintf(lt, llen, "Loading... %0*d/%d", fw, tns.loadnext, filecnt); | ||||
@@ -383,18 +383,18 @@ void update_info(void) | |||||
n += snprintf(rt + n, rlen - n, "%0*d/%d | ", | n += snprintf(rt + n, rlen - n, "%0*d/%d | ", | ||||
fn, img.multi.sel + 1, img.multi.cnt); | fn, img.multi.sel + 1, img.multi.cnt); | ||||
} | } | ||||
n += snprintf(rt + n, rlen - n, "%0*d/%d", fw, sel + 1, filecnt); | |||||
n += snprintf(rt + n, rlen - n, "%0*d/%d", fw, fileidx + 1, filecnt); | |||||
ow_info = info.cmd == NULL; | ow_info = info.cmd == NULL; | ||||
} | } | ||||
if (ow_info) { | if (ow_info) { | ||||
fn = strlen(files[sel].name); | |||||
fn = strlen(files[fileidx].name); | |||||
if (fn < llen && | if (fn < llen && | ||||
win_textwidth(files[sel].name, fn, true) + | |||||
win_textwidth(files[fileidx].name, fn, true) + | |||||
win_textwidth(rt, n, true) < win.w) | win_textwidth(rt, n, true) < win.w) | ||||
{ | { | ||||
strncpy(lt, files[sel].name, llen); | |||||
strncpy(lt, files[fileidx].name, llen); | |||||
} else { | } else { | ||||
strncpy(lt, files[sel].base, llen); | |||||
strncpy(lt, files[fileidx].base, llen); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -464,7 +464,7 @@ void clear_resize(void) | |||||
void run_key_handler(const char *key, unsigned int mask) | void run_key_handler(const char *key, unsigned int mask) | ||||
{ | { | ||||
pid_t pid; | pid_t pid; | ||||
int retval, status, n = mode == MODE_IMAGE ? fileidx : tns.sel; | |||||
int retval, status; | |||||
char kstr[32], oldbar[sizeof(win.bar.l)]; | char kstr[32], oldbar[sizeof(win.bar.l)]; | ||||
bool restore_bar = mode == MODE_IMAGE && info.cmd != NULL; | bool restore_bar = mode == MODE_IMAGE && info.cmd != NULL; | ||||
struct stat oldst, newst; | struct stat oldst, newst; | ||||
@@ -489,10 +489,10 @@ void run_key_handler(const char *key, unsigned int mask) | |||||
strncpy(win.bar.l, "Running key handler...", sizeof(win.bar.l)); | strncpy(win.bar.l, "Running key handler...", sizeof(win.bar.l)); | ||||
win_draw(&win); | win_draw(&win); | ||||
win_set_cursor(&win, CURSOR_WATCH); | win_set_cursor(&win, CURSOR_WATCH); | ||||
stat(files[n].path, &oldst); | |||||
stat(files[fileidx].path, &oldst); | |||||
if ((pid = fork()) == 0) { | if ((pid = fork()) == 0) { | ||||
execl(keyhandler.cmd, keyhandler.cmd, kstr, files[n].path, NULL); | |||||
execl(keyhandler.cmd, keyhandler.cmd, kstr, files[fileidx].path, NULL); | |||||
warn("could not exec key handler"); | warn("could not exec key handler"); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | ||||
} else if (pid < 0) { | } else if (pid < 0) { | ||||
@@ -504,7 +504,7 @@ void run_key_handler(const char *key, unsigned int mask) | |||||
if (WIFEXITED(status) == 0 || retval != 0) | if (WIFEXITED(status) == 0 || retval != 0) | ||||
warn("key handler exited with non-zero return value: %d", retval); | warn("key handler exited with non-zero return value: %d", retval); | ||||
if (stat(files[n].path, &newst) == 0 && | |||||
if (stat(files[fileidx].path, &newst) == 0 && | |||||
memcmp(&oldst.st_mtime, &newst.st_mtime, sizeof(oldst.st_mtime)) == 0) | memcmp(&oldst.st_mtime, &newst.st_mtime, sizeof(oldst.st_mtime)) == 0) | ||||
{ | { | ||||
/* file has not changed */ | /* file has not changed */ | ||||
@@ -518,13 +518,11 @@ void run_key_handler(const char *key, unsigned int mask) | |||||
img_close(&img, true); | img_close(&img, true); | ||||
load_image(fileidx); | load_image(fileidx); | ||||
} | } | ||||
if (!tns_load(&tns, n, &files[n], true, mode == MODE_IMAGE) && | |||||
if (!tns_load(&tns, fileidx, &files[fileidx], true, mode == MODE_IMAGE) && | |||||
mode == MODE_THUMB) | mode == MODE_THUMB) | ||||
{ | { | ||||
remove_file(tns.sel, false); | |||||
remove_file(fileidx, false); | |||||
tns.dirty = true; | tns.dirty = true; | ||||
if (tns.sel >= tns.cnt) | |||||
tns.sel = tns.cnt - 1; | |||||
} | } | ||||
end: | end: | ||||
if (restore_bar) | if (restore_bar) | ||||
@@ -610,16 +608,16 @@ void on_buttonpress(XButtonEvent *bev) | |||||
switch (bev->button) { | switch (bev->button) { | ||||
case Button1: | case Button1: | ||||
if ((sel = tns_translate(&tns, bev->x, bev->y)) >= 0) { | if ((sel = tns_translate(&tns, bev->x, bev->y)) >= 0) { | ||||
if (sel != tns.sel) { | |||||
tns_highlight(&tns, tns.sel, false); | |||||
if (sel != fileidx) { | |||||
tns_highlight(&tns, fileidx, false); | |||||
tns_highlight(&tns, sel, true); | tns_highlight(&tns, sel, true); | ||||
tns.sel = sel; | |||||
fileidx = sel; | |||||
firstclick = bev->time; | firstclick = bev->time; | ||||
redraw(); | redraw(); | ||||
} else if (bev->time - firstclick <= TO_DOUBLE_CLICK) { | } else if (bev->time - firstclick <= TO_DOUBLE_CLICK) { | ||||
mode = MODE_IMAGE; | mode = MODE_IMAGE; | ||||
set_timeout(reset_cursor, TO_CURSOR_HIDE, true); | set_timeout(reset_cursor, TO_CURSOR_HIDE, true); | ||||
load_image(tns.sel); | |||||
load_image(fileidx); | |||||
redraw(); | redraw(); | ||||
} else { | } else { | ||||
firstclick = bev->time; | firstclick = bev->time; | ||||
@@ -665,8 +663,6 @@ void run(void) | |||||
tns.cnt++; | tns.cnt++; | ||||
} else { | } else { | ||||
remove_file(tns.loadnext, false); | remove_file(tns.loadnext, false); | ||||
if (tns.sel > 0 && tns.sel >= tns.cnt) | |||||
tns.sel--; | |||||
} | } | ||||
while (tns.loadnext < filecnt && tns.thumbs[tns.loadnext].loaded) | while (tns.loadnext < filecnt && tns.thumbs[tns.loadnext].loaded) | ||||
tns.loadnext++; | tns.loadnext++; | ||||
@@ -766,7 +762,7 @@ int main(int argc, char **argv) | |||||
parse_options(argc, argv); | parse_options(argc, argv); | ||||
if (options->clean_cache) { | if (options->clean_cache) { | ||||
tns_init(&tns, 0, NULL); | |||||
tns_init(&tns, 0, NULL, NULL); | |||||
tns_clean_cache(&tns); | tns_clean_cache(&tns); | ||||
exit(EXIT_SUCCESS); | exit(EXIT_SUCCESS); | ||||
} | } | ||||
@@ -859,7 +855,7 @@ int main(int argc, char **argv) | |||||
if (options->thumb_mode) { | if (options->thumb_mode) { | ||||
mode = MODE_THUMB; | mode = MODE_THUMB; | ||||
tns_init(&tns, filecnt, &win); | |||||
tns_init(&tns, filecnt, &win, &fileidx); | |||||
while (!tns_load(&tns, 0, &files[0], false, false)) | while (!tns_load(&tns, 0, &files[0], false, false)) | ||||
remove_file(0, false); | remove_file(0, false); | ||||
tns.cnt = 1; | tns.cnt = 1; | ||||
@@ -150,7 +150,7 @@ void tns_clean_cache(tns_t *tns) | |||||
} | } | ||||
void tns_init(tns_t *tns, int cnt, win_t *win) | |||||
void tns_init(tns_t *tns, int cnt, win_t *win, int *sel) | |||||
{ | { | ||||
int len; | int len; | ||||
const char *homedir, *dsuffix = ""; | const char *homedir, *dsuffix = ""; | ||||
@@ -165,7 +165,8 @@ void tns_init(tns_t *tns, int cnt, win_t *win) | |||||
tns->thumbs = NULL; | tns->thumbs = NULL; | ||||
} | } | ||||
tns->cap = cnt; | tns->cap = cnt; | ||||
tns->cnt = tns->loadnext = tns->first = tns->sel = 0; | |||||
tns->cnt = tns->loadnext = tns->first = 0; | |||||
tns->sel = sel; | |||||
tns->win = win; | tns->win = win; | ||||
tns->dirty = false; | tns->dirty = false; | ||||
@@ -338,21 +339,21 @@ void tns_check_view(tns_t *tns, bool scrolled) | |||||
return; | return; | ||||
tns->first -= tns->first % tns->cols; | tns->first -= tns->first % tns->cols; | ||||
r = tns->sel % tns->cols; | |||||
r = *tns->sel % tns->cols; | |||||
if (scrolled) { | if (scrolled) { | ||||
/* move selection into visible area */ | /* move selection into visible area */ | ||||
if (tns->sel >= tns->first + tns->cols * tns->rows) | |||||
tns->sel = tns->first + r + tns->cols * (tns->rows - 1); | |||||
else if (tns->sel < tns->first) | |||||
tns->sel = tns->first + r; | |||||
if (*tns->sel >= tns->first + tns->cols * tns->rows) | |||||
*tns->sel = tns->first + r + tns->cols * (tns->rows - 1); | |||||
else if (*tns->sel < tns->first) | |||||
*tns->sel = tns->first + r; | |||||
} else { | } else { | ||||
/* scroll to selection */ | /* scroll to selection */ | ||||
if (tns->first + tns->cols * tns->rows <= tns->sel) { | |||||
tns->first = tns->sel - r - tns->cols * (tns->rows - 1); | |||||
if (tns->first + tns->cols * tns->rows <= *tns->sel) { | |||||
tns->first = *tns->sel - r - tns->cols * (tns->rows - 1); | |||||
tns->dirty = true; | tns->dirty = true; | ||||
} else if (tns->first > tns->sel) { | |||||
tns->first = tns->sel - r; | |||||
} else if (tns->first > *tns->sel) { | |||||
tns->first = *tns->sel - r; | |||||
tns->dirty = true; | tns->dirty = true; | ||||
} | } | ||||
} | } | ||||
@@ -409,7 +410,7 @@ void tns_render(tns_t *tns) | |||||
} | } | ||||
} | } | ||||
tns->dirty = false; | tns->dirty = false; | ||||
tns_highlight(tns, tns->sel, true); | |||||
tns_highlight(tns, *tns->sel, true); | |||||
} | } | ||||
void tns_mark(tns_t *tns, int n, bool mark) | void tns_mark(tns_t *tns, int n, bool mark) | ||||
@@ -423,7 +424,7 @@ void tns_mark(tns_t *tns, int n, bool mark) | |||||
win_t *win = tns->win; | win_t *win = tns->win; | ||||
int x = t->x, y = t->y, w = t->w, h = t->h; | int x = t->x, y = t->y, w = t->w, h = t->h; | ||||
if (mark || n == tns->sel) | |||||
if (mark || n == *tns->sel) | |||||
col = win->selcol; | col = win->selcol; | ||||
else if (win->fullscreen) | else if (win->fullscreen) | ||||
col = win->fscol; | col = win->fscol; | ||||
@@ -473,33 +474,33 @@ bool tns_move_selection(tns_t *tns, direction_t dir, int cnt) | |||||
if (tns == NULL || tns->thumbs == NULL) | if (tns == NULL || tns->thumbs == NULL) | ||||
return false; | return false; | ||||
old = tns->sel; | |||||
old = *tns->sel; | |||||
cnt = cnt > 1 ? cnt : 1; | cnt = cnt > 1 ? cnt : 1; | ||||
switch (dir) { | switch (dir) { | ||||
case DIR_UP: | case DIR_UP: | ||||
tns->sel = MAX(tns->sel - cnt * tns->cols, tns->sel % tns->cols); | |||||
*tns->sel = MAX(*tns->sel - cnt * tns->cols, *tns->sel % tns->cols); | |||||
break; | break; | ||||
case DIR_DOWN: | case DIR_DOWN: | ||||
max = tns->cols * ((tns->cnt - 1) / tns->cols) + | max = tns->cols * ((tns->cnt - 1) / tns->cols) + | ||||
MIN((tns->cnt - 1) % tns->cols, tns->sel % tns->cols); | |||||
tns->sel = MIN(tns->sel + cnt * tns->cols, max); | |||||
MIN((tns->cnt - 1) % tns->cols, *tns->sel % tns->cols); | |||||
*tns->sel = MIN(*tns->sel + cnt * tns->cols, max); | |||||
break; | break; | ||||
case DIR_LEFT: | case DIR_LEFT: | ||||
tns->sel = MAX(tns->sel - cnt, 0); | |||||
*tns->sel = MAX(*tns->sel - cnt, 0); | |||||
break; | break; | ||||
case DIR_RIGHT: | case DIR_RIGHT: | ||||
tns->sel = MIN(tns->sel + cnt, tns->cnt - 1); | |||||
*tns->sel = MIN(*tns->sel + cnt, tns->cnt - 1); | |||||
break; | break; | ||||
} | } | ||||
if (tns->sel != old) { | |||||
if (*tns->sel != old) { | |||||
tns_highlight(tns, old, false); | tns_highlight(tns, old, false); | ||||
tns_check_view(tns, false); | tns_check_view(tns, false); | ||||
if (!tns->dirty) | if (!tns->dirty) | ||||
tns_highlight(tns, tns->sel, true); | |||||
tns_highlight(tns, *tns->sel, true); | |||||
} | } | ||||
return tns->sel != old; | |||||
return *tns->sel != old; | |||||
} | } | ||||
bool tns_scroll(tns_t *tns, direction_t dir, bool screen) | bool tns_scroll(tns_t *tns, direction_t dir, bool screen) | ||||
@@ -41,7 +41,7 @@ typedef struct { | |||||
int cnt; | int cnt; | ||||
int loadnext; | int loadnext; | ||||
int first; | int first; | ||||
int sel; | |||||
int *sel; | |||||
win_t *win; | win_t *win; | ||||
int x; | int x; | ||||
@@ -54,7 +54,7 @@ typedef struct { | |||||
void tns_clean_cache(tns_t*); | void tns_clean_cache(tns_t*); | ||||
void tns_init(tns_t*, int, win_t*); | |||||
void tns_init(tns_t*, int, win_t*, int*); | |||||
void tns_free(tns_t*); | void tns_free(tns_t*); | ||||
bool tns_load(tns_t*, int, const fileinfo_t*, bool, bool); | bool tns_load(tns_t*, int, const fileinfo_t*, bool, bool); | ||||