1 /* $Id: window-more.c,v 1.29 2009-02-13 21:39:45 nicm Exp $ */
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_add(struct window_pane
*wp
, const char *fmt
, ...)
84 window_more_vadd(wp
, fmt
, ap
);
89 window_more_init(struct window_pane
*wp
)
91 struct window_more_mode_data
*data
;
94 wp
->modedata
= data
= xmalloc(sizeof *data
);
95 ARRAY_INIT(&data
->list
);
99 screen_init(s
, screen_size_x(&wp
->base
), screen_size_y(&wp
->base
), 0);
100 s
->mode
&= ~MODE_CURSOR
;
102 mode_key_init(&data
->mdata
,
103 options_get_number(&wp
->window
->options
, "mode-keys"), 0);
109 window_more_free(struct window_pane
*wp
)
111 struct window_more_mode_data
*data
= wp
->modedata
;
114 mode_key_free(&data
->mdata
);
116 for (i
= 0; i
< ARRAY_LENGTH(&data
->list
); i
++)
117 xfree(ARRAY_ITEM(&data
->list
, i
));
118 ARRAY_FREE(&data
->list
);
120 screen_free(&data
->screen
);
125 window_more_resize(struct window_pane
*wp
, u_int sx
, u_int sy
)
127 struct window_more_mode_data
*data
= wp
->modedata
;
128 struct screen
*s
= &data
->screen
;
130 screen_resize(s
, sx
, sy
);
131 window_more_redraw_screen(wp
);
135 window_more_key(struct window_pane
*wp
, unused
struct client
*c
, int key
)
137 struct window_more_mode_data
*data
= wp
->modedata
;
138 struct screen
*s
= &data
->screen
;
140 switch (mode_key_lookup(&data
->mdata
, key
)) {
141 case MODEKEYCMD_QUIT
:
142 window_pane_reset_mode(wp
);
145 window_more_scroll_up(wp
);
147 case MODEKEYCMD_DOWN
:
148 window_more_scroll_down(wp
);
150 case MODEKEYCMD_PREVIOUSPAGE
:
151 if (data
->top
< screen_size_y(s
))
154 data
->top
-= screen_size_y(s
);
155 window_more_redraw_screen(wp
);
157 case MODEKEYCMD_NEXTPAGE
:
158 if (data
->top
+ screen_size_y(s
) > ARRAY_LENGTH(&data
->list
))
159 data
->top
= ARRAY_LENGTH(&data
->list
);
161 data
->top
+= screen_size_y(s
);
162 window_more_redraw_screen(wp
);
170 window_more_write_line(
171 struct window_pane
*wp
, struct screen_write_ctx
*ctx
, u_int py
)
173 struct window_more_mode_data
*data
= wp
->modedata
;
174 struct screen
*s
= &data
->screen
;
179 memcpy(&gc
, &grid_default_cell
, sizeof gc
);
182 size
= xsnprintf(hdr
, sizeof hdr
,
183 "[%u/%u]", data
->top
, ARRAY_LENGTH(&data
->list
));
184 screen_write_cursormove(ctx
, screen_size_x(s
) - size
, 0);
185 gc
.bg
= options_get_number(&wp
->window
->options
, "mode-fg");
186 gc
.fg
= options_get_number(&wp
->window
->options
, "mode-bg");
187 gc
.attr
|= options_get_number(&wp
->window
->options
, "mode-attr");
188 screen_write_puts(ctx
, &gc
, "%s", hdr
);
189 memcpy(&gc
, &grid_default_cell
, sizeof gc
);
193 screen_write_cursormove(ctx
, 0, py
);
194 if (data
->top
+ py
< ARRAY_LENGTH(&data
->list
)) {
195 msg
= ARRAY_ITEM(&data
->list
, data
->top
+ py
);
197 ctx
, &gc
, "%.*s", (int) (screen_size_x(s
) - size
), msg
);
199 while (s
->cx
< screen_size_x(s
) - size
)
200 screen_write_putc(ctx
, &gc
, ' ');
204 window_more_redraw_screen(struct window_pane
*wp
)
206 struct window_more_mode_data
*data
= wp
->modedata
;
207 struct screen
*s
= &data
->screen
;
208 struct screen_write_ctx ctx
;
211 screen_write_start(&ctx
, wp
, NULL
);
212 for (i
= 0; i
< screen_size_y(s
); i
++)
213 window_more_write_line(wp
, &ctx
, i
);
214 screen_write_stop(&ctx
);
218 window_more_scroll_up(struct window_pane
*wp
)
220 struct window_more_mode_data
*data
= wp
->modedata
;
221 struct screen_write_ctx ctx
;
227 screen_write_start(&ctx
, wp
, NULL
);
228 screen_write_cursormove(&ctx
, 0, 0);
229 screen_write_insertline(&ctx
, 1);
230 window_more_write_line(wp
, &ctx
, 0);
231 window_more_write_line(wp
, &ctx
, 1);
232 screen_write_stop(&ctx
);
236 window_more_scroll_down(struct window_pane
*wp
)
238 struct window_more_mode_data
*data
= wp
->modedata
;
239 struct screen
*s
= &data
->screen
;
240 struct screen_write_ctx ctx
;
242 if (data
->top
>= ARRAY_LENGTH(&data
->list
))
246 screen_write_start(&ctx
, wp
, NULL
);
247 screen_write_cursormove(&ctx
, 0, 0);
248 screen_write_deleteline(&ctx
, 1);
249 window_more_write_line(wp
, &ctx
, screen_size_y(s
) - 1);
250 window_more_write_line(wp
, &ctx
, 0);
251 screen_write_stop(&ctx
);