Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
9259 libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/loadkeys/loadkeys.y
+++ new/usr/src/cmd/loadkeys/loadkeys.y
1 1 %{
2 2 /*
3 3 * CDDL HEADER START
4 4 *
5 5 * The contents of this file are subject to the terms of the
6 6 * Common Development and Distribution License, Version 1.0 only
7 7 * (the "License"). You may not use this file except in compliance
8 8 * with the License.
9 9 *
10 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 11 * or http://www.opensolaris.org/os/licensing.
12 12 * See the License for the specific language governing permissions
13 13 * and limitations under the License.
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 *
15 15 * When distributing Covered Code, include this CDDL HEADER in each
16 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 17 * If applicable, add the following below this CDDL HEADER, with the
18 18 * fields enclosed by brackets "[]" replaced with your own identifying
19 19 * information: Portions Copyright [yyyy] [name of copyright owner]
20 20 *
21 21 * CDDL HEADER END
22 22 */
23 23
24 -#ifndef lint
25 -#pragma ident "%Z%%M% %I% %E% SMI"
26 -#endif
27 -
28 24 /*
29 25 * Copyright (c) 1999 by Sun Microsystems, Inc.
30 26 * All rights reserved.
31 27 */
32 28
33 29 #include <sys/param.h>
34 30 #include <ctype.h>
35 31 #include <stdio.h>
36 32 #include <search.h>
37 33 #include <string.h>
38 34 #include <malloc.h>
39 35 #include <fcntl.h>
40 36 #include <stdlib.h>
41 37 #include <errno.h>
42 38 #include <unistd.h>
43 39 #include <sys/kbd.h>
44 40 #include <sys/kbio.h>
45 41
46 42 #define ALL -1 /* special symbol for all tables */
47 43
48 -/*
49 - * SunOS 4.x and Solaris 2.[1234] put Type 4 key tables into
50 - * the keytables directory with no type qualification.
51 - * If we're a SPARC, we might be using an NFS server that
52 - * doesn't have the new type-qualified directories.
53 - * (loadkeys wasn't used on non-SPARCs in 2.[1234].)
54 - */
55 -#ifdef sparc
56 -#define COMPATIBILITY_DIR
57 -#endif
58 -
59 44 static char keytable_dir[] = "/usr/share/lib/keytables/type_%d/";
60 -#ifdef COMPATIBILITY_DIR
61 -static char keytable_dir2[] = "/usr/share/lib/keytables/";
62 -#endif
63 45 static char layout_prefix[] = "layout_";
64 46
65 47 struct keyentry {
66 48 struct keyentry *ke_next;
67 49 struct kiockeymap ke_entry;
68 50 };
69 51
70 52 typedef struct keyentry keyentry;
71 53
72 54 static keyentry *firstentry;
73 55 static keyentry *lastentry;
74 56
75 57 struct dupentry {
76 58 struct dupentry *de_next;
77 59 int de_station;
78 60 int de_otherstation;
79 61 };
80 62
81 63 typedef struct dupentry dupentry;
82 64
83 65 static dupentry *firstduplicate;
84 66 static dupentry *lastduplicate;
85 67
86 68 static dupentry *firstswap;
87 69 static dupentry *lastswap;
88 70
89 71 static char *infilename;
90 72 static FILE *infile;
91 73 static int lineno;
92 74 static int begline;
93 75
94 76 static char *strings[16] = {
95 77 "\033[H", /* HOMEARROW */
96 78 "\033[A", /* UPARROW */
97 79 "\033[B", /* DOWNARROW */
98 80 "\033[D", /* LEFTARROW */
99 81 "\033[C", /* RIGHTARROW */
100 82 };
101 83
102 84 static int nstrings = 5; /* start out with 5 strings */
103 85
104 86 typedef enum {
105 87 SM_INVALID, /* this shift mask is invalid for this keyboard */
106 88 SM_NORMAL, /* "normal", valid shift mask */
107 89 SM_NUMLOCK, /* "Num Lock" shift mask */
108 90 SM_UP /* "Up" shift mask */
109 91 } smtype_t;
110 92
111 93 typedef struct {
112 94 int sm_mask;
113 95 smtype_t sm_type;
114 96 } smentry_t;
115 97
116 98 static smentry_t shiftmasks[] = {
117 99 { 0, SM_NORMAL },
118 100 { SHIFTMASK, SM_NORMAL },
119 101 { CAPSMASK, SM_NORMAL },
120 102 { CTRLMASK, SM_NORMAL },
121 103 { ALTGRAPHMASK, SM_NORMAL },
122 104 { NUMLOCKMASK, SM_NUMLOCK },
123 105 { UPMASK, SM_UP },
124 106 };
|
↓ open down ↓ |
52 lines elided |
↑ open up ↑ |
125 107
126 108
127 109 #define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0]))
128 110
129 111 static void enter_mapentry(int station, keyentry *entrylistp);
130 112 static keyentry *makeentry(int tablemask, int entry);
131 113 static int loadkey(int kbdfd, keyentry *kep);
132 114 static int dupkey(int kbdfd, dupentry *dep, int shiftmask);
133 115 static int swapkey(int kbdfd, dupentry *dep, int shiftmask);
134 116 static int yylex();
117 +extern int yyparse(void);
135 118 static int readesc(FILE *stream, int delim, int single_char);
136 119 static int wordcmp(const void *w1, const void *w2);
137 120 static int yyerror(char *msg);
138 121 static void usage(void);
139 122 static void set_layout(char *arg);
140 123 static FILE *open_mapping_file(char *pathbuf, char *name,
141 124 boolean_t explicit_name, int type);
142 125
143 126 int
144 -main(argc, argv)
145 - int argc;
146 - char **argv;
127 +main(int argc, char **argv)
147 128 {
148 - register int kbdfd;
129 + int kbdfd;
149 130 int type;
150 131 int layout;
151 132 /* maxint is 8 hex digits. */
152 133 char layout_filename[sizeof(layout_prefix)+8];
153 134 char pathbuf[MAXPATHLEN];
154 - register int shift;
135 + int shift;
155 136 struct kiockeymap mapentry;
156 - register keyentry *kep;
157 - register dupentry *dep;
137 + keyentry *kep;
138 + dupentry *dep;
158 139 boolean_t explicit_name;
159 140
160 141 while(++argv, --argc) {
161 142 if(argv[0][0] != '-') break;
162 143 switch(argv[0][1]) {
163 144 case 'e':
164 145 /* -e obsolete, silently ignore */
165 146 break;
166 147 case 's':
167 148 if (argc != 2) {
168 149 usage();
169 150 /* NOTREACHED */
170 151 }
171 152 set_layout(argv[1]);
172 153 exit(0);
173 154 default:
174 155 usage();
175 156 /* NOTREACHED */
176 157 }
177 158 }
178 159
179 160 if (argc > 1) usage();
180 161
181 162 if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
182 163 /* perror("loadkeys: /dev/kbd"); */
183 164 return (1);
184 165 }
185 166
186 167 if (ioctl(kbdfd, KIOCTYPE, &type) < 0) {
187 168 /*
188 169 * There may not be a keyboard connected,
189 170 * return silently
190 171 */
191 172 return (1);
192 173 }
193 174
194 175 if (argc == 0) {
195 176 /* If no keyboard detected, exit silently. */
196 177 if (type == -1)
197 178 return (0);
198 179
199 180 if (ioctl(kbdfd, KIOCLAYOUT, &layout) < 0) {
200 181 perror("loadkeys: ioctl(KIOCLAYOUT)");
201 182 return (1);
202 183 }
203 184
204 185 (void) sprintf(layout_filename,
205 186 "%s%.2x", layout_prefix, layout);
206 187 infilename = layout_filename;
207 188 explicit_name = B_FALSE;
208 189 } else {
209 190 infilename = argv[0];
210 191 explicit_name = B_TRUE;
211 192 }
212 193
213 194 infile = open_mapping_file(pathbuf, infilename, explicit_name, type);
214 195 if (infile == NULL) return (1);
215 196
216 197 infilename = pathbuf;
217 198
218 199 lineno = 0;
219 200 begline = 1;
220 201 yyparse();
221 202 fclose(infile);
222 203
223 204 /*
224 205 * See which shift masks are valid for this keyboard.
225 206 * We do that by trying to get the entry for keystation 0 and that
226 207 * shift mask; if the "ioctl" fails, we assume it's because the shift
227 208 * mask is invalid.
228 209 */
229 210 for (shift = 0; shift < NSHIFTS; shift++) {
230 211 mapentry.kio_tablemask =
231 212 shiftmasks[shift].sm_mask;
232 213 mapentry.kio_station = 0;
233 214 if (ioctl(kbdfd, KIOCGKEY, &mapentry) < 0)
234 215 shiftmasks[shift].sm_type = SM_INVALID;
235 216 }
236 217
237 218 for (kep = firstentry; kep != NULL; kep = kep->ke_next) {
238 219 if (kep->ke_entry.kio_tablemask == ALL) {
239 220 for (shift = 0; shift < NSHIFTS; shift++) {
240 221 switch (shiftmasks[shift].sm_type) {
241 222
242 223 case SM_INVALID:
243 224 continue;
244 225
245 226 case SM_NUMLOCK:
246 227 /*
247 228 * Defaults to NONL, not to a copy of
248 229 * the base entry.
249 230 */
250 231 if (kep->ke_entry.kio_entry != HOLE)
251 232 kep->ke_entry.kio_entry = NONL;
252 233 break;
253 234
254 235 case SM_UP:
255 236 /*
256 237 * Defaults to NOP, not to a copy of
257 238 * the base entry.
258 239 */
259 240 if (kep->ke_entry.kio_entry != HOLE)
260 241 kep->ke_entry.kio_entry = NOP;
261 242 break;
262 243 }
263 244 kep->ke_entry.kio_tablemask =
264 245 shiftmasks[shift].sm_mask;
265 246 if (!loadkey(kbdfd, kep))
266 247 return (1);
267 248 }
268 249 } else {
269 250 if (!loadkey(kbdfd, kep))
270 251 return (1);
271 252 }
272 253 }
273 254
274 255 for (dep = firstswap; dep != NULL; dep = dep->de_next) {
275 256 for (shift = 0; shift < NSHIFTS; shift++) {
276 257 if (shiftmasks[shift].sm_type != SM_INVALID) {
277 258 if (!swapkey(kbdfd, dep,
278 259 shiftmasks[shift].sm_mask))
279 260 return (0);
280 261 }
281 262 }
282 263 }
283 264
284 265 for (dep = firstduplicate; dep != NULL; dep = dep->de_next) {
285 266 for (shift = 0; shift < NSHIFTS; shift++) {
286 267 if (shiftmasks[shift].sm_type != SM_INVALID) {
287 268 if (!dupkey(kbdfd, dep,
288 269 shiftmasks[shift].sm_mask))
289 270 return (0);
290 271 }
291 272 }
292 273 }
293 274
294 275 close(kbdfd);
295 276 return (0);
296 277 }
297 278
298 279 static void
299 280 usage()
300 281 {
301 282 (void) fprintf(stderr, "usage: loadkeys [ file ]\n");
302 283 exit(1);
303 284 }
304 285
305 286 static void
306 287 set_layout(char *arg)
307 288 {
308 289 int layout;
309 290 int ret;
310 291 int kbdfd;
311 292
312 293 layout = (int) strtol(arg, &arg, 0);
313 294 if (*arg != '\0') {
314 295 fprintf(stderr, "usage: loadkeys -s layoutnumber\n");
315 296 exit(1);
316 297 }
317 298
318 299 if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
319 300 perror("/dev/kbd");
320 301 exit(1);
321 302 }
322 303
323 304 ret = ioctl(kbdfd, KIOCSLAYOUT, layout);
324 305 if (ret == -1) {
325 306 perror("KIOCSLAYOUT");
|
↓ open down ↓ |
158 lines elided |
↑ open up ↑ |
326 307 }
327 308
328 309 close(kbdfd);
329 310 }
330 311
331 312 /*
332 313 * Attempt to find the specified mapping file. Return a FILE * if found,
333 314 * else print a message on stderr and return NULL.
334 315 */
335 316 FILE *
336 -open_mapping_file(
337 - char *pathbuf,
338 - char *name,
339 - boolean_t explicit_name,
340 - int type
341 -) {
317 +open_mapping_file(char *pathbuf, char *name, boolean_t explicit_name, int type)
318 +{
342 319 /* If the user specified the name, try it "raw". */
343 320 if (explicit_name) {
344 321 strcpy(pathbuf, name);
345 322 infile = fopen(pathbuf, "r");
346 323 if (infile) return (infile);
347 324 if (errno != ENOENT) goto fopen_fail;
348 325 }
349 326
350 327 /* Everything after this point applies only to relative names. */
351 328 if (*name == '/') goto fopen_fail;
352 329
353 330 /* Try the type-qualified directory name. */
354 331 sprintf(pathbuf, keytable_dir, type);
355 332 if ((int)(strlen(pathbuf) + strlen(name) + 1) >= MAXPATHLEN) {
356 333 (void) fprintf(stderr, "loadkeys: Name %s is too long\n",
357 334 name);
358 335 return (NULL);
359 336 }
360 337 (void) strcat(pathbuf, name);
361 - infile = fopen(pathbuf, "r");
362 - if (infile) return (infile);
363 - if (errno != ENOENT) goto fopen_fail;
338 + if ((infile = fopen(pathbuf, "r")) != NULL)
339 + return (infile);
364 340
365 -#ifdef COMPATIBILITY_DIR
366 - /* If not, and either the name was specified explicitly */
367 - /* or this is a type 4... */
368 - if (explicit_name || type == KB_SUN4) {
369 - /* Try the compatibility name. */
370 - /* No need to check len here, it's shorter. */
371 - (void) strcpy(pathbuf, keytable_dir2);
372 - (void) strcat(pathbuf, infilename);
373 - infile = fopen(pathbuf, "r");
374 - if (infile) return (infile);
375 - if (errno != ENOENT) goto fopen_fail;
376 - }
377 -#endif
378 -
379 341 fopen_fail:
380 342 (void) fprintf(stderr, "loadkeys: ");
381 343 perror(name);
382 344 return (NULL);
383 345 }
384 346
385 347 /*
386 348 * We have a list of entries for a given keystation, and the keystation number
387 349 * for that keystation; put that keystation number into all the entries in that
388 350 * list, and chain that list to the end of the main list of entries.
389 351 */
390 352 static void
391 353 enter_mapentry(station, entrylistp)
392 354 int station;
393 355 keyentry *entrylistp;
394 356 {
395 357 register keyentry *kep;
396 358
397 359 if (lastentry == NULL)
398 360 firstentry = entrylistp;
399 361 else
400 362 lastentry->ke_next = entrylistp;
401 363 kep = entrylistp;
402 364 for (;;) {
403 365 kep->ke_entry.kio_station = (u_char)station;
404 366 if (kep->ke_next == NULL) {
405 367 lastentry = kep;
406 368 break;
407 369 }
408 370 kep = kep->ke_next;
409 371 }
410 372 }
411 373
412 374 /*
413 375 * Allocate and fill in a new entry.
414 376 */
415 377 static keyentry *
416 378 makeentry(tablemask, entry)
417 379 int tablemask;
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
418 380 int entry;
419 381 {
420 382 register keyentry *kep;
421 383 register int index;
422 384
423 385 if ((kep = (keyentry *) malloc((unsigned)sizeof (keyentry))) == NULL)
424 386 yyerror("out of memory for entries");
425 387 kep->ke_next = NULL;
426 388 kep->ke_entry.kio_tablemask = tablemask;
427 389 kep->ke_entry.kio_station = 0;
428 - kep->ke_entry.kio_entry = (u_short)entry;
390 + kep->ke_entry.kio_entry = entry;
429 391 index = entry - STRING;
430 392 if (index >= 0 && index <= 15)
431 393 (void) strncpy(kep->ke_entry.kio_string, strings[index],
432 394 KTAB_STRLEN);
433 395 return (kep);
434 396 }
435 397
436 398 /*
437 399 * Make a set of entries for a keystation that indicate that that keystation's
438 400 * settings should be copied from another keystation's settings.
439 401 */
440 402 static void
441 403 duplicate_mapentry(station, otherstation)
442 404 int station;
443 405 int otherstation;
444 406 {
445 407 register dupentry *dep;
446 408
447 409 if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL)
448 410 yyerror("out of memory for entries");
449 411
450 412 if (lastduplicate == NULL)
451 413 firstduplicate = dep;
452 414 else
453 415 lastduplicate->de_next = dep;
454 416 lastduplicate = dep;
455 417 dep->de_next = NULL;
456 418 dep->de_station = station;
457 419 dep->de_otherstation = otherstation;
458 420 }
459 421
460 422 /*
461 423 * Make a set of entries for a keystation that indicate that that keystation's
462 424 * settings should be swapped with another keystation's settings.
463 425 */
464 426 static void
465 427 swap_mapentry(station, otherstation)
466 428 int station;
467 429 int otherstation;
468 430 {
469 431 register dupentry *dep;
470 432
471 433 if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL)
472 434 yyerror("out of memory for entries");
473 435
474 436 if (lastswap == NULL)
475 437 firstswap = dep;
476 438 else
477 439 lastswap->de_next = dep;
478 440 lastswap = dep;
479 441 dep->de_next = NULL;
480 442 dep->de_station = station;
481 443 dep->de_otherstation = otherstation;
482 444 }
483 445
484 446 static int
485 447 loadkey(kbdfd, kep)
486 448 int kbdfd;
487 449 register keyentry *kep;
488 450 {
489 451 if (ioctl(kbdfd, KIOCSKEY, &kep->ke_entry) < 0) {
490 452 perror("loadkeys: ioctl(KIOCSKEY)");
491 453 return (0);
492 454 }
493 455 return (1);
494 456 }
495 457
496 458 static int
497 459 dupkey(kbdfd, dep, shiftmask)
498 460 int kbdfd;
499 461 register dupentry *dep;
500 462 int shiftmask;
501 463 {
502 464 struct kiockeymap entry;
503 465
504 466 entry.kio_tablemask = shiftmask;
505 467 entry.kio_station = dep->de_otherstation;
506 468 if (ioctl(kbdfd, KIOCGKEY, &entry) < 0) {
507 469 perror("loadkeys: ioctl(KIOCGKEY)");
508 470 return (0);
509 471 }
510 472 entry.kio_station = dep->de_station;
511 473 if (ioctl(kbdfd, KIOCSKEY, &entry) < 0) {
512 474 perror("loadkeys: ioctl(KIOCSKEY)");
513 475 return (0);
514 476 }
515 477 return (1);
516 478 }
517 479
518 480
519 481
520 482 static int
521 483 swapkey(kbdfd, dep, shiftmask)
522 484 int kbdfd;
523 485 register dupentry *dep;
524 486 int shiftmask;
525 487 {
526 488 struct kiockeymap entry1, entry2;
527 489
528 490 entry1.kio_tablemask = shiftmask;
529 491 entry1.kio_station = dep->de_station;
530 492 if (ioctl(kbdfd, KIOCGKEY, &entry1) < 0) {
531 493 perror("loadkeys: ioctl(KIOCGKEY)");
532 494 return (0);
533 495 }
534 496 entry2.kio_tablemask = shiftmask;
535 497 entry2.kio_station = dep->de_otherstation;
536 498 if (ioctl(kbdfd, KIOCGKEY, &entry2) < 0) {
537 499 perror("loadkeys: ioctl(KIOCGKEY)");
538 500 return (0);
539 501 }
540 502 entry1.kio_station = dep->de_otherstation;
541 503 if (ioctl(kbdfd, KIOCSKEY, &entry1) < 0) {
542 504 perror("loadkeys: ioctl(KIOCSKEY)");
543 505 return (0);
544 506 }
545 507 entry2.kio_station = dep->de_station;
546 508 if (ioctl(kbdfd, KIOCSKEY, &entry2) < 0) {
547 509 perror("loadkeys: ioctl(KIOCSKEY)");
548 510 return (0);
549 511 }
550 512 return (1);
551 513 }
552 514 %}
553 515
554 516 %term TABLENAME INT CHAR CHARSTRING CONSTANT FKEY KEY SAME AS SWAP WITH
555 517
556 518 %union {
557 519 keyentry *keyentry;
558 520 int number;
559 521 };
560 522
561 523 %type <keyentry> entrylist entry
562 524 %type <number> CHARSTRING CHAR INT CONSTANT FKEY TABLENAME
563 525 %type <number> code expr term number
564 526
565 527 %%
566 528
567 529 table:
568 530 table line
569 531 | /* null */
570 532 ;
571 533
572 534 line:
573 535 KEY number entrylist '\n'
574 536 {
575 537 enter_mapentry($2, $3);
576 538 }
577 539 | KEY number SAME AS number '\n'
578 540 {
579 541 duplicate_mapentry($2, $5);
580 542 }
581 543 | SWAP number WITH number '\n'
582 544 {
583 545 swap_mapentry($2, $4);
584 546 }
585 547 | '\n'
586 548 ;
587 549
588 550 entrylist:
589 551 entrylist entry
590 552 {
591 553 /*
592 554 * Append this entry to the end of the entry list.
593 555 */
594 556 register keyentry *kep;
595 557 kep = $1;
596 558 for (;;) {
597 559 if (kep->ke_next == NULL) {
598 560 kep->ke_next = $2;
599 561 break;
600 562 }
601 563 kep = kep->ke_next;
602 564 }
603 565 $$ = $1;
604 566 }
605 567 | entry
606 568 {
607 569 $$ = $1;
608 570 }
609 571 ;
610 572
611 573 entry:
612 574 TABLENAME code
613 575 {
614 576 $$ = makeentry($1, $2);
615 577 }
616 578 ;
|
↓ open down ↓ |
178 lines elided |
↑ open up ↑ |
617 579
618 580 code:
619 581 CHARSTRING
620 582 {
621 583 $$ = $1;
622 584 }
623 585 | CHAR
624 586 {
625 587 $$ = $1;
626 588 }
589 +| INT
590 + {
591 + $$ = $1;
592 + }
627 593 | '('
628 594 {
629 595 $$ = '(';
630 596 }
631 597 | ')'
632 598 {
633 599 $$ = ')';
634 600 }
635 601 | '+'
636 602 {
637 603 $$ = '+';
638 604 }
639 605 | expr
640 606 {
641 607 $$ = $1;
642 608 }
643 609 ;
644 610
645 611 expr:
646 612 term
647 613 {
648 614 $$ = $1;
649 615 }
650 616 | expr '+' term
651 617 {
652 618 $$ = $1 + $3;
653 619 }
654 620 ;
655 621
656 622 term:
657 623 CONSTANT
658 624 {
659 625 $$ = $1;
660 626 }
661 627 | FKEY '(' number ')'
662 628 {
663 629 if ($3 < 1 || $3 > 16)
664 630 yyerror("invalid function key number");
665 631 $$ = $1 + $3 - 1;
666 632 }
667 633 ;
668 634
669 635 number:
670 636 INT
671 637 {
672 638 $$ = $1;
673 639 }
674 640 | CHAR
675 641 {
676 642 if (isdigit($1))
677 643 $$ = $1 - '0';
678 644 else
679 645 yyerror("syntax error");
680 646 }
681 647 ;
682 648
683 649 %%
684 650
685 651 typedef struct {
686 652 char *w_string;
687 653 int w_type; /* token type */
688 654 int w_lval; /* yylval for this token */
689 655 } word_t;
690 656
691 657 /*
692 658 * Table must be in alphabetical order.
693 659 */
694 660 word_t wordtab[] = {
695 661 { "all", TABLENAME, ALL },
696 662 { "alt", CONSTANT, ALT },
697 663 { "altg", TABLENAME, ALTGRAPHMASK },
698 664 { "altgraph", CONSTANT, ALTGRAPH },
699 665 { "as", AS, 0 },
|
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
700 666 { "base", TABLENAME, 0 },
701 667 { "bf", FKEY, BOTTOMFUNC },
702 668 { "buckybits", CONSTANT, BUCKYBITS },
703 669 { "caps", TABLENAME, CAPSMASK },
704 670 { "capslock", CONSTANT, CAPSLOCK },
705 671 { "compose", CONSTANT, COMPOSE },
706 672 { "ctrl", TABLENAME, CTRLMASK },
707 673 { "downarrow", CONSTANT, DOWNARROW },
708 674 { "error", CONSTANT, ERROR },
709 675 { "fa_acute", CONSTANT, FA_ACUTE },
676 + { "fa_apostrophe", CONSTANT, FA_APOSTROPHE },
677 + { "fa_breve", CONSTANT, FA_BREVE },
678 + { "fa_caron", CONSTANT, FA_CARON },
710 679 { "fa_cedilla", CONSTANT, FA_CEDILLA },
711 680 { "fa_cflex", CONSTANT, FA_CFLEX },
681 + { "fa_dacute", CONSTANT, FA_DACUTE },
682 + { "fa_dot", CONSTANT, FA_DOT },
712 683 { "fa_grave", CONSTANT, FA_GRAVE },
684 + { "fa_macron", CONSTANT, FA_MACRON },
685 + { "fa_ogonek", CONSTANT, FA_OGONEK },
686 + { "fa_ring", CONSTANT, FA_RING },
687 + { "fa_slash", CONSTANT, FA_SLASH },
713 688 { "fa_tilde", CONSTANT, FA_TILDE },
714 689 { "fa_umlaut", CONSTANT, FA_UMLAUT },
715 690 { "hole", CONSTANT, HOLE },
716 691 { "homearrow", CONSTANT, HOMEARROW },
717 692 { "idle", CONSTANT, IDLE },
718 693 { "key", KEY, 0 },
719 694 { "leftarrow", CONSTANT, LEFTARROW },
720 695 { "leftctrl", CONSTANT, LEFTCTRL },
721 696 { "leftshift", CONSTANT, LEFTSHIFT },
722 697 { "lf", FKEY, LEFTFUNC },
723 698 { "metabit", CONSTANT, METABIT },
724 699 { "nonl", CONSTANT, NONL },
725 700 { "nop", CONSTANT, NOP },
726 701 { "numl", TABLENAME, NUMLOCKMASK },
727 702 { "numlock", CONSTANT, NUMLOCK },
728 703 { "oops", CONSTANT, OOPS },
729 704 { "pad0", CONSTANT, PAD0 },
730 705 { "pad1", CONSTANT, PAD1 },
731 706 { "pad2", CONSTANT, PAD2 },
732 707 { "pad3", CONSTANT, PAD3 },
733 708 { "pad4", CONSTANT, PAD4 },
734 709 { "pad5", CONSTANT, PAD5 },
735 710 { "pad6", CONSTANT, PAD6 },
736 711 { "pad7", CONSTANT, PAD7 },
737 712 { "pad8", CONSTANT, PAD8 },
738 713 { "pad9", CONSTANT, PAD9 },
739 714 { "paddot", CONSTANT, PADDOT },
740 715 { "padenter", CONSTANT, PADENTER },
741 716 { "padequal", CONSTANT, PADEQUAL },
742 717 { "padminus", CONSTANT, PADMINUS },
743 718 { "padplus", CONSTANT, PADPLUS },
744 719 { "padsep", CONSTANT, PADSEP },
745 720 { "padslash", CONSTANT, PADSLASH },
746 721 { "padstar", CONSTANT, PADSTAR },
747 722 { "reset", CONSTANT, RESET },
748 723 { "rf", FKEY, RIGHTFUNC },
749 724 { "rightarrow", CONSTANT, RIGHTARROW },
750 725 { "rightctrl", CONSTANT, RIGHTCTRL },
751 726 { "rightshift", CONSTANT, RIGHTSHIFT },
752 727 { "same", SAME, 0 },
753 728 { "shift", TABLENAME, SHIFTMASK },
754 729 { "shiftkeys", CONSTANT, SHIFTKEYS },
755 730 { "shiftlock", CONSTANT, SHIFTLOCK },
756 731 { "string", CONSTANT, STRING },
757 732 { "swap", SWAP, 0 },
758 733 { "systembit", CONSTANT, SYSTEMBIT },
759 734 { "tf", FKEY, TOPFUNC },
760 735 { "up", TABLENAME, UPMASK },
761 736 { "uparrow", CONSTANT, UPARROW },
762 737 { "with", WITH, 0 },
763 738 };
764 739
765 740 #define NWORDS (sizeof (wordtab) / sizeof (wordtab[0]))
766 741
767 742 static int
768 743 yylex()
769 744 {
770 745 register int c;
771 746 char tokbuf[256+1];
772 747 register char *cp;
773 748 register int tokentype;
774 749
775 750 while ((c = getc(infile)) == ' ' || c == '\t')
776 751 ;
777 752 if (begline) {
778 753 lineno++;
779 754 begline = 0;
780 755 if (c == '#') {
781 756 while ((c = getc(infile)) != EOF && c != '\n')
782 757 ;
783 758 }
784 759 }
785 760 if (c == EOF)
786 761 return (0); /* end marker */
787 762 if (c == '\n') {
788 763 begline = 1;
789 764 return (c);
790 765 }
791 766
792 767 switch (c) {
793 768
794 769 case '\'':
795 770 tokentype = CHAR;
796 771 if ((c = getc(infile)) == EOF)
797 772 yyerror("unterminated character constant");
798 773 if (c == '\n') {
799 774 (void) ungetc(c, infile);
800 775 yylval.number = '\'';
801 776 } else {
802 777 switch (c) {
803 778
804 779 case '\'':
805 780 yyerror("null character constant");
806 781 break;
807 782
808 783 case '\\':
809 784 yylval.number = readesc(infile, '\'', 1);
810 785 break;
811 786
812 787 default:
813 788 yylval.number = c;
814 789 break;
815 790 }
816 791 if ((c = getc(infile)) == EOF || c == '\n')
817 792 yyerror("unterminated character constant");
818 793 else if (c != '\'')
819 794 yyerror("only one character allowed in character constant");
820 795 }
821 796 break;
822 797
823 798 case '"':
824 799 if ((c = getc(infile)) == EOF)
825 800 yyerror("unterminated string constant");
826 801 if (c == '\n') {
827 802 (void) ungetc(c, infile);
828 803 tokentype = CHAR;
829 804 yylval.number = '"';
830 805 } else {
831 806 tokentype = CHARSTRING;
832 807 cp = &tokbuf[0];
833 808 do {
834 809 if (cp > &tokbuf[256])
835 810 yyerror("line too long");
836 811 if (c == '\\')
837 812 c = readesc(infile, '"', 0);
838 813 *cp++ = (char)c;
839 814 } while ((c = getc(infile)) != EOF && c != '\n' &&
840 815 c != '"');
841 816 if (c != '"')
842 817 yyerror("unterminated string constant");
843 818 *cp = '\0';
844 819 if (nstrings == 16)
845 820 yyerror("too many strings");
846 821 if ((int) strlen(tokbuf) > KTAB_STRLEN)
847 822 yyerror("string too long");
848 823 strings[nstrings] = strdup(tokbuf);
849 824 yylval.number = STRING+nstrings;
850 825 nstrings++;
851 826 }
852 827 break;
853 828
854 829 case '(':
855 830 case ')':
856 831 case '+':
857 832 tokentype = c;
858 833 break;
859 834
860 835 case '^':
861 836 if ((c = getc(infile)) == EOF)
862 837 yyerror("missing newline at end of line");
863 838 tokentype = CHAR;
864 839 if (c == ' ' || c == '\t' || c == '\n') {
865 840 /*
866 841 * '^' by itself.
867 842 */
868 843 yylval.number = '^';
869 844 } else {
870 845 yylval.number = c & 037;
871 846 if ((c = getc(infile)) == EOF)
872 847 yyerror("missing newline at end of line");
873 848 if (c != ' ' && c != '\t' && c != '\n')
874 849 yyerror("invalid control character");
875 850 }
876 851 (void) ungetc(c, infile);
877 852 break;
878 853
879 854 default:
880 855 cp = &tokbuf[0];
881 856 do {
882 857 if (cp > &tokbuf[256])
883 858 yyerror("line too long");
884 859 *cp++ = (char)c;
885 860 } while ((c = getc(infile)) != EOF && (isalnum(c) || c == '_'));
886 861 if (c == EOF)
887 862 yyerror("newline missing");
888 863 (void) ungetc(c, infile);
889 864 *cp = '\0';
890 865 if (strlen(tokbuf) == 1) {
891 866 tokentype = CHAR;
892 867 yylval.number = (unsigned char)tokbuf[0];
893 868 } else if (strlen(tokbuf) == 2 && tokbuf[0] == '^') {
894 869 tokentype = CHAR;
895 870 yylval.number = (unsigned char)(tokbuf[1] & 037);
896 871 } else {
897 872 word_t word;
898 873 register word_t *wptr;
899 874 char *ptr;
900 875
901 876 for (cp = &tokbuf[0]; (c = *cp) != '\0'; cp++) {
902 877 if (isupper(c))
|
↓ open down ↓ |
180 lines elided |
↑ open up ↑ |
903 878 *cp = tolower(c);
904 879 }
905 880 word.w_string = tokbuf;
906 881 wptr = (word_t *)bsearch((char *)&word,
907 882 (char *)wordtab, NWORDS, sizeof (word_t),
908 883 wordcmp);
909 884 if (wptr != NULL) {
910 885 yylval.number = wptr->w_lval;
911 886 tokentype = wptr->w_type;
912 887 } else {
913 - yylval.number = strtol(tokbuf, &ptr, 10);
888 + yylval.number = strtol(tokbuf, &ptr, 0);
914 889 if (ptr == tokbuf)
915 890 yyerror("syntax error");
916 891 else
917 892 tokentype = INT;
918 893 }
919 894 break;
920 895 }
921 896 }
922 897
923 898 return (tokentype);
924 899 }
925 900
926 901 static int
927 902 readesc(stream, delim, single_char)
928 903 FILE *stream;
929 904 int delim;
930 905 int single_char;
931 906 {
932 907 register int c;
933 908 register int val;
934 909 register int i;
935 910
936 911 if ((c = getc(stream)) == EOF || c == '\n')
937 912 yyerror("unterminated character constant");
938 913
939 914 if (c >= '0' && c <= '7') {
940 915 val = 0;
941 916 i = 1;
942 917 for (;;) {
943 918 val = val*8 + c - '0';
944 919 if ((c = getc(stream)) == EOF || c == '\n')
945 920 yyerror("unterminated character constant");
946 921 if (c == delim)
947 922 break;
948 923 i++;
949 924 if (i > 3) {
950 925 if (single_char)
951 926 yyerror("escape sequence too long");
952 927 else
953 928 break;
954 929 }
955 930 if (c < '0' || c > '7') {
956 931 if (single_char)
957 932 yyerror("illegal character in escape sequence");
958 933 else
959 934 break;
960 935 }
961 936 }
962 937 (void) ungetc(c, stream);
963 938 } else {
964 939 switch (c) {
965 940
966 941 case 'n':
967 942 val = '\n';
968 943 break;
969 944
970 945 case 't':
971 946 val = '\t';
972 947 break;
973 948
974 949 case 'b':
975 950 val = '\b';
976 951 break;
977 952
978 953 case 'r':
979 954 val = '\r';
980 955 break;
981 956
982 957 case 'v':
983 958 val = '\v';
984 959 break;
985 960
986 961 case '\\':
987 962 val = '\\';
988 963 break;
989 964
990 965 default:
991 966 if (c == delim)
992 967 val = delim;
993 968 else
994 969 yyerror("illegal character in escape sequence");
995 970 }
996 971 }
997 972 return (val);
998 973 }
999 974
1000 975 static int
1001 976 wordcmp(const void *w1, const void *w2)
1002 977 {
1003 978 return (strcmp(
1004 979 ((const word_t *)w1)->w_string,
1005 980 ((const word_t *)w2)->w_string));
1006 981 }
1007 982
1008 983 static int
1009 984 yyerror(msg)
1010 985 char *msg;
1011 986 {
1012 987 (void) fprintf(stderr, "%s, line %d: %s\n", infilename, lineno, msg);
1013 988 exit(1);
1014 989 }
|
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX