diff options
Diffstat (limited to 'window-more.c')
-rw-r--r-- | window-more.c | 227 |
1 files changed, 117 insertions, 110 deletions
diff --git a/window-more.c b/window-more.c index 618b4f81..64e4f03f 100644 --- a/window-more.c +++ b/window-more.c @@ -1,4 +1,4 @@ -/* $Id: window-more.c,v 1.5 2007-11-27 19:23:34 nicm Exp $ */ +/* $Id: window-more.c,v 1.6 2007-12-06 09:46:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -23,25 +23,27 @@ #include "tmux.h" void window_more_init(struct window *); +void window_more_free(struct window *); void window_more_resize(struct window *, u_int, u_int); -void window_more_draw( - struct window *, struct screen_draw_ctx *, u_int, u_int); void window_more_key(struct window *, int); -void window_more_draw_position(struct window *, struct screen_draw_ctx *); -void window_more_draw_line(struct window *, struct screen_draw_ctx *, u_int); +void window_more_redraw_screen(struct window *); +void window_more_write_line( + struct window *, struct screen_write_ctx *, u_int); -void window_more_up_1(struct window *); -void window_more_down_1(struct window *); +void window_more_scroll_up(struct window *); +void window_more_scroll_down(struct window *); const struct window_mode window_more_mode = { window_more_init, + window_more_free, window_more_resize, - window_more_draw, window_more_key }; struct window_more_mode_data { + struct screen screen; + ARRAY_DECL(, char *) list; u_int top; }; @@ -50,10 +52,25 @@ void window_more_vadd(struct window *w, const char *fmt, va_list ap) { struct window_more_mode_data *data = w->modedata; - char *s; + struct screen *s = &data->screen; + struct screen_write_ctx ctx; + char *msg; + u_int size; + + xvasprintf(&msg, fmt, ap); + ARRAY_ADD(&data->list, msg); - xvasprintf(&s, fmt, ap); - ARRAY_ADD(&data->list, s); + size = ARRAY_LENGTH(&data->list); + if (size == 0) + return; + size--; + if (size >= data->top && size <= data->top + screen_last_y(s)) { + screen_write_start_window(&ctx, w); + window_more_write_line(w, &ctx, size - data->top); + if (size != data->top) + window_more_write_line(w, &ctx, 0); + screen_write_stop(&ctx); + } } void @@ -70,170 +87,160 @@ void window_more_init(struct window *w) { struct window_more_mode_data *data; + struct screen *s; w->modedata = data = xmalloc(sizeof *data); ARRAY_INIT(&data->list); data->top = 0; - w->screen.mode |= MODE_BACKGROUND; - w->screen.mode &= ~MODE_BGCURSOR; -} - -void -window_more_resize(unused struct window *w, unused u_int sx, unused u_int sy) -{ + s = &data->screen; + screen_create(s, screen_size_x(&w->base), screen_size_y(&w->base)); + s->mode = 0; + w->screen = s; } void -window_more_draw_position(struct window *w, struct screen_draw_ctx *ctx) +window_more_free(struct window *w) { struct window_more_mode_data *data = w->modedata; - char *ptr, buf[32]; - size_t len; - char *line; - - len = xsnprintf( - buf, sizeof buf, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list)); - if (len <= screen_size_x(ctx->s)) - ptr = buf; - else { - ptr = buf + len - screen_size_x(ctx->s); - len -= len - screen_size_x(ctx->s); - } + u_int i; - screen_draw_move_cursor(ctx, 0, 0); + w->screen = &w->base; + screen_destroy(&data->screen); - if (data->top < ARRAY_LENGTH(&data->list)) { - line = xstrdup(ARRAY_ITEM(&data->list, data->top)); - if (strlen(line) > screen_size_x(ctx->s) - len) - line[screen_size_x(ctx->s) - len] = '\0'; - screen_draw_write_string(ctx, "%s", line); - xfree(line); - } - screen_draw_clear_line_to(ctx, screen_size_x(ctx->s) - len - 1); + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) + xfree(ARRAY_ITEM(&data->list, i)); + ARRAY_FREE(&data->list); - screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0); - screen_draw_set_attributes(ctx, 0, status_colour); - screen_draw_write_string(ctx, "%s", ptr); + w->mode = NULL; + xfree(w->modedata); } void -window_more_draw_line(struct window *w, struct screen_draw_ctx *ctx, u_int py) +window_more_resize(struct window *w, u_int sx, u_int sy) { struct window_more_mode_data *data = w->modedata; - u_int p; + struct screen *s = &data->screen; - screen_draw_move_cursor(ctx, 0, py); - screen_draw_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR); - - p = data->top + py; - if (p < ARRAY_LENGTH(&data->list)) - screen_draw_write_string(ctx, "%s", ARRAY_ITEM(&data->list, p)); - - screen_draw_clear_line_to(ctx, screen_last_x(ctx->s)); -} - -void -window_more_draw( - struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny) -{ - u_int i; - - for (i = py; i < py + ny; i++) { - if (i == 0) - window_more_draw_position(w, ctx); - else - window_more_draw_line(w, ctx, i); - } + screen_resize(s, sx, sy); + window_more_redraw_screen(w); } void window_more_key(struct window *w, int key) { struct window_more_mode_data *data = w->modedata; - u_int top, sy, i; - - sy = screen_size_y(&w->screen); - - top = data->top; + struct screen *s = &data->screen; switch (key) { case 'Q': case 'q': - for (i = 0; i < ARRAY_LENGTH(&data->list); i++) - xfree(ARRAY_ITEM(&data->list, i)); - ARRAY_FREE(&data->list); - - w->mode = NULL; - xfree(w->modedata); - - w->screen.mode &= ~MODE_BACKGROUND; - - recalculate_sizes(); + window_more_free(w); server_redraw_window(w); - return; + break; case 'k': case 'K': case KEYC_UP: - window_more_up_1(w); - return; + window_more_scroll_up(w); + break; case 'j': case 'J': case KEYC_DOWN: - window_more_down_1(w); - return; + window_more_scroll_down(w); + break; case '\025': /* C-u */ case KEYC_PPAGE: - if (data->top < sy) + if (data->top < screen_size_y(s)) data->top = 0; else - data->top -= sy; + data->top -= screen_size_y(s); + window_more_redraw_screen(w); break; case '\006': /* C-f */ case KEYC_NPAGE: - if (data->top + sy > ARRAY_LENGTH(&data->list)) + if (data->top + screen_size_y(s) > ARRAY_LENGTH(&data->list)) data->top = ARRAY_LENGTH(&data->list); else - data->top += sy; + data->top += screen_size_y(s); + window_more_redraw_screen(w); break; } - if (top != data->top) - server_redraw_window(w); } void -window_more_up_1(struct window *w) +window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py) +{ + struct window_more_mode_data *data = w->modedata; + struct screen *s = &data->screen; + char *msg; + size_t size; + + if (py == 0) { + screen_write_set_attributes(ctx, 0, status_colour); + screen_write_move_cursor(ctx, 0, 0); + size = screen_write_put_string_rjust( + ctx, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list)); + } else + size = 0; + + screen_write_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR); + screen_write_move_cursor(ctx, 0, py); + if (data->top + py < ARRAY_LENGTH(&data->list)) { + msg = ARRAY_ITEM(&data->list, data->top + py); + screen_write_put_string( + ctx, "%.*s", (int) (screen_size_x(s) - size), msg); + } + while (s->cx < screen_size_x(s) - size) + screen_write_put_character(ctx, SCREEN_DEFDATA); +} + +void +window_more_redraw_screen(struct window *w) +{ + struct window_more_mode_data *data = w->modedata; + struct screen *s = &data->screen; + struct screen_write_ctx ctx; + u_int i; + + screen_write_start_window(&ctx, w); + for (i = 0; i < screen_size_y(s); i++) + window_more_write_line(w, &ctx, i); + screen_write_stop(&ctx); +} + +void +window_more_scroll_up(struct window *w) { struct window_more_mode_data *data = w->modedata; - struct screen_draw_ctx ctx; + struct screen_write_ctx ctx; if (data->top == 0) return; data->top--; - screen_draw_start_window(&ctx, w, 0, 0); - screen_draw_move_cursor(&ctx, 0, 0); - screen_draw_insert_lines(&ctx, 1); - window_more_draw_position(w, &ctx); - window_more_draw_line(w, &ctx, 1); - screen_draw_stop(&ctx); + screen_write_start_window(&ctx, w); + screen_write_move_cursor(&ctx, 0, 0); + screen_write_insert_lines(&ctx, 1); + window_more_write_line(w, &ctx, 0); + window_more_write_line(w, &ctx, 1); + screen_write_stop(&ctx); } void -window_more_down_1(struct window *w) +window_more_scroll_down(struct window *w) { struct window_more_mode_data *data = w->modedata; - struct screen *s = &w->screen; - struct screen_draw_ctx ctx; + struct screen *s = &data->screen; + struct screen_write_ctx ctx; if (data->top >= ARRAY_LENGTH(&data->list)) return; data->top++; - screen_draw_start_window(&ctx, w, 0, 0); - screen_draw_move_cursor(&ctx, 0, 0); - screen_draw_delete_lines(&ctx, 1); - window_more_draw_line(w, &ctx, screen_last_y(s)); - window_more_draw_position(w, &ctx); - screen_draw_stop(&ctx); + screen_write_start_window(&ctx, w); + screen_write_move_cursor(&ctx, 0, 0); + screen_write_delete_lines(&ctx, 1); + window_more_write_line(w, &ctx, screen_last_y(s)); + window_more_write_line(w, &ctx, 0); + screen_write_stop(&ctx); } |