latin1.c (1952B)
1 #include "u.h" 2 #include "lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "keyboard.h" 7 8 9 /* 10 * The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be a 11 * prefix of latintab[j].ld only when j<i. 12 */ 13 struct cvlist 14 { 15 char *ld; /* must be seen before using this conversion */ 16 char *si; /* options for last input characters */ 17 Rune so[64]; /* the corresponding Rune for each si entry */ 18 } latintab[] = { 19 #include "latin1.h" 20 0, 0, 0 21 }; 22 23 /* 24 * Given 5 characters k[0]..k[4], find the rune or return -1 for failure. 25 */ 26 long 27 unicode(Rune *k) 28 { 29 long i, c; 30 31 k++; /* skip 'X' */ 32 c = 0; 33 for(i=0; i<4; i++,k++){ 34 c <<= 4; 35 if('0'<=*k && *k<='9') 36 c += *k-'0'; 37 else if('a'<=*k && *k<='f') 38 c += 10 + *k-'a'; 39 else if('A'<=*k && *k<='F') 40 c += 10 + *k-'A'; 41 else 42 return -1; 43 } 44 return c; 45 } 46 47 /* 48 * Given n characters k[0]..k[n-1], find the corresponding rune or return -1 for 49 * failure, or something < -1 if n is too small. In the latter case, the result 50 * is minus the required n. 51 */ 52 long 53 latin1(Rune *k, int n) 54 { 55 struct cvlist *l; 56 int c; 57 char* p; 58 59 if(k[0] == 'X'){ 60 if(n>=5) 61 return unicode(k); 62 else 63 return -5; 64 } 65 for(l=latintab; l->ld!=0; l++) 66 if(k[0] == l->ld[0]){ 67 if(n == 1) 68 return -2; 69 if(l->ld[1] == 0) 70 c = k[1]; 71 else if(l->ld[1] != k[1]) 72 continue; 73 else if(n == 2) 74 return -3; 75 else 76 c = k[2]; 77 for(p=l->si; *p!=0; p++) 78 if(*p == c) 79 return l->so[p - l->si]; 80 return -1; 81 } 82 return -1; 83 } 84 85 // Plan 9 VX 86 void 87 latin1putc(int c, void (*kputc)(int)) 88 { 89 int i; 90 static int collecting, nk; 91 static Rune kc[5]; 92 93 if(c == Kalt){ 94 collecting = !collecting; 95 nk = 0; 96 return; 97 } 98 99 if(!collecting){ 100 kputc(c); 101 return; 102 } 103 104 kc[nk++] = c; 105 c = latin1(kc, nk); 106 if(c < -1) /* need more keystrokes */ 107 return; 108 if(c != -1) /* valid sequence */ 109 kputc(c); 110 else 111 for(i=0; i<nk; i++) 112 kputc(kc[i]); 113 nk = 0; 114 collecting = 0; 115 } 116