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