Merge branch 'pu'
[jungerl.git] / lib / slang / demo / pager.erl
blob37f6a1401ca507ecc5e4dddbf33fe6044afb58bb
1 %%%----------------------------------------------------------------------
2 %%% File : pager.erl
3 %%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
4 %%% Purpose :
5 %%% Created : 1 Dec 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
6 %%%----------------------------------------------------------------------
8 -module(pager).
9 -author('klacke@kaja.hemma.net').
11 -compile(export_all).
13 -include ("slang.hrl").
15 -record(file_line, {next,
16 prev,
17 data}).
23 demolib_exit (Signal) ->
25 slang:reset_tty (),
26 slang:smg_reset_smg (),
29 Signal == 0 ->
30 halt();
31 true ->
32 io:format("Exiting on signal ~p\n", [Signal]),
33 halt()
34 end.
37 sigint_handler (Signal) ->
38 demolib_exit (Signal).
42 % static void init_signals (void)
43 % {
44 % #ifdef SIGTSTP
45 % SLsignal (SIGTSTP, sigtstp_handler);
46 % #endif
47 % #ifdef SIGINT
48 % SLsignal (SIGINT, sigint_handler);
49 % #endif
50 % }
52 exit_error_hook (Fmt, Args) ->
54 slang:reset_tty (),
55 slang:reset_smg (),
57 io:format(Fmt, Args),
58 io:nl(),
59 halt().
64 demolib_init_terminal () ->
66 %% SLang_Exit_Error_Hook = exit_error_hook
67 % It is wise to block the occurance of display related
68 %signals while we are
69 %initializing.
72 %SLsig_block_signals (),
74 slang:tt_get_terminfo (),
76 %% SLkp_init assumes that SLtt_get_terminfo has been called.
78 case slang:kp_init() of
79 -1 ->
80 -1;
81 Ret ->
83 slang:init_tty (-1, 0, 1),
84 %slang:tty_set_suspend_state (1),
86 case slang:smg_init_smg () of
87 -1 ->
88 -1;
89 _ ->
91 end
92 end.
95 main() ->
96 File="tmp/test",
101 int main (int argc, char **argv)
103 if (argc == 2)
105 File_Name = argv[1];
107 else if ((argc != 1) || (1 == isatty (fileno(stdin))))
108 usage (argv[0]);
111 if (-1 == read_file (File_Name))
113 fprintf (stderr, "Unable to read %s\n", File_Name);
114 return 1;
117 /* This sets up the terminal, signals, screen management routines, etc... */
118 if (-1 == demolib_init_terminal (1, 1))
120 fprintf (stderr, "Unable to initialize terminal.");
121 return 1;
124 #define APP_KEY_EOB 0x1001
125 #define APP_KEY_BOB 0x1002
127 /* Add a few application defined keysyms. 0x1000 and above are for
128 * applications.
130 (void) SLkp_define_keysym ("\033>", APP_KEY_EOB);
131 (void) SLkp_define_keysym ("\033<", APP_KEY_BOB);
133 main_loop (); /* should not return */
134 return 1;
138 /* The SLscroll routines will be used for pageup/down commands. They assume
139 * a linked list of lines. The first element of the structure MUST point to
140 * the NEXT line, the second MUST point to the PREVIOUS line.
142 typedef struct _File_Line_Type
144 struct _File_Line_Type *next;
145 struct _File_Line_Type *prev;
146 char *data; /* pointer to line data */
148 File_Line_Type;
150 static File_Line_Type *File_Lines;
152 /* The SLscroll routines will use this structure. */
153 static SLscroll_Window_Type Line_Window;
155 static void free_lines (void)
157 File_Line_Type *line, *next;
159 line = File_Lines;
160 while (line != NULL)
162 next = line->next;
163 if (line->data != NULL) free (line->data);
164 free (line);
165 line = next;
167 File_Lines = NULL;
170 static File_Line_Type *create_line (char *buf)
172 File_Line_Type *line;
174 line = (File_Line_Type *) malloc (sizeof (File_Line_Type));
175 if (line == NULL) return NULL;
177 memset ((char *) line, sizeof (File_Line_Type), 0);
179 line->data = SLmake_string (buf); /* use a slang routine */
180 if (line->data == NULL)
182 free (line);
183 return NULL;
186 return line;
190 static int read_file (char *file)
192 FILE *fp;
193 char buf [1024];
194 File_Line_Type *line, *last_line;
195 unsigned int num_lines;
197 if (file == NULL)
198 fp = stdin;
199 else fp = fopen (file, "r");
201 if (fp == NULL) return -1;
203 last_line = NULL;
204 num_lines = 0;
206 while (NULL != fgets (buf, sizeof(buf), fp))
208 num_lines++;
210 if (NULL == (line = create_line (buf)))
212 fprintf (stderr, "Out of memory.");
213 free_lines ();
214 return -1;
217 if (last_line == NULL)
218 File_Lines = line;
219 else
220 last_line->next = line;
222 line->prev = last_line;
223 line->next = NULL;
225 last_line = line;
228 memset ((char *)&Line_Window, 0, sizeof (SLscroll_Window_Type));
230 Line_Window.current_line = (SLscroll_Type *) File_Lines;
231 Line_Window.lines = (SLscroll_Type *) File_Lines;
232 Line_Window.line_num = 1;
233 Line_Window.num_lines = num_lines;
235 return 0;
239 static void update_display (void)
241 unsigned int row, nrows;
242 File_Line_Type *line;
244 /* All well behaved applications should block signals that may affect
245 * the display while performing screen update.
247 SLsig_block_signals ();
249 Line_Window.nrows = nrows = SLtt_Screen_Rows - 1;
251 /* Always make the current line equal to the top window line. */
252 if (Line_Window.top_window_line != NULL)
253 Line_Window.current_line = Line_Window.top_window_line;
255 SLscroll_find_top (&Line_Window);
257 row = 0;
258 line = (File_Line_Type *) Line_Window.top_window_line;
260 SLsmg_normal_video ();
262 while (row < Line_Window.nrows)
264 SLsmg_gotorc (row, 0);
266 if (line != NULL)
268 SLsmg_write_string (line->data);
269 line = line->next;
271 SLsmg_erase_eol ();
272 row++;
275 SLsmg_gotorc (row, 0);
276 SLsmg_reverse_video ();
277 SLsmg_printf ("%s", (File_Name == NULL) ? "<stdin>" : File_Name);
278 SLsmg_erase_eol ();
279 SLsmg_refresh ();
281 SLsig_unblock_signals ();
284 static int Screen_Start;
286 static void main_loop (void)
288 int screen_start;
290 while (1)
292 update_display ();
293 switch (SLkp_getkey ())
295 case SL_KEY_ERR:
296 case 'q':
297 case 'Q':
298 demolib_exit (0);
299 break;
301 case SL_KEY_RIGHT:
302 Screen_Start += 1;
303 screen_start = Screen_Start;
304 SLsmg_set_screen_start (NULL, &screen_start);
305 break;
307 case SL_KEY_LEFT:
308 Screen_Start -= 1;
309 if (Screen_Start < 0) Screen_Start = 0;
310 screen_start = Screen_Start;
311 SLsmg_set_screen_start (NULL, &screen_start);
312 break;
314 case SL_KEY_UP:
315 SLscroll_prev_n (&Line_Window, 1);
316 Line_Window.top_window_line = Line_Window.current_line;
317 break;
319 case '\r':
320 case SL_KEY_DOWN:
321 SLscroll_next_n (&Line_Window, 1);
322 Line_Window.top_window_line = Line_Window.current_line;
323 break;
325 case SL_KEY_NPAGE:
326 case ' ': case 4:
327 SLscroll_pagedown (&Line_Window);
328 break;
330 case SL_KEY_PPAGE:
331 case 127: case 21:
332 SLscroll_pageup (&Line_Window);
333 break;
335 case APP_KEY_BOB:
336 while (-1 != SLscroll_pageup (&Line_Window))
338 break;
340 case APP_KEY_EOB:
341 while (-1 != SLscroll_pagedown (&Line_Window))
343 break;
345 default:
346 SLtt_beep ();