mirror of
https://github.com/tmux/tmux.git
synced 2026-10-08 19:14:20 +00:00
Add local panes as well.
This commit is contained in:
478
active.c
478
active.c
@@ -43,6 +43,26 @@ struct active_window {
|
||||
};
|
||||
RB_HEAD(active_windows, active_window);
|
||||
|
||||
/* Pane entry in a client-local last-pane stack. */
|
||||
struct active_pane_entry {
|
||||
struct window_pane *wp;
|
||||
TAILQ_ENTRY(active_pane_entry) entry;
|
||||
};
|
||||
TAILQ_HEAD(active_pane_stack, active_pane_entry);
|
||||
|
||||
/* Per-client and per-window local active pane state. */
|
||||
struct active_pane {
|
||||
struct client *client;
|
||||
struct window *window;
|
||||
enum active_mode mode;
|
||||
struct window_pane *pane;
|
||||
struct active_pane_stack last_panes;
|
||||
|
||||
RB_ENTRY(active_pane) entry;
|
||||
};
|
||||
RB_HEAD(active_panes, active_pane);
|
||||
|
||||
/* Compare local active window states by client and session. */
|
||||
static int
|
||||
active_window_cmp(struct active_window *aw1, struct active_window *aw2)
|
||||
{
|
||||
@@ -63,22 +83,36 @@ active_window_cmp(struct active_window *aw1, struct active_window *aw2)
|
||||
}
|
||||
RB_GENERATE_STATIC(active_windows, active_window, entry, active_window_cmp);
|
||||
|
||||
static struct active_window *active_get(struct client *, struct session *);
|
||||
static struct active_window *active_add(struct client *, struct session *,
|
||||
struct winlink *);
|
||||
static void active_free(struct active_window *);
|
||||
static struct winlink *active_resolve(struct active_window *);
|
||||
static void active_stack_remove(struct active_window_stack *, u_int);
|
||||
static void active_stack_push(struct active_window_stack *, u_int);
|
||||
static void active_changed(struct client *, struct session *,
|
||||
struct winlink *, struct winlink *);
|
||||
/* Compare local active pane states by client and window. */
|
||||
static int
|
||||
active_pane_cmp(struct active_pane *ap1, struct active_pane *ap2)
|
||||
{
|
||||
uintptr_t c1 = (uintptr_t)ap1->client;
|
||||
uintptr_t c2 = (uintptr_t)ap2->client;
|
||||
uintptr_t w1 = (uintptr_t)ap1->window;
|
||||
uintptr_t w2 = (uintptr_t)ap2->window;
|
||||
|
||||
if (c1 < c2)
|
||||
return (-1);
|
||||
if (c1 > c2)
|
||||
return (1);
|
||||
if (w1 < w2)
|
||||
return (-1);
|
||||
if (w1 > w2)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
RB_GENERATE_STATIC(active_panes, active_pane, entry, active_pane_cmp);
|
||||
|
||||
/* All local active window states. */
|
||||
static struct active_windows active_windows = RB_INITIALIZER(&active_windows);
|
||||
|
||||
/* All local active pane states. */
|
||||
static struct active_panes active_panes = RB_INITIALIZER(&active_panes);
|
||||
|
||||
/* Find local active window state for a client and session. */
|
||||
static struct active_window *
|
||||
active_get(struct client *c, struct session *s)
|
||||
active_window_get(struct client *c, struct session *s)
|
||||
{
|
||||
struct active_window aw;
|
||||
|
||||
@@ -91,11 +125,11 @@ active_get(struct client *c, struct session *s)
|
||||
|
||||
/* Add local active window state for a client and session. */
|
||||
static struct active_window *
|
||||
active_add(struct client *c, struct session *s, struct winlink *wl)
|
||||
active_window_add(struct client *c, struct session *s, struct winlink *wl)
|
||||
{
|
||||
struct active_window *aw;
|
||||
|
||||
aw = active_get(c, s);
|
||||
aw = active_window_get(c, s);
|
||||
if (aw == NULL) {
|
||||
aw = xcalloc(1, sizeof *aw);
|
||||
aw->client = c;
|
||||
@@ -108,9 +142,35 @@ active_add(struct client *c, struct session *s, struct winlink *wl)
|
||||
return (aw);
|
||||
}
|
||||
|
||||
/* Remove a window from a local last-window stack. */
|
||||
static void
|
||||
active_window_stack_remove(struct active_window_stack *stack, u_int window)
|
||||
{
|
||||
struct active_window_entry *awe, *awe1;
|
||||
|
||||
TAILQ_FOREACH_SAFE(awe, stack, entry, awe1) {
|
||||
if (awe->window == window) {
|
||||
TAILQ_REMOVE(stack, awe, entry);
|
||||
free(awe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Push a window onto a local last-window stack. */
|
||||
static void
|
||||
active_window_stack_push(struct active_window_stack *stack, u_int window)
|
||||
{
|
||||
struct active_window_entry *awe;
|
||||
|
||||
active_window_stack_remove(stack, window);
|
||||
awe = xcalloc(1, sizeof *awe);
|
||||
awe->window = window;
|
||||
TAILQ_INSERT_HEAD(stack, awe, entry);
|
||||
}
|
||||
|
||||
/* Free local active window state. */
|
||||
static void
|
||||
active_free(struct active_window *aw)
|
||||
active_window_free(struct active_window *aw)
|
||||
{
|
||||
struct active_window_entry *awe;
|
||||
|
||||
@@ -125,7 +185,7 @@ active_free(struct active_window *aw)
|
||||
|
||||
/* Resolve local active window state to a valid winlink. */
|
||||
static struct winlink *
|
||||
active_resolve(struct active_window *aw)
|
||||
active_window_resolve(struct active_window *aw)
|
||||
{
|
||||
struct winlink *wl, *next;
|
||||
u_int window;
|
||||
@@ -141,7 +201,7 @@ active_resolve(struct active_window *aw)
|
||||
window = TAILQ_FIRST(&aw->lastw)->window;
|
||||
|
||||
next = winlink_find_by_window_id(&aw->session->windows, window);
|
||||
active_stack_remove(&aw->lastw, window);
|
||||
active_window_stack_remove(&aw->lastw, window);
|
||||
if (next != NULL) {
|
||||
aw->window = next->window->id;
|
||||
return (next);
|
||||
@@ -152,35 +212,9 @@ active_resolve(struct active_window *aw)
|
||||
return (aw->session->curw);
|
||||
}
|
||||
|
||||
/* Remove a window from a local last-window stack. */
|
||||
static void
|
||||
active_stack_remove(struct active_window_stack *stack, u_int window)
|
||||
{
|
||||
struct active_window_entry *awe, *awe1;
|
||||
|
||||
TAILQ_FOREACH_SAFE(awe, stack, entry, awe1) {
|
||||
if (awe->window == window) {
|
||||
TAILQ_REMOVE(stack, awe, entry);
|
||||
free(awe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Push a window onto a local last-window stack. */
|
||||
static void
|
||||
active_stack_push(struct active_window_stack *stack, u_int window)
|
||||
{
|
||||
struct active_window_entry *awe;
|
||||
|
||||
active_stack_remove(stack, window);
|
||||
awe = xcalloc(1, sizeof *awe);
|
||||
awe->window = window;
|
||||
TAILQ_INSERT_HEAD(stack, awe, entry);
|
||||
}
|
||||
|
||||
/* Notify the server that a client's effective window changed. */
|
||||
static void
|
||||
active_changed(struct client *c, struct session *s, struct winlink *wl,
|
||||
active_window_changed(struct client *c, struct session *s, struct winlink *wl,
|
||||
struct winlink *old)
|
||||
{
|
||||
struct event_payload *ep;
|
||||
@@ -225,17 +259,114 @@ active_changed(struct client *c, struct session *s, struct winlink *wl,
|
||||
recalculate_sizes();
|
||||
}
|
||||
|
||||
/* Find local active pane state for a client and window. */
|
||||
static struct active_pane *
|
||||
active_pane_get(struct client *c, struct window *w)
|
||||
{
|
||||
struct active_pane ap;
|
||||
|
||||
if (c == NULL || w == NULL)
|
||||
return (NULL);
|
||||
ap.client = c;
|
||||
ap.window = w;
|
||||
return (RB_FIND(active_panes, &active_panes, &ap));
|
||||
}
|
||||
|
||||
/* Add local active pane state for a client and window. */
|
||||
static struct active_pane *
|
||||
active_pane_add(struct client *c, struct window *w)
|
||||
{
|
||||
struct active_pane *ap;
|
||||
|
||||
ap = active_pane_get(c, w);
|
||||
if (ap == NULL) {
|
||||
ap = xcalloc(1, sizeof *ap);
|
||||
ap->client = c;
|
||||
ap->window = w;
|
||||
TAILQ_INIT(&ap->last_panes);
|
||||
RB_INSERT(active_panes, &active_panes, ap);
|
||||
}
|
||||
return (ap);
|
||||
}
|
||||
|
||||
/* Remove a pane from a client-local last-pane stack. */
|
||||
static void
|
||||
active_pane_stack_remove(struct active_pane *ap,
|
||||
struct window_pane *wp)
|
||||
{
|
||||
struct active_pane_entry *ape, *ape1;
|
||||
|
||||
TAILQ_FOREACH_SAFE(ape, &ap->last_panes, entry, ape1) {
|
||||
if (ape->wp == wp) {
|
||||
TAILQ_REMOVE(&ap->last_panes, ape, entry);
|
||||
free(ape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Push a pane onto a client-local last-pane stack. */
|
||||
static void
|
||||
active_pane_stack_push(struct active_pane *ap, struct window_pane *wp)
|
||||
{
|
||||
struct active_pane_entry *ape;
|
||||
|
||||
if (wp == NULL)
|
||||
return;
|
||||
active_pane_stack_remove(ap, wp);
|
||||
ape = xcalloc(1, sizeof *ape);
|
||||
ape->wp = wp;
|
||||
TAILQ_INSERT_HEAD(&ap->last_panes, ape, entry);
|
||||
}
|
||||
|
||||
/* Free local active pane state. */
|
||||
static void
|
||||
active_pane_free(struct active_pane *ap)
|
||||
{
|
||||
struct active_pane_entry *ape, *ape1;
|
||||
|
||||
RB_REMOVE(active_panes, &active_panes, ap);
|
||||
TAILQ_FOREACH_SAFE(ape, &ap->last_panes, entry, ape1) {
|
||||
TAILQ_REMOVE(&ap->last_panes, ape, entry);
|
||||
free(ape);
|
||||
}
|
||||
free(ap);
|
||||
}
|
||||
|
||||
/* Check whether a pane can be the effective pane for a window. */
|
||||
static int
|
||||
active_pane_valid(struct window *w, struct window_pane *wp)
|
||||
{
|
||||
if (w == NULL || wp == NULL || wp->window != w)
|
||||
return (0);
|
||||
if (!window_has_pane(w, wp))
|
||||
return (0);
|
||||
if (w->modal != NULL && wp != w->modal)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Get the shared pane for a window, accounting for modal panes. */
|
||||
static struct window_pane *
|
||||
active_pane_default(struct window *w)
|
||||
{
|
||||
if (w == NULL)
|
||||
return (NULL);
|
||||
if (w->modal != NULL)
|
||||
return (w->modal);
|
||||
return (w->active);
|
||||
}
|
||||
|
||||
/* Return if a client has local window selection for a session. */
|
||||
int
|
||||
active_is_local_window(struct client *c, struct session *s)
|
||||
{
|
||||
return (active_get(c, s) != NULL);
|
||||
return (active_window_get(c, s) != NULL);
|
||||
}
|
||||
|
||||
/* Make a client use local or shared window selection for a session. */
|
||||
void
|
||||
active_set_local_window(struct client *c, struct session *s,
|
||||
enum active_window_mode mode)
|
||||
enum active_mode mode)
|
||||
{
|
||||
struct active_window *aw;
|
||||
struct winlink *wl, *old;
|
||||
@@ -245,17 +376,17 @@ active_set_local_window(struct client *c, struct session *s,
|
||||
|
||||
old = active_get_effective_winlink(c, s);
|
||||
if (mode == ACTIVE_LOCAL) {
|
||||
active_add(c, s, old);
|
||||
active_window_add(c, s, old);
|
||||
if (c != NULL && c->session == s)
|
||||
c->flags |= CLIENT_REDRAWSTATUS;
|
||||
return;
|
||||
}
|
||||
|
||||
aw = active_get(c, s);
|
||||
aw = active_window_get(c, s);
|
||||
if (aw != NULL) {
|
||||
active_free(aw);
|
||||
active_window_free(aw);
|
||||
wl = active_get_effective_winlink(c, s);
|
||||
active_changed(c, s, wl, old);
|
||||
active_window_changed(c, s, wl, old);
|
||||
if (c != NULL && c->session == s)
|
||||
c->flags |= CLIENT_REDRAWSTATUS;
|
||||
}
|
||||
@@ -269,9 +400,9 @@ active_get_effective_winlink(struct client *c, struct session *s)
|
||||
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
aw = active_get(c, s);
|
||||
aw = active_window_get(c, s);
|
||||
if (aw != NULL)
|
||||
return (active_resolve(aw));
|
||||
return (active_window_resolve(aw));
|
||||
return (s->curw);
|
||||
}
|
||||
|
||||
@@ -297,19 +428,19 @@ active_select_window(struct client *c, struct session *s, struct winlink *wl)
|
||||
|
||||
if (wl == NULL)
|
||||
return (-1);
|
||||
aw = active_get(c, s);
|
||||
aw = active_window_get(c, s);
|
||||
if (aw == NULL)
|
||||
return (session_set_current(s, wl));
|
||||
|
||||
old = active_resolve(aw);
|
||||
old = active_window_resolve(aw);
|
||||
if (old == wl)
|
||||
return (1);
|
||||
if (old != NULL)
|
||||
active_stack_push(&aw->lastw, old->window->id);
|
||||
active_stack_remove(&aw->lastw, wl->window->id);
|
||||
active_window_stack_push(&aw->lastw, old->window->id);
|
||||
active_window_stack_remove(&aw->lastw, wl->window->id);
|
||||
aw->window = wl->window->id;
|
||||
changed = (old != wl);
|
||||
active_changed(c, s, wl, old);
|
||||
active_window_changed(c, s, wl, old);
|
||||
return (changed ? 0 : 1);
|
||||
}
|
||||
|
||||
@@ -369,7 +500,7 @@ active_last_window(struct client *c, struct session *s)
|
||||
struct winlink *wl;
|
||||
u_int window;
|
||||
|
||||
aw = active_get(c, s);
|
||||
aw = active_window_get(c, s);
|
||||
if (aw == NULL)
|
||||
return (session_last(s));
|
||||
while (!TAILQ_EMPTY(&aw->lastw)) {
|
||||
@@ -378,48 +509,11 @@ active_last_window(struct client *c, struct session *s)
|
||||
wl = winlink_find_by_window_id(&s->windows, window);
|
||||
if (wl != NULL)
|
||||
return (active_select_window(c, s, wl));
|
||||
active_stack_remove(&aw->lastw, window);
|
||||
active_window_stack_remove(&aw->lastw, window);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Remove all state for a client. */
|
||||
void
|
||||
active_remove_client(struct client *c)
|
||||
{
|
||||
struct active_window *aw, *aw1;
|
||||
|
||||
RB_FOREACH_SAFE(aw, active_windows, &active_windows, aw1) {
|
||||
if (aw->client == c)
|
||||
active_free(aw);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all state for a session. */
|
||||
void
|
||||
active_remove_session(struct session *s)
|
||||
{
|
||||
struct active_window *aw, *aw1;
|
||||
|
||||
RB_FOREACH_SAFE(aw, active_windows, &active_windows, aw1) {
|
||||
if (aw->session == s)
|
||||
active_free(aw);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove a window from all local state. */
|
||||
void
|
||||
active_remove_window(struct window *w)
|
||||
{
|
||||
struct active_window *aw;
|
||||
|
||||
RB_FOREACH(aw, active_windows, &active_windows) {
|
||||
active_stack_remove(&aw->lastw, w->id);
|
||||
if (aw->window == w->id && aw->session->curw != NULL)
|
||||
aw->window = aw->session->curw->window->id;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return if this winlink is the effective winlink. */
|
||||
int
|
||||
active_is_effective_window(struct client *c, struct session *s,
|
||||
@@ -437,7 +531,7 @@ active_is_last_window(struct client *c, struct session *s, struct winlink *wl)
|
||||
|
||||
if (wl == NULL)
|
||||
return (0);
|
||||
aw = active_get(c, s);
|
||||
aw = active_window_get(c, s);
|
||||
if (aw == NULL)
|
||||
return (wl == TAILQ_FIRST(&s->lastw));
|
||||
TAILQ_FOREACH(awe, &aw->lastw, entry) {
|
||||
@@ -447,3 +541,197 @@ active_is_last_window(struct client *c, struct session *s, struct winlink *wl)
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return if a client has local pane selection for a window. */
|
||||
int
|
||||
active_has_local_pane(struct client *c, struct window *w)
|
||||
{
|
||||
struct active_pane *ap;
|
||||
|
||||
ap = active_pane_get(c, w);
|
||||
return (ap != NULL && ap->mode == ACTIVE_LOCAL);
|
||||
}
|
||||
|
||||
/* Make a client use local or shared pane selection for a window. */
|
||||
void
|
||||
active_set_pane_mode(struct client *c, struct window *w, enum active_mode mode)
|
||||
{
|
||||
struct active_pane *ap;
|
||||
struct window_pane *wp;
|
||||
|
||||
if (c == NULL || w == NULL)
|
||||
return;
|
||||
if (mode == ACTIVE_SHARED) {
|
||||
ap = active_pane_get(c, w);
|
||||
if (ap != NULL)
|
||||
ap->mode = ACTIVE_SHARED;
|
||||
server_redraw_client(c);
|
||||
server_status_client(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (server_client_how_many() < 2) {
|
||||
ap = active_pane_get(c, w);
|
||||
if (ap != NULL)
|
||||
ap->mode = ACTIVE_SHARED;
|
||||
server_redraw_client(c);
|
||||
server_status_client(c);
|
||||
return;
|
||||
}
|
||||
|
||||
wp = active_get_effective_pane(c, w);
|
||||
if (wp == NULL)
|
||||
wp = active_pane_default(w);
|
||||
ap = active_pane_add(c, w);
|
||||
ap->mode = ACTIVE_LOCAL;
|
||||
ap->pane = wp;
|
||||
server_redraw_client(c);
|
||||
server_status_client(c);
|
||||
}
|
||||
|
||||
/* Return the effective active pane for a client and window. */
|
||||
struct window_pane *
|
||||
active_get_effective_pane(struct client *c, struct window *w)
|
||||
{
|
||||
struct active_pane *ap;
|
||||
struct window_pane *wp;
|
||||
|
||||
wp = active_pane_default(w);
|
||||
ap = active_pane_get(c, w);
|
||||
if (ap == NULL || ap->mode != ACTIVE_LOCAL)
|
||||
return (wp);
|
||||
if (!active_pane_valid(w, ap->pane)) {
|
||||
ap->pane = wp;
|
||||
if (wp != NULL)
|
||||
active_pane_stack_remove(ap, wp);
|
||||
return (wp);
|
||||
}
|
||||
return (ap->pane);
|
||||
}
|
||||
|
||||
/* Return the effective last pane for a client and window. */
|
||||
struct window_pane *
|
||||
active_get_last_pane(struct client *c, struct window *w)
|
||||
{
|
||||
struct active_pane *ap;
|
||||
struct active_pane_entry *ape, *ape1;
|
||||
|
||||
if (!active_has_local_pane(c, w))
|
||||
return (w == NULL ? NULL : TAILQ_FIRST(&w->last_panes));
|
||||
|
||||
ap = active_pane_get(c, w);
|
||||
TAILQ_FOREACH_SAFE(ape, &ap->last_panes, entry, ape1) {
|
||||
if (active_pane_valid(w, ape->wp))
|
||||
return (ape->wp);
|
||||
TAILQ_REMOVE(&ap->last_panes, ape, entry);
|
||||
free(ape);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Select a pane using either shared or local state. */
|
||||
int
|
||||
active_set_pane(struct client *c, struct window *w, struct window_pane *wp,
|
||||
int notify)
|
||||
{
|
||||
struct active_pane *ap;
|
||||
struct window_pane *lastwp;
|
||||
|
||||
if (!active_pane_valid(w, wp))
|
||||
return (0);
|
||||
if (!active_has_local_pane(c, w))
|
||||
return (window_set_active_pane(w, wp, notify));
|
||||
|
||||
lastwp = active_get_effective_pane(c, w);
|
||||
if (wp == lastwp)
|
||||
return (0);
|
||||
|
||||
ap = active_pane_add(c, w);
|
||||
active_pane_stack_remove(ap, wp);
|
||||
active_pane_stack_push(ap, lastwp);
|
||||
ap->pane = wp;
|
||||
|
||||
if (c != NULL) {
|
||||
server_redraw_client(c);
|
||||
server_status_client(c);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Remove all local pane state if fewer than two clients remain. */
|
||||
void
|
||||
active_check_clients(void)
|
||||
{
|
||||
struct active_pane *ap, *ap1;
|
||||
|
||||
if (server_client_how_many() >= 2)
|
||||
return;
|
||||
|
||||
RB_FOREACH_SAFE(ap, active_panes, &active_panes, ap1) {
|
||||
if (ap->mode == ACTIVE_LOCAL) {
|
||||
server_redraw_client(ap->client);
|
||||
server_status_client(ap->client);
|
||||
}
|
||||
active_pane_free(ap);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all state for a client. */
|
||||
void
|
||||
active_remove_client(struct client *c)
|
||||
{
|
||||
struct active_window *aw, *aw1;
|
||||
struct active_pane *ap, *ap1;
|
||||
|
||||
RB_FOREACH_SAFE(aw, active_windows, &active_windows, aw1) {
|
||||
if (aw->client == c)
|
||||
active_window_free(aw);
|
||||
}
|
||||
RB_FOREACH_SAFE(ap, active_panes, &active_panes, ap1) {
|
||||
if (ap->client == c)
|
||||
active_pane_free(ap);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all window state for a session. */
|
||||
void
|
||||
active_remove_session(struct session *s)
|
||||
{
|
||||
struct active_window *aw, *aw1;
|
||||
|
||||
RB_FOREACH_SAFE(aw, active_windows, &active_windows, aw1) {
|
||||
if (aw->session == s)
|
||||
active_window_free(aw);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove a window from all local state. */
|
||||
void
|
||||
active_remove_window(struct window *w)
|
||||
{
|
||||
struct active_window *aw;
|
||||
struct active_pane *ap, *ap1;
|
||||
|
||||
RB_FOREACH(aw, active_windows, &active_windows) {
|
||||
active_window_stack_remove(&aw->lastw, w->id);
|
||||
if (aw->window == w->id && aw->session->curw != NULL)
|
||||
aw->window = aw->session->curw->window->id;
|
||||
}
|
||||
RB_FOREACH_SAFE(ap, active_panes, &active_panes, ap1) {
|
||||
if (ap->window == w)
|
||||
active_pane_free(ap);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove a pane from all local pane state. */
|
||||
void
|
||||
active_remove_pane(struct window_pane *wp)
|
||||
{
|
||||
struct active_pane *ap, *ap1;
|
||||
|
||||
RB_FOREACH_SAFE(ap, active_panes, &active_panes, ap1) {
|
||||
active_pane_stack_remove(ap, wp);
|
||||
if (ap->pane == wp)
|
||||
ap->pane = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user