10 #include "graf/graf.h"
\r
12 #define KB_BACKSPACE (int)'\b' /* kb */
\r
13 #define KB_ENTER (int)'\r' /* RT */
\r
14 #define KB_TAB (int)'\t' /* TB */
\r
15 #define KB_ESC 0x1b /* EC */
\r
17 #define KB_HOME -71 /* kh or HM */
\r
18 #define KB_END -79 /* EN */
\r
19 #define KB_UP -72 /* ku or UP */
\r
20 #define KB_DOWN -80 /* kd */
\r
21 #define KB_LEFT -75 /* kl */
\r
22 #define KB_RIGHT -77 /* kr */
\r
23 #define KB_PGUP -73 /* PU */
\r
24 #define KB_PGDN -81 /* PD */
\r
25 #define KB_BACK_TAB -15 /* BT */
\r
26 #define KB_INS -82 /* al */
\r
27 #define KB_DEL -83 /* DL */
\r
29 #define KB_F1 -59 /* k1 */
\r
30 #define KB_F2 -60 /* k2 */
\r
31 #define KB_F3 -61 /* k3 */
\r
32 #define KB_F4 -62 /* k4 */
\r
33 #define KB_F5 -63 /* k5 */
\r
34 #define KB_F6 -64 /* k6 */
\r
35 #define KB_F7 -65 /* k7 */
\r
36 #define KB_F8 -66 /* k8 */
\r
37 #define KB_F9 -67 /* k9 */
\r
38 #define KB_F10 -68 /* k0 */
\r
40 #define KB_STR_EXISTS 1 /* string exists in tree or his prefix */
\r
41 #define KB_TOO_MANY_STRINGS 2
\r
42 #define KB_NULL_STRING 3
\r
43 #define KB_OUT_OF_MEMORY 4
\r
51 #include "process.h"
\r
52 #include "intproto.h"
\r
58 static char *capability,*capability_value;
\r
60 typedef struct _tree_node *tree; /* drzewo zawierajace ciagi znakow */
\r
61 struct _tree_node { /* odpowiadajace klawiszowi klawiatury */
\r
67 #ifndef NO_PROTOTYPES
\r
68 static int tfirst(int);
\r
69 static int tnext(void);
\r
70 static void *___allocate_object(unsigned);
\r
71 static void ___free_object(void *);
\r
72 static char *object_str(char *); /* allocate space and copy string */
\r
73 static int __testkey(int*,int*);
\r
74 static int getkey(void);
\r
75 static int __inkey(void);
\r
76 static void kbinit(void);
\r
77 static tree new_tree_node(void);
\r
78 static int _create_new_leaf(tree,int,unsigned char *,int);
\r
79 static int inskey(int,char *);
\r
81 static int tfirst();
\r
83 static void *___allocate_object();
\r
84 static void ___free_object();
\r
85 static char *object_str();
\r
86 static int __testkey();
\r
87 static int getkey();
\r
88 static int __inkey();
\r
89 static void kbinit();
\r
90 static tree new_tree_node();
\r
91 static int _create_new_leaf();
\r
92 static int inskey();
\r
99 #define object_kill(i) (___free_object(i),(i)=NULL)
\r
100 #define object_new(type) ((type *)___allocate_object(sizeof(type)))
\r
101 #define object_dim(i,type) ((type *)___allocate_object((i)*sizeof(type)))
\r
106 #define KB_NDEF 0xff /* KN - key suppressed by inkey() */
\r
108 #define NODE_SIZE 100
\r
112 static int cqueue[QSIZE]; /* implementacja kolejki */
\r
113 static int qh=0,qt=0,qs=0;
\r
116 if( qs == 0 ) return -1;
\r
117 c = cqueue[ qh++ ];
\r
122 static void bput( c ) int c; {
\r
123 if( qs == QSIZE ) return;
\r
124 cqueue[ qt++ ] = c;
\r
129 static int bfirst(){
\r
130 if( qs == 0 ) return -1;
\r
133 return cqueue[ qh ];
\r
135 static int bnext(){
\r
137 if( qq == qt ) return -1;
\r
138 c = cqueue[ qq++ ];
\r
144 static tree troot=NULL;
\r
147 static FILE *f=NULL;
\r
148 static void _show_tree(root,r) tree root;int r;{
\r
150 for(i=0;(i<NODE_SIZE) && (root[i].key!=-1);i++){
\r
151 for(j=0;j<r;j++) fprintf(f,"i");
\r
153 fprintf(f,"%d ",root[i].key);fflush(f);
\r
154 if(root[i].way==NULL){
\r
155 fprintf(f,"%d\n",root[i].outkey);fflush(f);
\r
156 }else _show_tree(root[i].way,r+1);
\r
159 static void show_tree(){
\r
160 f=fopen("show_tree","a");
\r
161 if(f==NULL){printf("cant open");exit(7);}
\r
162 fprintf(f,"%lx\n",troot);fflush(f);
\r
163 _show_tree(troot,0);
\r
164 fprintf(f,"********************\n");
\r
171 #define PART_SUBSTRING 1
\r
172 #define SUBSTRING 2
\r
176 static int __testkey(outkey,to_take) int *outkey,*to_take;
\r
184 if(c==-1) return NO_CHARS; /* buffer empty - wait for char */
\r
189 for(i=0;i<NODE_SIZE;i++){
\r
190 if(tact[i].key==-1){ i=NODE_SIZE; break; }
\r
192 if(tact[i].way!=NULL){
\r
196 *outkey=tact[i].outkey;
\r
197 if(*outkey != -1) return SUBSTRING;
\r
198 else return PART_SUBSTRING;
\r
204 *outkey = tact[i].outkey;
\r
208 if( i==NODE_SIZE ) return NO_MATCH;
\r
213 static void (*prev_fun)()=NULL;
\r
214 static void alarm_fun(){}
\r
217 static int getkey(){
\r
219 prev_fun = signal( SIGALRM, alarm_fun );
\r
223 signal( SIGALRM, prev_fun );
\r
229 static int __inkey()
\r
231 int c,i,outkey,chars;
\r
232 if(troot==NULL){printf("Not initialized\n\r");exit(7);}
\r
238 i=__testkey(&outkey,&chars);
\r
244 if( c != -1 ) bput( c );
\r
248 case PART_SUBSTRING :
\r
250 if( c==-1 ) return bget();
\r
257 while( chars-- ) bget();
\r
264 while( chars-- ) bget();
\r
276 static struct termio term_state,term_new;
\r
280 { /* podaj znak z klawiatury - zapominanie KB_NDEF */
\r
281 static int first_time=1;
\r
284 if( first_time ){ kbinit(); first_time=0; }
\r
286 ioctl(fileno(stdin),TCGETA,&term_state); /* RAW MODE */
\r
287 term_new = term_state;
\r
288 term_new.c_lflag&=~(ISIG|ICANON|ECHO); /* echo,canonical line processing */
\r
289 /* signal processing = OFF */
\r
290 term_new.c_iflag&=~(ICRNL|INLCR); /* conversions OFF */
\r
291 term_new.c_oflag=0;
\r
292 term_new.c_cc[VEOF]='\1'; /* every char flushed immedietly */
\r
293 ioctl(fileno(stdin),TCSETA,&term_new);
\r
295 do k=__inkey(); while(k==KB_NDEF);
\r
297 ioctl(fileno(stdin),TCSETA,&term_state); /* PREVIOUS MODE */
\r
303 static tree new_tree_node(){
\r
306 p=(tree)object_dim(NODE_SIZE+1,struct _tree_node);
\r
308 for(i=0;i<NODE_SIZE;i++){
\r
309 p[i].key=p[i].outkey=-1;
\r
316 static int inskey(ch,str)
\r
323 if(troot==NULL) return KB_OUT_OF_MEMORY;
\r
324 if(str==NULL || (!(*str))) return KB_NULL_STRING;
\r
327 for(i=0;i<NODE_SIZE;i++){
\r
328 if(tact[i].key==-1){
\r
329 tact[i].key=(int)(*(str++));
\r
330 return _create_new_leaf(tact,i,str,ch);
\r
332 if(tact[i].key==(int)(*str)){
\r
334 if(tact[i].way==NULL)
\r
335 if( *str!='\0' ) return _create_new_leaf(tact,i,str,ch);
\r
336 else return KB_STR_EXISTS;
\r
345 if(i==NODE_SIZE) return KB_TOO_MANY_STRINGS;
\r
350 static int _create_new_leaf(tact,i,str,ch)
\r
353 unsigned char *str;
\r
356 tact[i].way=new_tree_node();
\r
357 tact[i].way[-1].way=tact;
\r
360 tact[0].key=(int)(*(str++));
\r
367 static struct { int key; char capability[3]; } tab[]={
\r
369 { KB_NDEF , "KN" },
\r
370 { KB_BACKSPACE , "kb" },
\r
371 { KB_ENTER , "RT" },
\r
372 { KB_HOME , "kh" },
\r
373 { KB_HOME , "HM" },
\r
377 { KB_DOWN , "kd" },
\r
378 { KB_LEFT , "kl" },
\r
379 { KB_RIGHT , "kr" },
\r
380 { KB_PGUP , "PU" },
\r
381 { KB_PGDN , "PD" },
\r
382 { KB_BACK_TAB , "BT" },
\r
400 static void kb_install(){
\r
402 for(i=0;i<sizeof(tab)/sizeof(*tab);i++){
\r
403 if(tab[i].capability[0]!=capability[0]) continue;
\r
404 if(tab[i].capability[1]!=capability[1]) continue;
\r
405 if(capability_value==NULL) return;
\r
406 if(capability[2]!='='){
\r
407 if( capability_value!=NULL) object_kill(capability_value);
\r
411 int err = inskey(tab[i].key,capability_value);
\r
412 if(err==KB_OK) return;
\r
413 if(err==KB_STR_EXISTS || err==KB_NULL_STRING){
\r
414 object_kill(capability_value);
\r
417 printf("Capability %2.2s cannot be inserted:",capability);
\r
418 if(err==KB_TOO_MANY_STRINGS) printf("too many strings\n\r");
\r
419 if(err==KB_OUT_OF_MEMORY ) printf("out of memory\n\r");
\r
424 if(capability_value!=NULL) object_kill(capability_value);
\r
428 static void kbinit() /* inicjalizacja klawiatury */
\r
433 troot=new_tree_node();
\r
434 troot[-1].way=NULL;
\r
437 capability_value=object_str("\177");
\r
440 if(tfirst(KEYBOARD)==0){
\r
447 if(tfirst(TERMINAL)==0){
\r
459 /* FUNCTIONS for search through one TERMCAP entry */
\r
462 static char *termcap=NULL;
\r
463 static char *keybcap=NULL;
\r
465 #ifndef NO_PROTOTYPES
\r
466 static char *envset(char *,char*);
\r
467 static char *findchar(char *,char);
\r
468 static int convert(char *,char *,int);
\r
469 static int next_char(FILE *);
\r
470 static int find_name(FILE *,char *);
\r
472 static char *envset();
\r
473 static char *findchar();
\r
474 static int convert();
\r
475 static int next_char();
\r
476 static int find_name();
\r
480 static char *findchar(str,ch) char *str,ch;{
\r
481 if(str==NULL) return NULL;
\r
482 while( *str!='\0' && *str!=ch ) str++;
\r
483 if(*str=='\0') return NULL;
\r
487 static char *tgetent(dev)
\r
488 /* gets info from variable TERMCAP */
\r
489 /* or var INKEY or file /etc/inkey */
\r
493 if(termcap==NULL) termcap=envset("TERMCAP","termcap");
\r
495 fprintf(stderr,"\n\rfile [/etc/]termcap not found\n\r");
\r
496 fflush(stderr);exit(7);
\r
501 if(keybcap==NULL) keybcap=envset("INKEY","inkey");
\r
503 }else{ printf("bad device for tgetent \n\r"); exit(7); }
\r
509 static char stat_value[100];
\r
511 static int tfirst(dev)
\r
515 capability=tgetent(dev);
\r
516 if(capability==NULL) return 1;
\r
519 static int tnext(){
\r
520 char *value,*colon;
\r
522 capability=findchar(capability,':');
\r
523 if(capability==NULL) return 1;
\r
525 if(*capability=='\0') return 1;
\r
526 } while( capability[0]==' ' || capability[0]=='\t' );
\r
527 value=findchar(capability,'=');
\r
528 colon=findchar(capability,':');
\r
529 if( value==NULL || ( colon!=NULL && value!=NULL && colon<value ) ){
\r
530 capability_value=object_str("");
\r
534 if(*value=='\0') return 1;
\r
535 convert(stat_value,value,sizeof(stat_value));
\r
536 capability_value=object_str(stat_value);
\r
541 static int convert(ptr,tptr,ptr_size) char *ptr,*tptr; int ptr_size; {
\r
544 while( (tptr!=NULL) && (*tptr!=':') && (*tptr!='\0') )
\r
548 case 'E' :tptr++;ptr_size--;*(ptr++)='\x1b';break;
\r
549 case 'n' :tptr++;ptr_size--;*(ptr++)='\n';break;
\r
550 case 'r' :tptr++;ptr_size--;*(ptr++)='\r';break;
\r
551 case 't' :tptr++;ptr_size--;*(ptr++)='\t';break;
\r
552 case 'b' :tptr++;ptr_size--;*(ptr++)='\b';break;
\r
553 case 'f' :tptr++;ptr_size--;*(ptr++)='\f';break;
\r
554 case '\\':tptr++;ptr_size--;*(ptr++)='\\';break;
\r
555 case '^' :tptr++;ptr_size--;*(ptr++)='^';break;
\r
556 default :*ptr='\0';
\r
558 if(*tptr<'0' || *tptr>'7') return 1;
\r
560 *ptr+=*(tptr++)-'0';
\r
567 *(ptr++)=(char)((toupper(c))-'A'+1); ptr_size--;
\r
569 default: *(ptr++)=*(tptr++); ptr_size--;
\r
573 fprintf(stderr,"buffer exceeded in convert(%s)",__FILE__);
\r
581 /* FUNCTIONS looking for entries in /ETC/TERMCAP */
\r
585 static char etcname[80];
\r
586 static char termname[80];
\r
587 static char *fname;
\r
590 static char *envset(envname,envfile) char *envname,*envfile;{
\r
591 extern char *getenv();
\r
592 char *TERM=getenv("TERM");
\r
593 char *env=getenv(envname);
\r
598 ptr=str=object_dim(32000,char);
\r
600 fprintf(stderr,"Out of memory.\n");
\r
606 fprintf(stderr,"\n\renvironment variable TERM not found\n\r");
\r
611 strcpy(termname,TERM);
\r
614 if( f==NULL ) f=fopen(envfile,"r"); else fname=env;
\r
615 if( f==NULL ) f=fopen(strcat(strcpy(etcname,"/etc/"),envfile),"r");
\r
616 else fname=envfile;
\r
617 if( f==NULL ) return NULL;
\r
618 else fname=etcname;
\r
620 while( continued ){
\r
624 if( find_name(f,termname)==0 ) return object_str(":");
\r
630 if( c!='\0' ) *(ptr++)=(char)c;
\r
635 while( rev>str && rev[-1]!=':' ) rev--;
\r
636 if( rev[0]=='t' && rev[1]=='c' ){
\r
640 while( *rev!=':' ) *(tnm++)=*(rev++);
\r
647 ptr=object_str(str);
\r
653 static int find_name(f,termname) FILE *f; char *termname;{
\r
654 int i,c,lastc,found=0;
\r
661 if(c==EOF) return 0;
\r
662 if(c=='#' || c=='\t' || c==':' || c=='\n')
\r
666 if(c==EOF) return 0;
\r
667 if( lastc=='\\' ) c=' ';
\r
672 for(i=0;termname[i]!='\0';i++){
\r
673 if((char)c!=termname[i]) break;
\r
676 if( termname[i]=='\0' ){ found=1; break; }
\r
677 while( isalpha((char)c) ) c=fgetc(f);
\r
678 if( c=='|' ) c=fgetc(f);
\r
679 else{ ungetc('#',f); break; }
\r
686 if(c==EOF) return 0;
\r
693 static int next_char(f) FILE *f;{
\r
695 static int lastc='\0';
\r
702 if( c==EOF || c=='\n' ) return '\0';
\r
706 while( c=='\n' || c=='\t' || c==':' || c==' ' ) c=fgetc(f);
\r
718 static void *___allocate_object(size) unsigned size;{
\r
720 extern void *calloc();
\r
721 if(size==0) return NULL;
\r
725 printf("=======================================\r\n");
\r
726 printf("Memory overflow ... \r\n");
\r
727 printf("=======================================\r\n");
\r
729 system("stty sane");
\r
735 static void ___free_object(ff) void *ff;{
\r
740 static char *object_str(str) char *str;{
\r
741 char *buf=object_dim(strlen(str)+1,char);
\r