version 1.32, 2020/05/22 11:07:04 |
version 1.33, 2020/05/24 09:40:17 |
|
|
}; |
}; |
RB_HEAD(control_offsets, control_offset); |
RB_HEAD(control_offsets, control_offset); |
|
|
|
/* Control state. */ |
|
struct control_state { |
|
struct control_offsets offsets; |
|
}; |
|
|
/* Compare client offsets. */ |
/* Compare client offsets. */ |
static int |
static int |
control_offset_cmp(struct control_offset *co1, struct control_offset *co2) |
control_offset_cmp(struct control_offset *co1, struct control_offset *co2) |
|
|
static struct control_offset * |
static struct control_offset * |
control_get_offset(struct client *c, struct window_pane *wp) |
control_get_offset(struct client *c, struct window_pane *wp) |
{ |
{ |
struct control_offset co = { .pane = wp->id }; |
struct control_state *cs = c->control_state; |
|
struct control_offset co = { .pane = wp->id }; |
|
|
if (c->offsets == NULL) |
return (RB_FIND(control_offsets, &cs->offsets, &co)); |
return (NULL); |
|
return (RB_FIND(control_offsets, c->offsets, &co)); |
|
} |
} |
|
|
/* Add pane offsets for this client. */ |
/* Add pane offsets for this client. */ |
static struct control_offset * |
static struct control_offset * |
control_add_offset(struct client *c, struct window_pane *wp) |
control_add_offset(struct client *c, struct window_pane *wp) |
{ |
{ |
|
struct control_state *cs = c->control_state; |
struct control_offset *co; |
struct control_offset *co; |
|
|
co = control_get_offset(c, wp); |
co = control_get_offset(c, wp); |
if (co != NULL) |
if (co != NULL) |
return (co); |
return (co); |
|
|
if (c->offsets == NULL) { |
|
c->offsets = xmalloc(sizeof *c->offsets); |
|
RB_INIT(c->offsets); |
|
} |
|
|
|
co = xcalloc(1, sizeof *co); |
co = xcalloc(1, sizeof *co); |
co->pane = wp->id; |
co->pane = wp->id; |
RB_INSERT(control_offsets, c->offsets, co); |
RB_INSERT(control_offsets, &cs->offsets, co); |
memcpy(&co->offset, &wp->offset, sizeof co->offset); |
memcpy(&co->offset, &wp->offset, sizeof co->offset); |
return (co); |
return (co); |
} |
} |
|
|
void |
void |
control_free_offsets(struct client *c) |
control_free_offsets(struct client *c) |
{ |
{ |
|
struct control_state *cs = c->control_state; |
struct control_offset *co, *co1; |
struct control_offset *co, *co1; |
|
|
if (c->offsets == NULL) |
RB_FOREACH_SAFE(co, control_offsets, &cs->offsets, co1) { |
return; |
RB_REMOVE(control_offsets, &cs->offsets, co); |
RB_FOREACH_SAFE(co, control_offsets, c->offsets, co1) { |
|
RB_REMOVE(control_offsets, c->offsets, co); |
|
free(co); |
free(co); |
} |
} |
free(c->offsets); |
|
} |
} |
|
|
/* Get offsets for client. */ |
/* Get offsets for client. */ |
|
|
void |
void |
control_start(struct client *c) |
control_start(struct client *c) |
{ |
{ |
|
struct control_state *cs; |
|
|
|
cs = c->control_state = xcalloc(1, sizeof *cs); |
|
RB_INIT(&cs->offsets); |
|
|
file_read(c, "-", control_callback, c); |
file_read(c, "-", control_callback, c); |
|
|
if (c->flags & CLIENT_CONTROLCONTROL) |
if (c->flags & CLIENT_CONTROLCONTROL) |
file_print(c, "\033P1000p"); |
file_print(c, "\033P1000p"); |
|
} |
|
|
|
/* Stop control mode. */ |
|
void |
|
control_stop(struct client *c) |
|
{ |
|
struct control_state *cs = c->control_state; |
|
|
|
control_free_offsets(c); |
|
free(cs); |
} |
} |