1 /* widgets.c by Adam Rogoyski <apoc@laker.net> Temperanc on EFNet irc
2  * Copyright (C) 1998, 1999 Adam Rogoyski
3  * --- GNU General Public License Disclamer ---
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 
14 
15 #include "hexedit.h"
16 
17 #define S_BOX_COLOR  (COLOR_PAIR(4) | A_BOLD)
18 
19 
20 WINDOW *
popupWindow(int width,int height)21 popupWindow (int width, int height)
22 /* Generic blank popup window with a border.  Comes out centered.
23  */
24 {
25    int winy = 0, winx = 0;
26    WINDOW *wpopup = NULL;
27 
28    if (LINES < height)
29       height = LINES;
30    if (COLS < width)
31       width = COLS;
32 
33    winy = (LINES / 2) - (height / 2);
34    winx = (COLS / 2) - (width / 2);
35    wpopup = newwin (height, width, winy, winx);
36    if (wpopup == NULL)
37    {
38       fprintf (stderr, "Cannot open up popup window\n");
39       return NULL;
40    }
41    scrollok (wpopup, FALSE);
42    box (wpopup, 0, 0);
43    return wpopup;
44 }
45 
46 
47 char *
stringBox(WINDOW * win,int y,int x,int len,int max,char * sample)48 stringBox (WINDOW *win, int y, int x, int len, int max, char *sample)
49 /* Creates a entry box to type in a string and returns it.
50  * You are responsible for freeing the returned pointer.
51  */
52 {
53    char *str = NULL;
54    int done = 0;
55    int i = 0;
56    int n = 0;
57    int oldx = 0;
58    int left = 0;
59    int right = max - 1;
60    int samplelen = strlen (sample ? sample : "");
61    wchar_t in = 0;
62 
63    wmove (win, y, x);
64    wattrset (win, color_term ? S_BOX_COLOR : A_REVERSE);
65    str = malloc (len + 2);
66    if (!str)
67    {
68 /*      fprintf (stderr, "%s - StringBox\n", NOT_ENOUGH_MEMORY); */
69       popup_Error (NOT_ENOUGH_MEMORY, 0);
70       return NULL;
71    }
72    *(str + len + 1) = '\0';
73    memset (str, ' ', len + 1);
74    strncpy (str, sample ? sample : "", samplelen);
75    for (i = 0; i < max; i++)
76    {
77       if (*(str + i) && (i < max))
78       {
79          wprintw (win, "%c", *(str + i));
80       }
81       else
82          wprintw (win, " ");
83    }
84    i = samplelen;
85    if (i >= max)
86       i = max - 1;
87    wmove (win, y, x + i);
88    wrefresh (win);
89 
90    while (!done && ((in = getch ()) != '\n'))
91    {
92       switch (in)
93       {
94          case CONTROL_C:
95          case CONTROL_G:
96          case CONTROL_X:
97          case ESCAPE_CHARACTER:
98             *str = '\0';
99             done = 1;
100             break;
101          case KEY_LEFT:
102             if (i > 0)
103             {
104                if (win->_curx > x)
105                /* not at left hand side */
106                {
107                   i--;
108                   wmove (win, y, win->_curx - 1);
109                }
110                else if (i > 0)
111                /* left hand side */
112                {
113                   i--;
114                   if (left > 0)
115                   {
116                      left--;
117                      right--;
118                   }
119                   wmove (win, y, x);
120                   for (n = left; n <= right; n++)
121                   {
122                      if ((n < len) && *(str + n))
123                         wprintw (win, "%c", *(str + n));
124                      else
125                         wprintw (win, " ");
126                   }
127                   wmove (win, y, x);
128                }
129 
130             }
131             break;
132          case KEY_RIGHT:
133             if (win->_curx < (x + max - 1))
134             /* not at right hand side */
135             {
136                i++;
137                wmove (win, y, win->_curx + 1);
138             }
139             else if (i < len - 1)
140             /* right hand side */
141             {
142                i++;
143                if (right < len - 1)
144                {
145                   left++;
146                   right++;
147                }
148                wmove (win, y, x);
149                for (n = left; n <= right; n++)
150                {
151                   if (*(str + n))
152                      wprintw (win, "%c", *(str + n));
153                   else
154                      wprintw (win, " ");
155                }
156                wmove (win, y, x + max - 1);
157             }
158             break;
159          case BACKSPACE:
160          case CONTROL_H:
161          case KEY_BACKSPACE:
162          case KEY_DC:
163 #ifdef __PDCURSES__
164             case CTL_BKSP:
165 #endif
166             if (i > 0)
167             {
168                if (win->_curx > x)
169                /* not at left hand side */
170                {
171                   i--;
172                   for (n = strlen (str); n < len; n++)
173                      *(str + n) = ' ';
174                   for (n = i; n < len; n++)
175                      *(str + n) = *(str + n + 1);
176                   *(str + n) = ' ';
177                   oldx = win->_curx;
178                   wmove (win, y, x);
179                   for (n = left; n <= right; n++)
180                   {
181                      if (*(str + n))
182                         wprintw (win, "%c", *(str + n));
183                      else
184                         wprintw (win, " ");
185                   }
186                   wmove (win, y, oldx - 1);
187                }
188                else
189                /* at left hand side, not begining of buffer */
190                {
191                   i--;
192                   for (n = i; n < len - 1; n++)
193                      *(str + n) = *(str + n + 1);
194                   if (left > 0)
195                   {
196                      left--;
197                      right--;
198                   }
199                   wmove (win, y, x);
200                   for (n = left; n <= right; n++)
201                   {
202                      if (*(str + n))
203                         wprintw (win, "%c", *(str + n));
204                      else
205                         wprintw (win, " ");
206                   }
207                   wmove (win, y, x);
208                }
209             }
210             else
211                do_beep ();
212             break;
213          case SPACEBAR:
214             oldx = win->_curx;
215             if ((win->_curx < x + max - 1)
216              && (i < len - 1) && (*(str + len - 1) <= ' '))
217             {
218                for (n = len - 1; n > i; n--)
219                {
220                   *(str + n) = *(str + n - 1);
221                }
222                *(str + i) = ' ';
223                *(str + len) = ' ';
224                i++;
225                wmove (win, y, x);
226                for (n = left; n <= right; n++)
227                {
228                   if (*(str + n))
229                      wprintw (win, "%c", *(str + n));
230                   else
231                      wprintw (win, " ");
232                }
233                wmove (win, y, oldx + 1);
234             }
235             else if ((win->_curx == x + max - 1)
236              && (i < len - 1) && (*(str + len - 1) <= ' '))
237             {
238                for (n = len - 1; n > i; n--)
239                {
240                   *(str + n) = *(str + n - 1);
241                }
242                *(str + i) = ' ';
243                *(str + len) = ' ';
244                i++;
245                if (right < len - 1)
246                {
247                   left++;
248                   right++;
249                }
250                wmove (win, y, x);
251                for (n = left; n <= right; n++)
252                {
253                   if (*(str + n))
254                      wprintw (win, "%c", *(str + n));
255                   else
256                      wprintw (win, " ");
257                }
258                wmove (win, y, x + max - 1);
259             }
260             else if ((win->_curx == x + max - 1)
261              && (i == len - 1))
262             {
263                *(str + len - 1) = ' ';
264                wmove (win, y, x + max - 1);
265                wprintw (win, " ");
266                wmove (win, y, x + max - 1);
267                do_beep ();
268             }
269             else
270                do_beep ();
271             break;
272 
273             /* erase whole line and bring cursor back to begining */
274          case CONTROL_U:
275             memset (str, 0x00, len);
276 
277             wmove (win, y, x);
278             for (i = 0; i < max; i++)
279                wprintw (win, " ");
280             i = 0;
281             left = 0;
282             right = max - 1;
283             wmove (win, y, x);
284             wrefresh (win);
285             break;
286 
287          default: /* normal input */
288             if (isprintable (in))
289             {
290                if (win->_curx != (x + max - 1))
291                /* not at right hand side */
292                {
293                   *(str + i) = in;
294                   i++;
295                   oldx = win->_curx;
296                   wmove (win, y, x);
297                   for (n = left; n <= right; n++)
298                   {
299                      if (*(str + n))
300                         wprintw (win, "%c", *(str + n));
301                      else
302                         wprintw (win, " ");
303                   }
304                   wmove (win, y, oldx + 1);
305                }
306                else if (i < len - 1)
307                /* right hand side, not end of buffer */
308                {
309                   *(str + i) = in;
310                   i++;
311                   if (right < len - 1)
312                   {
313                      left++;
314                      right++;
315                   }
316                   wmove (win, y, x);
317                   for (n = left; n <= right; n++)
318                   {
319                      if (*(str + n))
320                         wprintw (win, "%c", *(str + n));
321                      else
322                         wprintw (win, " ");
323                   }
324                   wmove (win, y, x + max - 1);
325                }
326                else if (i == len - 1)
327                /* right hand side, end of buffer */
328                {
329                   *(str + i) = in;
330                   do_beep ();
331                   wmove (win, y, x);
332                   for (n = left; n <= right; n++)
333                   {
334                      if (*(str + n))
335                         wprintw (win, "%c", *(str + n));
336                      else
337                         wprintw (win, " ");
338                   }
339                   wmove (win, y, x + max - 1);
340                }
341             }
342       }
343       wrefresh (win);
344    }
345    return str;
346 }
347 
348 
349 struct ret_string *
hex_string_box(WINDOW * win,int searchlen,int boxwidth)350 hex_string_box (WINDOW *win, int searchlen, int boxwidth)
351 {
352    wchar_t in = 0;
353    int newbyte = 1;
354    int i = 0;
355    int move = 0;
356    int width = (searchlen * 3) - 1;
357    int boxleft = (boxwidth / 2) - (width / 2);
358    static struct ret_string rstr = { 0, NULL };
359 
360    rstr.len = 0;
361    if (rstr.str)
362    {
363       rstr.len = 0;
364       free (rstr.str);
365       rstr.str = NULL;
366    }
367    rstr.str = malloc (searchlen);
368    if (!rstr.str)
369    {
370       wmove (win, 4, boxleft);
371       wprintw (win, (char *) NOT_ENOUGH_MEMORY);
372       getch ();
373       return NULL;
374    }
375    memset (rstr.str, 0, searchlen);
376    wmove (win, 3, boxleft);
377    wprintw (win, "text: ");
378    wattrset (win, color_term ? S_BOX_COLOR : A_REVERSE);
379    wmove (win, 6, boxleft);
380    for (i = 0; i < width + 3; i++)
381       wprintw (win, " ");
382    wattroff (win, color_term ? S_BOX_COLOR : A_REVERSE);
383    wmove (win, 6, boxleft);
384    wrefresh (win);
385    while ((in = getch ()) != '\n')
386    {
387       if (isHexChar (in))
388       {
389          if (rstr.len >= 16)
390          {
391             do_beep ();
392             wrefresh (win);
393             continue;
394          }
395          *(rstr.str + rstr.len) |= newbyte ?
396                            getHexValue (in) << 4:
397                            getHexValue (in);
398          move = 0;
399          if (rstr.len > 0)
400             move = rstr.len + (2 * rstr.len);
401          if (!newbyte)
402             move += 1;
403          wmove (win, 3, boxleft + strlen ("text:  ") + rstr.len);
404          if (Globals.charset == ASCII_CHAR_SET)
405          {
406             if (isprintable (*(rstr.str + rstr.len)))
407                wprintw (win, "%c", *(rstr.str + rstr.len));
408             else
409                wprintw (win, ".");
410          }
411          else
412             wprintw (win, "%c", EBCDIC[*(rstr.str + rstr.len)]);
413          wmove (win, 6, boxleft + move);
414          wattrset (win, color_term ? S_BOX_COLOR : A_REVERSE);
415          wprintw (win, "%c", isupper (in) ? in : (toupper (in)));
416 /* isupper (in) ? in : toupper (in)); */
417          if (newbyte)
418             wprintw (win, "0");
419          wattroff (win, color_term ? S_BOX_COLOR : A_REVERSE);
420          if (newbyte)
421          {
422             wmove (win, 6, boxleft + move + 1);
423             newbyte = 0;
424          }
425          else
426          {
427             wmove (win, 6, boxleft + move + 2);
428             newbyte = 1;
429             rstr.len++;
430          }
431          wrefresh (win);
432       }
433       else
434          switch (in)
435          {
436             case BACKSPACE:
437             case CONTROL_H:
438             case KEY_BACKSPACE:
439             case KEY_DC:
440 #ifdef __PDCURSES__
441                case CTL_BKSP:
442 #endif
443                if (newbyte)
444                {
445                   if (rstr.len <= 0)
446                   {
447                      do_beep ();
448                      wrefresh (win);
449                      continue;
450                   }
451                   newbyte = 0;
452                   rstr.len--;
453                   *(rstr.str + rstr.len) &= M_0xF0;
454                   move = rstr.len + (2 * rstr.len) + 1;
455                   wmove (win, 3, boxleft + strlen ("text:  ") + rstr.len + 1);
456                   wprintw (win, " ");
457                   wmove (win, 6, boxleft + move + 2);
458                   wattrset (win, color_term ? S_BOX_COLOR : A_REVERSE);
459                   wprintw (win, "  ");
460                   wmove (win, 6, boxleft + move);
461                   wprintw (win, "0");
462                   wattroff (win, color_term ? S_BOX_COLOR : A_REVERSE);
463                   wmove (win, 6, boxleft + move);
464                   wmove (win, 3, boxleft + strlen ("text:  ") + rstr.len);
465                   if (isprintable (*(rstr.str + rstr.len)))
466                      wprintw (win, "%c", *(rstr.str + rstr.len));
467                   else
468                      wprintw (win, ".");
469                   wmove (win, 6, boxleft + move);
470                   wrefresh (win);
471                }
472                else
473                {
474                   newbyte = 1;
475                   *(rstr.str + rstr.len) = 0x00;
476                   if (rstr.len > 0)
477                      move = rstr.len + (2 * rstr.len);
478                   else
479                      move = 0;
480                   wmove (win, 3, boxleft + strlen ("text:  ") + rstr.len);
481                   if (isprintable (*(rstr.str + rstr.len)))
482                      wprintw (win, "%c", *(rstr.str + rstr.len));
483                   else
484                      wprintw (win, ".");
485                   wmove (win, 6, boxleft + move);
486                   wattrset (win, color_term ? S_BOX_COLOR : A_REVERSE);
487                   wprintw (win, "0");
488                   wattroff (win, color_term ? S_BOX_COLOR : A_REVERSE);
489                   wmove (win, 6, boxleft + move);
490                   wrefresh (win);
491                }
492                break;
493 
494             case CONTROL_C:
495             case CONTROL_G:
496             case CONTROL_X:
497             case ESCAPE_CHARACTER:
498                return NULL;
499          }
500    }
501    return &rstr;
502 }
503