Whamcloud - gitweb
Fix up ncurses interface so that it handles resizes correctly.
[tools/e2fsprogs.git] / ext2ed / win.c
1 /*
2
3 /usr/src/ext2ed/win.c
4
5 A part of the extended file system 2 disk editor.
6
7 --------------------------------------------------------
8 Window management - Interfacing with the ncurses library
9 --------------------------------------------------------
10
11 First written on: April 17 1995
12 Modified on : April 05 2001 Christian.Bac@int-evry.fr
13 it looks like readline does not like that initscr decides to set the tty to
14 noecho.
15
16 Copyright (C) 1995 Gadi Oxman
17
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <termios.h>
24 #include <unistd.h>
25 #include <sys/ioctl.h>
26
27 #include "ext2ed.h"
28 #include "../version.h"
29
30 struct struct_pad_info show_pad_info;
31 WINDOW *title_win,*show_win,*command_win,*mt_win1,*mt_win2,*show_pad;
32
33 /* to remember configuration after initscr 
34  * and modify it
35  */
36 struct termios termioInit, termioCurrent;
37
38 void draw_title_win (void)
39 {
40         char title_string [128];
41
42         werase(title_win);
43         box (title_win,0,0);
44         sprintf (title_string,"EXT2ED - Extended-2 File System editor ver %s (%s)", E2FSPROGS_VERSION, E2FSPROGS_DATE);
45         wmove (title_win,TITLE_WIN_LINES/2,(COLS-strlen (title_string))/2);
46         wprintw (title_win,title_string);
47         wrefresh(title_win);
48 }
49
50 void setup_show_win(void)
51 {
52         wbkgdset (show_win,A_REVERSE);werase (show_win);
53         show_pad_info.line=0;
54         show_pad_info.col=0;
55         show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2;
56         show_pad_info.display_cols=COLS;
57         show_pad_info.max_line=show_pad_info.display_lines-1;show_pad_info.max_col=show_pad_info.display_cols-1;
58         show_pad_info.disable_output=0;
59 }       
60
61 void init_windows (void)
62 {
63         initscr ();
64         tcgetattr(0,&termioInit); /* save initial config */
65         termioCurrent = termioInit;
66         termioCurrent.c_lflag |= ECHO; /* set echo on */
67         tcsetattr(0,TCSANOW,&termioCurrent);
68         
69         if (LINES<TITLE_WIN_LINES+SHOW_WIN_LINES+COMMAND_WIN_LINES+3) {
70                 printf ("Sorry, your terminal screen is too small\n");
71                 printf ("Error - Can not initialize windows\n");
72                 exit (1);
73         }
74
75         title_win=newwin (TITLE_WIN_LINES,COLS,0,0);
76         show_win=newwin (SHOW_WIN_LINES,COLS,TITLE_WIN_LINES,0);
77         show_pad=newpad (SHOW_PAD_LINES,SHOW_PAD_COLS);
78         mt_win1=newwin (1,COLS,TITLE_WIN_LINES+SHOW_WIN_LINES,0);
79         mt_win2=newwin (1,COLS,LINES-COMMAND_WIN_LINES-1,0);
80         command_win=newwin (COMMAND_WIN_LINES,COLS,LINES-COMMAND_WIN_LINES,0);
81
82         if (title_win==NULL || show_win==NULL || show_pad==NULL || command_win==NULL) {
83                 printf ("Error - Not enough memory - Can not initialize windows\n");exit (1);
84         }
85
86         draw_title_win();
87
88         setup_show_win();
89
90         scrollok (command_win,TRUE);
91
92         refresh_title_win ();
93         refresh_show_win ();
94         refresh_show_pad();
95         refresh_command_win ();
96         wrefresh(mt_win1);
97         wrefresh(mt_win2);
98 }
99
100 void refresh_title_win (void)
101 {
102         wrefresh (title_win);
103 }
104
105 void refresh_show_win (void)
106 {
107         int current_page,total_pages;
108         
109         current_page=show_pad_info.line/show_pad_info.display_lines+1;
110         if (show_pad_info.line%show_pad_info.display_lines)
111                 current_page++;
112         total_pages=show_pad_info.max_line/show_pad_info.display_lines+1;
113
114         wmove (show_win,2,COLS-18);
115         wprintw (show_win,"Page %d of %d\n",current_page,total_pages);
116
117         wmove (show_win,2,COLS-18);
118         wrefresh (show_win);
119 }
120
121
122 void refresh_show_pad (void)
123
124 {
125         int left,top,right,bottom,i;
126         
127         if (show_pad_info.disable_output)
128                 return;
129                 
130         if (show_pad_info.max_line < show_pad_info.display_lines-1) {
131                 for (i=show_pad_info.max_line+1;i<show_pad_info.display_lines;i++) {
132                         wmove (show_pad,i,0);wprintw (show_pad,"\n");
133                 }
134         }
135         left=0;right=show_pad_info.display_cols-1;
136         top=TITLE_WIN_LINES+SHOW_WIN_LINES+1;bottom=top+show_pad_info.display_lines-1;
137
138         if (show_pad_info.line > show_pad_info.max_line-show_pad_info.display_lines+1)
139                 show_pad_info.line=show_pad_info.max_line-show_pad_info.display_lines+1;
140
141         if (show_pad_info.line < 0)
142                 show_pad_info.line=0;
143
144 #ifdef OLD_NCURSES
145         prefresh (show_pad,show_pad_info.line,show_pad_info.col,top,left,show_pad_info.display_lines-1,show_pad_info.display_cols-1);
146 #else
147         prefresh (show_pad,show_pad_info.line,show_pad_info.col,top,left,top+show_pad_info.display_lines-1,left+show_pad_info.display_cols-1);
148 #endif
149 }
150
151 void refresh_command_win (void)
152 {
153         wrefresh (command_win);
154 }
155
156 void close_windows (void)
157 {
158 //      echo ();
159         tcsetattr(0,TCSANOW,&termioInit);
160         
161         delwin (title_win);
162         delwin (command_win);
163         delwin (show_win);
164         delwin (show_pad);
165         
166         endwin ();
167 }
168
169 void show_info (void)
170 {
171         int block_num,block_offset;
172         
173         block_num=device_offset/file_system_info.block_size;
174         block_offset=device_offset%file_system_info.block_size;
175
176         wmove (show_win,0,0);
177         wprintw (show_win,"Offset %-3ld in block %ld. ",block_offset,block_num);
178         if (current_type != NULL)
179                 wprintw (show_win,"Type: %s\n",current_type->name);
180         else
181                 wprintw (show_win,"Type: %s\n","none");
182
183         refresh_show_win ();
184 }
185
186
187 void redraw_all (void)
188 {
189         int min_lines = TITLE_WIN_LINES+SHOW_WIN_LINES+COMMAND_WIN_LINES+3;
190         struct winsize ws;
191         int     save_col, save_lines;
192
193         /* get the size of the terminal connected to stdout */
194         ioctl(1, TIOCGWINSZ, &ws);
195         /*
196          * Do it again because GDB doesn't stop before the first ioctl
197          * call, we want an up-to-date size when we're
198          * single-stepping.
199          */
200         if (ioctl(1, TIOCGWINSZ, &ws) == 0) {
201                 if (ws.ws_row < min_lines)
202                         ws.ws_row = min_lines;
203                 if ((ws.ws_row != LINES) || (ws.ws_col != COLS)) {
204                         wmove (show_win,2,COLS-18);
205                         wclrtoeol(show_win);
206                         wrefresh(show_win);
207                         resizeterm(ws.ws_row, ws.ws_col);
208                         wresize(title_win, TITLE_WIN_LINES,COLS);
209                         wresize(show_win, SHOW_WIN_LINES,COLS);
210                         wresize(command_win, COMMAND_WIN_LINES,COLS);
211                         wresize(mt_win1, 1,COLS);
212                         wresize(mt_win2, 1,COLS);
213                         mvwin(mt_win2, LINES-COMMAND_WIN_LINES-1,0);
214                         mvwin(command_win, LINES-COMMAND_WIN_LINES,0);
215                         draw_title_win();
216                         show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2;
217                         show_pad_info.display_cols=COLS;
218                 }
219         }
220         clearok(title_win, 1);
221         clearok(show_win, 1);
222         clearok(command_win, 1);
223         clearok(mt_win1, 1);
224         clearok(mt_win2, 1);
225         wrefresh(mt_win1);
226         wrefresh(mt_win2);
227         refresh_show_pad();
228         refresh_show_win();
229         refresh_title_win ();
230         refresh_command_win ();
231 }