diff options
Diffstat (limited to 'scripts/lxdialog/textbox.c')
-rw-r--r-- | scripts/lxdialog/textbox.c | 968 |
1 files changed, 493 insertions, 475 deletions
diff --git a/scripts/lxdialog/textbox.c b/scripts/lxdialog/textbox.c index ed23df2d096a..d6e7f2afe31a 100644 --- a/scripts/lxdialog/textbox.c +++ b/scripts/lxdialog/textbox.c | |||
@@ -21,11 +21,11 @@ | |||
21 | 21 | ||
22 | #include "dialog.h" | 22 | #include "dialog.h" |
23 | 23 | ||
24 | static void back_lines (int n); | 24 | static void back_lines(int n); |
25 | static void print_page (WINDOW * win, int height, int width); | 25 | static void print_page(WINDOW * win, int height, int width); |
26 | static void print_line (WINDOW * win, int row, int width); | 26 | static void print_line(WINDOW * win, int row, int width); |
27 | static char *get_line (void); | 27 | static char *get_line(void); |
28 | static void print_position (WINDOW * win, int height, int width); | 28 | static void print_position(WINDOW * win, int height, int width); |
29 | 29 | ||
30 | static int hscroll, fd, file_size, bytes_read; | 30 | static int hscroll, fd, file_size, bytes_read; |
31 | static int begin_reached = 1, end_reached, page_length; | 31 | static int begin_reached = 1, end_reached, page_length; |
@@ -34,450 +34,466 @@ static char *buf, *page; | |||
34 | /* | 34 | /* |
35 | * Display text from a file in a dialog box. | 35 | * Display text from a file in a dialog box. |
36 | */ | 36 | */ |
37 | int | 37 | int dialog_textbox(const char *title, const char *file, int height, int width) |
38 | dialog_textbox (const char *title, const char *file, int height, int width) | ||
39 | { | 38 | { |
40 | int i, x, y, cur_x, cur_y, fpos, key = 0; | 39 | int i, x, y, cur_x, cur_y, fpos, key = 0; |
41 | int passed_end; | 40 | int passed_end; |
42 | char search_term[MAX_LEN + 1]; | 41 | char search_term[MAX_LEN + 1]; |
43 | WINDOW *dialog, *text; | 42 | WINDOW *dialog, *text; |
44 | 43 | ||
45 | search_term[0] = '\0'; /* no search term entered yet */ | 44 | search_term[0] = '\0'; /* no search term entered yet */ |
46 | 45 | ||
47 | /* Open input file for reading */ | 46 | /* Open input file for reading */ |
48 | if ((fd = open (file, O_RDONLY)) == -1) { | 47 | if ((fd = open(file, O_RDONLY)) == -1) { |
49 | endwin (); | 48 | endwin(); |
50 | fprintf (stderr, | 49 | fprintf(stderr, |
51 | "\nCan't open input file in dialog_textbox().\n"); | 50 | "\nCan't open input file in dialog_textbox().\n"); |
52 | exit (-1); | 51 | exit(-1); |
53 | } | 52 | } |
54 | /* Get file size. Actually, 'file_size' is the real file size - 1, | 53 | /* Get file size. Actually, 'file_size' is the real file size - 1, |
55 | since it's only the last byte offset from the beginning */ | 54 | since it's only the last byte offset from the beginning */ |
56 | if ((file_size = lseek (fd, 0, SEEK_END)) == -1) { | 55 | if ((file_size = lseek(fd, 0, SEEK_END)) == -1) { |
57 | endwin (); | 56 | endwin(); |
58 | fprintf (stderr, "\nError getting file size in dialog_textbox().\n"); | 57 | fprintf(stderr, |
59 | exit (-1); | 58 | "\nError getting file size in dialog_textbox().\n"); |
60 | } | 59 | exit(-1); |
61 | /* Restore file pointer to beginning of file after getting file size */ | 60 | } |
62 | if (lseek (fd, 0, SEEK_SET) == -1) { | 61 | /* Restore file pointer to beginning of file after getting file size */ |
63 | endwin (); | 62 | if (lseek(fd, 0, SEEK_SET) == -1) { |
64 | fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); | 63 | endwin(); |
65 | exit (-1); | 64 | fprintf(stderr, |
66 | } | 65 | "\nError moving file pointer in dialog_textbox().\n"); |
67 | /* Allocate space for read buffer */ | 66 | exit(-1); |
68 | if ((buf = malloc (BUF_SIZE + 1)) == NULL) { | 67 | } |
69 | endwin (); | 68 | /* Allocate space for read buffer */ |
70 | fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n"); | 69 | if ((buf = malloc(BUF_SIZE + 1)) == NULL) { |
71 | exit (-1); | 70 | endwin(); |
72 | } | 71 | fprintf(stderr, |
73 | if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { | 72 | "\nCan't allocate memory in dialog_textbox().\n"); |
74 | endwin (); | 73 | exit(-1); |
75 | fprintf (stderr, "\nError reading file in dialog_textbox().\n"); | 74 | } |
76 | exit (-1); | 75 | if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) { |
77 | } | 76 | endwin(); |
78 | buf[bytes_read] = '\0'; /* mark end of valid data */ | 77 | fprintf(stderr, "\nError reading file in dialog_textbox().\n"); |
79 | page = buf; /* page is pointer to start of page to be displayed */ | 78 | exit(-1); |
80 | 79 | } | |
81 | /* center dialog box on screen */ | 80 | buf[bytes_read] = '\0'; /* mark end of valid data */ |
82 | x = (COLS - width) / 2; | 81 | page = buf; /* page is pointer to start of page to be displayed */ |
83 | y = (LINES - height) / 2; | 82 | |
84 | 83 | /* center dialog box on screen */ | |
85 | 84 | x = (COLS - width) / 2; | |
86 | draw_shadow (stdscr, y, x, height, width); | 85 | y = (LINES - height) / 2; |
87 | 86 | ||
88 | dialog = newwin (height, width, y, x); | 87 | draw_shadow(stdscr, y, x, height, width); |
89 | keypad (dialog, TRUE); | 88 | |
90 | 89 | dialog = newwin(height, width, y, x); | |
91 | /* Create window for text region, used for scrolling text */ | 90 | keypad(dialog, TRUE); |
92 | text = subwin (dialog, height - 4, width - 2, y + 1, x + 1); | 91 | |
93 | wattrset (text, dialog_attr); | 92 | /* Create window for text region, used for scrolling text */ |
94 | wbkgdset (text, dialog_attr & A_COLOR); | 93 | text = subwin(dialog, height - 4, width - 2, y + 1, x + 1); |
95 | 94 | wattrset(text, dialog_attr); | |
96 | keypad (text, TRUE); | 95 | wbkgdset(text, dialog_attr & A_COLOR); |
97 | 96 | ||
98 | /* register the new window, along with its borders */ | 97 | keypad(text, TRUE); |
99 | draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); | 98 | |
100 | 99 | /* register the new window, along with its borders */ | |
101 | wattrset (dialog, border_attr); | 100 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); |
102 | mvwaddch (dialog, height-3, 0, ACS_LTEE); | 101 | |
103 | for (i = 0; i < width - 2; i++) | 102 | wattrset(dialog, border_attr); |
104 | waddch (dialog, ACS_HLINE); | 103 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); |
105 | wattrset (dialog, dialog_attr); | 104 | for (i = 0; i < width - 2; i++) |
106 | wbkgdset (dialog, dialog_attr & A_COLOR); | 105 | waddch(dialog, ACS_HLINE); |
107 | waddch (dialog, ACS_RTEE); | 106 | wattrset(dialog, dialog_attr); |
108 | 107 | wbkgdset(dialog, dialog_attr & A_COLOR); | |
109 | if (title != NULL && strlen(title) >= width-2 ) { | 108 | waddch(dialog, ACS_RTEE); |
110 | /* truncate long title -- mec */ | 109 | |
111 | char * title2 = malloc(width-2+1); | 110 | if (title != NULL && strlen(title) >= width - 2) { |
112 | memcpy( title2, title, width-2 ); | 111 | /* truncate long title -- mec */ |
113 | title2[width-2] = '\0'; | 112 | char *title2 = malloc(width - 2 + 1); |
114 | title = title2; | 113 | memcpy(title2, title, width - 2); |
115 | } | 114 | title2[width - 2] = '\0'; |
116 | 115 | title = title2; | |
117 | if (title != NULL) { | 116 | } |
118 | wattrset (dialog, title_attr); | ||
119 | mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); | ||
120 | waddstr (dialog, (char *)title); | ||
121 | waddch (dialog, ' '); | ||
122 | } | ||
123 | print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE); | ||
124 | wnoutrefresh (dialog); | ||
125 | getyx (dialog, cur_y, cur_x); /* Save cursor position */ | ||
126 | |||
127 | /* Print first page of text */ | ||
128 | attr_clear (text, height - 4, width - 2, dialog_attr); | ||
129 | print_page (text, height - 4, width - 2); | ||
130 | print_position (dialog, height, width); | ||
131 | wmove (dialog, cur_y, cur_x); /* Restore cursor position */ | ||
132 | wrefresh (dialog); | ||
133 | |||
134 | while ((key != ESC) && (key != '\n')) { | ||
135 | key = wgetch (dialog); | ||
136 | switch (key) { | ||
137 | case 'E': /* Exit */ | ||
138 | case 'e': | ||
139 | case 'X': | ||
140 | case 'x': | ||
141 | delwin (dialog); | ||
142 | free (buf); | ||
143 | close (fd); | ||
144 | return 0; | ||
145 | case 'g': /* First page */ | ||
146 | case KEY_HOME: | ||
147 | if (!begin_reached) { | ||
148 | begin_reached = 1; | ||
149 | /* First page not in buffer? */ | ||
150 | if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { | ||
151 | endwin (); | ||
152 | fprintf (stderr, | ||
153 | "\nError moving file pointer in dialog_textbox().\n"); | ||
154 | exit (-1); | ||
155 | } | ||
156 | if (fpos > bytes_read) { /* Yes, we have to read it in */ | ||
157 | if (lseek (fd, 0, SEEK_SET) == -1) { | ||
158 | endwin (); | ||
159 | fprintf (stderr, "\nError moving file pointer in " | ||
160 | "dialog_textbox().\n"); | ||
161 | exit (-1); | ||
162 | } | ||
163 | if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { | ||
164 | endwin (); | ||
165 | fprintf (stderr, | ||
166 | "\nError reading file in dialog_textbox().\n"); | ||
167 | exit (-1); | ||
168 | } | ||
169 | buf[bytes_read] = '\0'; | ||
170 | } | ||
171 | page = buf; | ||
172 | print_page (text, height - 4, width - 2); | ||
173 | print_position (dialog, height, width); | ||
174 | wmove (dialog, cur_y, cur_x); /* Restore cursor position */ | ||
175 | wrefresh (dialog); | ||
176 | } | ||
177 | break; | ||
178 | case 'G': /* Last page */ | ||
179 | case KEY_END: | ||
180 | |||
181 | end_reached = 1; | ||
182 | /* Last page not in buffer? */ | ||
183 | if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { | ||
184 | endwin (); | ||
185 | fprintf (stderr, | ||
186 | "\nError moving file pointer in dialog_textbox().\n"); | ||
187 | exit (-1); | ||
188 | } | ||
189 | if (fpos < file_size) { /* Yes, we have to read it in */ | ||
190 | if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) { | ||
191 | endwin (); | ||
192 | fprintf (stderr, | ||
193 | "\nError moving file pointer in dialog_textbox().\n"); | ||
194 | exit (-1); | ||
195 | } | ||
196 | if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { | ||
197 | endwin (); | ||
198 | fprintf (stderr, | ||
199 | "\nError reading file in dialog_textbox().\n"); | ||
200 | exit (-1); | ||
201 | } | ||
202 | buf[bytes_read] = '\0'; | ||
203 | } | ||
204 | page = buf + bytes_read; | ||
205 | back_lines (height - 4); | ||
206 | print_page (text, height - 4, width - 2); | ||
207 | print_position (dialog, height, width); | ||
208 | wmove (dialog, cur_y, cur_x); /* Restore cursor position */ | ||
209 | wrefresh (dialog); | ||
210 | break; | ||
211 | case 'K': /* Previous line */ | ||
212 | case 'k': | ||
213 | case KEY_UP: | ||
214 | if (!begin_reached) { | ||
215 | back_lines (page_length + 1); | ||
216 | |||
217 | /* We don't call print_page() here but use scrolling to ensure | ||
218 | faster screen update. However, 'end_reached' and | ||
219 | 'page_length' should still be updated, and 'page' should | ||
220 | point to start of next page. This is done by calling | ||
221 | get_line() in the following 'for' loop. */ | ||
222 | scrollok (text, TRUE); | ||
223 | wscrl (text, -1); /* Scroll text region down one line */ | ||
224 | scrollok (text, FALSE); | ||
225 | page_length = 0; | ||
226 | passed_end = 0; | ||
227 | for (i = 0; i < height - 4; i++) { | ||
228 | if (!i) { | ||
229 | /* print first line of page */ | ||
230 | print_line (text, 0, width - 2); | ||
231 | wnoutrefresh (text); | ||
232 | } else | ||
233 | /* Called to update 'end_reached' and 'page' */ | ||
234 | get_line (); | ||
235 | if (!passed_end) | ||
236 | page_length++; | ||
237 | if (end_reached && !passed_end) | ||
238 | passed_end = 1; | ||
239 | } | ||
240 | 117 | ||
241 | print_position (dialog, height, width); | 118 | if (title != NULL) { |
242 | wmove (dialog, cur_y, cur_x); /* Restore cursor position */ | 119 | wattrset(dialog, title_attr); |
243 | wrefresh (dialog); | 120 | mvwaddch(dialog, 0, (width - strlen(title)) / 2 - 1, ' '); |
244 | } | 121 | waddstr(dialog, (char *)title); |
245 | break; | 122 | waddch(dialog, ' '); |
246 | case 'B': /* Previous page */ | 123 | } |
247 | case 'b': | 124 | print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE); |
248 | case KEY_PPAGE: | 125 | wnoutrefresh(dialog); |
249 | if (begin_reached) | 126 | getyx(dialog, cur_y, cur_x); /* Save cursor position */ |
250 | break; | 127 | |
251 | back_lines (page_length + height - 4); | 128 | /* Print first page of text */ |
252 | print_page (text, height - 4, width - 2); | 129 | attr_clear(text, height - 4, width - 2, dialog_attr); |
253 | print_position (dialog, height, width); | 130 | print_page(text, height - 4, width - 2); |
254 | wmove (dialog, cur_y, cur_x); | 131 | print_position(dialog, height, width); |
255 | wrefresh (dialog); | 132 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
256 | break; | 133 | wrefresh(dialog); |
257 | case 'J': /* Next line */ | 134 | |
258 | case 'j': | 135 | while ((key != ESC) && (key != '\n')) { |
259 | case KEY_DOWN: | 136 | key = wgetch(dialog); |
260 | if (!end_reached) { | 137 | switch (key) { |
261 | begin_reached = 0; | 138 | case 'E': /* Exit */ |
262 | scrollok (text, TRUE); | 139 | case 'e': |
263 | scroll (text); /* Scroll text region up one line */ | 140 | case 'X': |
264 | scrollok (text, FALSE); | 141 | case 'x': |
265 | print_line (text, height - 5, width - 2); | 142 | delwin(dialog); |
266 | wnoutrefresh (text); | 143 | free(buf); |
267 | print_position (dialog, height, width); | 144 | close(fd); |
268 | wmove (dialog, cur_y, cur_x); /* Restore cursor position */ | 145 | return 0; |
269 | wrefresh (dialog); | 146 | case 'g': /* First page */ |
270 | } | 147 | case KEY_HOME: |
271 | break; | 148 | if (!begin_reached) { |
272 | case KEY_NPAGE: /* Next page */ | 149 | begin_reached = 1; |
273 | case ' ': | 150 | /* First page not in buffer? */ |
274 | if (end_reached) | 151 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { |
275 | break; | 152 | endwin(); |
276 | 153 | fprintf(stderr, | |
277 | begin_reached = 0; | 154 | "\nError moving file pointer in dialog_textbox().\n"); |
278 | print_page (text, height - 4, width - 2); | 155 | exit(-1); |
279 | print_position (dialog, height, width); | 156 | } |
280 | wmove (dialog, cur_y, cur_x); | 157 | if (fpos > bytes_read) { /* Yes, we have to read it in */ |
281 | wrefresh (dialog); | 158 | if (lseek(fd, 0, SEEK_SET) == -1) { |
282 | break; | 159 | endwin(); |
283 | case '0': /* Beginning of line */ | 160 | fprintf(stderr, |
284 | case 'H': /* Scroll left */ | 161 | "\nError moving file pointer in " |
285 | case 'h': | 162 | "dialog_textbox().\n"); |
286 | case KEY_LEFT: | 163 | exit(-1); |
287 | if (hscroll <= 0) | 164 | } |
288 | break; | 165 | if ((bytes_read = |
289 | 166 | read(fd, buf, BUF_SIZE)) == -1) { | |
290 | if (key == '0') | 167 | endwin(); |
291 | hscroll = 0; | 168 | fprintf(stderr, |
292 | else | 169 | "\nError reading file in dialog_textbox().\n"); |
293 | hscroll--; | 170 | exit(-1); |
294 | /* Reprint current page to scroll horizontally */ | 171 | } |
295 | back_lines (page_length); | 172 | buf[bytes_read] = '\0'; |
296 | print_page (text, height - 4, width - 2); | 173 | } |
297 | wmove (dialog, cur_y, cur_x); | 174 | page = buf; |
298 | wrefresh (dialog); | 175 | print_page(text, height - 4, width - 2); |
299 | break; | 176 | print_position(dialog, height, width); |
300 | case 'L': /* Scroll right */ | 177 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
301 | case 'l': | 178 | wrefresh(dialog); |
302 | case KEY_RIGHT: | 179 | } |
303 | if (hscroll >= MAX_LEN) | 180 | break; |
304 | break; | 181 | case 'G': /* Last page */ |
305 | hscroll++; | 182 | case KEY_END: |
306 | /* Reprint current page to scroll horizontally */ | 183 | |
307 | back_lines (page_length); | 184 | end_reached = 1; |
308 | print_page (text, height - 4, width - 2); | 185 | /* Last page not in buffer? */ |
309 | wmove (dialog, cur_y, cur_x); | 186 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { |
310 | wrefresh (dialog); | 187 | endwin(); |
311 | break; | 188 | fprintf(stderr, |
312 | case ESC: | 189 | "\nError moving file pointer in dialog_textbox().\n"); |
313 | break; | 190 | exit(-1); |
191 | } | ||
192 | if (fpos < file_size) { /* Yes, we have to read it in */ | ||
193 | if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) { | ||
194 | endwin(); | ||
195 | fprintf(stderr, | ||
196 | "\nError moving file pointer in dialog_textbox().\n"); | ||
197 | exit(-1); | ||
198 | } | ||
199 | if ((bytes_read = | ||
200 | read(fd, buf, BUF_SIZE)) == -1) { | ||
201 | endwin(); | ||
202 | fprintf(stderr, | ||
203 | "\nError reading file in dialog_textbox().\n"); | ||
204 | exit(-1); | ||
205 | } | ||
206 | buf[bytes_read] = '\0'; | ||
207 | } | ||
208 | page = buf + bytes_read; | ||
209 | back_lines(height - 4); | ||
210 | print_page(text, height - 4, width - 2); | ||
211 | print_position(dialog, height, width); | ||
212 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
213 | wrefresh(dialog); | ||
214 | break; | ||
215 | case 'K': /* Previous line */ | ||
216 | case 'k': | ||
217 | case KEY_UP: | ||
218 | if (!begin_reached) { | ||
219 | back_lines(page_length + 1); | ||
220 | |||
221 | /* We don't call print_page() here but use scrolling to ensure | ||
222 | faster screen update. However, 'end_reached' and | ||
223 | 'page_length' should still be updated, and 'page' should | ||
224 | point to start of next page. This is done by calling | ||
225 | get_line() in the following 'for' loop. */ | ||
226 | scrollok(text, TRUE); | ||
227 | wscrl(text, -1); /* Scroll text region down one line */ | ||
228 | scrollok(text, FALSE); | ||
229 | page_length = 0; | ||
230 | passed_end = 0; | ||
231 | for (i = 0; i < height - 4; i++) { | ||
232 | if (!i) { | ||
233 | /* print first line of page */ | ||
234 | print_line(text, 0, width - 2); | ||
235 | wnoutrefresh(text); | ||
236 | } else | ||
237 | /* Called to update 'end_reached' and 'page' */ | ||
238 | get_line(); | ||
239 | if (!passed_end) | ||
240 | page_length++; | ||
241 | if (end_reached && !passed_end) | ||
242 | passed_end = 1; | ||
243 | } | ||
244 | |||
245 | print_position(dialog, height, width); | ||
246 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
247 | wrefresh(dialog); | ||
248 | } | ||
249 | break; | ||
250 | case 'B': /* Previous page */ | ||
251 | case 'b': | ||
252 | case KEY_PPAGE: | ||
253 | if (begin_reached) | ||
254 | break; | ||
255 | back_lines(page_length + height - 4); | ||
256 | print_page(text, height - 4, width - 2); | ||
257 | print_position(dialog, height, width); | ||
258 | wmove(dialog, cur_y, cur_x); | ||
259 | wrefresh(dialog); | ||
260 | break; | ||
261 | case 'J': /* Next line */ | ||
262 | case 'j': | ||
263 | case KEY_DOWN: | ||
264 | if (!end_reached) { | ||
265 | begin_reached = 0; | ||
266 | scrollok(text, TRUE); | ||
267 | scroll(text); /* Scroll text region up one line */ | ||
268 | scrollok(text, FALSE); | ||
269 | print_line(text, height - 5, width - 2); | ||
270 | wnoutrefresh(text); | ||
271 | print_position(dialog, height, width); | ||
272 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
273 | wrefresh(dialog); | ||
274 | } | ||
275 | break; | ||
276 | case KEY_NPAGE: /* Next page */ | ||
277 | case ' ': | ||
278 | if (end_reached) | ||
279 | break; | ||
280 | |||
281 | begin_reached = 0; | ||
282 | print_page(text, height - 4, width - 2); | ||
283 | print_position(dialog, height, width); | ||
284 | wmove(dialog, cur_y, cur_x); | ||
285 | wrefresh(dialog); | ||
286 | break; | ||
287 | case '0': /* Beginning of line */ | ||
288 | case 'H': /* Scroll left */ | ||
289 | case 'h': | ||
290 | case KEY_LEFT: | ||
291 | if (hscroll <= 0) | ||
292 | break; | ||
293 | |||
294 | if (key == '0') | ||
295 | hscroll = 0; | ||
296 | else | ||
297 | hscroll--; | ||
298 | /* Reprint current page to scroll horizontally */ | ||
299 | back_lines(page_length); | ||
300 | print_page(text, height - 4, width - 2); | ||
301 | wmove(dialog, cur_y, cur_x); | ||
302 | wrefresh(dialog); | ||
303 | break; | ||
304 | case 'L': /* Scroll right */ | ||
305 | case 'l': | ||
306 | case KEY_RIGHT: | ||
307 | if (hscroll >= MAX_LEN) | ||
308 | break; | ||
309 | hscroll++; | ||
310 | /* Reprint current page to scroll horizontally */ | ||
311 | back_lines(page_length); | ||
312 | print_page(text, height - 4, width - 2); | ||
313 | wmove(dialog, cur_y, cur_x); | ||
314 | wrefresh(dialog); | ||
315 | break; | ||
316 | case ESC: | ||
317 | break; | ||
318 | } | ||
314 | } | 319 | } |
315 | } | ||
316 | 320 | ||
317 | delwin (dialog); | 321 | delwin(dialog); |
318 | free (buf); | 322 | free(buf); |
319 | close (fd); | 323 | close(fd); |
320 | return -1; /* ESC pressed */ | 324 | return -1; /* ESC pressed */ |
321 | } | 325 | } |
322 | 326 | ||
323 | /* | 327 | /* |
324 | * Go back 'n' lines in text file. Called by dialog_textbox(). | 328 | * Go back 'n' lines in text file. Called by dialog_textbox(). |
325 | * 'page' will be updated to point to the desired line in 'buf'. | 329 | * 'page' will be updated to point to the desired line in 'buf'. |
326 | */ | 330 | */ |
327 | static void | 331 | static void back_lines(int n) |
328 | back_lines (int n) | ||
329 | { | 332 | { |
330 | int i, fpos; | 333 | int i, fpos; |
331 | 334 | ||
332 | begin_reached = 0; | 335 | begin_reached = 0; |
333 | /* We have to distinguish between end_reached and !end_reached | 336 | /* We have to distinguish between end_reached and !end_reached |
334 | since at end of file, the line is not ended by a '\n'. | 337 | since at end of file, the line is not ended by a '\n'. |
335 | The code inside 'if' basically does a '--page' to move one | 338 | The code inside 'if' basically does a '--page' to move one |
336 | character backward so as to skip '\n' of the previous line */ | 339 | character backward so as to skip '\n' of the previous line */ |
337 | if (!end_reached) { | 340 | if (!end_reached) { |
338 | /* Either beginning of buffer or beginning of file reached? */ | 341 | /* Either beginning of buffer or beginning of file reached? */ |
339 | if (page == buf) { | 342 | if (page == buf) { |
340 | if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { | 343 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { |
341 | endwin (); | 344 | endwin(); |
342 | fprintf (stderr, "\nError moving file pointer in " | 345 | fprintf(stderr, |
343 | "back_lines().\n"); | 346 | "\nError moving file pointer in " |
344 | exit (-1); | 347 | "back_lines().\n"); |
345 | } | 348 | exit(-1); |
346 | if (fpos > bytes_read) { /* Not beginning of file yet */ | 349 | } |
347 | /* We've reached beginning of buffer, but not beginning of | 350 | if (fpos > bytes_read) { /* Not beginning of file yet */ |
348 | file yet, so read previous part of file into buffer. | 351 | /* We've reached beginning of buffer, but not beginning of |
349 | Note that we only move backward for BUF_SIZE/2 bytes, | 352 | file yet, so read previous part of file into buffer. |
350 | but not BUF_SIZE bytes to avoid re-reading again in | 353 | Note that we only move backward for BUF_SIZE/2 bytes, |
351 | print_page() later */ | 354 | but not BUF_SIZE bytes to avoid re-reading again in |
352 | /* Really possible to move backward BUF_SIZE/2 bytes? */ | 355 | print_page() later */ |
353 | if (fpos < BUF_SIZE / 2 + bytes_read) { | 356 | /* Really possible to move backward BUF_SIZE/2 bytes? */ |
354 | /* No, move less then */ | 357 | if (fpos < BUF_SIZE / 2 + bytes_read) { |
355 | if (lseek (fd, 0, SEEK_SET) == -1) { | 358 | /* No, move less then */ |
356 | endwin (); | 359 | if (lseek(fd, 0, SEEK_SET) == -1) { |
357 | fprintf (stderr, "\nError moving file pointer in " | 360 | endwin(); |
358 | "back_lines().\n"); | 361 | fprintf(stderr, |
359 | exit (-1); | 362 | "\nError moving file pointer in " |
360 | } | 363 | "back_lines().\n"); |
361 | page = buf + fpos - bytes_read; | 364 | exit(-1); |
362 | } else { /* Move backward BUF_SIZE/2 bytes */ | 365 | } |
363 | if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) | 366 | page = buf + fpos - bytes_read; |
364 | == -1) { | 367 | } else { /* Move backward BUF_SIZE/2 bytes */ |
365 | endwin (); | 368 | if (lseek |
366 | fprintf (stderr, "\nError moving file pointer " | 369 | (fd, -(BUF_SIZE / 2 + bytes_read), |
367 | "in back_lines().\n"); | 370 | SEEK_CUR) |
368 | exit (-1); | 371 | == -1) { |
369 | } | 372 | endwin(); |
370 | page = buf + BUF_SIZE / 2; | 373 | fprintf(stderr, |
374 | "\nError moving file pointer " | ||
375 | "in back_lines().\n"); | ||
376 | exit(-1); | ||
377 | } | ||
378 | page = buf + BUF_SIZE / 2; | ||
379 | } | ||
380 | if ((bytes_read = | ||
381 | read(fd, buf, BUF_SIZE)) == -1) { | ||
382 | endwin(); | ||
383 | fprintf(stderr, | ||
384 | "\nError reading file in back_lines().\n"); | ||
385 | exit(-1); | ||
386 | } | ||
387 | buf[bytes_read] = '\0'; | ||
388 | } else { /* Beginning of file reached */ | ||
389 | begin_reached = 1; | ||
390 | return; | ||
391 | } | ||
371 | } | 392 | } |
372 | if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { | 393 | if (*(--page) != '\n') { /* '--page' here */ |
373 | endwin (); | 394 | /* Something's wrong... */ |
374 | fprintf (stderr, "\nError reading file in back_lines().\n"); | 395 | endwin(); |
375 | exit (-1); | 396 | fprintf(stderr, "\nInternal error in back_lines().\n"); |
397 | exit(-1); | ||
376 | } | 398 | } |
377 | buf[bytes_read] = '\0'; | ||
378 | } else { /* Beginning of file reached */ | ||
379 | begin_reached = 1; | ||
380 | return; | ||
381 | } | ||
382 | } | ||
383 | if (*(--page) != '\n') { /* '--page' here */ | ||
384 | /* Something's wrong... */ | ||
385 | endwin (); | ||
386 | fprintf (stderr, "\nInternal error in back_lines().\n"); | ||
387 | exit (-1); | ||
388 | } | 399 | } |
389 | } | 400 | /* Go back 'n' lines */ |
390 | /* Go back 'n' lines */ | 401 | for (i = 0; i < n; i++) |
391 | for (i = 0; i < n; i++) | 402 | do { |
392 | do { | 403 | if (page == buf) { |
393 | if (page == buf) { | 404 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { |
394 | if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { | 405 | endwin(); |
395 | endwin (); | 406 | fprintf(stderr, |
396 | fprintf (stderr, | 407 | "\nError moving file pointer in back_lines().\n"); |
397 | "\nError moving file pointer in back_lines().\n"); | 408 | exit(-1); |
398 | exit (-1); | 409 | } |
399 | } | 410 | if (fpos > bytes_read) { |
400 | if (fpos > bytes_read) { | 411 | /* Really possible to move backward BUF_SIZE/2 bytes? */ |
401 | /* Really possible to move backward BUF_SIZE/2 bytes? */ | 412 | if (fpos < BUF_SIZE / 2 + bytes_read) { |
402 | if (fpos < BUF_SIZE / 2 + bytes_read) { | 413 | /* No, move less then */ |
403 | /* No, move less then */ | 414 | if (lseek(fd, 0, SEEK_SET) == |
404 | if (lseek (fd, 0, SEEK_SET) == -1) { | 415 | -1) { |
405 | endwin (); | 416 | endwin(); |
406 | fprintf (stderr, "\nError moving file pointer " | 417 | fprintf(stderr, |
407 | "in back_lines().\n"); | 418 | "\nError moving file pointer " |
408 | exit (-1); | 419 | "in back_lines().\n"); |
409 | } | 420 | exit(-1); |
410 | page = buf + fpos - bytes_read; | 421 | } |
411 | } else { /* Move backward BUF_SIZE/2 bytes */ | 422 | page = buf + fpos - bytes_read; |
412 | if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), | 423 | } else { /* Move backward BUF_SIZE/2 bytes */ |
413 | SEEK_CUR) == -1) { | 424 | if (lseek |
414 | endwin (); | 425 | (fd, |
415 | fprintf (stderr, "\nError moving file pointer" | 426 | -(BUF_SIZE / 2 + |
416 | " in back_lines().\n"); | 427 | bytes_read), |
417 | exit (-1); | 428 | SEEK_CUR) == -1) { |
429 | endwin(); | ||
430 | fprintf(stderr, | ||
431 | "\nError moving file pointer" | ||
432 | " in back_lines().\n"); | ||
433 | exit(-1); | ||
434 | } | ||
435 | page = buf + BUF_SIZE / 2; | ||
436 | } | ||
437 | if ((bytes_read = | ||
438 | read(fd, buf, BUF_SIZE)) == -1) { | ||
439 | endwin(); | ||
440 | fprintf(stderr, | ||
441 | "\nError reading file in " | ||
442 | "back_lines().\n"); | ||
443 | exit(-1); | ||
444 | } | ||
445 | buf[bytes_read] = '\0'; | ||
446 | } else { /* Beginning of file reached */ | ||
447 | begin_reached = 1; | ||
448 | return; | ||
449 | } | ||
418 | } | 450 | } |
419 | page = buf + BUF_SIZE / 2; | 451 | } while (*(--page) != '\n'); |
420 | } | 452 | page++; |
421 | if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { | ||
422 | endwin (); | ||
423 | fprintf (stderr, "\nError reading file in " | ||
424 | "back_lines().\n"); | ||
425 | exit (-1); | ||
426 | } | ||
427 | buf[bytes_read] = '\0'; | ||
428 | } else { /* Beginning of file reached */ | ||
429 | begin_reached = 1; | ||
430 | return; | ||
431 | } | ||
432 | } | ||
433 | } while (*(--page) != '\n'); | ||
434 | page++; | ||
435 | } | 453 | } |
436 | 454 | ||
437 | /* | 455 | /* |
438 | * Print a new page of text. Called by dialog_textbox(). | 456 | * Print a new page of text. Called by dialog_textbox(). |
439 | */ | 457 | */ |
440 | static void | 458 | static void print_page(WINDOW * win, int height, int width) |
441 | print_page (WINDOW * win, int height, int width) | ||
442 | { | 459 | { |
443 | int i, passed_end = 0; | 460 | int i, passed_end = 0; |
444 | 461 | ||
445 | page_length = 0; | 462 | page_length = 0; |
446 | for (i = 0; i < height; i++) { | 463 | for (i = 0; i < height; i++) { |
447 | print_line (win, i, width); | 464 | print_line(win, i, width); |
448 | if (!passed_end) | 465 | if (!passed_end) |
449 | page_length++; | 466 | page_length++; |
450 | if (end_reached && !passed_end) | 467 | if (end_reached && !passed_end) |
451 | passed_end = 1; | 468 | passed_end = 1; |
452 | } | 469 | } |
453 | wnoutrefresh (win); | 470 | wnoutrefresh(win); |
454 | } | 471 | } |
455 | 472 | ||
456 | /* | 473 | /* |
457 | * Print a new line of text. Called by dialog_textbox() and print_page(). | 474 | * Print a new line of text. Called by dialog_textbox() and print_page(). |
458 | */ | 475 | */ |
459 | static void | 476 | static void print_line(WINDOW * win, int row, int width) |
460 | print_line (WINDOW * win, int row, int width) | ||
461 | { | 477 | { |
462 | int y, x; | 478 | int y, x; |
463 | char *line; | 479 | char *line; |
464 | 480 | ||
465 | line = get_line (); | 481 | line = get_line(); |
466 | line += MIN (strlen (line), hscroll); /* Scroll horizontally */ | 482 | line += MIN(strlen(line), hscroll); /* Scroll horizontally */ |
467 | wmove (win, row, 0); /* move cursor to correct line */ | 483 | wmove(win, row, 0); /* move cursor to correct line */ |
468 | waddch (win, ' '); | 484 | waddch(win, ' '); |
469 | waddnstr (win, line, MIN (strlen (line), width - 2)); | 485 | waddnstr(win, line, MIN(strlen(line), width - 2)); |
470 | 486 | ||
471 | getyx (win, y, x); | 487 | getyx(win, y, x); |
472 | /* Clear 'residue' of previous line */ | 488 | /* Clear 'residue' of previous line */ |
473 | #if OLD_NCURSES | 489 | #if OLD_NCURSES |
474 | { | 490 | { |
475 | int i; | 491 | int i; |
476 | for (i = 0; i < width - x; i++) | 492 | for (i = 0; i < width - x; i++) |
477 | waddch (win, ' '); | 493 | waddch(win, ' '); |
478 | } | 494 | } |
479 | #else | 495 | #else |
480 | wclrtoeol(win); | 496 | wclrtoeol(win); |
481 | #endif | 497 | #endif |
482 | } | 498 | } |
483 | 499 | ||
@@ -486,71 +502,73 @@ print_line (WINDOW * win, int row, int width) | |||
486 | * 'page' should point to start of current line before calling, and will be | 502 | * 'page' should point to start of current line before calling, and will be |
487 | * updated to point to start of next line. | 503 | * updated to point to start of next line. |
488 | */ | 504 | */ |
489 | static char * | 505 | static char *get_line(void) |
490 | get_line (void) | ||
491 | { | 506 | { |
492 | int i = 0, fpos; | 507 | int i = 0, fpos; |
493 | static char line[MAX_LEN + 1]; | 508 | static char line[MAX_LEN + 1]; |
494 | 509 | ||
495 | end_reached = 0; | 510 | end_reached = 0; |
496 | while (*page != '\n') { | 511 | while (*page != '\n') { |
497 | if (*page == '\0') { | 512 | if (*page == '\0') { |
498 | /* Either end of file or end of buffer reached */ | 513 | /* Either end of file or end of buffer reached */ |
499 | if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { | 514 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { |
500 | endwin (); | 515 | endwin(); |
501 | fprintf (stderr, "\nError moving file pointer in " | 516 | fprintf(stderr, |
502 | "get_line().\n"); | 517 | "\nError moving file pointer in " |
503 | exit (-1); | 518 | "get_line().\n"); |
504 | } | 519 | exit(-1); |
505 | if (fpos < file_size) { /* Not end of file yet */ | 520 | } |
506 | /* We've reached end of buffer, but not end of file yet, | 521 | if (fpos < file_size) { /* Not end of file yet */ |
507 | so read next part of file into buffer */ | 522 | /* We've reached end of buffer, but not end of file yet, |
508 | if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { | 523 | so read next part of file into buffer */ |
509 | endwin (); | 524 | if ((bytes_read = |
510 | fprintf (stderr, "\nError reading file in get_line().\n"); | 525 | read(fd, buf, BUF_SIZE)) == -1) { |
511 | exit (-1); | 526 | endwin(); |
527 | fprintf(stderr, | ||
528 | "\nError reading file in get_line().\n"); | ||
529 | exit(-1); | ||
530 | } | ||
531 | buf[bytes_read] = '\0'; | ||
532 | page = buf; | ||
533 | } else { | ||
534 | if (!end_reached) | ||
535 | end_reached = 1; | ||
536 | break; | ||
537 | } | ||
538 | } else if (i < MAX_LEN) | ||
539 | line[i++] = *(page++); | ||
540 | else { | ||
541 | /* Truncate lines longer than MAX_LEN characters */ | ||
542 | if (i == MAX_LEN) | ||
543 | line[i++] = '\0'; | ||
544 | page++; | ||
512 | } | 545 | } |
513 | buf[bytes_read] = '\0'; | ||
514 | page = buf; | ||
515 | } else { | ||
516 | if (!end_reached) | ||
517 | end_reached = 1; | ||
518 | break; | ||
519 | } | ||
520 | } else if (i < MAX_LEN) | ||
521 | line[i++] = *(page++); | ||
522 | else { | ||
523 | /* Truncate lines longer than MAX_LEN characters */ | ||
524 | if (i == MAX_LEN) | ||
525 | line[i++] = '\0'; | ||
526 | page++; | ||
527 | } | 546 | } |
528 | } | 547 | if (i <= MAX_LEN) |
529 | if (i <= MAX_LEN) | 548 | line[i] = '\0'; |
530 | line[i] = '\0'; | 549 | if (!end_reached) |
531 | if (!end_reached) | 550 | page++; /* move pass '\n' */ |
532 | page++; /* move pass '\n' */ | ||
533 | 551 | ||
534 | return line; | 552 | return line; |
535 | } | 553 | } |
536 | 554 | ||
537 | /* | 555 | /* |
538 | * Print current position | 556 | * Print current position |
539 | */ | 557 | */ |
540 | static void | 558 | static void print_position(WINDOW * win, int height, int width) |
541 | print_position (WINDOW * win, int height, int width) | ||
542 | { | 559 | { |
543 | int fpos, percent; | 560 | int fpos, percent; |
544 | 561 | ||
545 | if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { | 562 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { |
546 | endwin (); | 563 | endwin(); |
547 | fprintf (stderr, "\nError moving file pointer in print_position().\n"); | 564 | fprintf(stderr, |
548 | exit (-1); | 565 | "\nError moving file pointer in print_position().\n"); |
549 | } | 566 | exit(-1); |
550 | wattrset (win, position_indicator_attr); | 567 | } |
551 | wbkgdset (win, position_indicator_attr & A_COLOR); | 568 | wattrset(win, position_indicator_attr); |
552 | percent = !file_size ? | 569 | wbkgdset(win, position_indicator_attr & A_COLOR); |
553 | 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; | 570 | percent = !file_size ? |
554 | wmove (win, height - 3, width - 9); | 571 | 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; |
555 | wprintw (win, "(%3d%%)", percent); | 572 | wmove(win, height - 3, width - 9); |
573 | wprintw(win, "(%3d%%)", percent); | ||
556 | } | 574 | } |