Annotation of src/usr.bin/tmux/window-scroll.c, Revision 1.2
1.2 ! nicm 1: /* $OpenBSD: window-scroll.c,v 1.1 2009/06/01 22:58:49 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;
66:
67: wp->modedata = data = xmalloc(sizeof *data);
68: data->ox = 0;
69: data->oy = 0;
70:
71: s = &data->screen;
72: screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
73: s->mode &= ~MODE_CURSOR;
74:
75: mode_key_init(&data->mdata,
76: options_get_number(&wp->window->options, "mode-keys"), 0);
77:
78: screen_write_start(&ctx, NULL, s);
79: for (i = 0; i < screen_size_y(s); i++)
80: window_scroll_write_line(wp, &ctx, i);
81: screen_write_stop(&ctx);
82:
83: return (s);
84: }
85:
86: void
87: window_scroll_free(struct window_pane *wp)
88: {
89: struct window_scroll_mode_data *data = wp->modedata;
90:
91: screen_free(&data->screen);
92: xfree(data);
93: }
94:
95: void
96: window_scroll_pageup(struct window_pane *wp)
97: {
98: struct window_scroll_mode_data *data = wp->modedata;
99: struct screen *s = &data->screen;
100:
101: if (data->oy + screen_size_y(s) > screen_hsize(&wp->base))
102: data->oy = screen_hsize(&wp->base);
103: else
104: data->oy += screen_size_y(s);
105:
106: window_scroll_redraw_screen(wp);
107: }
108:
109: void
110: window_scroll_resize(struct window_pane *wp, u_int sx, u_int sy)
111: {
112: struct window_scroll_mode_data *data = wp->modedata;
113: struct screen *s = &data->screen;
114: struct screen_write_ctx ctx;
115: u_int i;
116:
117: screen_resize(s, sx, sy);
118: screen_write_start(&ctx, NULL, s);
119: for (i = 0; i < screen_size_y(s); i++)
120: window_scroll_write_line(wp, &ctx, i);
121: screen_write_stop(&ctx);
122: }
123:
124: void
125: window_scroll_key(struct window_pane *wp, unused struct client *c, int key)
126: {
127: struct window_scroll_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_LEFT:
135: window_scroll_scroll_left(wp);
136: break;
137: case MODEKEYCMD_RIGHT:
138: window_scroll_scroll_right(wp);
139: break;
140: case MODEKEYCMD_UP:
141: window_scroll_scroll_up(wp);
142: break;
143: case MODEKEYCMD_DOWN:
144: window_scroll_scroll_down(wp);
145: break;
146: case MODEKEYCMD_PREVIOUSPAGE:
147: window_scroll_pageup(wp);
148: break;
149: case MODEKEYCMD_NEXTPAGE:
150: if (data->oy < screen_size_y(s))
151: data->oy = 0;
152: else
153: data->oy -= screen_size_y(s);
154: window_scroll_redraw_screen(wp);
155: break;
156: default:
157: break;
158: }
159: }
160:
161: void
162: window_scroll_write_line(
163: struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
164: {
165: struct window_scroll_mode_data *data = wp->modedata;
166: struct screen *s = &data->screen;
167: struct grid_cell gc;
168: char hdr[32];
169: size_t size;
170:
171: if (py == 0) {
172: memcpy(&gc, &grid_default_cell, sizeof gc);
173: size = xsnprintf(hdr, sizeof hdr,
174: "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&wp->base));
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_cursormove(ctx, screen_size_x(s) - size, 0);
179: screen_write_puts(ctx, &gc, "%s", hdr);
180: memcpy(&gc, &grid_default_cell, sizeof gc);
181: } else
182: size = 0;
183:
184: screen_write_cursormove(ctx, 0, py);
185: screen_write_copy(ctx, &wp->base, data->ox, (screen_hsize(&wp->base) -
186: data->oy) + py, screen_size_x(s) - size, 1);
187: }
188:
189: void
190: window_scroll_write_column(
191: struct window_pane *wp, struct screen_write_ctx *ctx, u_int px)
192: {
193: struct window_scroll_mode_data *data = wp->modedata;
194: struct screen *s = &data->screen;
195:
196: screen_write_cursormove(ctx, px, 0);
197: screen_write_copy(ctx, &wp->base, data->ox + px,
198: screen_hsize(&wp->base) - data->oy, 1, screen_size_y(s));
199: }
200:
201: void
202: window_scroll_redraw_screen(struct window_pane *wp)
203: {
204: struct window_scroll_mode_data *data = wp->modedata;
205: struct screen *s = &data->screen;
206: struct screen_write_ctx ctx;
207: u_int i;
208:
209: screen_write_start(&ctx, wp, NULL);
210: for (i = 0; i < screen_size_y(s); i++)
211: window_scroll_write_line(wp, &ctx, i);
212: screen_write_stop(&ctx);
213: }
214:
215: void
216: window_scroll_scroll_up(struct window_pane *wp)
217: {
218: struct window_scroll_mode_data *data = wp->modedata;
219: struct screen_write_ctx ctx;
220:
221: if (data->oy >= screen_hsize(&wp->base))
222: return;
223: data->oy++;
224:
225: screen_write_start(&ctx, wp, NULL);
226: screen_write_cursormove(&ctx, 0, 0);
227: screen_write_insertline(&ctx, 1);
228: window_scroll_write_line(wp, &ctx, 0);
229: window_scroll_write_line(wp, &ctx, 1);
230: screen_write_stop(&ctx);
231: }
232:
233: void
234: window_scroll_scroll_down(struct window_pane *wp)
235: {
236: struct window_scroll_mode_data *data = wp->modedata;
237: struct screen *s = &data->screen;
238: struct screen_write_ctx ctx;
239:
240: if (data->oy == 0)
241: return;
242: data->oy--;
243:
244: screen_write_start(&ctx, wp, NULL);
245: screen_write_cursormove(&ctx, 0, 0);
246: screen_write_deleteline(&ctx, 1);
247: window_scroll_write_line(wp, &ctx, screen_size_y(s) - 1);
248: window_scroll_write_line(wp, &ctx, 0);
249: screen_write_stop(&ctx);
250: }
251:
252: void
253: window_scroll_scroll_right(struct window_pane *wp)
254: {
255: struct window_scroll_mode_data *data = wp->modedata;
256: struct screen *s = &data->screen;
257: struct screen_write_ctx ctx;
258: u_int i;
259:
260: if (data->ox >= SHRT_MAX)
261: return;
262: data->ox++;
263:
264: screen_write_start(&ctx, wp, NULL);
265: for (i = 1; i < screen_size_y(s); i++) {
266: screen_write_cursormove(&ctx, 0, i);
267: screen_write_deletecharacter(&ctx, 1);
268: }
269: window_scroll_write_column(wp, &ctx, screen_size_x(s) - 1);
270: window_scroll_write_line(wp, &ctx, 0);
271: screen_write_stop(&ctx);
272: }
273:
274: void
275: window_scroll_scroll_left(struct window_pane *wp)
276: {
277: struct window_scroll_mode_data *data = wp->modedata;
278: struct screen *s = &data->screen;
279: struct screen_write_ctx ctx;
280: u_int i;
281:
282: if (data->ox == 0)
283: return;
284: data->ox--;
285:
286: screen_write_start(&ctx, wp, NULL);
287: for (i = 1; i < screen_size_y(s); i++) {
288: screen_write_cursormove(&ctx, 0, i);
289: screen_write_insertcharacter(&ctx, 1);
290: }
291: window_scroll_write_column(wp, &ctx, 0);
292: window_scroll_write_line(wp, &ctx, 0);
293: screen_write_stop(&ctx);
294: }