Annotation of src/usr.bin/tmux/window-scroll.c, Revision 1.9
1.9 ! nicm 1: /* $OpenBSD: window-scroll.c,v 1.8 2009/08/13 22:32:18 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;
1.7 nicm 104: u_int n;
1.1 nicm 105:
1.7 nicm 106: n = 1;
107: if (screen_size_y(s) > 2)
108: n = screen_size_y(s) - 2;
109: if (data->oy + n > screen_hsize(&wp->base))
1.1 nicm 110: data->oy = screen_hsize(&wp->base);
111: else
1.7 nicm 112: data->oy += n;
1.1 nicm 113:
114: window_scroll_redraw_screen(wp);
115: }
116:
117: void
118: window_scroll_resize(struct window_pane *wp, u_int sx, u_int sy)
119: {
120: struct window_scroll_mode_data *data = wp->modedata;
121: struct screen *s = &data->screen;
122: struct screen_write_ctx ctx;
123: u_int i;
124:
125: screen_resize(s, sx, sy);
126: screen_write_start(&ctx, NULL, s);
127: for (i = 0; i < screen_size_y(s); i++)
128: window_scroll_write_line(wp, &ctx, i);
129: screen_write_stop(&ctx);
130: }
131:
132: void
133: window_scroll_key(struct window_pane *wp, unused struct client *c, int key)
134: {
135: struct window_scroll_mode_data *data = wp->modedata;
136: struct screen *s = &data->screen;
1.7 nicm 137: u_int n;
1.1 nicm 138:
139: switch (mode_key_lookup(&data->mdata, key)) {
1.4 nicm 140: case MODEKEYCOPY_CANCEL:
1.1 nicm 141: window_pane_reset_mode(wp);
142: break;
1.3 nicm 143: case MODEKEYCOPY_LEFT:
1.1 nicm 144: window_scroll_scroll_left(wp);
145: break;
1.3 nicm 146: case MODEKEYCOPY_RIGHT:
1.1 nicm 147: window_scroll_scroll_right(wp);
148: break;
1.3 nicm 149: case MODEKEYCOPY_UP:
1.1 nicm 150: window_scroll_scroll_up(wp);
151: break;
1.3 nicm 152: case MODEKEYCOPY_DOWN:
1.1 nicm 153: window_scroll_scroll_down(wp);
154: break;
1.3 nicm 155: case MODEKEYCOPY_PREVIOUSPAGE:
1.1 nicm 156: window_scroll_pageup(wp);
157: break;
1.3 nicm 158: case MODEKEYCOPY_NEXTPAGE:
1.7 nicm 159: n = 1;
160: if (screen_size_y(s) > 2)
161: n = screen_size_y(s) - 2;
1.8 nicm 162: if (data->oy < n)
163: data->oy = 0;
164: else
165: data->oy -= n;
166: window_scroll_redraw_screen(wp);
167: break;
168: case MODEKEYCOPY_HALFPAGEUP:
169: n = screen_size_y(s) / 2;
170: if (data->oy + n > screen_hsize(&wp->base))
171: data->oy = screen_hsize(&wp->base);
172: else
173: data->oy += n;
174: window_scroll_redraw_screen(wp);
175: break;
176: case MODEKEYCOPY_HALFPAGEDOWN:
177: n = screen_size_y(s) / 2;
1.7 nicm 178: if (data->oy < n)
1.1 nicm 179: data->oy = 0;
180: else
1.7 nicm 181: data->oy -= n;
1.1 nicm 182: window_scroll_redraw_screen(wp);
183: break;
184: default:
185: break;
186: }
187: }
188:
189: void
190: window_scroll_write_line(
191: struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
192: {
193: struct window_scroll_mode_data *data = wp->modedata;
194: struct screen *s = &data->screen;
1.9 ! nicm 195: struct options *oo = &wp->window->options;
1.1 nicm 196: struct grid_cell gc;
197: char hdr[32];
198: size_t size;
199:
200: if (py == 0) {
201: memcpy(&gc, &grid_default_cell, sizeof gc);
202: size = xsnprintf(hdr, sizeof hdr,
203: "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&wp->base));
1.9 ! nicm 204: colour_set_fg(&gc, options_get_number(oo, "mode-fg"));
! 205: colour_set_bg(&gc, options_get_number(oo, "mode-bg"));
! 206: gc.attr |= options_get_number(oo, "mode-attr");
1.1 nicm 207: screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
208: screen_write_puts(ctx, &gc, "%s", hdr);
209: memcpy(&gc, &grid_default_cell, sizeof gc);
210: } else
211: size = 0;
212:
213: screen_write_cursormove(ctx, 0, py);
214: screen_write_copy(ctx, &wp->base, data->ox, (screen_hsize(&wp->base) -
215: data->oy) + py, screen_size_x(s) - size, 1);
216: }
217:
218: void
219: window_scroll_write_column(
220: struct window_pane *wp, struct screen_write_ctx *ctx, u_int px)
221: {
222: struct window_scroll_mode_data *data = wp->modedata;
223: struct screen *s = &data->screen;
224:
225: screen_write_cursormove(ctx, px, 0);
226: screen_write_copy(ctx, &wp->base, data->ox + px,
227: screen_hsize(&wp->base) - data->oy, 1, screen_size_y(s));
228: }
229:
230: void
231: window_scroll_redraw_screen(struct window_pane *wp)
232: {
233: struct window_scroll_mode_data *data = wp->modedata;
234: struct screen *s = &data->screen;
235: struct screen_write_ctx ctx;
236: u_int i;
237:
238: screen_write_start(&ctx, wp, NULL);
239: for (i = 0; i < screen_size_y(s); i++)
240: window_scroll_write_line(wp, &ctx, i);
241: screen_write_stop(&ctx);
242: }
243:
244: void
245: window_scroll_scroll_up(struct window_pane *wp)
246: {
247: struct window_scroll_mode_data *data = wp->modedata;
248: struct screen_write_ctx ctx;
249:
250: if (data->oy >= screen_hsize(&wp->base))
251: return;
252: data->oy++;
253:
254: screen_write_start(&ctx, wp, NULL);
255: screen_write_cursormove(&ctx, 0, 0);
256: screen_write_insertline(&ctx, 1);
257: window_scroll_write_line(wp, &ctx, 0);
258: window_scroll_write_line(wp, &ctx, 1);
259: screen_write_stop(&ctx);
260: }
261:
262: void
263: window_scroll_scroll_down(struct window_pane *wp)
264: {
265: struct window_scroll_mode_data *data = wp->modedata;
266: struct screen *s = &data->screen;
267: struct screen_write_ctx ctx;
268:
269: if (data->oy == 0)
270: return;
271: data->oy--;
272:
273: screen_write_start(&ctx, wp, NULL);
274: screen_write_cursormove(&ctx, 0, 0);
275: screen_write_deleteline(&ctx, 1);
276: window_scroll_write_line(wp, &ctx, screen_size_y(s) - 1);
277: window_scroll_write_line(wp, &ctx, 0);
278: screen_write_stop(&ctx);
279: }
280:
281: void
282: window_scroll_scroll_right(struct window_pane *wp)
283: {
284: struct window_scroll_mode_data *data = wp->modedata;
285: struct screen *s = &data->screen;
286: struct screen_write_ctx ctx;
287: u_int i;
288:
289: if (data->ox >= SHRT_MAX)
290: return;
291: data->ox++;
292:
293: screen_write_start(&ctx, wp, NULL);
294: for (i = 1; i < screen_size_y(s); i++) {
295: screen_write_cursormove(&ctx, 0, i);
296: screen_write_deletecharacter(&ctx, 1);
297: }
298: window_scroll_write_column(wp, &ctx, screen_size_x(s) - 1);
299: window_scroll_write_line(wp, &ctx, 0);
300: screen_write_stop(&ctx);
301: }
302:
303: void
304: window_scroll_scroll_left(struct window_pane *wp)
305: {
306: struct window_scroll_mode_data *data = wp->modedata;
307: struct screen *s = &data->screen;
308: struct screen_write_ctx ctx;
309: u_int i;
310:
311: if (data->ox == 0)
312: return;
313: data->ox--;
314:
315: screen_write_start(&ctx, wp, NULL);
316: for (i = 1; i < screen_size_y(s); i++) {
317: screen_write_cursormove(&ctx, 0, i);
318: screen_write_insertcharacter(&ctx, 1);
319: }
320: window_scroll_write_column(wp, &ctx, 0);
321: window_scroll_write_line(wp, &ctx, 0);
322: screen_write_stop(&ctx);
323: }