"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.4/src/global.c" (20 Nov 2019, 9172 Bytes) of package /linux/misc/tin-2.4.4.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.4.3_vs_2.4.4.

    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   : 2005-10-19
    7  *  Notes     : Generic navigation and key handling routines
    8  *
    9  * Copyright (c) 1999-2020 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 = xrow - INDEX_TOP + currmenu->first;
  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(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 }