Main Page | Class List | Directories | File List | Class Members | File Members

pager.c

Go to the documentation of this file.
00001 /* This file pager demo illustrates the screen management and 
00002  * keyboard routines.
00003  */
00004 
00005 #include <stdio.h>
00006 #include <string.h>
00007 
00008 #include <stdlib.h>
00009 
00010 #include <signal.h>
00011 
00012 #ifdef unix
00013 # include <unistd.h>
00014 #endif
00015 
00016 #include <slang.h>
00017 
00018 #include "demolib.c"
00019 
00020 static void usage (char *pgm)
00021 {
00022    fprintf (stderr, "Usage: %s [FILENAME]\n", pgm);
00023    exit (1);
00024 }
00025 
00026 static int read_file (char *);
00027 static void main_loop (void);
00028 
00029 static char *File_Name;                /* if NULL, use stdin */
00030 
00031 int main (int argc, char **argv)
00032 {  
00033    if (argc == 2)
00034      {
00035         File_Name = argv[1];
00036      }
00037    else if ((argc != 1) || (1 == isatty (fileno(stdin))))
00038      usage (argv[0]);
00039 
00040    
00041    if (-1 == read_file (File_Name))
00042      {
00043         fprintf (stderr, "Unable to read %s\n", File_Name);
00044         return 1;
00045      }
00046    
00047    /* This sets up the terminal, signals, screen management routines, etc... */
00048    if (-1 == demolib_init_terminal (1, 1))
00049      {
00050         fprintf (stderr, "Unable to initialize terminal.");
00051         return 1;
00052      }
00053    
00054 #define APP_KEY_EOB  0x1001
00055 #define APP_KEY_BOB  0x1002
00056    
00057    /* Add a few application defined keysyms.  0x1000 and above are for 
00058     * applications.
00059     */
00060    (void) SLkp_define_keysym ("\033>", APP_KEY_EOB);
00061    (void) SLkp_define_keysym ("\033<", APP_KEY_BOB);
00062    
00063    main_loop ();                       /* should not return */
00064    return 1;
00065 }
00066 
00067    
00068 /* The SLscroll routines will be used for pageup/down commands.  They assume
00069  * a linked list of lines.  The first element of the structure MUST point to 
00070  * the NEXT line, the second MUST point to the PREVIOUS line.
00071  */
00072 typedef struct _File_Line_Type
00073 {
00074    struct _File_Line_Type *next;
00075    struct _File_Line_Type *prev;
00076    char *data;                         /* pointer to line data */
00077 }
00078 File_Line_Type;
00079 
00080 static File_Line_Type *File_Lines;
00081 
00082 /* The SLscroll routines will use this structure. */
00083 static SLscroll_Window_Type Line_Window;
00084 
00085 static void free_lines (void)
00086 {
00087    File_Line_Type *line, *next;
00088    
00089    line = File_Lines;
00090    while (line != NULL)
00091      {
00092         next = line->next;
00093         if (line->data != NULL) free (line->data);
00094         free (line);
00095         line = next;
00096      }
00097    File_Lines = NULL;
00098 }
00099 
00100 static File_Line_Type *create_line (char *buf)
00101 {
00102    File_Line_Type *line;
00103    
00104    line = (File_Line_Type *) malloc (sizeof (File_Line_Type));
00105    if (line == NULL) return NULL;
00106    
00107    memset ((char *) line, sizeof (File_Line_Type), 0);
00108    
00109    line->data = SLmake_string (buf);   /* use a slang routine */
00110    if (line->data == NULL)
00111      {
00112         free (line);
00113         return NULL;
00114      }
00115    
00116    return line;
00117 }
00118 
00119 
00120 static int read_file (char *file)
00121 {
00122    FILE *fp;
00123    char buf [1024];
00124    File_Line_Type *line, *last_line;
00125    unsigned int num_lines;
00126    
00127    if (file == NULL) 
00128      fp = stdin;
00129    else fp = fopen (file, "r");
00130    
00131    if (fp == NULL) return -1;
00132    
00133    last_line = NULL;
00134    num_lines = 0;
00135    
00136    while (NULL != fgets (buf, sizeof(buf), fp))
00137      {
00138         num_lines++;
00139         
00140         if (NULL == (line = create_line (buf)))
00141           {
00142              fprintf (stderr, "Out of memory.");
00143              free_lines ();
00144              return -1;
00145           }
00146         
00147         if (last_line == NULL)
00148           File_Lines = line;
00149         else 
00150           last_line->next = line;
00151         
00152         line->prev = last_line;
00153         line->next = NULL;
00154         
00155         last_line = line;
00156      }
00157    
00158    memset ((char *)&Line_Window, 0, sizeof (SLscroll_Window_Type));
00159    
00160    Line_Window.current_line = (SLscroll_Type *) File_Lines;
00161    Line_Window.lines = (SLscroll_Type *) File_Lines;
00162    Line_Window.line_num = 1;
00163    Line_Window.num_lines = num_lines;
00164    /* Line_Window.border = 3; */
00165    
00166    return 0;
00167 }
00168 
00169 
00170 static void update_display (void)
00171 {
00172    unsigned int row, nrows;
00173    File_Line_Type *line;
00174 
00175    /* All well behaved applications should block signals that may affect
00176     * the display while performing screen update.
00177     */
00178    SLsig_block_signals ();
00179    
00180    Line_Window.nrows = nrows = SLtt_Screen_Rows - 1;
00181 
00182    /* Always make the current line equal to the top window line. */
00183    if (Line_Window.top_window_line != NULL)
00184      Line_Window.current_line = Line_Window.top_window_line;
00185 
00186    SLscroll_find_top (&Line_Window);
00187    
00188    row = 0;
00189    line = (File_Line_Type *) Line_Window.top_window_line;
00190    
00191    SLsmg_normal_video ();
00192    
00193    while (row < Line_Window.nrows)
00194      {
00195         SLsmg_gotorc (row, 0);
00196         
00197         if (line != NULL) 
00198           {
00199              SLsmg_write_string (line->data);
00200              line = line->next;
00201           }
00202         SLsmg_erase_eol ();
00203         row++;
00204      }
00205    
00206    SLsmg_gotorc (row, 0);
00207    SLsmg_reverse_video ();
00208    SLsmg_printf ("%s", (File_Name == NULL) ? "<stdin>" : File_Name);
00209    SLsmg_erase_eol ();
00210    SLsmg_refresh ();
00211    
00212    SLsig_unblock_signals ();
00213 }
00214 
00215 static int Screen_Start;
00216 
00217 static void main_loop (void)
00218 {
00219    int screen_start;
00220 
00221    while (1)
00222      {
00223         update_display ();
00224         switch (SLkp_getkey ())
00225           {
00226            case SL_KEY_ERR:
00227            case 'q':
00228            case 'Q':
00229              demolib_exit (0);
00230              break;
00231              
00232            case SL_KEY_RIGHT:
00233              Screen_Start += 1;
00234              screen_start = Screen_Start;
00235              SLsmg_set_screen_start (NULL, &screen_start);
00236              break;
00237              
00238            case SL_KEY_LEFT:
00239              Screen_Start -= 1;
00240              if (Screen_Start < 0) Screen_Start = 0;
00241              screen_start = Screen_Start;
00242              SLsmg_set_screen_start (NULL, &screen_start);
00243              break;
00244 
00245            case SL_KEY_UP:
00246              SLscroll_prev_n (&Line_Window, 1);
00247              Line_Window.top_window_line = Line_Window.current_line;
00248              break;
00249              
00250            case '\r':
00251            case SL_KEY_DOWN:
00252              SLscroll_next_n (&Line_Window, 1);
00253              Line_Window.top_window_line = Line_Window.current_line;
00254              break;
00255              
00256            case SL_KEY_NPAGE:
00257            case ' ': case 4:
00258              SLscroll_pagedown (&Line_Window);
00259              break;
00260 
00261            case SL_KEY_PPAGE:
00262            case 127: case 21:
00263              SLscroll_pageup (&Line_Window);
00264              break;
00265 
00266            case APP_KEY_BOB:
00267              while (-1 != SLscroll_pageup (&Line_Window))
00268                ;
00269              break;
00270              
00271            case APP_KEY_EOB:
00272              while (-1 != SLscroll_pagedown (&Line_Window))
00273                ;
00274              break;
00275              
00276            default:
00277              SLtt_beep ();
00278           }
00279      }
00280 }

© sourcejam.com 2005-2008