Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/cmd/kbmap.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <draw.h>
4
#include <event.h>
5
 
6
typedef struct KbMap KbMap;
7
struct KbMap {
8
	char *name;
9
	char *file;
10
	Rectangle r;
11
	int current;
12
};
13
 
14
KbMap *map;
15
int nmap;
16
Image *lightblue;
17
Image *justblue;
18
 
19
enum {
20
	PAD = 3,
21
	MARGIN = 5
22
};
23
 
24
char *dir = "/sys/lib/kbmap";
25
 
26
void*
27
erealloc(void *v, ulong n)
28
{
29
	v = realloc(v, n);
30
	if(v == nil)
31
		sysfatal("out of memory reallocating %lud", n);
32
	return v;
33
}
34
 
35
void*
36
emalloc(ulong n)
37
{
38
	void *v;
39
 
40
	v = malloc(n);
41
	if(v == nil)
42
		sysfatal("out of memory allocating %lud", n);
43
	memset(v, 0, n);
44
	return v;
45
}
46
 
47
char*
48
estrdup(char *s)
49
{
50
	int l;
51
	char *t;
52
 
53
	if (s == nil)
54
		return nil;
55
	l = strlen(s)+1;
56
	t = emalloc(l);
57
	memcpy(t, s, l);
58
 
59
	return t;
60
}
61
 
62
void
63
init(void)
64
{
65
	int i, fd, nr;
66
	Dir *pd;
67
	char buf[128];
68
 
69
	if((fd = open(dir, OREAD)) < 0)
70
		return;
71
 
72
	nmap = nr = dirreadall(fd, &pd);
73
	map = emalloc(nr * sizeof(KbMap));
74
	for(i=0; i<nr; i++){
75
		sprint(buf, "%s/%s", dir, pd[i].name);
76
		map[i].file = estrdup(buf);
77
		map[i].name = estrdup(pd[i].name);
78
		map[i].current = 0;
79
	}
80
	free(pd);
81
 
82
	close(fd);
83
}
84
 
85
void
86
drawmap(int i)
87
{
88
	if(map[i].current)
89
		draw(screen, map[i].r, justblue, nil, ZP);
90
	else
91
		draw(screen, map[i].r, lightblue, nil, ZP);
92
 
93
	_string(screen, addpt(map[i].r.min, Pt(2,0)), display->black, ZP,
94
		font, map[i].name, nil, strlen(map[i].name), 
95
		map[i].r, nil, ZP, SoverD);
96
	border(screen, map[i].r, 1, display->black, ZP);	
97
}
98
 
99
void
100
geometry(void)
101
{
102
	int i, rows;
103
	Rectangle r;
104
 
105
	rows = (Dy(screen->r)-2*MARGIN+PAD)/(font->height+PAD);
106
 
107
	r = Rect(0,0,(Dx(screen->r)-2*MARGIN), font->height);
108
	for(i=0; i<nmap; i++)
109
		map[i].r = rectaddpt(rectaddpt(r, Pt(MARGIN+(PAD+Dx(r))*(i/rows),
110
					MARGIN+(PAD+Dy(r))*(i%rows))), screen->r.min);
111
 
112
}
113
 
114
void
115
redraw(Image *screen)
116
{
117
	int i;
118
 
119
	draw(screen, screen->r, lightblue, nil, ZP);
120
	for(i=0; i<nmap; i++)
121
		drawmap(i);
122
	flushimage(display, 1);
123
}
124
 
125
void
126
eresized(int new)
127
{
128
	if(new && getwindow(display, Refmesg) < 0)
129
		fprint(2,"can't reattach to window");
130
	geometry();
131
	redraw(screen);
132
}
133
 
134
int
135
writemap(char *file)
136
{
137
	int i, fd, ofd;
138
	char buf[8192];
139
 
140
	if((fd = open(file, OREAD)) < 0){
141
		fprint(2, "cannot open %s: %r", file);
142
		return -1;
143
	}
144
	if((ofd = open("/dev/kbmap", OWRITE)) < 0) {
145
		fprint(2, "cannot open /dev/kbmap: %r");
146
		close(fd);
147
		return -1;
148
	}
149
	while((i = read(fd, buf, sizeof buf)) > 0)
150
		if(write(ofd, buf, i) != i){
151
			fprint(2, "writing /dev/kbmap: %r");
152
			break;
153
		}
154
 
155
	close(fd);
156
	close(ofd);
157
	return 0;
158
}
159
 
160
void
161
click(Mouse m)
162
{
163
	int i, j;
164
	char buf[128];
165
 
166
	if(m.buttons == 0 || (m.buttons & ~4))
167
		return;
168
 
169
	for(i=0; i<nmap; i++)
170
		if(ptinrect(m.xy, map[i].r))
171
			break;
172
	if(i == nmap)
173
		return;
174
 
175
	do
176
		m = emouse();
177
	while(m.buttons == 4);
178
 
179
	if(m.buttons != 0){
180
		do
181
			m = emouse();
182
		while(m.buttons);
183
		return;
184
	}
185
 
186
	for(j=0; j<nmap; j++)
187
		if(ptinrect(m.xy, map[j].r))
188
			break;
189
	if(j != i)
190
		return;
191
 
192
	/* since maps are often just a delta of the distributed map... */
193
	snprint(buf, sizeof buf, "%s/ascii", dir);
194
	writemap(buf);
195
	writemap(map[i].file);
196
 
197
	/* clean the previous current map */
198
	for(j=0; j<nmap; j++)
199
		map[j].current = 0;
200
 
201
	map[i].current = 1;
202
 
203
	redraw(screen);
204
}
205
 
206
void
207
usage(void)
208
{
209
	fprint(2, "usage: kbmap [file...]\n");
210
	exits("usage");
211
}
212
 
213
void
214
main(int argc, char **argv)
215
{
216
	Event e;
217
	char *c;
218
 
219
	if(argc > 1) {
220
		argv++; argc--;
221
		map = emalloc((argc)*sizeof(KbMap));
222
		while(argc--) {
223
			map[argc].file = estrdup(argv[argc]);
224
			c = strrchr(map[argc].file, '/');
225
			map[argc].name = (c == nil ? map[argc].file : c+1);
226
			map[argc].current = 0;
227
			nmap++;
228
		}
229
	} else 
230
		init();
231
 
232
	initdraw(0, 0, "kbmap");
233
	lightblue = allocimagemix(display, DPalebluegreen, DWhite);
234
	if(lightblue == nil)
235
		sysfatal("allocimagemix: %r");
236
	justblue = allocimagemix(display, DBlue, DWhite);
237
	if(justblue == nil)
238
		sysfatal("allocimagemix: %r");
239
 
240
	eresized(0);
241
	einit(Emouse|Ekeyboard);
242
 
243
	for(;;){
244
		switch(eread(Emouse|Ekeyboard, &e)){
245
		case Ekeyboard:
246
			if(e.kbdc==0x7F || e.kbdc=='q')
247
				exits(0);
248
			break;
249
		case Emouse:
250
			if(e.mouse.buttons)
251
				click(e.mouse);
252
			break;
253
		}
254
	}
255
}
256