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