Annotation of src/usr.bin/tmux/window-more.c, Revision 1.12
1.12 ! nicm 1: /* $OpenBSD: window-more.c,v 1.11 2009/12/03 22:50:10 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
21: #include <string.h>
22:
23: #include "tmux.h"
24:
25: struct screen *window_more_init(struct window_pane *);
26: void window_more_free(struct window_pane *);
27: void window_more_resize(struct window_pane *, u_int, u_int);
28: void window_more_key(struct window_pane *, struct client *, int);
29:
30: void window_more_redraw_screen(struct window_pane *);
31: void window_more_write_line(
1.11 nicm 32: struct window_pane *, struct screen_write_ctx *, u_int);
1.1 nicm 33:
34: void window_more_scroll_up(struct window_pane *);
35: void window_more_scroll_down(struct window_pane *);
36:
37: const struct window_mode window_more_mode = {
38: window_more_init,
39: window_more_free,
40: window_more_resize,
41: window_more_key,
42: NULL,
43: NULL,
44: };
45:
46: struct window_more_mode_data {
47: struct screen screen;
48:
49: struct mode_key_data mdata;
50:
51: ARRAY_DECL(, char *) list;
52: u_int top;
53: };
54:
55: void
56: window_more_vadd(struct window_pane *wp, const char *fmt, va_list ap)
57: {
58: struct window_more_mode_data *data = wp->modedata;
59: struct screen *s = &data->screen;
60: struct screen_write_ctx ctx;
61: char *msg;
62: u_int size;
63:
64: xvasprintf(&msg, fmt, ap);
65: ARRAY_ADD(&data->list, msg);
66:
67: screen_write_start(&ctx, wp, NULL);
68: size = ARRAY_LENGTH(&data->list) - 1;
69: if (size >= data->top && size <= data->top + screen_size_y(s) - 1) {
70: window_more_write_line(wp, &ctx, size - data->top);
71: if (size != data->top)
72: window_more_write_line(wp, &ctx, 0);
73: } else
74: window_more_write_line(wp, &ctx, 0);
75: screen_write_stop(&ctx);
76: }
77:
78: struct screen *
79: window_more_init(struct window_pane *wp)
80: {
81: struct window_more_mode_data *data;
82: struct screen *s;
1.5 nicm 83: int keys;
1.1 nicm 84:
85: wp->modedata = data = xmalloc(sizeof *data);
86: ARRAY_INIT(&data->list);
87: data->top = 0;
88:
89: s = &data->screen;
90: screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
91: s->mode &= ~MODE_CURSOR;
92:
1.5 nicm 93: keys = options_get_number(&wp->window->options, "mode-keys");
94: if (keys == MODEKEY_EMACS)
1.6 nicm 95: mode_key_init(&data->mdata, &mode_key_tree_emacs_choice);
1.5 nicm 96: else
1.6 nicm 97: mode_key_init(&data->mdata, &mode_key_tree_vi_choice);
1.1 nicm 98:
99: return (s);
100: }
101:
102: void
103: window_more_free(struct window_pane *wp)
104: {
105: struct window_more_mode_data *data = wp->modedata;
106: u_int i;
107:
108: for (i = 0; i < ARRAY_LENGTH(&data->list); i++)
109: xfree(ARRAY_ITEM(&data->list, i));
110: ARRAY_FREE(&data->list);
111:
112: screen_free(&data->screen);
113: xfree(data);
114: }
115:
116: void
117: window_more_resize(struct window_pane *wp, u_int sx, u_int sy)
118: {
119: struct window_more_mode_data *data = wp->modedata;
120: struct screen *s = &data->screen;
121:
122: screen_resize(s, sx, sy);
123: window_more_redraw_screen(wp);
124: }
125:
1.10 nicm 126: /* ARGSUSED */
1.1 nicm 127: void
128: window_more_key(struct window_pane *wp, unused struct client *c, int key)
129: {
130: struct window_more_mode_data *data = wp->modedata;
131: struct screen *s = &data->screen;
132:
133: switch (mode_key_lookup(&data->mdata, key)) {
1.5 nicm 134: case MODEKEYCHOICE_CANCEL:
1.1 nicm 135: window_pane_reset_mode(wp);
136: break;
1.5 nicm 137: case MODEKEYCHOICE_UP:
1.12 ! nicm 138: case MODEKEYCHOICE_SCROLLUP:
1.1 nicm 139: window_more_scroll_up(wp);
140: break;
1.5 nicm 141: case MODEKEYCHOICE_DOWN:
1.12 ! nicm 142: case MODEKEYCHOICE_SCROLLDOWN:
1.1 nicm 143: window_more_scroll_down(wp);
144: break;
1.5 nicm 145: case MODEKEYCHOICE_PAGEUP:
1.1 nicm 146: if (data->top < screen_size_y(s))
147: data->top = 0;
148: else
149: data->top -= screen_size_y(s);
150: window_more_redraw_screen(wp);
151: break;
1.5 nicm 152: case MODEKEYCHOICE_PAGEDOWN:
1.1 nicm 153: if (data->top + screen_size_y(s) > ARRAY_LENGTH(&data->list))
154: data->top = ARRAY_LENGTH(&data->list);
155: else
156: data->top += screen_size_y(s);
157: window_more_redraw_screen(wp);
158: break;
159: default:
160: break;
161: }
162: }
163:
164: void
165: window_more_write_line(
166: struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
167: {
168: struct window_more_mode_data *data = wp->modedata;
169: struct screen *s = &data->screen;
1.11 nicm 170: struct options *oo = &wp->window->options;
1.1 nicm 171: struct grid_cell gc;
172: char *msg, hdr[32];
173: size_t size;
1.11 nicm 174: int utf8flag;
1.1 nicm 175:
1.2 nicm 176: utf8flag = options_get_number(&wp->window->options, "utf8");
1.1 nicm 177: memcpy(&gc, &grid_default_cell, sizeof gc);
178:
179: if (py == 0) {
180: size = xsnprintf(hdr, sizeof hdr,
181: "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
182: screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
1.9 nicm 183: colour_set_fg(&gc, options_get_number(oo, "mode-fg"));
184: colour_set_bg(&gc, options_get_number(oo, "mode-bg"));
185: gc.attr |= options_get_number(oo, "mode-attr");
1.1 nicm 186: screen_write_puts(ctx, &gc, "%s", hdr);
187: memcpy(&gc, &grid_default_cell, sizeof gc);
188: } else
189: size = 0;
190:
191: screen_write_cursormove(ctx, 0, py);
192: if (data->top + py < ARRAY_LENGTH(&data->list)) {
193: msg = ARRAY_ITEM(&data->list, data->top + py);
1.2 nicm 194: screen_write_nputs(
1.8 nicm 195: ctx, screen_size_x(s) - size, &gc, utf8flag, "%s", msg);
1.1 nicm 196: }
197: while (s->cx < screen_size_x(s) - size)
198: screen_write_putc(ctx, &gc, ' ');
199: }
200:
201: void
202: window_more_redraw_screen(struct window_pane *wp)
203: {
204: struct window_more_mode_data *data = wp->modedata;
205: struct screen *s = &data->screen;
206: struct screen_write_ctx ctx;
207: u_int i;
208:
209: screen_write_start(&ctx, wp, NULL);
210: for (i = 0; i < screen_size_y(s); i++)
211: window_more_write_line(wp, &ctx, i);
212: screen_write_stop(&ctx);
213: }
214:
215: void
216: window_more_scroll_up(struct window_pane *wp)
217: {
218: struct window_more_mode_data *data = wp->modedata;
219: struct screen_write_ctx ctx;
220:
221: if (data->top == 0)
222: return;
223: data->top--;
224:
225: screen_write_start(&ctx, wp, NULL);
226: screen_write_cursormove(&ctx, 0, 0);
227: screen_write_insertline(&ctx, 1);
228: window_more_write_line(wp, &ctx, 0);
229: window_more_write_line(wp, &ctx, 1);
230: screen_write_stop(&ctx);
231: }
232:
233: void
234: window_more_scroll_down(struct window_pane *wp)
235: {
236: struct window_more_mode_data *data = wp->modedata;
237: struct screen *s = &data->screen;
238: struct screen_write_ctx ctx;
239:
240: if (data->top >= ARRAY_LENGTH(&data->list))
241: return;
242: data->top++;
243:
244: screen_write_start(&ctx, wp, NULL);
245: screen_write_cursormove(&ctx, 0, 0);
246: screen_write_deleteline(&ctx, 1);
247: window_more_write_line(wp, &ctx, screen_size_y(s) - 1);
248: window_more_write_line(wp, &ctx, 0);
249: screen_write_stop(&ctx);
250: }