1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <strings.h>
5 #include "machine_type.h"
6 #include "input.h"
7 #include "output.h"
8 #include "unistd.h"
9
initkeytab(tOutput * output)10 void initkeytab(tOutput* output)
11 {
12 // those values are for mac os x
13 const tKeyTab KeyTab[NUM_SPECIALKEYS]={
14 // key return value (retval),allowed_in_inputfield,seqlen,seq[8],config[16]
15 {KEYESC, 1,1,{0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYESC:","The standard cancel key"},
16 {KEYF1, 0,2,{0xc2,0xa1,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF1:","This key opens the goto dialog"},
17 {KEYF2, 0,3,{0xe2,0x84,0xa2,0x00,0x00,0x00,0x00,0x00},"KEYF2:","This key opens the search dialog"},
18 {KEYF3, 0,2,{0xc2,0xa3,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF3:","This key jumps to the next search item"},
19 {KEYF4, 0,2,{0xc2,0xa2,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF4:","This key jumps to the previous search item"},
20 {KEYF5, 0,3,{0xe2,0x88,0x9e,0x00,0x00,0x00,0x00,0x00},"KEYF5:","This key openes the hexcalc tool"},
21 {KEYF6, 0,2,{0xc2,0xa7,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF6:","This key is not used yet"},
22 {KEYF7, 0,2,{0xc2,0xb6,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF7:","This key is not used yet"},
23 {KEYF8, 0,3,{0xe2,0x80,0xa2,0x00,0x00,0x00,0x00,0x00},"KEYF8:","This key is not used yet"},
24 {KEYF9, 0,2,{0xc2,0xaa,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF9:","This key is for undo"},
25 {KEYF10, 0,2,{0xc2,0xba,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF10:","This key is for saving and quitting"},
26 {KEYBACKSPACE, 1,1,{0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYBACKSPACE:","Erases a character in input fields"},
27 {KEYDEL, 1,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYDEL:","Erases a character in input fields"},
28 {KEYENTER, 1,1,{0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYENTER:","The standard Enter key"},
29 {KEYTAB, 1,1,{0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYTAB:","This key jumps trough windows and menu items"},
30 {KEYUP, 0,3,{0x1b,0x5b,0x41,0x00,0x00,0x00,0x00,0x00},"KEYUP:","Standard scroll key"},
31 {KEYDOWN, 0,3,{0x1b,0x5b,0x42,0x00,0x00,0x00,0x00,0x00},"KEYDOWN:","Standard scroll key"},
32 {KEYRIGHT, 0,3,{0x1b,0x5b,0x43,0x00,0x00,0x00,0x00,0x00},"KEYRIGHT:","Standard scroll key"},
33 {KEYLEFT, 0,3,{0x1b,0x5b,0x44,0x00,0x00,0x00,0x00,0x00},"KEYLEFT:","Standard scroll key"},
34 {KEYPGUP, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYPGUP:","Scrolls up a full page"},
35 {KEYPGDOWN, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYPGDOWN:","Scrolls down a full page"},
36 {KEYHOME, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYHOME:","Jumps to beginning"},
37 {KEYEND, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYEND:","Jumps to the end"}
38 };
39 if (output->pKeyTab) free(output->pKeyTab);
40 output->pKeyTab=malloc(sizeof(tKeyTab)*NUM_SPECIALKEYS);
41 memcpy(output->pKeyTab,KeyTab,sizeof(tKeyTab)*NUM_SPECIALKEYS);
42 }
getkey(tKeyTab * pKeyTab,tBool inputfield)43 tInt16 getkey(tKeyTab* pKeyTab,tBool inputfield) // =1 this is an inputfield. which means that certain allowed_in_inputfields may not be used
44 {
45 tInt16 ch;
46 unsigned char seq[8];
47 tUInt8 seqlen=0;
48 tBool done;
49 tInt16 donecnt;
50 tInt16 lastch=ERR;
51 tBool partial;
52 tBool exact;
53 int i,j;
54
55 donecnt=1000;
56 done=0;
57 partial=0;
58 exact=0;
59 while (!done)
60 {
61 while (!done)
62 {
63 ch=getch();
64
65 if ((lastch!=ERR && ch==ERR) || seqlen==8) done=1;
66 if (ch!=ERR)
67 {
68 if (seqlen<8) seq[seqlen++]=ch;
69 lastch=ch;
70 done=1; // a key was pressed
71 } else {
72 usleep(1000);
73 donecnt=donecnt-partial;
74 done=!donecnt;
75 }
76 }
77 exact=0;
78 partial=0;
79 for (i=0;i<NUM_SPECIALKEYS;i++) // check if it was a special key
80 {
81 if (pKeyTab[i].seqlen==seqlen)
82 {
83 j=memcmp(pKeyTab[i].seq,seq,seqlen);
84 if (j==0)
85 {
86 lastch=pKeyTab[i].retval; // in an inputfield, certain special keys have to be disabled
87 exact=1;
88 }
89 } else if (pKeyTab[i].seqlen>seqlen) {
90 j=memcmp(pKeyTab[i].seq,seq,seqlen);
91 if (j==0) partial=1;
92 }
93 }
94 if (exact && (!partial || !donecnt)) done=1;
95 else if (partial && donecnt) done=0;
96 }
97 return lastch;
98 }
99
100
decinput(tOutput * output,tInt16 y,tInt16 x,tUInt64 * val,tInt16 len)101 tInt16 decinput(tOutput* output,tInt16 y,tInt16 x,tUInt64* val,tInt16 len)
102 {
103 tInt16 i;
104 tInt16 ch;
105 tInt16 done=0;
106 tUInt64 newval;
107 char tmpbuf[21];
108
109 newval=*val;
110 setcolor(output,COLOR_BRACKETS);
111 mvwprintw(output->win,y,x,"[");
112 mvwprintw(output->win,y,x+len,"]");
113 while (!done)
114 {
115 setcolor(output,COLOR_INPUT);
116 snprintf(tmpbuf,21,"%20lli",newval);
117 for (i=0;i<len && i<20;i++) mvwprintw(output->win,y,x+len-i,"%c",tmpbuf[20-i]);
118 wmove(output->win,y,x+len);
119 ch=getkey(output->pKeyTab,1);
120 if (ch==KEYENTER) done=1;
121 if (ch==KEYTAB) done=1;
122 if (ch==KEYESC) done=1;
123 if (ch>='0' && ch<='9')
124 {
125 newval=newval*10;
126 newval=newval+(ch-'0');
127 }
128 if (ch==KEYBACKSPACE || ch==KEYDEL)
129 {
130 newval=newval/10;
131 }
132 }
133 if (ch!=KEYESC) {
134 *val=newval;
135 }
136 return ch;
137 }
hexinput(tOutput * output,tInt16 y,tInt16 x,tUInt64 * val,char * relative,tInt16 len)138 tInt16 hexinput(tOutput* output,tInt16 y,tInt16 x,tUInt64* val,char* relative,tInt16 len)
139 {
140 char e;
141 tInt16 i;
142 tInt16 ch;
143 tInt16 done=0;
144 tUInt64 newval;
145 tUInt64 t;
146
147 newval=*val;
148 if (relative) e=*relative; else e='=';
149 setcolor(output,COLOR_BRACKETS);
150 mvwprintw(output->win,y,x,"[");
151 mvwprintw(output->win,y,x+len+1,"]");
152 while (!done)
153 {
154 setcolor(output,COLOR_BRACKETS);
155 for (i=0;i<len;i++) mvwprintw(output->win,y,x+i+1," ");
156 setcolor(output,COLOR_INPUT);
157 t=newval;
158 for (i=len-2;i>=0 && t;i--)
159 {
160 tUInt8 c=t&0xf;
161 t>>=4;
162 mvwprintw(output->win,y,x+i+2,"%1x",c);
163 }
164 mvwprintw(output->win,y,x+i+2,"%c",e);
165 refresh();
166 ch=getkey(output->pKeyTab,1);
167 if (ch=='=' || ch=='-' || ch=='+') e=ch;
168
169 if (ch>='a' && ch<='f') ch-=32; // make it uppercase
170 if (ch==KEYENTER) done=1;
171 if (ch==KEYTAB) done=1;
172 if (ch==KEYESC) done=1;
173 if (ch>='0' && ch<='9')
174 {
175 newval=newval*16;
176 newval=newval+(ch-'0');
177 }
178 else if (ch>='A' && ch<='F')
179 {
180 newval=newval*16;
181 newval=newval+(ch-'A'+10);
182 }
183 if (ch==KEYBACKSPACE || ch==KEYDEL)
184 {
185 newval=newval/16;
186 }
187 }
188 if (ch!=KEYESC && relative==NULL)
189 {
190 if (e=='=') *val=newval;
191 if (e=='-') *val-=newval;
192 if (e=='+') *val+=newval;
193 } else if (ch!=KEYESC) {
194 *val=newval;
195 *relative=e;
196 }
197 return ch;
198 }
hexinput2(tOutput * output,tInt16 y,tInt16 x,char * s,tInt16 * usedlen,tInt16 len)199 tInt16 hexinput2(tOutput* output,tInt16 y,tInt16 x,char* s,tInt16* usedlen,tInt16 len)
200 {
201 char* buf;
202 tInt16 ch;
203 tBool done=0;
204 tInt16 newusedlen;
205 tBool nibble=0;
206 tUInt8 newchar=0;
207 int i;
208
209 buf=malloc(len);
210 memcpy(buf,s,len);
211 newusedlen=*usedlen;
212
213 setcolor(output,COLOR_BRACKETS);
214 mvwprintw(output->win,y,x,"[");
215 mvwprintw(output->win,y,x+len*3,"]");
216 while (!done)
217 {
218 setcolor(output,COLOR_INPUT);
219 for (i=0;i<len;i++)
220 {
221 if (i<newusedlen) mvwprintw(output->win,y,x+1+i*3,"%02x",((tUInt16)buf[i]&0xff));
222 else if (i==newusedlen && nibble) mvwprintw(output->win,y,x+1+i*3,"%1x ",newchar&0xf);
223 else mvwprintw(output->win,y,x+1+i*3," ");
224 if (i!=(len-1)) mvwprintw(output->win,y,x+3+i*3," ");
225 }
226 wmove(output->win,y,x+1+newusedlen*3+nibble);
227 ch=getkey(output->pKeyTab,1);
228 if (ch>='a' && ch<='z') ch-=32;
229 if (newusedlen<len && ((ch>='0' && ch<='9') || (ch>='A' && ch<='F')))
230 {
231 newchar<<=4;
232 newchar|=(ch>='A')?(ch-'A'+10):(ch-'0');
233 if (nibble) buf[newusedlen++]=newchar;
234 nibble=!nibble;
235 }
236 if ((newusedlen>0 || nibble) && ch==KEYBACKSPACE)
237 {
238 if (!nibble && newusedlen) newchar=buf[--newusedlen];
239 newchar>>=4;
240 nibble=!nibble;
241 }
242 if (ch==KEYENTER || ch==KEYTAB || ch==KEYUP || ch==KEYDOWN) done=1;
243 if (ch==KEYESC) done=1;
244 }
245 if (ch!=KEYESC)
246 {
247 memcpy(s,buf,len);
248 *usedlen=newusedlen;
249 }
250 setcolor(output,COLOR_TEXT);
251 newusedlen=*usedlen;
252 for (i=0;i<len;i++)
253 {
254 if (i<newusedlen) mvwprintw(output->win,y,x+1+i*3,"%02x",((tUInt16)buf[i]&0xff));
255 else if (i==newusedlen && nibble) mvwprintw(output->win,y,x+1+i*3,"%1x ",newchar&0xf);
256 else mvwprintw(output->win,y,x+1+i*3," ");
257 if (i!=(len-1)) mvwprintw(output->win,y,x+3+i*3," ");
258 }
259 free(buf);
260 return ch;
261 }
stringinput(tOutput * output,tInt16 y,tInt16 x,char * s,tInt16 len)262 tInt16 stringinput(tOutput* output,tInt16 y,tInt16 x,char* s,tInt16 len)
263 {
264 tInt16 i;
265 tInt16 cursorpos;
266 tInt16 ch;
267 tInt16 done=0;
268 char* buf;
269
270 buf=malloc(len);
271 memcpy(buf,s,len);
272
273
274
275 cursorpos=strlen(s);
276 setcolor(output,COLOR_BRACKETS);
277 mvwprintw(output->win,y,x,"[");
278 mvwprintw(output->win,y,x+len+1,"]");
279 while (!done)
280 {
281 setcolor(output,COLOR_INPUT);
282 for (i=0;i<len;i++)
283 {
284 mvwprintw(output->win,y,x+i+1,"%c",(i<strlen(buf))?buf[i]:'_');
285 }
286
287 if (cursorpos<len)
288 {
289 setcolor(output,COLOR_CURSOR);
290 mvwprintw(output->win,y,x+cursorpos+1,"%c",(cursorpos<strlen(buf))?buf[cursorpos]:'_');
291 }
292 move(y,x+cursorpos+1);
293 refresh();
294 ch=getkey(output->pKeyTab,1);
295 if (ch==KEYENTER)
296 done=1;
297 if (ch==KEYTAB) done=1;
298 if (ch==KEYESC) done=1;
299 if (ch==KEYLEFT && cursorpos) cursorpos--;
300 if (ch==KEYRIGHT && cursorpos<strlen(buf)) cursorpos++;
301 if (ch>=' ' && ch<127 && cursorpos<len)
302 {
303 memmove(&buf[cursorpos+1],&buf[cursorpos],len-cursorpos);
304 buf[cursorpos++]=ch;
305 } else if (ch==KEYBACKSPACE && cursorpos>0) {
306 memmove(&buf[cursorpos-1],&buf[cursorpos],len-cursorpos);
307 cursorpos--;
308 } else if (ch==KEYDEL && cursorpos<(strlen(buf))) {
309 memmove(&buf[cursorpos],&buf[cursorpos+1],len-cursorpos);
310 }
311 }
312 if (ch!=KEYESC) memcpy(s,buf,len);
313 setcolor(output,COLOR_TEXT);
314 for (i=0;i<len;i++)
315 {
316 mvwprintw(output->win,y,x+i+1,"%c",(i<strlen(s))?s[i]:' ');
317 }
318 free(buf);
319 return ch;
320 }
configkeytab(tKeyTab * pKeyTab,char * line)321 int configkeytab(tKeyTab* pKeyTab,char* line)
322 {
323 int i;
324 int j;
325 unsigned int x;
326 int retval=1;
327
328 for (i=0;i<NUM_SPECIALKEYS;i++)
329 {
330 if (strncmp(pKeyTab[i].config,line,strlen(pKeyTab[i].config))==0)
331 {
332 retval=0;
333 x=1;
334 pKeyTab[i].seqlen=0;
335 for (j=strlen(pKeyTab[i].config);j<strlen(line);j++)
336 {
337 x<<=4;
338 if (line[j]>='0' && line[j]<='9') x|=(line[j]-'0');
339 if (line[j]>='A' && line[j]<='F') x|=(line[j]-'A'+10);
340 if (x&0x100 && pKeyTab[i].seqlen<8)
341 {
342 pKeyTab[i].seq[pKeyTab[i].seqlen++]=(x&0xff);
343 x=1;
344 }
345 }
346
347 }
348 }
349 return retval;
350 }
writeconfigfile(tOutput * output,char * configfilename)351 int writeconfigfile(tOutput* output,char* configfilename)
352 {
353 tFptr f;
354 char tmpbuf[65536];
355 char lineorig[512];
356 char lineupcase[512];
357 char c;
358 int lineorigidx;
359 int lineupcaseidx;
360 int i,j,size;
361 tBool found;
362 tKeyTab* pKeyTab=(tKeyTab*)output->pKeyTab;
363
364 f=fopen(configfilename,"rb");
365 if (!f) return RETNOK;
366 size=fread(tmpbuf,sizeof(char),65536,f);
367 fclose(f);
368 if (size>=65536) return RETNOK;
369 tmpbuf[size++]=0;
370
371 lineorigidx=0;
372 lineupcaseidx=0;
373 f=fopen(configfilename,"w");
374 for (i=0;i<size;i++)
375 {
376 c=tmpbuf[i];
377
378 lineorig[lineorigidx++]=c;
379 lineorig[lineorigidx]=0;
380 if (c>='a' && c<='z') c-=32;
381 if (c==9) c=32;
382 if (c!=32)
383 {
384 lineupcase[lineupcaseidx++]=c;
385 lineupcase[lineupcaseidx]=0;
386 }
387
388 if (c<32)
389 {
390 found=0;
391 for (j=0;j<NUM_SPECIALKEYS;j++)
392 {
393 if (strncmp(pKeyTab[j].config,lineupcase,strlen(pKeyTab[j].config))==0)
394 {
395 found=1;
396 }
397 }
398 if (!found)
399 fprintf(f,"%s",lineorig);
400 lineorigidx=0;
401 lineupcaseidx=0;
402 }
403 }
404 for (i=0;i<NUM_SPECIALKEYS;i++)
405 {
406 fprintf(f,"%s",pKeyTab[i].config);
407 for (j=0;j<pKeyTab[i].seqlen;j++)
408 {
409 fprintf(f,"%02x ",((unsigned int)pKeyTab[i].seq[j])&0xff);
410 }
411 fprintf(f,"\n");
412 }
413 fclose(f);
414 return RETOK;
415 }
keyboardsetup(tOutput * output,char * configfilename)416 void keyboardsetup(tOutput* output,char* configfilename)
417 {
418 int i,j;
419 int ch=0;
420 int lastkey=0;
421 int keyesc=0;
422 unsigned char seq[8];
423 unsigned int seqlen;
424 tBool done;
425 tKeyTab* pKeyTab=(tKeyTab*)output->pKeyTab;
426
427 mvwprintw(output->win,0,0,"Please press the following keys");
428 mvwprintw(output->win,1,0,"(Press ESC if your keyboard does not have them)");
429 mvwprintw(output->win,3,0,"Config file:%s",configfilename);
430
431 for (i=0;i<NUM_SPECIALKEYS;i++)
432 {
433 lastkey=-1;
434 done=0;
435 seqlen=0;
436 memset(seq,0,sizeof(seq));
437 mvwprintw(output->win,21,0," ");
438 mvwprintw(output->win,21,0,"%s",pKeyTab[i].desc);
439 if (i<12) mvwprintw(output->win,5+i,0,"%s",pKeyTab[i].config);
440 else mvwprintw(output->win,i-7,40,"%s",pKeyTab[i].config);
441 memset(pKeyTab[i].seq,0,8);
442 while (!done)
443 {
444 ch=getch();
445 if (ch==-1 && lastkey!=-1) done=1;
446 if (ch!=-1 && seqlen<8) seq[seqlen++]=ch;
447 lastkey=ch;
448 }
449 pKeyTab[i].seqlen=seqlen;
450 memcpy(pKeyTab[i].seq,seq,seqlen);
451 if (pKeyTab[i].retval==KEYESC) keyesc=i;
452 else
453 if (memcmp(pKeyTab[i].seq,pKeyTab[keyesc].seq,8)==0 && i!=keyesc) pKeyTab[i].seqlen=0;
454 for (j=0;j<pKeyTab[i].seqlen;j++)
455 {
456 if (i<12) mvwprintw(output->win,5+i,15+j*3,"%02x",seq[j]);
457 else mvwprintw(output->win,i-7,55+j*3,"%02x",seq[j]);
458 }
459 if (seqlen==1 && seq[0]>=32 && seq[0]<127)
460 {
461 mvwprintw(output->win,(i<12)?(5+i):(i-7),(i<12)?0:40,"%s(*)",pKeyTab[i].config);
462 mvwprintw(output->win,20,0,"WARNING: Keystrokes with (*) cannot be used in an input field\n");
463 }
464 }
465 for (i=0;i<NUM_SPECIALKEYS;i++)
466 {
467 if (memcmp(pKeyTab[i].seq,pKeyTab[keyesc].seq,8)==0 && i!=keyesc) pKeyTab[i].seqlen=0;
468 }
469 mvwprintw(output->win,21,0,"Would you like me to write this into the config file? (Y/N)");
470 done=0;
471 while (!done)
472 {
473 ch=getch();
474 if (ch=='n' || ch=='N') done=1;
475 else if (ch=='y' || ch=='Y')
476 {
477 writeconfigfile(output,configfilename);
478 done=1;
479 } else usleep(1);
480 }
481 }
482