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