1 /***************************************************************************
2 * Pinfo is a ncurses based lynx style info documentation browser
3 *
4 * Copyright (C) 1999 Przemek Borys <pborys@dione.ids.pl>
5 * Copyright (C) 2005 Bas Zoetekouw <bas@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 ***************************************************************************/
21 #include "common_includes.h"
22
23 char **rlhistory = 0;
24 int rlhistorylen = 0;
25 int rlhistorypos = 0;
26
27 #define KEY_BCKSPC 8
28
29 char *
readlinewrapper(char * prompt)30 readlinewrapper(char *prompt)
31 {
32 /* number of keys pressed */
33 int numkeys = 0;
34 /* initial buffer for the read line */
35 char *buf = xmalloc(1024);
36 /* start coords of input line */
37 int origx, origy;
38 /* cursor position in input string */
39 int cursor = 0;
40 /* key - a variable for getch() */
41 int key = 0, i;
42 /* initial value of line - "" */
43 buf[0] = 0;
44 /* print prompt */
45 addstr(prompt);
46 /* get origx,origy coordinates */
47 getyx(stdscr, origy, origx);
48 /* turn off echoing chars by getch() */
49 noecho();
50 /* create input line bar */
51 mvhline(origy, origx, ' ', maxx - origx);
52
53 /* history entry for this line */
54 rlhistorylen++;
55 /* move history pos to current entry */
56 rlhistorypos = rlhistorylen;
57 /* alloc memory for this entry */
58 if (!rlhistory)
59 rlhistory = xmalloc(sizeof(char *));
60 else
61 rlhistory = xrealloc(rlhistory, sizeof(char *) * rlhistorylen);
62 rlhistory[rlhistorylen - 1] = xmalloc(1024);
63 /* and copy there the current value of input line */
64 strcpy(rlhistory[rlhistorylen - 1], buf);
65 /* call history to be present */
66 if (CallReadlineHistory)
67 {
68 ungetch(KEY_UP);
69 numkeys = -1;
70 }
71
72 while (key != '\n')
73 {
74 /* read key */
75 key = getch();
76 switch(key)
77 {
78 /* move cursor left */
79 case KEY_LEFT:
80 if (cursor > 0)
81 cursor--;
82 break;
83 /* move cursor right */
84 case KEY_RIGHT:
85 if (cursor < strlen(buf))
86 cursor++;
87 break;
88 case KEY_END:
89 cursor = strlen(buf);
90 break;
91 /* handle backspace: copy all */
92 case KEY_BCKSPC:
93 /* chars starting from curpos */
94 case KEY_BACKSPACE:
95 /* - 1 from buf[n+1] to buf */
96 if (cursor > 0)
97 {
98 for (i = cursor - 1; buf[i] != 0; i++)
99 buf[i] = buf[i + 1];
100 cursor--;
101 }
102 break;
103 /* handle delete key. As above */
104 case KEY_DC:
105 if (cursor <= strlen(buf) - 1)
106 {
107 for (i = cursor; buf[i] != 0; i++)
108 buf[i] = buf[i + 1];
109 }
110 break;
111 /* backwards-history call */
112 case KEY_UP:
113 /* if there is history */
114 if (rlhistorylen)
115 /* and we have */
116 if (rlhistorypos > 1)
117 { /* where to move */
118 /* decrement history position */
119 rlhistorypos--;
120 /* if the previous pos was the input line */
121 /* save it's value to history */
122 if (rlhistorypos == rlhistorylen - 1)
123 strcpy(rlhistory[rlhistorylen - 1], buf);
124 /* recall value from history to input buf */
125 strcpy(buf, rlhistory[rlhistorypos - 1]);
126 }
127 cursor = strlen(buf);
128 numkeys = -1;
129 break;
130 /* forwards-history call */
131 case KEY_DOWN:
132 if (rlhistorylen)
133 if (rlhistorypos < rlhistorylen)
134 {
135 rlhistorypos++;
136 strcpy(buf, rlhistory[rlhistorypos - 1]);
137 }
138 cursor = strlen(buf);
139 numkeys = -1;
140 break;
141 /* eliminate nonprintable chars */
142 case '\n':
143 case KEY_PPAGE:
144 case KEY_NPAGE:
145 case KEY_F(1):
146 case KEY_F(2):
147 case KEY_F(3):
148 case KEY_F(4):
149 case KEY_F(5):
150 case KEY_F(6):
151 case KEY_F(7):
152 case KEY_F(8):
153 case KEY_F(9):
154 case KEY_F(10):
155 break;
156 default:
157 if (key >= 32)
158 {
159 /* if this is the first key, delete the buffer */
160 if (numkeys==0 && cursor!=0)
161 {
162 for (i=0; buf[i]!=0; i++)
163 buf[i] = 0;
164 cursor = 0;
165 /* and empty the line */
166 move(origy, origx);
167 for (i = origx; i < maxx; i++)
168 addch(' ');
169 move(origy, origx + cursor);
170 }
171
172 /* if the cursor is not at the last pos */
173 if (strlen(buf + cursor))
174 {
175 char *tmp = 0;
176 tmp = xmalloc(strlen(buf + cursor) + 1);
177 strcpy(tmp, buf + cursor);
178 buf[cursor] = key;
179 buf[cursor + 1] = 0;
180 strcat(&buf[cursor + 1], tmp);
181 xfree(tmp);
182 cursor++;
183 }
184 else
185 {
186 buf[cursor + 1] = 0;
187 buf[cursor] = key;
188 cursor++;
189 }
190 }
191 }
192 move(origy, origx);
193 for (i = origx; i < maxx; i++)
194 addch(' ');
195 move(origy, origx);
196 addstr(buf);
197 move(origy, origx + cursor);
198
199 numkeys++;
200
201 }
202 strcpy(rlhistory[rlhistorylen - 1], buf);
203 if (strlen(buf))
204 {
205 rlhistory[rlhistorylen - 1] = xrealloc(rlhistory[rlhistorylen - 1],
206 strlen(rlhistory[rlhistorylen - 1]) + 1);
207 }
208 else
209 {
210 xfree(rlhistory[rlhistorylen - 1]);
211 rlhistorylen--;
212 rlhistorypos = rlhistorylen;
213 }
214 buf = xrealloc(buf, strlen(buf) + 1);
215 return buf;
216 }
217