Annotation of src/usr.bin/tmux/window-scroll.c, Revision 1.5
1.5 ! nicm 1: /* $OpenBSD: window-scroll.c,v 1.4 2009/07/27 20:36: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_scroll_init(struct window_pane *);
26: void window_scroll_free(struct window_pane *);
27: void window_scroll_resize(struct window_pane *, u_int, u_int);
28: void window_scroll_key(struct window_pane *, struct client *, int);
29:
30: void window_scroll_redraw_screen(struct window_pane *);
31: void window_scroll_write_line(
32: struct window_pane *, struct screen_write_ctx *, u_int);
33: void window_scroll_write_column(
34: struct window_pane *, struct screen_write_ctx *, u_int);
35:
36: void window_scroll_scroll_up(struct window_pane *);
37: void window_scroll_scroll_down(struct window_pane *);
38: void window_scroll_scroll_left(struct window_pane *);
39: void window_scroll_scroll_right(struct window_pane *);
40:
41: const struct window_mode window_scroll_mode = {
42: window_scroll_init,
43: window_scroll_free,
44: window_scroll_resize,
45: window_scroll_key,
46: NULL,
47: NULL,
48: };
49:
50: struct window_scroll_mode_data {
51: struct screen screen;
52:
53: struct mode_key_data mdata;
54:
55: u_int ox;
56: u_int oy;
57: };
58:
59: struct screen *
60: window_scroll_init(struct window_pane *wp)
61: {
62: struct window_scroll_mode_data *data;
63: struct screen *s;
64: struct screen_write_ctx ctx;
65: u_int i;
1.3 nicm 66: int keys;
1.1 nicm 67:
68: wp->modedata = data = xmalloc(sizeof *data);
69: data->ox = 0;
70: data->oy = 0;
71:
72: s = &data->screen;
73: screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
74: s->mode &= ~MODE_CURSOR;
75:
1.3 nicm 76: keys = options_get_number(&wp->window->options, "mode-keys");
77: if (keys == MODEKEY_EMACS)
1.5 ! nicm 78: mode_key_init(&data->mdata, &mode_key_tree_emacs_copy);
1.3 nicm 79: else
1.5 ! nicm 80: mode_key_init(&data->mdata, &mode_key_tree_vi_copy);
1.1 nicm 81:
82: screen_write_start(&ctx, NULL, s);
83: for (i = 0; i < screen_size_y(s); i++)
84: window_scroll_write_line(wp, &ctx, i);
85: screen_write_stop(&ctx);
86:
87: return (s);
88: }
89:
90: void
91: window_scroll_free(struct window_pane *wp)
92: {
93: struct window_scroll_mode_data *data = wp->modedata;
94:
95: screen_free(&data->screen);
96: xfree(data);
97: }
98:
99: void
100: window_scroll_pageup(struct window_pane *wp)
101: {
102: struct window_scroll_mode_data *data = wp->modedata;
103: struct screen *s = &data->screen;
104:
105: if (data->oy + screen_size_y(s) > screen_hsize(&wp->base))
106: data->oy = screen_hsize(&wp->base);
107: else
108: data->oy += screen_size_y(s);
109:
110: window_scroll_redraw_screen(wp);
111: }
112:
113: void
114: window_scroll_resize(struct window_pane *wp, u_int sx, u_int sy)
115: {
116: struct window_scroll_mode_data *data = wp->modedata;
117: struct screen *s = &data->screen;
118: struct screen_write_ctx ctx;
119: u_int i;
120:
121: screen_resize(s, sx, sy);
122: screen_write_start(&ctx, NULL, s);
123: for (i = 0; i < screen_size_y(s); i++)
124: window_scroll_write_line(wp, &ctx, i);
125: screen_write_stop(&ctx);
126: }
127:
128: void
129: window_scroll_key(struct window_pane *wp, unused struct client *c, int key)
130: {
131: struct window_scroll_mode_data *data = wp->modedata;
132: struct screen *s = &data->screen;
133:
134: switch (mode_key_lookup(&data->mdata, key)) {
1.4 nicm 135: case MODEKEYCOPY_CANCEL:
1.1 nicm 136: window_pane_reset_mode(wp);
137: break;
1.3 nicm 138: case MODEKEYCOPY_LEFT:
1.1 nicm 139: window_scroll_scroll_left(wp);
140: break;
1.3 nicm 141: case MODEKEYCOPY_RIGHT:
1.1 nicm 142: window_scroll_scroll_right(wp);
143: break;
1.3 nicm 144: case MODEKEYCOPY_UP:
1.1 nicm 145: window_scroll_scroll_up(wp);
146: break;
1.3 nicm 147: case MODEKEYCOPY_DOWN:
1.1 nicm 148: window_scroll_scroll_down(wp);
149: break;
1.3 nicm 150: case MODEKEYCOPY_PREVIOUSPAGE:
1.1 nicm 151: window_scroll_pageup(wp);
152: break;
1.3 nicm 153: case MODEKEYCOPY_NEXTPAGE:
1.1 nicm 154: if (data->oy < screen_size_y(s))
155: data->oy = 0;
156: else
157: data->oy -= screen_size_y(s);
158: window_scroll_redraw_screen(wp);
159: break;
160: default:
161: break;
162: }
163: }
164:
165: void
166: window_scroll_write_line(
167: struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
168: {
169: struct window_scroll_mode_data *data = wp->modedata;
170: struct screen *s = &data->screen;
171: struct grid_cell gc;
172: char hdr[32];
173: size_t size;
174:
175: if (py == 0) {
176: memcpy(&gc, &grid_default_cell, sizeof gc);
177: size = xsnprintf(hdr, sizeof hdr,
178: "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&wp->base));
179: gc.bg = options_get_number(&wp->window->options, "mode-fg");
180: gc.fg = options_get_number(&wp->window->options, "mode-bg");
181: gc.attr |= options_get_number(&wp->window->options, "mode-attr");
182: screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
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: screen_write_copy(ctx, &wp->base, data->ox, (screen_hsize(&wp->base) -
190: data->oy) + py, screen_size_x(s) - size, 1);
191: }
192:
193: void
194: window_scroll_write_column(
195: struct window_pane *wp, struct screen_write_ctx *ctx, u_int px)
196: {
197: struct window_scroll_mode_data *data = wp->modedata;
198: struct screen *s = &data->screen;
199:
200: screen_write_cursormove(ctx, px, 0);
201: screen_write_copy(ctx, &wp->base, data->ox + px,
202: screen_hsize(&wp->base) - data->oy, 1, screen_size_y(s));
203: }
204:
205: void
206: window_scroll_redraw_screen(struct window_pane *wp)
207: {
208: struct window_scroll_mode_data *data = wp->modedata;
209: struct screen *s = &data->screen;
210: struct screen_write_ctx ctx;
211: u_int i;
212:
213: screen_write_start(&ctx, wp, NULL);
214: for (i = 0; i < screen_size_y(s); i++)
215: window_scroll_write_line(wp, &ctx, i);
216: screen_write_stop(&ctx);
217: }
218:
219: void
220: window_scroll_scroll_up(struct window_pane *wp)
221: {
222: struct window_scroll_mode_data *data = wp->modedata;
223: struct screen_write_ctx ctx;
224:
225: if (data->oy >= screen_hsize(&wp->base))
226: return;
227: data->oy++;
228:
229: screen_write_start(&ctx, wp, NULL);
230: screen_write_cursormove(&ctx, 0, 0);
231: screen_write_insertline(&ctx, 1);
232: window_scroll_write_line(wp, &ctx, 0);
233: window_scroll_write_line(wp, &ctx, 1);
234: screen_write_stop(&ctx);
235: }
236:
237: void
238: window_scroll_scroll_down(struct window_pane *wp)
239: {
240: struct window_scroll_mode_data *data = wp->modedata;
241: struct screen *s = &data->screen;
242: struct screen_write_ctx ctx;
243:
244: if (data->oy == 0)
245: return;
246: data->oy--;
247:
248: screen_write_start(&ctx, wp, NULL);
249: screen_write_cursormove(&ctx, 0, 0);
250: screen_write_deleteline(&ctx, 1);
251: window_scroll_write_line(wp, &ctx, screen_size_y(s) - 1);
252: window_scroll_write_line(wp, &ctx, 0);
253: screen_write_stop(&ctx);
254: }
255:
256: void
257: window_scroll_scroll_right(struct window_pane *wp)
258: {
259: struct window_scroll_mode_data *data = wp->modedata;
260: struct screen *s = &data->screen;
261: struct screen_write_ctx ctx;
262: u_int i;
263:
264: if (data->ox >= SHRT_MAX)
265: return;
266: data->ox++;
267:
268: screen_write_start(&ctx, wp, NULL);
269: for (i = 1; i < screen_size_y(s); i++) {
270: screen_write_cursormove(&ctx, 0, i);
271: screen_write_deletecharacter(&ctx, 1);
272: }
273: window_scroll_write_column(wp, &ctx, screen_size_x(s) - 1);
274: window_scroll_write_line(wp, &ctx, 0);
275: screen_write_stop(&ctx);
276: }
277:
278: void
279: window_scroll_scroll_left(struct window_pane *wp)
280: {
281: struct window_scroll_mode_data *data = wp->modedata;
282: struct screen *s = &data->screen;
283: struct screen_write_ctx ctx;
284: u_int i;
285:
286: if (data->ox == 0)
287: return;
288: data->ox--;
289:
290: screen_write_start(&ctx, wp, NULL);
291: for (i = 1; i < screen_size_y(s); i++) {
292: screen_write_cursormove(&ctx, 0, i);
293: screen_write_insertcharacter(&ctx, 1);
294: }
295: window_scroll_write_column(wp, &ctx, 0);
296: window_scroll_write_line(wp, &ctx, 0);
297: screen_write_stop(&ctx);
298: }