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