version 1.18, 2012/04/23 22:40:47 |
version 1.19, 2012/06/25 14:08:55 |
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
|
|
#include <ctype.h> |
#include <string.h> |
#include <string.h> |
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
void window_choose_mouse( |
void window_choose_mouse( |
struct window_pane *, struct session *, struct mouse_event *); |
struct window_pane *, struct session *, struct mouse_event *); |
|
|
void window_choose_fire_callback(struct window_pane *, int); |
void window_choose_fire_callback( |
|
struct window_pane *, struct window_choose_data *); |
void window_choose_redraw_screen(struct window_pane *); |
void window_choose_redraw_screen(struct window_pane *); |
void window_choose_write_line( |
void window_choose_write_line( |
struct window_pane *, struct screen_write_ctx *, u_int); |
struct window_pane *, struct screen_write_ctx *, u_int); |
|
|
NULL, |
NULL, |
}; |
}; |
|
|
struct window_choose_mode_item { |
|
char *name; |
|
int idx; |
|
}; |
|
|
|
struct window_choose_mode_data { |
struct window_choose_mode_data { |
struct screen screen; |
struct screen screen; |
|
|
|
|
u_int top; |
u_int top; |
u_int selected; |
u_int selected; |
|
|
void (*callbackfn)(void *, int); |
void (*callbackfn)(struct window_choose_data *); |
void (*freefn)(void *); |
void (*freefn)(struct window_choose_data *); |
void *data; |
|
}; |
}; |
|
|
int window_choose_key_index(struct window_choose_mode_data *, u_int); |
int window_choose_key_index(struct window_choose_mode_data *, u_int); |
int window_choose_index_key(struct window_choose_mode_data *, int); |
int window_choose_index_key(struct window_choose_mode_data *, int); |
|
|
void |
void |
window_choose_vadd(struct window_pane *wp, int idx, const char *fmt, va_list ap) |
window_choose_add(struct window_pane *wp, struct window_choose_data *wcd) |
{ |
{ |
struct window_choose_mode_data *data = wp->modedata; |
struct window_choose_mode_data *data = wp->modedata; |
struct window_choose_mode_item *item; |
struct window_choose_mode_item *item; |
|
|
ARRAY_EXPAND(&data->list, 1); |
ARRAY_EXPAND(&data->list, 1); |
item = &ARRAY_LAST(&data->list); |
item = &ARRAY_LAST(&data->list); |
xvasprintf(&item->name, fmt, ap); |
|
item->idx = idx; |
|
} |
|
|
|
void printflike3 |
item->name = format_expand(wcd->ft, wcd->ft_template); |
window_choose_add(struct window_pane *wp, int idx, const char *fmt, ...) |
item->wcd = wcd; |
{ |
|
va_list ap; |
|
|
|
va_start(ap, fmt); |
|
window_choose_vadd(wp, idx, fmt, ap); |
|
va_end(ap); |
|
} |
} |
|
|
void |
void |
window_choose_ready(struct window_pane *wp, u_int cur, |
window_choose_ready(struct window_pane *wp, u_int cur, |
void (*callbackfn)(void *, int), void (*freefn)(void *), void *cdata) |
void (*callbackfn)(struct window_choose_data *), |
|
void (*freefn)(struct window_choose_data *)) |
{ |
{ |
struct window_choose_mode_data *data = wp->modedata; |
struct window_choose_mode_data *data = wp->modedata; |
struct screen *s = &data->screen; |
struct screen *s = &data->screen; |
|
|
|
|
data->callbackfn = callbackfn; |
data->callbackfn = callbackfn; |
data->freefn = freefn; |
data->freefn = freefn; |
data->data = cdata; |
|
|
|
window_choose_redraw_screen(wp); |
window_choose_redraw_screen(wp); |
} |
} |
|
|
|
|
data->callbackfn = NULL; |
data->callbackfn = NULL; |
data->freefn = NULL; |
data->freefn = NULL; |
data->data = NULL; |
|
|
|
ARRAY_INIT(&data->list); |
ARRAY_INIT(&data->list); |
data->top = 0; |
data->top = 0; |
|
|
return (s); |
return (s); |
} |
} |
|
|
|
struct window_choose_data * |
|
window_choose_data_create(struct cmd_ctx *ctx) |
|
{ |
|
struct window_choose_data *wcd; |
|
|
|
wcd = xmalloc(sizeof *wcd); |
|
wcd->ft = format_create(); |
|
wcd->ft_template = NULL; |
|
wcd->action = NULL; |
|
wcd->raw_format = NULL; |
|
wcd->client = ctx->curclient; |
|
wcd->session = ctx->curclient->session; |
|
wcd->idx = -1; |
|
|
|
return (wcd); |
|
} |
|
|
void |
void |
window_choose_free(struct window_pane *wp) |
window_choose_free(struct window_pane *wp) |
{ |
{ |
struct window_choose_mode_data *data = wp->modedata; |
struct window_choose_mode_data *data = wp->modedata; |
|
struct window_choose_mode_item *item; |
u_int i; |
u_int i; |
|
|
if (data->freefn != NULL && data->data != NULL) |
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) { |
data->freefn(data->data); |
item = &ARRAY_ITEM(&data->list, i); |
|
if (data->freefn != NULL && item->wcd != NULL) |
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) |
data->freefn(item->wcd); |
xfree(ARRAY_ITEM(&data->list, i).name); |
xfree(item->name); |
|
} |
ARRAY_FREE(&data->list); |
ARRAY_FREE(&data->list); |
|
|
screen_free(&data->screen); |
screen_free(&data->screen); |
|
|
} |
} |
|
|
void |
void |
window_choose_fire_callback(struct window_pane *wp, int idx) |
window_choose_fire_callback( |
|
struct window_pane *wp, struct window_choose_data *wcd) |
{ |
{ |
struct window_choose_mode_data *data = wp->modedata; |
struct window_choose_mode_data *data = wp->modedata; |
const struct window_mode *oldmode; |
const struct window_mode *oldmode; |
|
|
oldmode = wp->mode; |
oldmode = wp->mode; |
wp->mode = NULL; |
wp->mode = NULL; |
|
|
data->callbackfn(data->data, idx); |
data->callbackfn(wcd); |
|
|
wp->mode = oldmode; |
wp->mode = oldmode; |
} |
} |
|
|
|
|
switch (mode_key_lookup(&data->mdata, key)) { |
switch (mode_key_lookup(&data->mdata, key)) { |
case MODEKEYCHOICE_CANCEL: |
case MODEKEYCHOICE_CANCEL: |
window_choose_fire_callback(wp, -1); |
window_choose_fire_callback(wp, NULL); |
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
break; |
break; |
case MODEKEYCHOICE_CHOOSE: |
case MODEKEYCHOICE_CHOOSE: |
item = &ARRAY_ITEM(&data->list, data->selected); |
item = &ARRAY_ITEM(&data->list, data->selected); |
window_choose_fire_callback(wp, item->idx); |
window_choose_fire_callback(wp, item->wcd); |
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
break; |
break; |
case MODEKEYCHOICE_UP: |
case MODEKEYCHOICE_UP: |
|
|
data->selected = idx; |
data->selected = idx; |
|
|
item = &ARRAY_ITEM(&data->list, data->selected); |
item = &ARRAY_ITEM(&data->list, data->selected); |
window_choose_fire_callback(wp, item->idx); |
window_choose_fire_callback(wp, item->wcd); |
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
break; |
break; |
} |
} |
|
|
data->selected = idx; |
data->selected = idx; |
|
|
item = &ARRAY_ITEM(&data->list, data->selected); |
item = &ARRAY_ITEM(&data->list, data->selected); |
window_choose_fire_callback(wp, item->idx); |
window_choose_fire_callback(wp, item->wcd); |
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
} |
} |
|
|
|
|
if (screen_size_y(&data->screen) > 1) |
if (screen_size_y(&data->screen) > 1) |
window_choose_write_line(wp, &ctx, screen_size_y(s) - 2); |
window_choose_write_line(wp, &ctx, screen_size_y(s) - 2); |
screen_write_stop(&ctx); |
screen_write_stop(&ctx); |
|
} |
|
|
|
void |
|
window_choose_ctx(struct window_choose_data *cdata) |
|
{ |
|
struct cmd_ctx ctx; |
|
struct cmd_list *cmdlist; |
|
char *template, *cause; |
|
|
|
template = cmd_template_replace(cdata->action, |
|
cdata->raw_format, 1); |
|
|
|
if (cmd_string_parse(template, &cmdlist, &cause) != 0) { |
|
if (cause != NULL) { |
|
*cause = toupper((u_char) *cause); |
|
status_message_set(cdata->client, "%s", cause); |
|
xfree(cause); |
|
} |
|
xfree(template); |
|
return; |
|
} |
|
xfree(template); |
|
|
|
ctx.msgdata = NULL; |
|
ctx.curclient = cdata->client; |
|
|
|
ctx.error = key_bindings_error; |
|
ctx.print = key_bindings_print; |
|
ctx.info = key_bindings_info; |
|
|
|
ctx.cmdclient = NULL; |
|
|
|
cmd_list_exec(cmdlist, &ctx); |
|
cmd_list_free(cmdlist); |
} |
} |