#include <lib9.h>#include <draw.h>#include <cursor.h>#include "dat.h"#include "fns.h" static void addkbd(Kbdbuf*, int);static void matchkbd(Kbdbuf*, Reqbuf*);static void replykbd(Kbdbuf*, void*);static int kbdputc(Kbdbuf*, int);long latin1(uchar*, int); voidreadkbd(Window *w, void* r){ Kbdbuf *kbd; Reqbuf *kbdreqs; kbd = &w->kbd; kbdreqs = &w->kbdreqs; addreq(kbdreqs, r); // fprint(2, "kbd unstall\n"); kbd->stall = 0; matchkbd(kbd, kbdreqs);} voidwritekbd(Window *w, int ch){ Kbdbuf *kbd; Reqbuf *kbdreqs; kbd = &w->kbd; kbdreqs = &w->kbdreqs; addkbd(kbd, ch); matchkbd(kbd, kbdreqs);} staticvoidaddkbd(Kbdbuf *kbd, int ch){ Rune r; ch = kbdputc(kbd, ch); if(kbd->stall || ch == -1) return; r = ch; kbd->r[kbd->wi++] = r; if(kbd->wi == nelem(kbd->r)) kbd->wi = 0; if(kbd->ri == kbd->wi){ kbd->stall = 1; /* fprint(2, "kbd stall\n"); */ }} staticvoidmatchkbd(Kbdbuf *kbd, Reqbuf *kbdreqs){ while(kbd->ri != kbd->wi && kbdreqs->ri != kbdreqs->wi){ replykbd(kbd, nextreq(kbdreqs)); kbd->ri++; if(kbd->ri == nelem(kbd->r)) kbd->ri = 0; }} staticvoidreplykbd(Kbdbuf *kbd, void *r){ char buf[5]; Rune rune; rune = kbd->r[kbd->ri]; sprint(buf, "%C", rune); ixprread(r, buf);} staticintkbdputc(Kbdbuf *kbd, int ch){ int n; Rune r; if(ch < 0) { kbd->alting = 0; kbd->nk = 0; return -1; } r = ch; if(kbd->alting){ /* * Kludge for Mac's X11 3-button emulation. * It treats Command+Button as button 3, but also * ends up sending XK_Meta_L twice. */ if(ch == Kalt){ kbd->alting = 0; return -1; } kbd->nk += runetochar((char*)&kbd->k[kbd->nk], &r); n = latin1(kbd->k, kbd->nk); if(n > 0){ kbd->alting = 0; r = (Rune)n; return r; } if(n == -1){ kbd->alting = 0; kbd->k[kbd->nk] = 0; r = (Rune)0; return r; } /* n < -1, need more input */ return -1; }else if(ch == Kalt){ kbd->alting = 1; kbd->nk = 0; return -1; } return r;}
#include <lib9.h>
#include <draw.h>
#include <cursor.h>
#include "dat.h"
#include "fns.h"
static void addkbd(Kbdbuf*, int);
static void matchkbd(Kbdbuf*, Reqbuf*);
static void replykbd(Kbdbuf*, void*);
static int kbdputc(Kbdbuf*, int);
long latin1(uchar*, int);
void
readkbd(Window *w, void* r)
{
Kbdbuf *kbd;
Reqbuf *kbdreqs;
kbd = &w->kbd;
kbdreqs = &w->kbdreqs;
addreq(kbdreqs, r);
// fprint(2, "kbd unstall\n");
kbd->stall = 0;
matchkbd(kbd, kbdreqs);
}
void
writekbd(Window *w, int ch)
{
Kbdbuf *kbd;
Reqbuf *kbdreqs;
kbd = &w->kbd;
kbdreqs = &w->kbdreqs;
addkbd(kbd, ch);
matchkbd(kbd, kbdreqs);
}
static
void
addkbd(Kbdbuf *kbd, int ch)
{
Rune r;
ch = kbdputc(kbd, ch);
if(kbd->stall || ch == -1)
return;
r = ch;
kbd->r[kbd->wi++] = r;
if(kbd->wi == nelem(kbd->r))
kbd->wi = 0;
if(kbd->ri == kbd->wi){
kbd->stall = 1;
/* fprint(2, "kbd stall\n"); */
}
}
static
void
matchkbd(Kbdbuf *kbd, Reqbuf *kbdreqs)
{
while(kbd->ri != kbd->wi && kbdreqs->ri != kbdreqs->wi){
replykbd(kbd, nextreq(kbdreqs));
kbd->ri++;
if(kbd->ri == nelem(kbd->r))
kbd->ri = 0;
}
}
static
void
replykbd(Kbdbuf *kbd, void *r)
{
char buf[5];
Rune rune;
rune = kbd->r[kbd->ri];
sprint(buf, "%C", rune);
ixprread(r, buf);
}
static
int
kbdputc(Kbdbuf *kbd, int ch)
{
int n;
Rune r;
if(ch < 0) {
kbd->alting = 0;
kbd->nk = 0;
return -1;
}
r = ch;
if(kbd->alting){
/*
* Kludge for Mac's X11 3-button emulation.
* It treats Command+Button as button 3, but also
* ends up sending XK_Meta_L twice.
*/
if(ch == Kalt){
kbd->alting = 0;
return -1;
}
kbd->nk += runetochar((char*)&kbd->k[kbd->nk], &r);
n = latin1(kbd->k, kbd->nk);
if(n > 0){
kbd->alting = 0;
r = (Rune)n;
return r;
}
if(n == -1){
kbd->alting = 0;
kbd->k[kbd->nk] = 0;
r = (Rune)0;
return r;
}
/* n < -1, need more input */
return -1;
}else if(ch == Kalt){
kbd->alting = 1;
kbd->nk = 0;
return -1;
}
return r;
}