"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.1/src/global.c" (22 Dec 2021, 9216 Bytes) of package /linux/misc/tin-2.6.1.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "global.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.6.0_vs_2.6.1.
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 */
60 void
61 set_first_screen_item(
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 */
76 currmenu->first = (currmenu->curr / NOTESLINES) * NOTESLINES;
77 }
78
79
80 void
81 move_up(
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);
91 currmenu->draw_item(currmenu->curr - 1);
92 #else
93 currmenu->redraw();
94 #endif /* USE_CURSES */
95 }
96 if (currmenu->curr == 0) {
97 currmenu->first = MAX(0, currmenu->max - NOTESLINES);
98
99 if (currmenu->max - 1 >= NOTESLINES) {
100 currmenu->curr = currmenu->max - 1;
101 currmenu->redraw();
102 } else
103 move_to_item(currmenu->max - 1);
104 } else
105 move_to_item(currmenu->curr - 1);
106 }
107
108
109 void
110 move_down(
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);
120 currmenu->draw_item(currmenu->curr + 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
129 void
130 page_up(
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);
146 currmenu->curr = currmenu->first;
147 }
148 currmenu->redraw();
149 } else
150 move_to_item(currmenu->first);
151 }
152
153
154 void
155 page_down(
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)
171 move_to_item(currmenu->max - 1);
172 else {
173 currmenu->first += scroll_lines;
174 currmenu->curr = currmenu->first;
175 currmenu->redraw();
176 }
177 }
178 }
179
180
181 void
182 top_of_list(
183 void)
184 {
185 if (currmenu->max)
186 move_to_item(0);
187 }
188
189
190 void
191 end_of_list(
192 void)
193 {
194 if (currmenu->max)
195 move_to_item(currmenu->max - 1);
196 }
197
198
199 void
200 prompt_item_num(
201 int ch,
202 const char *prompt)
203 {
204 int num;
205
206 clear_message();
207
208 if ((num = prompt_num(ch, prompt)) == -1) {
209 clear_message();
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 */
226 void
227 move_to_item(
228 int n)
229 {
230 if (currmenu->curr == n)
231 return;
232
233 HpGlitch(erase_arrow());
234 erase_arrow();
235
236 if ((currmenu->curr = n) < 0)
237 currmenu->curr = 0;
238 clear_message();
239
240 if (n >= currmenu->first && n < currmenu->first + NOTESLINES)
241 currmenu->draw_arrow();
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 */
251 void
252 scroll_down(
253 void)
254 {
255 if (!currmenu->max || currmenu->first + NOTESLINES >= currmenu->max)
256 return;
257
258 currmenu->first++;
259 #ifdef USE_CURSES
260 do_scroll(1);
261 currmenu->draw_item(currmenu->first + NOTESLINES - 1);
262 stow_cursor();
263 if (currmenu->curr < currmenu->first)
264 move_to_item(currmenu->curr + 1);
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 */
277 void
278 scroll_up(
279 void)
280 {
281 if (!currmenu->max || currmenu->first == 0)
282 return;
283
284 currmenu->first--;
285 #ifdef USE_CURSES
286 do_scroll(-1);
287 currmenu->draw_item(currmenu->first);
288 stow_cursor();
289 if (currmenu->curr >= currmenu->first + NOTESLINES)
290 move_to_item(currmenu->curr - 1);
291 #else
292 if (currmenu->curr >= currmenu->first + NOTESLINES)
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) */
302 static void
303 do_scroll(
304 int jump)
305 {
306 scrollok(stdscr, TRUE);
307 MoveCursor(INDEX_TOP, 0);
308 SetScrollRegion(INDEX_TOP, INDEX_TOP + NOTESLINES - 1);
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 */
320 t_function
321 global_mouse_action(
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();
334 currmenu->curr = MIN(xrow - INDEX_TOP + currmenu->first, currmenu->max - INDEX_TOP + 1);
335 currmenu->draw_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
354 t_function
355 handle_keypad(
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 */
368 t_function func = NOT_ASSIGNED;
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:
377 func = GLOBAL_LINE_UP;
378 break;
379
380 case KEYMAP_DOWN:
381 func = GLOBAL_LINE_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:
393 func = GLOBAL_PAGE_UP;
394 break;
395
396 case KEYMAP_PAGE_DOWN:
397 func = GLOBAL_PAGE_DOWN;
398 break;
399
400 case KEYMAP_HOME:
401 func = GLOBAL_FIRST_PAGE;
402 break;
403
404 case KEYMAP_END:
405 func = GLOBAL_LAST_PAGE;
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 */
429 void
430 bug_report(
431 void)
432 {
433 mail_bug_report();
434 ClearScreen();
435 currmenu->redraw();
436 }