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