version 1.17, 2010/06/21 00:25:32 |
version 1.18, 2010/06/21 01:27:46 |
|
|
struct sessions dead_sessions; |
struct sessions dead_sessions; |
struct session_groups session_groups; |
struct session_groups session_groups; |
|
|
struct winlink *session_next_alert(struct session *, struct winlink *); |
struct winlink *session_next_alert(struct winlink *); |
struct winlink *session_previous_alert(struct session *, struct winlink *); |
struct winlink *session_previous_alert(struct winlink *); |
|
|
void |
|
session_alert_cancel(struct session *s, struct winlink *wl) |
|
{ |
|
struct session_alert *sa, *sb; |
|
|
|
sa = SLIST_FIRST(&s->alerts); |
|
while (sa != NULL) { |
|
sb = sa; |
|
sa = SLIST_NEXT(sa, entry); |
|
|
|
if (wl == NULL || sb->wl == wl) { |
|
SLIST_REMOVE(&s->alerts, sb, session_alert, entry); |
|
xfree(sb); |
|
} |
|
} |
|
} |
|
|
|
void |
|
session_alert_add(struct session *s, struct window *w, int type) |
|
{ |
|
struct session_alert *sa; |
|
struct winlink *wl; |
|
|
|
RB_FOREACH(wl, winlinks, &s->windows) { |
|
if (wl == s->curw) |
|
continue; |
|
|
|
if (wl->window == w && |
|
!session_alert_has(s, wl, type)) { |
|
sa = xmalloc(sizeof *sa); |
|
sa->wl = wl; |
|
sa->type = type; |
|
SLIST_INSERT_HEAD(&s->alerts, sa, entry); |
|
} |
|
} |
|
} |
|
|
|
int |
|
session_alert_has(struct session *s, struct winlink *wl, int type) |
|
{ |
|
struct session_alert *sa; |
|
|
|
SLIST_FOREACH(sa, &s->alerts, entry) { |
|
if (sa->wl == wl && sa->type == type) |
|
return (1); |
|
} |
|
|
|
return (0); |
|
} |
|
|
|
int |
|
session_alert_has_window(struct session *s, struct window *w, int type) |
|
{ |
|
struct session_alert *sa; |
|
|
|
SLIST_FOREACH(sa, &s->alerts, entry) { |
|
if (sa->wl->window == w && sa->type == type) |
|
return (1); |
|
} |
|
|
|
return (0); |
|
} |
|
|
|
/* Find session by name. */ |
/* Find session by name. */ |
struct session * |
struct session * |
session_find(const char *name) |
session_find(const char *name) |
|
|
s->curw = NULL; |
s->curw = NULL; |
TAILQ_INIT(&s->lastw); |
TAILQ_INIT(&s->lastw); |
RB_INIT(&s->windows); |
RB_INIT(&s->windows); |
SLIST_INIT(&s->alerts); |
|
|
|
paste_init_stack(&s->buffers); |
paste_init_stack(&s->buffers); |
|
|
|
|
xfree(s->tio); |
xfree(s->tio); |
|
|
session_group_remove(s); |
session_group_remove(s); |
session_alert_cancel(s, NULL); |
|
environ_free(&s->environ); |
environ_free(&s->environ); |
options_free(&s->options); |
options_free(&s->options); |
paste_free_stack(&s->buffers); |
paste_free_stack(&s->buffers); |
|
|
session_last(s) != 0 && session_previous(s, 0) != 0) |
session_last(s) != 0 && session_previous(s, 0) != 0) |
session_next(s, 0); |
session_next(s, 0); |
|
|
session_alert_cancel(s, wl); |
wl->flags &= ~WINLINK_ALERTFLAGS; |
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_remove(&s->lastw, wl); |
winlink_remove(&s->windows, wl); |
winlink_remove(&s->windows, wl); |
session_group_synchronize_from(s); |
session_group_synchronize_from(s); |
|
|
} |
} |
|
|
/* Return if session has window. */ |
/* Return if session has window. */ |
int |
struct winlink * |
session_has(struct session *s, struct window *w) |
session_has(struct session *s, struct window *w) |
{ |
{ |
struct winlink *wl; |
struct winlink *wl; |
|
|
RB_FOREACH(wl, winlinks, &s->windows) { |
RB_FOREACH(wl, winlinks, &s->windows) { |
if (wl->window == w) |
if (wl->window == w) |
return (1); |
return (wl); |
} |
} |
return (0); |
return (NULL); |
} |
} |
|
|
struct winlink * |
struct winlink * |
session_next_alert(struct session *s, struct winlink *wl) |
session_next_alert(struct winlink *wl) |
{ |
{ |
while (wl != NULL) { |
while (wl != NULL) { |
if (session_alert_has(s, wl, WINDOW_BELL)) |
if (wl->flags & WINLINK_ALERTFLAGS) |
break; |
break; |
if (session_alert_has(s, wl, WINDOW_ACTIVITY)) |
|
break; |
|
if (session_alert_has(s, wl, WINDOW_CONTENT)) |
|
break; |
|
wl = winlink_next(wl); |
wl = winlink_next(wl); |
} |
} |
return (wl); |
return (wl); |
|
|
|
|
wl = winlink_next(s->curw); |
wl = winlink_next(s->curw); |
if (alert) |
if (alert) |
wl = session_next_alert(s, wl); |
wl = session_next_alert(wl); |
if (wl == NULL) { |
if (wl == NULL) { |
wl = RB_MIN(winlinks, &s->windows); |
wl = RB_MIN(winlinks, &s->windows); |
if (alert && ((wl = session_next_alert(s, wl)) == NULL)) |
if (alert && ((wl = session_next_alert(wl)) == NULL)) |
return (-1); |
return (-1); |
} |
} |
if (wl == s->curw) |
if (wl == s->curw) |
|
|
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_push(&s->lastw, s->curw); |
winlink_stack_push(&s->lastw, s->curw); |
s->curw = wl; |
s->curw = wl; |
session_alert_cancel(s, wl); |
wl->flags &= ~WINLINK_ALERTFLAGS; |
return (0); |
return (0); |
} |
} |
|
|
struct winlink * |
struct winlink * |
session_previous_alert(struct session *s, struct winlink *wl) |
session_previous_alert(struct winlink *wl) |
{ |
{ |
while (wl != NULL) { |
while (wl != NULL) { |
if (session_alert_has(s, wl, WINDOW_BELL)) |
if (wl->flags & WINLINK_ALERTFLAGS) |
break; |
break; |
if (session_alert_has(s, wl, WINDOW_ACTIVITY)) |
|
break; |
|
if (session_alert_has(s, wl, WINDOW_CONTENT)) |
|
break; |
|
wl = winlink_previous(wl); |
wl = winlink_previous(wl); |
} |
} |
return (wl); |
return (wl); |
|
|
|
|
wl = winlink_previous(s->curw); |
wl = winlink_previous(s->curw); |
if (alert) |
if (alert) |
wl = session_previous_alert(s, wl); |
wl = session_previous_alert(wl); |
if (wl == NULL) { |
if (wl == NULL) { |
wl = RB_MAX(winlinks, &s->windows); |
wl = RB_MAX(winlinks, &s->windows); |
if (alert && (wl = session_previous_alert(s, wl)) == NULL) |
if (alert && (wl = session_previous_alert(wl)) == NULL) |
return (-1); |
return (-1); |
} |
} |
if (wl == s->curw) |
if (wl == s->curw) |
|
|
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_push(&s->lastw, s->curw); |
winlink_stack_push(&s->lastw, s->curw); |
s->curw = wl; |
s->curw = wl; |
session_alert_cancel(s, wl); |
wl->flags &= ~WINLINK_ALERTFLAGS; |
return (0); |
return (0); |
} |
} |
|
|
|
|
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_push(&s->lastw, s->curw); |
winlink_stack_push(&s->lastw, s->curw); |
s->curw = wl; |
s->curw = wl; |
session_alert_cancel(s, wl); |
wl->flags &= ~WINLINK_ALERTFLAGS; |
return (0); |
return (0); |
} |
} |
|
|
|
|
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_remove(&s->lastw, wl); |
winlink_stack_push(&s->lastw, s->curw); |
winlink_stack_push(&s->lastw, s->curw); |
s->curw = wl; |
s->curw = wl; |
session_alert_cancel(s, wl); |
wl->flags &= ~WINLINK_ALERTFLAGS; |
return (0); |
return (0); |
} |
} |
|
|
|
|
struct winlinks old_windows, *ww; |
struct winlinks old_windows, *ww; |
struct winlink_stack old_lastw; |
struct winlink_stack old_lastw; |
struct winlink *wl, *wl2; |
struct winlink *wl, *wl2; |
struct session_alert *sa; |
|
|
|
/* Don't do anything if the session is empty (it'll be destroyed). */ |
/* Don't do anything if the session is empty (it'll be destroyed). */ |
ww = &target->windows; |
ww = &target->windows; |
|
|
RB_INIT(&s->windows); |
RB_INIT(&s->windows); |
|
|
/* Link all the windows from the target. */ |
/* Link all the windows from the target. */ |
RB_FOREACH(wl, winlinks, ww) |
RB_FOREACH(wl, winlinks, ww) { |
winlink_add(&s->windows, wl->window, wl->idx); |
wl2 = winlink_add(&s->windows, wl->window, wl->idx); |
|
wl2->flags |= wl->flags & WINLINK_ALERTFLAGS; |
|
} |
|
|
/* Fix up the current window. */ |
/* Fix up the current window. */ |
if (s->curw != NULL) |
if (s->curw != NULL) |
|
|
wl2 = winlink_find_by_index(&s->windows, wl->idx); |
wl2 = winlink_find_by_index(&s->windows, wl->idx); |
if (wl2 != NULL) |
if (wl2 != NULL) |
TAILQ_INSERT_TAIL(&s->lastw, wl2, sentry); |
TAILQ_INSERT_TAIL(&s->lastw, wl2, sentry); |
} |
|
|
|
/* And update the alerts list. */ |
|
SLIST_FOREACH(sa, &s->alerts, entry) { |
|
wl = winlink_find_by_index(&s->windows, sa->wl->idx); |
|
if (wl == NULL) |
|
session_alert_cancel(s, sa->wl); |
|
else |
|
sa->wl = wl; |
|
} |
} |
|
|
/* Then free the old winlinks list. */ |
/* Then free the old winlinks list. */ |