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