"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.1/src/global.c" (12 Oct 2016, 9070 Bytes) of archive /linux/misc/tin-2.4.1.tar.gz:


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