| @@ -0,0 +1,271 @@ |
| | 1 | #include <u.h> |
| | 2 | #include <libc.h> |
| | 3 | #include <ctype.h> |
| | 4 | #include <bio.h> |
| | 5 | #include <draw.h> |
| | 6 | #include <keyboard.h> |
| | 7 | #include <mouse.h> |
| | 8 | #include <thread.h> |
| | 9 | |
| | 10 | typedef struct { |
| | 11 | u8int e; |
| | 12 | u8int c; |
| | 13 | Rune r; |
| | 14 | }K; |
| | 15 | |
| | 16 | enum { |
| | 17 | Kmbase = 0xf0000, |
| | 18 | }; |
| | 19 | |
| | 20 | static K k[10*128]; |
| | 21 | static int nk; |
| | 22 | static int kbd; |
| | 23 | static Biobuf *kbmap; |
| | 24 | |
| | 25 | static char * |
| | 26 | k2s(Rune r) |
| | 27 | { |
| | 28 | switch(r){ |
| | 29 | case Kack: return "Kack"; |
| | 30 | case Kalt: return "Kalt"; |
| | 31 | case Kaltgr: return "Kaltgr"; |
| | 32 | case Kbreak: return "Kbreak"; |
| | 33 | case Kbs: return "Kbs"; |
| | 34 | case Kcaps: return "Kcaps"; |
| | 35 | case Kctl: return "Kctl"; |
| | 36 | case Kdel: return "Kdel"; |
| | 37 | case Kdown: return "Kdown"; |
| | 38 | case Kend: return "Kend"; |
| | 39 | case Kenq: return "Kenq"; |
| | 40 | case Keof: return "Keof"; |
| | 41 | case Kesc: return "Kesc"; |
| | 42 | case Ketb: return "Ketb"; |
| | 43 | case Ketx: return "Ketx"; |
| | 44 | case Khome: return "Khome"; |
| | 45 | case Kins: return "Kins"; |
| | 46 | case Kleft: return "Kleft"; |
| | 47 | case Kmiddle: return "Kmiddle"; |
| | 48 | case Kmod4: return "Kmod4"; |
| | 49 | case Knack: return "Knack"; |
| | 50 | case Knum: return "Knum"; |
| | 51 | case Kpgdown: return "Kpgdown"; |
| | 52 | case Kpgup: return "Kpgup"; |
| | 53 | case Kprint: return "Kprint"; |
| | 54 | case Kright: return "Kright"; |
| | 55 | case Kscroll: return "Kscroll"; |
| | 56 | case Kscrollonedown: return "Kscrollonedown"; |
| | 57 | case Kscrolloneup: return "Kscrolloneup"; |
| | 58 | case Kshift: return "Kshift"; |
| | 59 | case Ksoh: return "Ksoh"; |
| | 60 | case Kstx: return "Kstx"; |
| | 61 | case Kup: return "Kup"; |
| | 62 | case KF|1: return "F1"; |
| | 63 | case KF|2: return "F2"; |
| | 64 | case KF|3: return "F3"; |
| | 65 | case KF|4: return "F4"; |
| | 66 | case KF|5: return "F5"; |
| | 67 | case KF|6: return "F6"; |
| | 68 | case KF|7: return "F7"; |
| | 69 | case KF|8: return "F8"; |
| | 70 | case KF|9: return "F9"; |
| | 71 | case KF|10: return "F10"; |
| | 72 | case KF|11: return "F11"; |
| | 73 | case KF|12: return "F12"; |
| | 74 | case Kmouse|1: return "Kmouse1"; |
| | 75 | case Kmouse|2: return "Kmouse2"; |
| | 76 | case Kmouse|3: return "Kmouse3"; |
| | 77 | case Kmouse|4: return "Kmouse4"; |
| | 78 | case Kmouse|5: return "Kmouse5"; |
| | 79 | case '\n': return "\\n"; |
| | 80 | } |
| | 81 | |
| | 82 | return nil; |
| | 83 | } |
| | 84 | |
| | 85 | static void |
| | 86 | kmreset(void) |
| | 87 | { |
| | 88 | int i; |
| | 89 | |
| | 90 | for(i = 0; i <= nk; i++) |
| | 91 | Bprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, k[i].r); |
| | 92 | Bflush(kbmap); |
| | 93 | } |
| | 94 | |
| | 95 | static void |
| | 96 | kmset(void) |
| | 97 | { |
| | 98 | int i; |
| | 99 | |
| | 100 | for(i = 0; i <= nk; i++) |
| | 101 | Bprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, Kmbase+i); |
| | 102 | Bflush(kbmap); |
| | 103 | } |
| | 104 | |
| | 105 | static void |
| | 106 | key(Rune r, char *type) |
| | 107 | { |
| | 108 | char *s, t[32]; |
| | 109 | Rune c; |
| | 110 | K q; |
| | 111 | |
| | 112 | if(r < Kmbase || r >= Kmbase+nk){ |
| | 113 | if((s = k2s(r)) != nil) |
| | 114 | snprint(t, sizeof(t), "%s", s); |
| | 115 | else if((r < 0x80 && isprint(r)) || r >= 0x20) |
| | 116 | snprint(t, sizeof(t), "%C (0x%x)", r, r); |
| | 117 | else |
| | 118 | snprint(t, sizeof(t), "0x%x", r); |
| | 119 | print("unexpected key %s %s\n", type, t); |
| | 120 | return; |
| | 121 | } |
| | 122 | q = k[r-Kmbase]; |
| | 123 | c = q.r; |
| | 124 | if((s = k2s(c)) != nil) |
| | 125 | snprint(t, sizeof(t), "%s", s); |
| | 126 | else if((c < 0x80 && isprint(c)) || c >= 0x20) |
| | 127 | snprint(t, sizeof(t), "%C (0x%x)", c, c); |
| | 128 | else |
| | 129 | snprint(t, sizeof(t), "0x%x", c); |
| | 130 | |
| | 131 | print("key %s %s: %d %d %d\n", type, t, q.e, q.c, q.r); |
| | 132 | } |
| | 133 | |
| | 134 | static void |
| | 135 | kbproc(void *) |
| | 136 | { |
| | 137 | char *s, buf[128], buf2[128]; |
| | 138 | int kbd, n; |
| | 139 | Rune r; |
| | 140 | |
| | 141 | threadsetname("kbproc"); |
| | 142 | if((kbd = open("/dev/kbd", OREAD)) < 0) |
| | 143 | sysfatal("/dev/kbd: %r"); |
| | 144 | |
| | 145 | buf2[0] = 0; |
| | 146 | buf2[1] = 0; |
| | 147 | buf[0] = 0; |
| | 148 | for(;;){ |
| | 149 | if(buf[0] != 0){ |
| | 150 | n = strlen(buf)+1; |
| | 151 | memmove(buf, buf+n, sizeof(buf)-n); |
| | 152 | } |
| | 153 | if(buf[0] == 0){ |
| | 154 | n = read(kbd, buf, sizeof(buf)-1); |
| | 155 | if(n <= 0) |
| | 156 | break; |
| | 157 | buf[n-1] = 0; |
| | 158 | buf[n] = 0; |
| | 159 | } |
| | 160 | |
| | 161 | switch(buf[0]){ |
| | 162 | case 'k': |
| | 163 | for(s = buf+1; *s;){ |
| | 164 | s += chartorune(&r, s); |
| | 165 | if(utfrune(buf2+1, r) == nil) |
| | 166 | key(r, "down"); |
| | 167 | } |
| | 168 | break; |
| | 169 | case 'K': |
| | 170 | for(s = buf2+1; *s;){ |
| | 171 | s += chartorune(&r, s); |
| | 172 | if(utfrune(buf+1, r) == nil) |
| | 173 | key(r, "up"); |
| | 174 | } |
| | 175 | break; |
| | 176 | case 'c': |
| | 177 | if(chartorune(&r, buf+1) > 0 && r != Runeerror) |
| | 178 | key(r, "repeat"); |
| | 179 | default: |
| | 180 | continue; |
| | 181 | } |
| | 182 | |
| | 183 | strcpy(buf2, buf); |
| | 184 | } |
| | 185 | |
| | 186 | close(kbd); |
| | 187 | |
| | 188 | threadexits(nil); |
| | 189 | } |
| | 190 | |
| | 191 | static void |
| | 192 | usage(void) |
| | 193 | { |
| | 194 | fprint(2, "usage: %s\n", argv0); |
| | 195 | threadexitsall("usage"); |
| | 196 | } |
| | 197 | |
| | 198 | void |
| | 199 | threadmain(int argc, char **argv) |
| | 200 | { |
| | 201 | Mousectl *mctl; |
| | 202 | char tmp[32]; |
| | 203 | Mouse m; |
| | 204 | char *s; |
| | 205 | enum { Cmouse, Cresize, Numchan }; |
| | 206 | Alt a[Numchan+1] = { |
| | 207 | [Cmouse] = { nil, &m, CHANRCV }, |
| | 208 | [Cresize] = { nil, nil, CHANRCV }, |
| | 209 | { nil, nil, CHANEND }, |
| | 210 | }; |
| | 211 | |
| | 212 | ARGBEGIN{ |
| | 213 | default: |
| | 214 | usage(); |
| | 215 | }ARGEND |
| | 216 | |
| | 217 | if(argc != 0) |
| | 218 | usage(); |
| | 219 | |
| | 220 | if((kbmap = Bopen("/dev/kbmap", OREAD)) == nil) |
| | 221 | sysfatal("%r"); |
| | 222 | for(nk = 0; nk < nelem(k); nk++){ |
| | 223 | if((s = Brdline(kbmap, '\n')) == nil) |
| | 224 | break; |
| | 225 | k[nk].e = strtoul(s, &s, 10); |
| | 226 | k[nk].c = strtoul(s, &s, 10); |
| | 227 | k[nk].r = strtoul(s, &s, 10); |
| | 228 | } |
| | 229 | Bterm(kbmap); |
| | 230 | |
| | 231 | if((kbmap = Bopen("/dev/kbmap", OWRITE)) == nil) |
| | 232 | sysfatal("%r"); |
| | 233 | atexit(kmreset); |
| | 234 | |
| | 235 | snprint(tmp, sizeof(tmp), "-pid %d -dx %d -dy %d", getpid(), 256, 256); |
| | 236 | newwindow(tmp); |
| | 237 | |
| | 238 | if(initdraw(nil, nil, "evdump") < 0) |
| | 239 | sysfatal("initdraw: %r"); |
| | 240 | if((mctl = initmouse(nil, screen)) == nil) |
| | 241 | sysfatal("initmouse: %r"); |
| | 242 | a[Cmouse].c = mctl->c; |
| | 243 | a[Cresize].c = mctl->resizec; |
| | 244 | |
| | 245 | proccreate(kbproc, nil, mainstacksize); |
| | 246 | |
| | 247 | for (;;) { |
| | 248 | draw(screen, screen->r, display->black, nil, ZP); |
| | 249 | |
| | 250 | switch (alt(a)) { |
| | 251 | case -1: |
| | 252 | goto end; |
| | 253 | |
| | 254 | case Cmouse: |
| | 255 | print("mouse buttons 0x%x x %d y %d\n", m.buttons, m.xy.x, m.xy.y); |
| | 256 | break; |
| | 257 | |
| | 258 | case Cresize: |
| | 259 | getwindow(display, Refnone); |
| | 260 | print( |
| | 261 | "resize min %d %d max %d %d\n", |
| | 262 | screen->r.min.x, screen->r.min.y, |
| | 263 | screen->r.max.x, screen->r.max.y |
| | 264 | ); |
| | 265 | break; |
| | 266 | } |
| | 267 | } |
| | 268 | |
| | 269 | end: |
| | 270 | threadexitsall(nil); |
| | 271 | } |