tin  2.6.1
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.6.1.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

global.c
Go to the documentation of this file.
1/*
2 * Project : tin - a Usenet reader
3 * Module : global.c
4 * Author : Jason Faultless <jason@altarstone.com>
5 * Created : 1999-12-12
6 * Updated : 2021-02-23
7 * Notes : Generic navigation and key handling routines
8 *
9 * Copyright (c) 1999-2022 Jason Faultless <jason@altarstone.com>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * 3. Neither the name of the copyright holder nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40
41#ifndef TIN_H
42# include "tin.h"
43#endif /* !TIN_H */
44#ifndef TCURSES_H
45# include "tcurses.h"
46#endif /* !TCURSES_H */
47
48/*
49 * Local prototypes
50 */
51#ifdef USE_CURSES
52 static void do_scroll(int jump);
53#endif /* USE_CURSES */
54
55
56/*
57 * Calculate the first and last objects that will appear on the current screen
58 * based on the current position and the max available
59 */
60void
62 void)
63{
64 if (currmenu->max == 0) {
65 currmenu->first = 0;
66 currmenu->curr = -1;
67 return;
68 }
69
70 if (currmenu->curr >= currmenu->max)
71 currmenu->curr = currmenu->max - 1;
72 else if (currmenu->curr < -1)
73 currmenu->curr = -1;
74
75 if (currmenu->curr < currmenu->first || currmenu->curr > currmenu->first + NOTESLINES - 1) /* current selection is out of screen */
77}
78
79
80void
82 void)
83{
84 if (!currmenu->max)
85 return;
86
87 if (currmenu->curr - 1 < currmenu->first && currmenu->curr != 0) {
88 currmenu->first--;
89#ifdef USE_CURSES
90 do_scroll(-1);
92#else
94#endif /* USE_CURSES */
95 }
96 if (currmenu->curr == 0) {
98
99 if (currmenu->max - 1 >= NOTESLINES) {
100 currmenu->curr = currmenu->max - 1;
101 currmenu->redraw();
102 } else
104 } else
106}
107
108
109void
111 void)
112{
113 if (!currmenu->max)
114 return;
115
116 if (currmenu->curr + 1 > currmenu->first + NOTESLINES - 1 && currmenu->curr + 1 < currmenu->max) {
117 currmenu->first++;
118#ifdef USE_CURSES
119 do_scroll(1);
121#else
122 currmenu->redraw();
123#endif /* USE_CURSES */
124 }
125 move_to_item((currmenu->curr + 1 >= currmenu->max) ? 0 : (currmenu->curr + 1));
126}
127
128
129void
131 void)
132{
133 int scroll_lines;
134
135 if (!currmenu->max)
136 return;
137
138 if (currmenu->curr == currmenu->first) {
139 scroll_lines = (tinrc.scroll_lines == -2) ? NOTESLINES / 2 : NOTESLINES;
140 if (currmenu->first == 0) {
141 /* wrap around */
142 currmenu->first = MAX(0, currmenu->max - scroll_lines);
143 currmenu->curr = currmenu->max - 1;
144 } else {
145 currmenu->first = MAX(0, currmenu->first - scroll_lines);
147 }
148 currmenu->redraw();
149 } else
151}
152
153
154void
156 void)
157{
158 int scroll_lines;
159
160 if (!currmenu->max)
161 return;
162
163 if (currmenu->curr == currmenu->max - 1) {
164 /* wrap around */
165 currmenu->first = 0;
166 currmenu->curr = 0;
167 currmenu->redraw();
168 } else {
169 scroll_lines = (tinrc.scroll_lines == -2) ? NOTESLINES / 2 : NOTESLINES;
170 if (currmenu->first + scroll_lines >= currmenu->max)
172 else {
173 currmenu->first += scroll_lines;
175 currmenu->redraw();
176 }
177 }
178}
179
180
181void
183 void)
184{
185 if (currmenu->max)
186 move_to_item(0);
187}
188
189
190void
192 void)
193{
194 if (currmenu->max)
196}
197
198
199void
201 int ch,
202 const char *prompt)
203{
204 int num;
205
207
208 if ((num = prompt_num(ch, prompt)) == -1) {
210 return;
211 }
212
213 if (--num < 0) /* index from 0 (internal) vs. 1 (user) */
214 num = 0;
215
216 if (num >= currmenu->max)
217 num = currmenu->max - 1;
218
219 move_to_item(num);
220}
221
222
223/*
224 * Move the on-screen pointer & internal pointer variable to a new position
225 */
226void
228 int n)
229{
230 if (currmenu->curr == n)
231 return;
232
234 erase_arrow();
235
236 if ((currmenu->curr = n) < 0)
237 currmenu->curr = 0;
239
240 if (n >= currmenu->first && n < currmenu->first + NOTESLINES)
242 else
243 currmenu->redraw();
244}
245
246
247/*
248 * scroll the screen one line down
249 * the selected item is only moved if it is scrolled off the screen
250 */
251void
253 void)
254{
256 return;
257
258 currmenu->first++;
259#ifdef USE_CURSES
260 do_scroll(1);
262 stow_cursor();
263 if (currmenu->curr < currmenu->first)
265#else
266 if (currmenu->curr < currmenu->first)
267 currmenu->curr++;
268 currmenu->redraw();
269#endif /* USE_CURSES */
270}
271
272
273/*
274 * scroll the screen one line up
275 * the selected item is only moved if it is scrolled off the screen
276 */
277void
279 void)
280{
281 if (!currmenu->max || currmenu->first == 0)
282 return;
283
284 currmenu->first--;
285#ifdef USE_CURSES
286 do_scroll(-1);
288 stow_cursor();
291#else
293 currmenu->curr--;
294 currmenu->redraw();
295#endif /* USE_CURSES */
296}
297
298
299#ifdef USE_CURSES
300/* TODO: merge with options_menu.c:do_scroll() and move to tcurses.c */
301/* scroll the screen 'jump' lines down or up (if 'jump' < 0) */
302static void
303do_scroll(
304 int jump)
305{
306 scrollok(stdscr, TRUE);
309 ScrollScreen(jump);
310 SetScrollRegion(0, LINES - 1);
311 scrollok(stdscr, FALSE);
312}
313#endif /* USE_CURSES */
314
315
316/*
317 * Handle mouse clicks. We simply map the event to a return
318 * keymap code that will drop through to call the correct function
319 */
322 t_function (*left_action) (void),
323 t_function (*right_action) (void))
324{
325 int INDEX_BOTTOM = INDEX_TOP + NOTESLINES;
326
327 switch (xmouse) {
328 case MOUSE_BUTTON_1:
329 case MOUSE_BUTTON_3:
330 if (xrow < INDEX_TOP || xrow >= INDEX_BOTTOM)
331 return GLOBAL_PAGE_DOWN;
332
333 erase_arrow();
336
337 if (xmouse == MOUSE_BUTTON_1)
338 return right_action();
339 break;
340
341 case MOUSE_BUTTON_2:
342 if (xrow < INDEX_TOP || xrow >= INDEX_BOTTOM)
343 return GLOBAL_PAGE_UP;
344
345 return left_action();
346
347 default:
348 break;
349 }
350 return NOT_ASSIGNED;
351}
352
353
356 t_function (*left_action) (void),
357 t_function (*right_action) (void),
358 t_function (*mouse_action) (
359 t_function (*left_action) (void),
360 t_function (*right_action) (void)),
361 const struct keylist keys)
362{
363#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
364 wint_t ch = ReadWch();
365#else
366 int ch = ReadCh();
367#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
369
370 switch (ch) {
371 case ESC: /* common arrow keys */
372#ifdef HAVE_KEY_PREFIX
373 case KEY_PREFIX:
374#endif /* HAVE_KEY_PREFIX */
375 switch (get_arrow_key((int) ch)) {
376 case KEYMAP_UP:
378 break;
379
380 case KEYMAP_DOWN:
382 break;
383
384 case KEYMAP_LEFT:
385 func = left_action();
386 break;
387
388 case KEYMAP_RIGHT:
389 func = right_action();
390 break;
391
392 case KEYMAP_PAGE_UP:
394 break;
395
396 case KEYMAP_PAGE_DOWN:
398 break;
399
400 case KEYMAP_HOME:
402 break;
403
404 case KEYMAP_END:
406 break;
407
408 case KEYMAP_MOUSE:
409 if (mouse_action)
410 func = mouse_action(left_action, right_action);
411 break;
412
413 default:
414 break;
415 }
416 break;
417
418 default:
419 func = key_to_func((wchar_t) ch, keys);
420 break;
421 }
422 return func;
423}
424
425
426/*
427 * bug/gripe/comment mailed to author
428 */
429void
431 void)
432{
434 ClearScreen();
435 currmenu->redraw();
436}
#define TRUE
Definition: bool.h:74
#define FALSE
Definition: bool.h:70
int NOTESLINES
Definition: signal.c:111
int xrow
Definition: init.c:123
t_menu * currmenu
Definition: init.c:166
int xmouse
Definition: init.c:123
struct t_config tinrc
Definition: init.c:192
void scroll_down(void)
Definition: global.c:252
void move_to_item(int n)
Definition: global.c:227
void page_up(void)
Definition: global.c:130
void prompt_item_num(int ch, const char *prompt)
Definition: global.c:200
t_function global_mouse_action(t_function(*left_action)(void), t_function(*right_action)(void))
Definition: global.c:321
t_function handle_keypad(t_function(*left_action)(void), t_function(*right_action)(void), t_function(*mouse_action)(t_function(*left_action)(void), t_function(*right_action)(void)), const struct keylist keys)
Definition: global.c:355
void scroll_up(void)
Definition: global.c:278
void page_down(void)
Definition: global.c:155
void move_up(void)
Definition: global.c:81
void move_down(void)
Definition: global.c:110
void set_first_screen_item(void)
Definition: global.c:61
void end_of_list(void)
Definition: global.c:191
void top_of_list(void)
Definition: global.c:182
void bug_report(void)
Definition: global.c:430
t_function key_to_func(const char key, const struct keylist keys)
Definition: keymap.c:98
#define ESC
Definition: keymap.h:140
@ GLOBAL_PAGE_UP
Definition: keymap.h:201
@ GLOBAL_LINE_DOWN
Definition: keymap.h:194
@ NOT_ASSIGNED
Definition: keymap.h:149
@ GLOBAL_PAGE_DOWN
Definition: keymap.h:200
@ GLOBAL_FIRST_PAGE
Definition: keymap.h:190
@ GLOBAL_LAST_PAGE
Definition: keymap.h:192
@ GLOBAL_LINE_UP
Definition: keymap.h:195
enum defined_functions t_function
Definition: keymap.h:375
int ReadCh(void)
Definition: curses.c:1110
void ClearScreen(void)
Definition: curses.c:410
void ScrollScreen(int lines_to_scroll)
Definition: curses.c:509
void erase_arrow(void)
Definition: screen.c:404
void SetScrollRegion(int topline, int bottomline)
Definition: curses.c:490
void MoveCursor(int row, int col)
Definition: curses.c:441
void clear_message(void)
Definition: screen.c:283
t_bool mail_bug_report(void)
Definition: post.c:3911
void stow_cursor(void)
Definition: screen.c:59
int prompt_num(int ch, const char *prompt)
Definition: prompt.c:65
int get_arrow_key(int prech)
Definition: curses.c:961
void(* func)(SIG_ARGS)
Definition: signal.c:176
int scroll_lines
Definition: tinrc.h:156
int curr
Definition: tin.h:2056
void(* draw_item)(int item)
Definition: tin.h:2061
void(* redraw)(void)
Definition: tin.h:2059
void(* draw_arrow)(void)
Definition: tin.h:2060
int first
Definition: tin.h:2058
int max
Definition: tin.h:2057
#define HpGlitch(func)
Definition: tcurses.h:182
#define MOUSE_BUTTON_1
Definition: tin.h:2159
#define KEYMAP_END
Definition: tin.h:1084
#define KEYMAP_RIGHT
Definition: tin.h:1080
#define MIN(a, b)
Definition: tin.h:811
#define KEYMAP_UP
Definition: tin.h:1077
#define MOUSE_BUTTON_3
Definition: tin.h:2161
#define KEYMAP_LEFT
Definition: tin.h:1079
#define KEYMAP_PAGE_DOWN
Definition: tin.h:1082
#define KEYMAP_PAGE_UP
Definition: tin.h:1081
#define KEYMAP_MOUSE
Definition: tin.h:1087
#define KEYMAP_DOWN
Definition: tin.h:1078
#define INDEX_TOP
Definition: tin.h:1019
#define MOUSE_BUTTON_2
Definition: tin.h:2160
#define KEYMAP_HOME
Definition: tin.h:1083
#define MAX(a, b)
Definition: tin.h:808