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