Annotation of src/usr.bin/tmux/window-more.c, Revision 1.3
1.3 ! nicm 1: /* $OpenBSD: window-more.c,v 1.2 2009/06/24 23:00:31 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;
83:
84: wp->modedata = data = xmalloc(sizeof *data);
85: ARRAY_INIT(&data->list);
86: data->top = 0;
87:
88: s = &data->screen;
89: screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
90: s->mode &= ~MODE_CURSOR;
91:
92: mode_key_init(&data->mdata,
93: options_get_number(&wp->window->options, "mode-keys"), 0);
94:
95: return (s);
96: }
97:
98: void
99: window_more_free(struct window_pane *wp)
100: {
101: struct window_more_mode_data *data = wp->modedata;
102: u_int i;
103:
104: mode_key_free(&data->mdata);
105:
106: for (i = 0; i < ARRAY_LENGTH(&data->list); i++)
107: xfree(ARRAY_ITEM(&data->list, i));
108: ARRAY_FREE(&data->list);
109:
110: screen_free(&data->screen);
111: xfree(data);
112: }
113:
114: void
115: window_more_resize(struct window_pane *wp, u_int sx, u_int sy)
116: {
117: struct window_more_mode_data *data = wp->modedata;
118: struct screen *s = &data->screen;
119:
120: screen_resize(s, sx, sy);
121: window_more_redraw_screen(wp);
122: }
123:
124: void
125: window_more_key(struct window_pane *wp, unused struct client *c, int key)
126: {
127: struct window_more_mode_data *data = wp->modedata;
128: struct screen *s = &data->screen;
129:
130: switch (mode_key_lookup(&data->mdata, key)) {
131: case MODEKEYCMD_QUIT:
132: window_pane_reset_mode(wp);
133: break;
134: case MODEKEYCMD_UP:
135: window_more_scroll_up(wp);
136: break;
137: case MODEKEYCMD_DOWN:
138: window_more_scroll_down(wp);
139: break;
140: case MODEKEYCMD_PREVIOUSPAGE:
141: if (data->top < screen_size_y(s))
142: data->top = 0;
143: else
144: data->top -= screen_size_y(s);
145: window_more_redraw_screen(wp);
146: break;
147: case MODEKEYCMD_NEXTPAGE:
148: if (data->top + screen_size_y(s) > ARRAY_LENGTH(&data->list))
149: data->top = ARRAY_LENGTH(&data->list);
150: else
151: data->top += screen_size_y(s);
152: window_more_redraw_screen(wp);
153: break;
154: default:
155: break;
156: }
157: }
158:
159: void
160: window_more_write_line(
161: struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
162: {
163: struct window_more_mode_data *data = wp->modedata;
164: struct screen *s = &data->screen;
165: struct grid_cell gc;
166: char *msg, hdr[32];
167: size_t size;
1.2 nicm 168: int utf8flag;
1.1 nicm 169:
1.2 nicm 170: utf8flag = options_get_number(&wp->window->options, "utf8");
1.1 nicm 171: memcpy(&gc, &grid_default_cell, sizeof gc);
172:
173: if (py == 0) {
174: size = xsnprintf(hdr, sizeof hdr,
175: "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
176: screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
177: gc.bg = options_get_number(&wp->window->options, "mode-fg");
178: gc.fg = options_get_number(&wp->window->options, "mode-bg");
179: gc.attr |= options_get_number(&wp->window->options, "mode-attr");
180: screen_write_puts(ctx, &gc, "%s", hdr);
181: memcpy(&gc, &grid_default_cell, sizeof gc);
182: } else
183: size = 0;
184:
185: screen_write_cursormove(ctx, 0, py);
186: if (data->top + py < ARRAY_LENGTH(&data->list)) {
187: msg = ARRAY_ITEM(&data->list, data->top + py);
1.2 nicm 188: screen_write_nputs(
189: ctx, screen_size_x(s) - 1 - size, &gc, utf8flag, "%s", msg);
1.1 nicm 190: }
191: while (s->cx < screen_size_x(s) - size)
192: screen_write_putc(ctx, &gc, ' ');
193: }
194:
195: void
196: window_more_redraw_screen(struct window_pane *wp)
197: {
198: struct window_more_mode_data *data = wp->modedata;
199: struct screen *s = &data->screen;
200: struct screen_write_ctx ctx;
201: u_int i;
202:
203: screen_write_start(&ctx, wp, NULL);
204: for (i = 0; i < screen_size_y(s); i++)
205: window_more_write_line(wp, &ctx, i);
206: screen_write_stop(&ctx);
207: }
208:
209: void
210: window_more_scroll_up(struct window_pane *wp)
211: {
212: struct window_more_mode_data *data = wp->modedata;
213: struct screen_write_ctx ctx;
214:
215: if (data->top == 0)
216: return;
217: data->top--;
218:
219: screen_write_start(&ctx, wp, NULL);
220: screen_write_cursormove(&ctx, 0, 0);
221: screen_write_insertline(&ctx, 1);
222: window_more_write_line(wp, &ctx, 0);
223: window_more_write_line(wp, &ctx, 1);
224: screen_write_stop(&ctx);
225: }
226:
227: void
228: window_more_scroll_down(struct window_pane *wp)
229: {
230: struct window_more_mode_data *data = wp->modedata;
231: struct screen *s = &data->screen;
232: struct screen_write_ctx ctx;
233:
234: if (data->top >= ARRAY_LENGTH(&data->list))
235: return;
236: data->top++;
237:
238: screen_write_start(&ctx, wp, NULL);
239: screen_write_cursormove(&ctx, 0, 0);
240: screen_write_deleteline(&ctx, 1);
241: window_more_write_line(wp, &ctx, screen_size_y(s) - 1);
242: window_more_write_line(wp, &ctx, 0);
243: screen_write_stop(&ctx);
244: }