Annotation of src/usr.bin/tmux/window-more.c, Revision 1.11
1.11 ! nicm 1: /* $OpenBSD: window-more.c,v 1.10 2009/11/26 21:37:13 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.1 nicm 138: window_more_scroll_up(wp);
139: break;
1.5 nicm 140: case MODEKEYCHOICE_DOWN:
1.1 nicm 141: window_more_scroll_down(wp);
142: break;
1.5 nicm 143: case MODEKEYCHOICE_PAGEUP:
1.1 nicm 144: if (data->top < screen_size_y(s))
145: data->top = 0;
146: else
147: data->top -= screen_size_y(s);
148: window_more_redraw_screen(wp);
149: break;
1.5 nicm 150: case MODEKEYCHOICE_PAGEDOWN:
1.1 nicm 151: if (data->top + screen_size_y(s) > ARRAY_LENGTH(&data->list))
152: data->top = ARRAY_LENGTH(&data->list);
153: else
154: data->top += screen_size_y(s);
155: window_more_redraw_screen(wp);
156: break;
157: default:
158: break;
159: }
160: }
161:
162: void
163: window_more_write_line(
164: struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
165: {
166: struct window_more_mode_data *data = wp->modedata;
167: struct screen *s = &data->screen;
1.11 ! nicm 168: struct options *oo = &wp->window->options;
1.1 nicm 169: struct grid_cell gc;
170: char *msg, hdr[32];
171: size_t size;
1.11 ! nicm 172: int utf8flag;
1.1 nicm 173:
1.2 nicm 174: utf8flag = options_get_number(&wp->window->options, "utf8");
1.1 nicm 175: memcpy(&gc, &grid_default_cell, sizeof gc);
176:
177: if (py == 0) {
178: size = xsnprintf(hdr, sizeof hdr,
179: "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
180: screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
1.9 nicm 181: colour_set_fg(&gc, options_get_number(oo, "mode-fg"));
182: colour_set_bg(&gc, options_get_number(oo, "mode-bg"));
183: gc.attr |= options_get_number(oo, "mode-attr");
1.1 nicm 184: screen_write_puts(ctx, &gc, "%s", hdr);
185: memcpy(&gc, &grid_default_cell, sizeof gc);
186: } else
187: size = 0;
188:
189: screen_write_cursormove(ctx, 0, py);
190: if (data->top + py < ARRAY_LENGTH(&data->list)) {
191: msg = ARRAY_ITEM(&data->list, data->top + py);
1.2 nicm 192: screen_write_nputs(
1.8 nicm 193: ctx, screen_size_x(s) - size, &gc, utf8flag, "%s", msg);
1.1 nicm 194: }
195: while (s->cx < screen_size_x(s) - size)
196: screen_write_putc(ctx, &gc, ' ');
197: }
198:
199: void
200: window_more_redraw_screen(struct window_pane *wp)
201: {
202: struct window_more_mode_data *data = wp->modedata;
203: struct screen *s = &data->screen;
204: struct screen_write_ctx ctx;
205: u_int i;
206:
207: screen_write_start(&ctx, wp, NULL);
208: for (i = 0; i < screen_size_y(s); i++)
209: window_more_write_line(wp, &ctx, i);
210: screen_write_stop(&ctx);
211: }
212:
213: void
214: window_more_scroll_up(struct window_pane *wp)
215: {
216: struct window_more_mode_data *data = wp->modedata;
217: struct screen_write_ctx ctx;
218:
219: if (data->top == 0)
220: return;
221: data->top--;
222:
223: screen_write_start(&ctx, wp, NULL);
224: screen_write_cursormove(&ctx, 0, 0);
225: screen_write_insertline(&ctx, 1);
226: window_more_write_line(wp, &ctx, 0);
227: window_more_write_line(wp, &ctx, 1);
228: screen_write_stop(&ctx);
229: }
230:
231: void
232: window_more_scroll_down(struct window_pane *wp)
233: {
234: struct window_more_mode_data *data = wp->modedata;
235: struct screen *s = &data->screen;
236: struct screen_write_ctx ctx;
237:
238: if (data->top >= ARRAY_LENGTH(&data->list))
239: return;
240: data->top++;
241:
242: screen_write_start(&ctx, wp, NULL);
243: screen_write_cursormove(&ctx, 0, 0);
244: screen_write_deleteline(&ctx, 1);
245: window_more_write_line(wp, &ctx, screen_size_y(s) - 1);
246: window_more_write_line(wp, &ctx, 0);
247: screen_write_stop(&ctx);
248: }