#include "kbd.h"
#include "error.h"
-typedef struct Queue Queue;
-struct Queue
-{
- QLock qwait;
- Rendez rwait;
-
- Lock lock;
- int notempty;
- char buf[1024];
- char *w;
- char *r;
- char *e;
-};
-
-Queue* kbdq; /* unprocessed console input */
-Queue* lineq; /* processed console input */
Snarf snarf = {
.vers = 1
};
-static struct
-{
- QLock;
- int raw; /* true if we shouldn't process input */
- int ctl; /* number of opens to the control file */
- int x; /* index into line */
- char line[1024]; /* current input line */
-} kbd;
-
-/*
- * cheapo fixed-length queues
- */
-static void
-qwrite(Queue *q, void *v, int n)
-{
- char *buf, *next;
- int i;
-
- buf = v;
- lock(&q->lock);
- for(i = 0; i < n; i++){
- next = q->w+1;
- if(next >= q->e)
- next = q->buf;
- if(next == q->r)
- break;
- *q->w = buf[i];
- q->w = next;
- }
- q->notempty = 1;
- unlock(&q->lock);
- rendwakeup(&q->rwait);
-}
-
-static int
-qcanread(void *vq)
-{
- Queue *q;
- int ne;
-
- q = vq;
- lock(&q->lock);
- ne = q->notempty;
- unlock(&q->lock);
- return ne;
-}
-
-static int
-qread(Queue *q, void *v, int n)
-{
- char *a;
- int nn, notempty;
-
- if(n == 0)
- return 0;
- a = v;
- nn = 0;
- for(;;){
- lock(&q->lock);
-
- while(nn < n && q->r != q->w){
- a[nn++] = *q->r++;
- if(q->r >= q->e)
- q->r = q->buf;
- }
-
- notempty = q->notempty;
- q->notempty = q->r != q->w;
- unlock(&q->lock);
- if(notempty)
- break;
-
- /*
- * wait for something to show up in the kbd buffer.
- */
- qlock(&q->qwait);
- if(waserror()){
- qunlock(&q->qwait);
- nexterror();
- }
- rendsleep(&q->rwait, qcanread, q);
- qunlock(&q->qwait);
- poperror();
- }
- return nn;
-}
-
-static Queue *
-mkqueue(void)
-{
- Queue *q;
-
- q = smalloc(sizeof(Queue));
- q->r = q->buf;
- q->w = q->r;
- q->e = &q->buf[sizeof q->buf];
- q->notempty = 0;
- return q;
-}
-
-static void
-echoscreen(char *buf, int n)
-{
- char *e, *p;
- char ebuf[128];
- int x;
-
- p = ebuf;
- e = ebuf + sizeof(ebuf) - 4;
- while(n-- > 0){
- if(p >= e){
- screenputs(ebuf, p - ebuf);
- p = ebuf;
- }
- x = *buf++;
- if(x == 0x15){
- *p++ = '^';
- *p++ = 'U';
- *p++ = '\n';
- } else
- *p++ = x;
- }
- if(p != ebuf)
- screenputs(ebuf, p - ebuf);
-}
-
-/*
- * Put character, possibly a rune, into read queue at interrupt time.
- * Called at interrupt time to process a character.
- */
-void
-kbdputc(int ch)
-{
- int n;
- char buf[3];
- Rune r;
-
- r = ch;
- n = runetochar(buf, &r);
- qwrite(kbdq, buf, n);
- if(!kbd.raw)
- echoscreen(buf, n);
-}
-
-static void
-kbdputcinit(void)
-{
- kbdq = mkqueue();
- lineq = mkqueue();
- kbd.raw = 0;
- kbd.ctl = 0;
- kbd.x = 0;
-}
-
enum{
Qdir,
Qcons,
"winname", {Qwinname}, 0, 0000,
};
-static void
-consinit(void)
-{
- kbdputcinit();
-}
-
static Chan*
consattach(char *spec)
{
c = devopen(c, omode, consdir, nelem(consdir), devgen);
switch((ulong)c->qid.path){
case Qconsctl:
- qlock(&kbd);
- kbd.ctl++;
- qunlock(&kbd);
break;
case Qsnarf:
if((c->mode&3) == OWRITE || (c->mode&3) == ORDWR)
switch((ulong)c->qid.path){
/* last close of control file turns off raw */
case Qconsctl:
- if(c->flag&COPEN){
- qlock(&kbd);
- if(--kbd.ctl == 0)
- kbd.raw = 0;
- qunlock(&kbd);
- }
break;
/* odd behavior but really ok: replace snarf buffer when /dev/snarf is closed */
case Qsnarf:
static long
consread(Chan *c, void *buf, long n, vlong off)
{
- char ch;
- int send;
-
if(n <= 0)
return n;
switch((ulong)c->qid.path){
return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
case Qcons:
- qlock(&kbd);
- if(waserror()){
- qunlock(&kbd);
- nexterror();
- }
- while(!qcanread(lineq)){
- qread(kbdq, &ch, 1);
- send = 0;
- if(ch == 0){
- /* flush output on rawoff -> rawon */
- if(kbd.x > 0)
- send = !qcanread(kbdq);
- }else if(kbd.raw){
- kbd.line[kbd.x++] = ch;
- send = !qcanread(kbdq);
- }else{
- switch(ch){
- case '\b':
- if(kbd.x > 0)
- kbd.x--;
- break;
- case 0x15: /* ^U */
- kbd.x = 0;
- break;
- case '\n':
- case 0x04: /* ^D */
- send = 1;
- default:
- if(ch != 0x04)
- kbd.line[kbd.x++] = ch;
- break;
- }
- }
- if(send || kbd.x == sizeof kbd.line){
- qwrite(lineq, kbd.line, kbd.x);
- kbd.x = 0;
- }
- }
- n = qread(lineq, buf, n);
- qunlock(&kbd);
- poperror();
- return n;
+ error(Egreg);
+ return -1;
default:
print("consread 0x%llux\n", c->qid.path);
conswrite(Chan *c, void *va, long n, vlong)
{
Snarf *t;
- char buf[256], *a;
- char ch;
+ char *a;
switch((ulong)c->qid.path){
case Qcons:
break;
case Qconsctl:
- if(n >= sizeof(buf))
- n = sizeof(buf)-1;
- strncpy(buf, va, n);
- buf[n] = 0;
- for(a = buf; a;){
- if(strncmp(a, "rawon", 5) == 0){
- kbd.raw = 1;
- /* clumsy hack - wake up reader */
- ch = 0;
- qwrite(kbdq, &ch, 1);
- } else if(strncmp(a, "rawoff", 6) == 0){
- kbd.raw = 0;
- }
- if(a = strchr(a, ' '))
- a++;
- }
+ error(Egreg);
break;
case Qsnarf:
"cons",
devreset,
- consinit,
+ devinit,
consattach,
conswalk,
consstat,
#include <u.h>
#include <libc.h>
+#include <keyboard.h>
#include "compat.h"
#include "kbd.h"
#include "ksym2utf.h"
-enum
-{
+enum {
VKSpecial = 0xff00,
-
- /*
- * plan 9 key mappings
- */
- Spec= 0xF800,
-
- PF= Spec|0x20, /* num pad function key */
- View= Spec|0x00, /* view (shift window up) */
- KF= 0xF000, /* function key (begin Unicode private space) */
- Shift= Spec|0x60,
- Break= Spec|0x61,
- Ctrl= Spec|0x62,
- Latin= Spec|0x63,
- Caps= Spec|0x64,
- Num= Spec|0x65,
- Middle= Spec|0x66,
- No= 0x00, /* peter */
-
- Home= KF|13,
- Up= KF|14,
- Pgup= KF|15,
- Print= KF|16,
- Left= KF|17,
- Right= KF|18,
- End= '\r',
- Down= View,
- Pgdown= KF|19,
- Ins= KF|20,
- Del= 0x7F,
- Scroll= KF|21,
-
- Esc = 0x1b,
- Delete = 0x7f,
};
static Rune vnckeys[] =
{
-[0x00] No, No, No, No, No, No, No, No,
-[0x08] '\b', '\t', '\r', No, No, '\n', No, No,
-[0x10] No, No, No, No, Scroll, No, No, No,
-[0x18] No, No, No, Esc, No, No, No, No,
-[0x20] No, No, No, No, No, No, No, No,
-[0x28] No, No, No, No, No, No, No, No,
-[0x30] No, No, No, No, No, No, No, No,
-[0x38] No, No, No, No, No, No, No, No,
-[0x40] No, No, No, No, No, No, No, No,
-[0x48] No, No, No, No, No, No, No, No,
-[0x50] Home, Left, Up, Right, Down, Pgup, Pgdown, No,
-[0x58] No, No, No, No, No, No, No, No,
-[0x60] No, Print, No, Ins, No, No, No, No,
-[0x68] No, No, No, Break, No, No, No, No,
-[0x70] No, No, No, No, No, No, No, No,
-[0x78] No, No, No, No, No, No, No, Num,
-[0x80] No, No, No, No, No, No, No, No,
-[0x88] No, No, No, No, No, No, No, No,
-[0x90] No, No, No, No, No, No, No, No,
-[0x98] No, No, No, No, No, No, No, No,
-[0xa0] No, No, No, No, No, No, No, No,
-[0xa8] No, No, '*', '+', No, '-', '.', '/',
+[0x00] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x08] '\b', '\t', '\r', 0, 0, '\n', 0, 0,
+[0x10] 0, 0, 0, 0, Kscroll,0, 0, 0,
+[0x18] 0, 0, 0, Kesc, 0, 0, 0, 0,
+[0x20] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x28] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x30] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x38] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x40] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x48] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x50] Khome, Kleft, Kup, Kright, Kdown, Kpgup, Kpgdown,0,
+[0x58] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x60] 0, Kprint, 0, Kins, 0, 0, 0, 0,
+[0x68] 0, 0, 0, Kbreak, 0, 0, 0, 0,
+[0x70] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x78] 0, 0, 0, 0, 0, 0, 0, Knum,
+[0x80] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x88] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x90] 0, 0, 0, 0, 0, 0, 0, 0,
+[0x98] 0, 0, 0, 0, 0, 0, 0, 0,
+[0xa0] 0, 0, 0, 0, 0, 0, 0, 0,
+[0xa8] 0, 0, '*', '+', 0, '-', '.', '/',
[0xb0] '0', '1', '2', '3', '4', '5', '6', '7',
-[0xb8] '8', '9', No, No, No, '=', No, No,
-[0xc0] No, No, No, No, No, No, No, No,
-[0xc8] No, No, No, No, No, No, No, No,
-[0xd0] No, No, No, No, No, No, No, No,
-[0xd8] No, No, No, No, No, No, No, No,
-[0xe0] No, Shift, Shift, Ctrl, Ctrl, Caps, Caps, No,
-[0xe8] No, Latin, Latin, No, No, No, No, No,
-[0xf0] No, No, No, No, No, No, No, No,
-[0xf8] No, No, No, No, No, No, No, Delete,
+[0xb8] '8', '9', 0, 0, 0, '=', 0, 0,
+[0xc0] 0, 0, 0, 0, 0, 0, 0, 0,
+[0xc8] 0, 0, 0, 0, 0, 0, 0, 0,
+[0xd0] 0, 0, 0, 0, 0, 0, 0, 0,
+[0xd8] 0, 0, 0, 0, 0, 0, 0, 0,
+[0xe0] 0, Kshift, Kshift, Kctl, Kctl, Kcaps, Kcaps, 0,
+[0xe8] 0, Kalt, Kalt, 0, 0, 0, 0, 0,
+[0xf0] 0, 0, 0, 0, 0, 0, 0, 0,
+[0xf8] 0, 0, 0, 0, 0, 0, 0, Kdel,
};
/*
void
vncputc(int keyup, int c)
{
- int i;
- static int esc1, esc2;
- static int alt, caps, ctl, num, shift;
- static int collecting, nk;
- static Rune kc[5];
-
- if(caps && c<='z' && c>='a')
- c += 'A' - 'a';
+ char buf[16];
/*
* character mapping
*/
if((c & VKSpecial) == VKSpecial){
c = vnckeys[c & 0xff];
- if(c == No)
+ if(c == 0)
return;
}
/*
* map an xkeysym onto a utf-8 char
*/
if((c & 0xff00) && c < nelem(ksym2utf) && ksym2utf[c] != 0)
- c = ksym2utf[c];
-
- /*
- * keyup only important for shifts
- */
- if(keyup){
- switch(c){
- case Latin:
- alt = 0;
- break;
- case Shift:
- shift = 0;
- break;
- case Ctrl:
- ctl = 0;
- break;
- }
- return;
- }
-
- /*
- * normal character
- */
- if(!(c & (Spec|KF))){
- if(ctl){
- c &= 0x1f;
- }
- if(!collecting){
- kbdputc(c);
- return;
- }
- kc[nk++] = c;
- c = latin1(kc, nk);
- if(c < -1) /* need more keystrokes */
- return;
- if(c != -1) /* valid sequence */
- kbdputc(c);
- else /* dump characters */
- for(i=0; i<nk; i++)
- kbdputc(kc[i]);
- nk = 0;
- collecting = 0;
- return;
- }else{
- switch(c){
- case Caps:
- caps ^= 1;
- return;
- case Num:
- num ^= 1;
- return;
- case Shift:
- shift = 1;
- return;
- case Latin:
- alt = 1;
- collecting = 1;
- nk = 0;
- return;
- case Ctrl:
- ctl = 1;
- return;
- }
- }
- kbdputc(c);
+ c = ksym2utf[c];
+ snprint(buf, sizeof(buf), "r%C", c);
+ if(keyup)
+ buf[0] = 'R';
+ if(kbdin >= 0)
+ write(kbdin, buf, strlen(buf)+1);
}
+++ /dev/null
- " ", " i", L"␣ı",
- "!~", "-=~", L"≄≇≉",
- "!", "!<=>?bmp", L"¡≮≠≯‽⊄∉⊅",
- "\"*", "IUiu", L"ΪΫϊϋ",
- "\"", "\"AEIOUYaeiouy", L"¨ÄËÏÖÜŸäëïöüÿ",
- "$*", "fhk", L"ϕϑϰ",
- "$", "BEFHILMRVaefglopv", L"ℬℰℱℋℐℒℳℛƲɑℯƒℊℓℴ℘ʋ",
- "\'\"", "Uu", L"Ǘǘ",
- "\'", "\'ACEILNORSUYZacegilnorsuyz", L"´ÁĆÉÍĹŃÓŔŚÚÝŹáćéģíĺńóŕśúýź",
- "*", "*ABCDEFGHIKLMNOPQRSTUWXYZabcdefghiklmnopqrstuwxyz", L"∗ΑΒΞΔΕΦΓΘΙΚΛΜΝΟΠΨΡΣΤΥΩΧΗΖαβξδεφγθικλμνοπψρστυωχηζ",
- "+", "-O", L"±⊕",
- ",", ",ACEGIKLNORSTUacegiklnorstu", L"¸ĄÇĘĢĮĶĻŅǪŖŞŢŲąçęģįķļņǫŗşţų",
- "-*", "l", L"ƛ",
- "-", "+-2:>DGHILOTZbdghiltuz~", L"∓ƻ÷→ÐǤĦƗŁ⊖ŦƵƀðǥℏɨłŧʉƶ≂",
- ".", ".CEGILOZceglz", L"·ĊĖĠİĿ⊙Żċėġŀż",
- "/", "Oo", L"Øø",
- "1", ".234568", L"․½⅓¼⅕⅙⅛",
- "2", "-.35", L"ƻ‥⅔⅖",
- "3", ".458", L"…¾⅗⅜",
- "4", "5", L"⅘",
- "5", "68", L"⅚⅝",
- "7", "8", L"⅞",
- ":", "()-=", L"☹☺÷≔",
- "<!", "=~", L"≨⋦",
- "<", "-<=>~", L"←«≤≶≲",
- "=", ":<=>OV", L"≕⋜≡⋝⊜⇒",
- ">!", "=~", L"≩⋧",
- ">", "<=>~", L"≷≥»≳",
- "?", "!?", L"‽¿",
- "@\'", "\'", L"ъ",
- "@@", "\'EKSTYZekstyz", L"ьЕКСТЫЗекстыз",
- "@C", "Hh", L"ЧЧ",
- "@E", "Hh", L"ЭЭ",
- "@K", "Hh", L"ХХ",
- "@S", "CHch", L"ЩШЩШ",
- "@T", "Ss", L"ЦЦ",
- "@Y", "AEOUaeou", L"ЯЕЁЮЯЕЁЮ",
- "@Z", "Hh", L"ЖЖ",
- "@c", "h", L"ч",
- "@e", "h", L"э",
- "@k", "h", L"х",
- "@s", "ch", L"щш",
- "@t", "s", L"ц",
- "@y", "aeou", L"яеёю",
- "@z", "h", L"ж",
- "@", "ABDFGIJLMNOPRUVXabdfgijlmnopruvx", L"АБДФГИЙЛМНОПРУВХабдфгийлмнопрувх",
- "A", "E", L"Æ",
- "C", "ACU", L"⋂ℂ⋃",
- "Dv", "Zz", L"DŽDž",
- "D", "-e", L"Ð∆",
- "G", "-", L"Ǥ",
- "H", "-H", L"Ħℍ",
- "I", "-J", L"ƗIJ",
- "L", "&-Jj|", L"⋀ŁLJLj⋁",
- "M", "#48bs", L"♮♩♪♭♯",
- "N", "JNj", L"NJℕNj",
- "O", "*+-./=EIcoprx", L"⊛⊕⊖⊙⊘⊜ŒƢ©⊚℗®⊗",
- "P", "P", L"ℙ",
- "Q", "Q", L"ℚ",
- "R", "R", L"ℝ",
- "S", "S", L"§",
- "T", "-u", L"Ŧ⊨",
- "V", "=", L"⇐",
- "Y", "R", L"Ʀ",
- "Z", "-ACSZ", L"Ƶℤ",
- "^", "ACEGHIJOSUWYaceghijosuwy", L"ÂĈÊĜĤÎĴÔŜÛŴŶâĉêĝĥîĵôŝûŵŷ",
- "_\"", "AUau", L"ǞǕǟǖ",
- "_,", "Oo", L"Ǭǭ",
- "_.", "Aa", L"Ǡǡ",
- "_", "AEIOU_aeiou", L"ĀĒĪŌŪ¯āēīōū",
- "`\"", "Uu", L"Ǜǜ",
- "`", "AEIOUaeiou", L"ÀÈÌÒÙàèìòù",
- "a", "ben", L"↔æ∠",
- "b", "()+-0123456789=bknpqru", L"₍₎₊₋₀₁₂₃₄₅₆₇₈₉₌♝♚♞♟♛♜•",
- "c", "$Oagu", L"¢©∩≅∪",
- "dv", "z", L"dž",
- "d", "-adegz", L"ð↓‡°†ʣ",
- "e", "$lmns", L"€⋯—–∅",
- "f", "a", L"∀",
- "g", "$-r", L"¤ǥ∇",
- "h", "-v", L"ℏƕ",
- "i", "-bfjps", L"ɨ⊆∞ij⊇∫",
- "l", "\"$&\'-jz|", L"“£∧‘łlj⋄∨",
- "m", "iou", L"µ∈×",
- "n", "jo", L"nj¬",
- "o", "AOUaeiu", L"Å⊚Ůåœƣů",
- "p", "Odgrt", L"℗∂¶∏∝",
- "r", "\"\'O", L"”’®",
- "s", "()+-0123456789=abnoprstu", L"⁽⁾⁺⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁼ª⊂ⁿº⊃√ß∍∑",
- "t", "-efmsu", L"ŧ∃∴™ς⊢",
- "u", "-AEGIOUaegiou", L"ʉĂĔĞĬŎŬ↑ĕğĭŏŭ",
- "v\"", "Uu", L"Ǚǚ",
- "v", "ACDEGIKLNORSTUZacdegijklnorstuz", L"ǍČĎĚǦǏǨĽŇǑŘŠŤǓŽǎčďěǧǐǰǩľňǒřšťǔž",
- "w", "bknpqr", L"♗♔♘♙♕♖",
- "x", "O", L"⊗",
- "y", "$", L"¥",
- "z", "-", L"ƶ",
- "|", "Pp|", L"Þþ¦",
- "~!", "=", L"≆",
- "~", "-=AINOUainou~", L"≃≅ÃĨÑÕŨãĩñõũ≈",