00001
00002
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;
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
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
00058
00059
00060 (void) SLkp_define_keysym ("\033>", APP_KEY_EOB);
00061 (void) SLkp_define_keysym ("\033<", APP_KEY_BOB);
00062
00063 main_loop ();
00064 return 1;
00065 }
00066
00067
00068
00069
00070
00071
00072 typedef struct _File_Line_Type
00073 {
00074 struct _File_Line_Type *next;
00075 struct _File_Line_Type *prev;
00076 char *data;
00077 }
00078 File_Line_Type;
00079
00080 static File_Line_Type *File_Lines;
00081
00082
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);
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
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
00176
00177
00178 SLsig_block_signals ();
00179
00180 Line_Window.nrows = nrows = SLtt_Screen_Rows - 1;
00181
00182
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 }