4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
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);
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
);
34 void window_more_scroll_up(struct window_pane
*);
35 void window_more_scroll_down(struct window_pane
*);
37 const struct window_mode window_more_mode
= {
46 struct window_more_mode_data
{
49 struct mode_key_data mdata
;
51 ARRAY_DECL(, char *) list
;
56 window_more_vadd(struct window_pane
*wp
, const char *fmt
, va_list ap
)
58 struct window_more_mode_data
*data
= wp
->modedata
;
59 struct screen
*s
= &data
->screen
;
60 struct screen_write_ctx ctx
;
64 xvasprintf(&msg
, fmt
, ap
);
65 ARRAY_ADD(&data
->list
, msg
);
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);
74 window_more_write_line(wp
, &ctx
, 0);
75 screen_write_stop(&ctx
);
79 window_more_init(struct window_pane
*wp
)
81 struct window_more_mode_data
*data
;
85 wp
->modedata
= data
= xmalloc(sizeof *data
);
86 ARRAY_INIT(&data
->list
);
90 screen_init(s
, screen_size_x(&wp
->base
), screen_size_y(&wp
->base
), 0);
91 s
->mode
&= ~MODE_CURSOR
;
93 keys
= options_get_number(&wp
->window
->options
, "mode-keys");
94 if (keys
== MODEKEY_EMACS
)
95 mode_key_init(&data
->mdata
, &mode_key_tree_emacs_choice
);
97 mode_key_init(&data
->mdata
, &mode_key_tree_vi_choice
);
103 window_more_free(struct window_pane
*wp
)
105 struct window_more_mode_data
*data
= wp
->modedata
;
108 for (i
= 0; i
< ARRAY_LENGTH(&data
->list
); i
++)
109 xfree(ARRAY_ITEM(&data
->list
, i
));
110 ARRAY_FREE(&data
->list
);
112 screen_free(&data
->screen
);
117 window_more_resize(struct window_pane
*wp
, u_int sx
, u_int sy
)
119 struct window_more_mode_data
*data
= wp
->modedata
;
120 struct screen
*s
= &data
->screen
;
122 screen_resize(s
, sx
, sy
);
123 window_more_redraw_screen(wp
);
128 window_more_key(struct window_pane
*wp
, unused
struct client
*c
, int key
)
130 struct window_more_mode_data
*data
= wp
->modedata
;
131 struct screen
*s
= &data
->screen
;
133 switch (mode_key_lookup(&data
->mdata
, key
)) {
134 case MODEKEYCHOICE_CANCEL
:
135 window_pane_reset_mode(wp
);
137 case MODEKEYCHOICE_UP
:
138 case MODEKEYCHOICE_SCROLLUP
:
139 window_more_scroll_up(wp
);
141 case MODEKEYCHOICE_DOWN
:
142 case MODEKEYCHOICE_SCROLLDOWN
:
143 window_more_scroll_down(wp
);
145 case MODEKEYCHOICE_PAGEUP
:
146 if (data
->top
< screen_size_y(s
))
149 data
->top
-= screen_size_y(s
);
150 window_more_redraw_screen(wp
);
152 case MODEKEYCHOICE_PAGEDOWN
:
153 if (data
->top
+ screen_size_y(s
) > ARRAY_LENGTH(&data
->list
))
154 data
->top
= ARRAY_LENGTH(&data
->list
);
156 data
->top
+= screen_size_y(s
);
157 window_more_redraw_screen(wp
);
165 window_more_write_line(
166 struct window_pane
*wp
, struct screen_write_ctx
*ctx
, u_int py
)
168 struct window_more_mode_data
*data
= wp
->modedata
;
169 struct screen
*s
= &data
->screen
;
170 struct options
*oo
= &wp
->window
->options
;
176 utf8flag
= options_get_number(&wp
->window
->options
, "utf8");
177 memcpy(&gc
, &grid_default_cell
, sizeof gc
);
180 size
= xsnprintf(hdr
, sizeof hdr
,
181 "[%u/%u]", data
->top
, ARRAY_LENGTH(&data
->list
));
182 screen_write_cursormove(ctx
, screen_size_x(s
) - size
, 0);
183 colour_set_fg(&gc
, options_get_number(oo
, "mode-fg"));
184 colour_set_bg(&gc
, options_get_number(oo
, "mode-bg"));
185 gc
.attr
|= options_get_number(oo
, "mode-attr");
186 screen_write_puts(ctx
, &gc
, "%s", hdr
);
187 memcpy(&gc
, &grid_default_cell
, sizeof gc
);
191 screen_write_cursormove(ctx
, 0, py
);
192 if (data
->top
+ py
< ARRAY_LENGTH(&data
->list
)) {
193 msg
= ARRAY_ITEM(&data
->list
, data
->top
+ py
);
195 ctx
, screen_size_x(s
) - size
, &gc
, utf8flag
, "%s", msg
);
197 while (s
->cx
< screen_size_x(s
) - size
)
198 screen_write_putc(ctx
, &gc
, ' ');
202 window_more_redraw_screen(struct window_pane
*wp
)
204 struct window_more_mode_data
*data
= wp
->modedata
;
205 struct screen
*s
= &data
->screen
;
206 struct screen_write_ctx ctx
;
209 screen_write_start(&ctx
, wp
, NULL
);
210 for (i
= 0; i
< screen_size_y(s
); i
++)
211 window_more_write_line(wp
, &ctx
, i
);
212 screen_write_stop(&ctx
);
216 window_more_scroll_up(struct window_pane
*wp
)
218 struct window_more_mode_data
*data
= wp
->modedata
;
219 struct screen_write_ctx ctx
;
225 screen_write_start(&ctx
, wp
, NULL
);
226 screen_write_cursormove(&ctx
, 0, 0);
227 screen_write_insertline(&ctx
, 1);
228 window_more_write_line(wp
, &ctx
, 0);
229 window_more_write_line(wp
, &ctx
, 1);
230 screen_write_stop(&ctx
);
234 window_more_scroll_down(struct window_pane
*wp
)
236 struct window_more_mode_data
*data
= wp
->modedata
;
237 struct screen
*s
= &data
->screen
;
238 struct screen_write_ctx ctx
;
240 if (data
->top
>= ARRAY_LENGTH(&data
->list
))
244 screen_write_start(&ctx
, wp
, NULL
);
245 screen_write_cursormove(&ctx
, 0, 0);
246 screen_write_deleteline(&ctx
, 1);
247 window_more_write_line(wp
, &ctx
, screen_size_y(s
) - 1);
248 window_more_write_line(wp
, &ctx
, 0);
249 screen_write_stop(&ctx
);