1*d9ae653dSDavid du Colombier /*
2*d9ae653dSDavid du Colombier * keyboard map
3*d9ae653dSDavid du Colombier */
4*d9ae653dSDavid du Colombier
5*d9ae653dSDavid du Colombier #include "u.h"
6*d9ae653dSDavid du Colombier #include "../port/lib.h"
7*d9ae653dSDavid du Colombier #include "mem.h"
8*d9ae653dSDavid du Colombier #include "dat.h"
9*d9ae653dSDavid du Colombier #include "fns.h"
10*d9ae653dSDavid du Colombier #include "../port/error.h"
11*d9ae653dSDavid du Colombier
12*d9ae653dSDavid du Colombier enum{
13*d9ae653dSDavid du Colombier Qdir,
14*d9ae653dSDavid du Colombier Qdata,
15*d9ae653dSDavid du Colombier };
16*d9ae653dSDavid du Colombier Dirtab kbmaptab[]={
17*d9ae653dSDavid du Colombier ".", {Qdir, 0, QTDIR}, 0, 0555,
18*d9ae653dSDavid du Colombier "kbmap", {Qdata, 0}, 0, 0600,
19*d9ae653dSDavid du Colombier };
20*d9ae653dSDavid du Colombier #define NKBFILE sizeof(kbmaptab)/sizeof(kbmaptab[0])
21*d9ae653dSDavid du Colombier
22*d9ae653dSDavid du Colombier #define KBLINELEN (3*NUMSIZE+1) /* t code val\n */
23*d9ae653dSDavid du Colombier
24*d9ae653dSDavid du Colombier static Chan *
kbmapattach(char * spec)25*d9ae653dSDavid du Colombier kbmapattach(char *spec)
26*d9ae653dSDavid du Colombier {
27*d9ae653dSDavid du Colombier return devattach(L'κ', spec);
28*d9ae653dSDavid du Colombier }
29*d9ae653dSDavid du Colombier
30*d9ae653dSDavid du Colombier static Walkqid*
kbmapwalk(Chan * c,Chan * nc,char ** name,int nname)31*d9ae653dSDavid du Colombier kbmapwalk(Chan *c, Chan *nc, char **name, int nname)
32*d9ae653dSDavid du Colombier {
33*d9ae653dSDavid du Colombier return devwalk(c, nc, name, nname, kbmaptab, NKBFILE, devgen);
34*d9ae653dSDavid du Colombier }
35*d9ae653dSDavid du Colombier
36*d9ae653dSDavid du Colombier static long
kbmapstat(Chan * c,uchar * dp,long n)37*d9ae653dSDavid du Colombier kbmapstat(Chan *c, uchar *dp, long n)
38*d9ae653dSDavid du Colombier {
39*d9ae653dSDavid du Colombier return devstat(c, dp, n, kbmaptab, NKBFILE, devgen);
40*d9ae653dSDavid du Colombier }
41*d9ae653dSDavid du Colombier
42*d9ae653dSDavid du Colombier static Chan*
kbmapopen(Chan * c,int omode)43*d9ae653dSDavid du Colombier kbmapopen(Chan *c, int omode)
44*d9ae653dSDavid du Colombier {
45*d9ae653dSDavid du Colombier if(!iseve())
46*d9ae653dSDavid du Colombier error(Eperm);
47*d9ae653dSDavid du Colombier return devopen(c, omode, kbmaptab, NKBFILE, devgen);
48*d9ae653dSDavid du Colombier }
49*d9ae653dSDavid du Colombier
50*d9ae653dSDavid du Colombier static void
kbmapclose(Chan * c)51*d9ae653dSDavid du Colombier kbmapclose(Chan *c)
52*d9ae653dSDavid du Colombier {
53*d9ae653dSDavid du Colombier if(c->aux){
54*d9ae653dSDavid du Colombier free(c->aux);
55*d9ae653dSDavid du Colombier c->aux = nil;
56*d9ae653dSDavid du Colombier }
57*d9ae653dSDavid du Colombier }
58*d9ae653dSDavid du Colombier
59*d9ae653dSDavid du Colombier static long
kbmapread(Chan * c,void * a,long n,vlong offset)60*d9ae653dSDavid du Colombier kbmapread(Chan *c, void *a, long n, vlong offset)
61*d9ae653dSDavid du Colombier {
62*d9ae653dSDavid du Colombier char *bp;
63*d9ae653dSDavid du Colombier char tmp[KBLINELEN+1];
64*d9ae653dSDavid du Colombier int t, sc;
65*d9ae653dSDavid du Colombier Rune r;
66*d9ae653dSDavid du Colombier
67*d9ae653dSDavid du Colombier if(c->qid.type == QTDIR)
68*d9ae653dSDavid du Colombier return devdirread(c, a, n, kbmaptab, NKBFILE, devgen);
69*d9ae653dSDavid du Colombier
70*d9ae653dSDavid du Colombier switch((int)(c->qid.path)){
71*d9ae653dSDavid du Colombier case Qdata:
72*d9ae653dSDavid du Colombier if(kbdgetmap(offset/KBLINELEN, &t, &sc, &r)) {
73*d9ae653dSDavid du Colombier bp = tmp;
74*d9ae653dSDavid du Colombier bp += readnum(0, bp, NUMSIZE, t, NUMSIZE);
75*d9ae653dSDavid du Colombier bp += readnum(0, bp, NUMSIZE, sc, NUMSIZE);
76*d9ae653dSDavid du Colombier bp += readnum(0, bp, NUMSIZE, r, NUMSIZE);
77*d9ae653dSDavid du Colombier *bp++ = '\n';
78*d9ae653dSDavid du Colombier *bp = 0;
79*d9ae653dSDavid du Colombier n = readstr(offset%KBLINELEN, a, n, tmp);
80*d9ae653dSDavid du Colombier } else
81*d9ae653dSDavid du Colombier n = 0;
82*d9ae653dSDavid du Colombier break;
83*d9ae653dSDavid du Colombier default:
84*d9ae653dSDavid du Colombier n=0;
85*d9ae653dSDavid du Colombier break;
86*d9ae653dSDavid du Colombier }
87*d9ae653dSDavid du Colombier return n;
88*d9ae653dSDavid du Colombier }
89*d9ae653dSDavid du Colombier
90*d9ae653dSDavid du Colombier static long
kbmapwrite(Chan * c,void * a,long n,vlong)91*d9ae653dSDavid du Colombier kbmapwrite(Chan *c, void *a, long n, vlong)
92*d9ae653dSDavid du Colombier {
93*d9ae653dSDavid du Colombier char line[100], *lp, *b;
94*d9ae653dSDavid du Colombier int key, m, l;
95*d9ae653dSDavid du Colombier Rune r;
96*d9ae653dSDavid du Colombier
97*d9ae653dSDavid du Colombier if(c->qid.type == QTDIR)
98*d9ae653dSDavid du Colombier error(Eperm);
99*d9ae653dSDavid du Colombier
100*d9ae653dSDavid du Colombier switch((int)(c->qid.path)){
101*d9ae653dSDavid du Colombier case Qdata:
102*d9ae653dSDavid du Colombier b = a;
103*d9ae653dSDavid du Colombier l = n;
104*d9ae653dSDavid du Colombier lp = line;
105*d9ae653dSDavid du Colombier if(c->aux){
106*d9ae653dSDavid du Colombier strcpy(line, c->aux);
107*d9ae653dSDavid du Colombier lp = line+strlen(line);
108*d9ae653dSDavid du Colombier free(c->aux);
109*d9ae653dSDavid du Colombier c->aux = nil;
110*d9ae653dSDavid du Colombier }
111*d9ae653dSDavid du Colombier while(--l >= 0) {
112*d9ae653dSDavid du Colombier *lp++ = *b++;
113*d9ae653dSDavid du Colombier if(lp[-1] == '\n' || lp == &line[sizeof(line)-1]) {
114*d9ae653dSDavid du Colombier *lp = 0;
115*d9ae653dSDavid du Colombier if(*line == 0)
116*d9ae653dSDavid du Colombier error(Ebadarg);
117*d9ae653dSDavid du Colombier if(*line == '\n' || *line == '#'){
118*d9ae653dSDavid du Colombier lp = line;
119*d9ae653dSDavid du Colombier continue;
120*d9ae653dSDavid du Colombier }
121*d9ae653dSDavid du Colombier lp = line;
122*d9ae653dSDavid du Colombier while(*lp == ' ' || *lp == '\t')
123*d9ae653dSDavid du Colombier lp++;
124*d9ae653dSDavid du Colombier m = strtoul(line, &lp, 0);
125*d9ae653dSDavid du Colombier key = strtoul(lp, &lp, 0);
126*d9ae653dSDavid du Colombier while(*lp == ' ' || *lp == '\t')
127*d9ae653dSDavid du Colombier lp++;
128*d9ae653dSDavid du Colombier r = 0;
129*d9ae653dSDavid du Colombier if(*lp == '\'' && lp[1])
130*d9ae653dSDavid du Colombier chartorune(&r, lp+1);
131*d9ae653dSDavid du Colombier else if(*lp == '^' && lp[1]){
132*d9ae653dSDavid du Colombier chartorune(&r, lp+1);
133*d9ae653dSDavid du Colombier if(0x40 <= r && r < 0x60)
134*d9ae653dSDavid du Colombier r -= 0x40;
135*d9ae653dSDavid du Colombier else
136*d9ae653dSDavid du Colombier error(Ebadarg);
137*d9ae653dSDavid du Colombier }else if(*lp == 'M' && ('1' <= lp[1] && lp[1] <= '5'))
138*d9ae653dSDavid du Colombier r = 0xF900+lp[1]-'0';
139*d9ae653dSDavid du Colombier else if(*lp>='0' && *lp<='9') /* includes 0x... */
140*d9ae653dSDavid du Colombier r = strtoul(lp, &lp, 0);
141*d9ae653dSDavid du Colombier else
142*d9ae653dSDavid du Colombier error(Ebadarg);
143*d9ae653dSDavid du Colombier kbdputmap(m, key, r);
144*d9ae653dSDavid du Colombier lp = line;
145*d9ae653dSDavid du Colombier }
146*d9ae653dSDavid du Colombier }
147*d9ae653dSDavid du Colombier if(lp != line){
148*d9ae653dSDavid du Colombier l = lp-line;
149*d9ae653dSDavid du Colombier c->aux = lp = smalloc(l+1);
150*d9ae653dSDavid du Colombier memmove(lp, line, l);
151*d9ae653dSDavid du Colombier lp[l] = 0;
152*d9ae653dSDavid du Colombier }
153*d9ae653dSDavid du Colombier break;
154*d9ae653dSDavid du Colombier default:
155*d9ae653dSDavid du Colombier error(Ebadusefd);
156*d9ae653dSDavid du Colombier }
157*d9ae653dSDavid du Colombier return n;
158*d9ae653dSDavid du Colombier }
159*d9ae653dSDavid du Colombier
160*d9ae653dSDavid du Colombier Dev kbmapdevtab = {
161*d9ae653dSDavid du Colombier L'κ',
162*d9ae653dSDavid du Colombier "kbmap",
163*d9ae653dSDavid du Colombier
164*d9ae653dSDavid du Colombier devreset,
165*d9ae653dSDavid du Colombier devinit,
166*d9ae653dSDavid du Colombier devshutdown,
167*d9ae653dSDavid du Colombier kbmapattach,
168*d9ae653dSDavid du Colombier kbmapwalk,
169*d9ae653dSDavid du Colombier kbmapstat,
170*d9ae653dSDavid du Colombier kbmapopen,
171*d9ae653dSDavid du Colombier devcreate,
172*d9ae653dSDavid du Colombier kbmapclose,
173*d9ae653dSDavid du Colombier kbmapread,
174*d9ae653dSDavid du Colombier devbread,
175*d9ae653dSDavid du Colombier kbmapwrite,
176*d9ae653dSDavid du Colombier devbwrite,
177*d9ae653dSDavid du Colombier devremove,
178*d9ae653dSDavid du Colombier devwstat,
179*d9ae653dSDavid du Colombier };
180