1 #include <u.h> 2 #include <libc.h> 3 #include "compat.h" 4 #include "kbd.h" 5 #include "ksym2utf.h" 6 7 enum 8 { 9 VKSpecial = 0xff00, 10 11 /* 12 * plan 9 key mappings 13 */ 14 Spec= 0xF800, 15 16 PF= Spec|0x20, /* num pad function key */ 17 View= Spec|0x00, /* view (shift window up) */ 18 KF= 0xF000, /* function key (begin Unicode private space) */ 19 Shift= Spec|0x60, 20 Break= Spec|0x61, 21 Ctrl= Spec|0x62, 22 Latin= Spec|0x63, 23 Caps= Spec|0x64, 24 Num= Spec|0x65, 25 Middle= Spec|0x66, 26 No= 0x00, /* peter */ 27 28 Home= KF|13, 29 Up= KF|14, 30 Pgup= KF|15, 31 Print= KF|16, 32 Left= KF|17, 33 Right= KF|18, 34 End= '\r', 35 Down= View, 36 Pgdown= KF|19, 37 Ins= KF|20, 38 Del= 0x7F, 39 Scroll= KF|21, 40 41 Esc = 0x1b, 42 Delete = 0x7f, 43 }; 44 45 static Rune vnckeys[] = 46 { 47 [0x00] No, No, No, No, No, No, No, No, 48 [0x08] '\b', '\t', '\r', No, No, '\n', No, No, 49 [0x10] No, No, No, No, Scroll, No, No, No, 50 [0x18] No, No, No, Esc, No, No, No, No, 51 [0x20] No, No, No, No, No, No, No, No, 52 [0x28] No, No, No, No, No, No, No, No, 53 [0x30] No, No, No, No, No, No, No, No, 54 [0x38] No, No, No, No, No, No, No, No, 55 [0x40] No, No, No, No, No, No, No, No, 56 [0x48] No, No, No, No, No, No, No, No, 57 [0x50] Home, Left, Up, Right, Down, Pgup, Pgdown, No, 58 [0x58] No, No, No, No, No, No, No, No, 59 [0x60] No, Print, No, Ins, No, No, No, No, 60 [0x68] No, No, No, Break, No, No, No, No, 61 [0x70] No, No, No, No, No, No, No, No, 62 [0x78] No, No, No, No, No, No, No, Num, 63 [0x80] No, No, No, No, No, No, No, No, 64 [0x88] No, No, No, No, No, No, No, No, 65 [0x90] No, No, No, No, No, No, No, No, 66 [0x98] No, No, No, No, No, No, No, No, 67 [0xa0] No, No, No, No, No, No, No, No, 68 [0xa8] No, No, '*', '+', No, '-', '.', '/', 69 [0xb0] '0', '1', '2', '3', '4', '5', '6', '7', 70 [0xb8] '8', '9', No, No, No, '=', No, No, 71 [0xc0] No, No, No, No, No, No, No, No, 72 [0xc8] No, No, No, No, No, No, No, No, 73 [0xd0] No, No, No, No, No, No, No, No, 74 [0xd8] No, No, No, No, No, No, No, No, 75 [0xe0] No, Shift, Shift, Ctrl, Ctrl, Caps, Caps, No, 76 [0xe8] No, Latin, Latin, No, No, No, No, No, 77 [0xf0] No, No, No, No, No, No, No, No, 78 [0xf8] No, No, No, No, No, No, No, Delete, 79 }; 80 81 /* 82 * keyboard interrupt 83 */ 84 void 85 vncputc(int keyup, int c) 86 { 87 int i; 88 static int esc1, esc2; 89 static int alt, caps, ctl, num, shift; 90 static int collecting, nk; 91 static Rune kc[5]; 92 93 if(caps && c<='z' && c>='a') 94 c += 'A' - 'a'; 95 96 /* 97 * character mapping 98 */ 99 if((c & VKSpecial) == VKSpecial){ 100 c = vnckeys[c & 0xff]; 101 if(c == No) 102 return; 103 } 104 /* 105 * map an xkeysym onto a utf-8 char 106 */ 107 if((c & 0xff00) && c < nelem(ksym2utf) && ksym2utf[c] != 0) 108 c = ksym2utf[c]; 109 110 /* 111 * keyup only important for shifts 112 */ 113 if(keyup){ 114 switch(c){ 115 case Latin: 116 alt = 0; 117 break; 118 case Shift: 119 shift = 0; 120 break; 121 case Ctrl: 122 ctl = 0; 123 break; 124 } 125 return; 126 } 127 128 /* 129 * normal character 130 */ 131 if(!(c & (Spec|KF))){ 132 if(ctl){ 133 c &= 0x1f; 134 } 135 if(!collecting){ 136 kbdputc(c); 137 return; 138 } 139 kc[nk++] = c; 140 c = latin1(kc, nk); 141 if(c < -1) /* need more keystrokes */ 142 return; 143 if(c != -1) /* valid sequence */ 144 kbdputc(c); 145 else /* dump characters */ 146 for(i=0; i<nk; i++) 147 kbdputc(kc[i]); 148 nk = 0; 149 collecting = 0; 150 return; 151 }else{ 152 switch(c){ 153 case Caps: 154 caps ^= 1; 155 return; 156 case Num: 157 num ^= 1; 158 return; 159 case Shift: 160 shift = 1; 161 return; 162 case Latin: 163 alt = 1; 164 collecting = 1; 165 nk = 0; 166 return; 167 case Ctrl: 168 ctl = 1; 169 return; 170 } 171 } 172 kbdputc(c); 173 } 174