1 1.12 christos /* $NetBSD: map_parse.y,v 1.12 2012/10/23 15:30:45 christos Exp $ */ 2 1.1 hannken 3 1.1 hannken /*- 4 1.1 hannken * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 1.1 hannken * All rights reserved. 6 1.1 hannken * 7 1.1 hannken * This code is derived from software contributed to The NetBSD Foundation 8 1.1 hannken * by Juergen Hannken-Illjes. 9 1.1 hannken * 10 1.1 hannken * Redistribution and use in source and binary forms, with or without 11 1.1 hannken * modification, are permitted provided that the following conditions 12 1.1 hannken * are met: 13 1.1 hannken * 1. Redistributions of source code must retain the above copyright 14 1.1 hannken * notice, this list of conditions and the following disclaimer. 15 1.1 hannken * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 hannken * notice, this list of conditions and the following disclaimer in the 17 1.1 hannken * documentation and/or other materials provided with the distribution. 18 1.1 hannken * 19 1.1 hannken * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 hannken * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 hannken * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 hannken * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 hannken * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 hannken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 hannken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 hannken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 hannken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 hannken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 hannken * POSSIBILITY OF SUCH DAMAGE. 30 1.1 hannken */ 31 1.1 hannken 32 1.1 hannken /* Parse a keyboard map. Statements are one of 33 1.1 hannken * 34 1.1 hannken * keysym sym1 = sym2 Assign the key containing `sym2' to 35 1.1 hannken * the key containing `sym1'. This is a copy 36 1.1 hannken * from the old to the new map. Therefore it 37 1.1 hannken * is possible to exchange keys. 38 1.1 hannken * 39 1.3 itohy * keycode pos = sym ... assign the symbols to key `pos'. 40 1.1 hannken * The first symbol may be a command. 41 1.1 hannken * The following symbols are assigned 42 1.1 hannken * to the normal and altgr groups. 43 1.3 itohy * Missing symbols are generated automatically 44 1.1 hannken * as either the upper case variant or the 45 1.1 hannken * normal group. 46 1.1 hannken */ 47 1.1 hannken 48 1.1 hannken %{ 49 1.1 hannken 50 1.1 hannken #include <sys/time.h> 51 1.6 jmmv 52 1.1 hannken #include <dev/wscons/wsksymdef.h> 53 1.1 hannken #include <dev/wscons/wsconsio.h> 54 1.6 jmmv 55 1.1 hannken #include <err.h> 56 1.6 jmmv #include <stdlib.h> 57 1.6 jmmv 58 1.1 hannken #include "wsconsctl.h" 59 1.1 hannken 60 1.1 hannken extern struct wskbd_map_data kbmap; /* from keyboard.c */ 61 1.1 hannken 62 1.1 hannken static struct wscons_keymap mapdata[KS_NUMKEYCODES]; 63 1.1 hannken struct wskbd_map_data newkbmap; /* used in util.c */ 64 1.1 hannken static struct wscons_keymap *cur_mp; 65 1.1 hannken 66 1.8 lukem static size_t ksym_lookup(keysym_t); 67 1.1 hannken 68 1.8 lukem static size_t 69 1.4 xtraeme ksym_lookup(keysym_t ksym) 70 1.1 hannken { 71 1.8 lukem size_t i; 72 1.1 hannken struct wscons_keymap *mp; 73 1.1 hannken 74 1.1 hannken for (i = 0; i < kbmap.maplen; i++) { 75 1.1 hannken mp = kbmap.map + i; 76 1.1 hannken if (mp->command == ksym || 77 1.1 hannken mp->group1[0] == ksym || mp->group1[1] == ksym || 78 1.1 hannken mp->group2[0] == ksym || mp->group2[1] == ksym) 79 1.1 hannken return(i); 80 1.1 hannken } 81 1.1 hannken 82 1.6 jmmv errx(EXIT_FAILURE, "keysym %s not found", ksym2name(ksym)); 83 1.1 hannken } 84 1.1 hannken 85 1.1 hannken %} 86 1.1 hannken 87 1.1 hannken %union { 88 1.1 hannken keysym_t kval; 89 1.1 hannken int ival; 90 1.1 hannken } 91 1.1 hannken 92 1.9 phx %token T_KEYSYM T_KEYCODE T_CMD 93 1.1 hannken %token <kval> T_KEYSYM_VAR T_KEYSYM_CMD_VAR 94 1.1 hannken %token <ival> T_NUMBER 95 1.1 hannken 96 1.2 hannken %type <kval> keysym_var 97 1.2 hannken 98 1.1 hannken %% 99 1.1 hannken 100 1.11 christos program : { 101 1.1 hannken int i; 102 1.1 hannken struct wscons_keymap *mp; 103 1.1 hannken 104 1.1 hannken for (i = 0; i < KS_NUMKEYCODES; i++) { 105 1.1 hannken mp = mapdata + i; 106 1.1 hannken mp->command = KS_voidSymbol; 107 1.1 hannken mp->group1[0] = KS_voidSymbol; 108 1.1 hannken mp->group1[1] = KS_voidSymbol; 109 1.1 hannken mp->group2[0] = KS_voidSymbol; 110 1.1 hannken mp->group2[1] = KS_voidSymbol; 111 1.1 hannken } 112 1.1 hannken 113 1.1 hannken newkbmap.maplen = 0; 114 1.1 hannken newkbmap.map = mapdata; 115 1.1 hannken } expr_list 116 1.1 hannken ; 117 1.1 hannken 118 1.1 hannken expr_list : expr 119 1.1 hannken | expr_list expr 120 1.1 hannken ; 121 1.1 hannken 122 1.1 hannken expr : keysym_expr 123 1.1 hannken | keycode_expr 124 1.1 hannken ; 125 1.1 hannken 126 1.11 christos keysym_expr : T_KEYSYM keysym_var "=" keysym_var { 127 1.8 lukem size_t src, dst; 128 1.1 hannken 129 1.1 hannken dst = ksym_lookup($2); 130 1.1 hannken src = ksym_lookup($4); 131 1.1 hannken newkbmap.map[dst] = kbmap.map[src]; 132 1.1 hannken if (dst >= newkbmap.maplen) 133 1.1 hannken newkbmap.maplen = dst + 1; 134 1.1 hannken } 135 1.1 hannken ; 136 1.1 hannken 137 1.11 christos keycode_expr : T_KEYCODE T_NUMBER "=" { 138 1.1 hannken if ($2 >= KS_NUMKEYCODES) 139 1.6 jmmv errx(EXIT_FAILURE, "%d: keycode too large", $2); 140 1.8 lukem if ((unsigned int)$2 >= newkbmap.maplen) 141 1.1 hannken newkbmap.maplen = $2 + 1; 142 1.1 hannken cur_mp = mapdata + $2; 143 1.1 hannken } keysym_cmd keysym_list 144 1.1 hannken ; 145 1.1 hannken 146 1.1 hannken keysym_cmd : /* empty */ 147 1.11 christos | T_KEYSYM_CMD_VAR { 148 1.1 hannken cur_mp->command = $1; 149 1.1 hannken } 150 1.11 christos | T_CMD T_KEYSYM_CMD_VAR { 151 1.9 phx cur_mp->command = KS_Cmd; 152 1.9 phx cur_mp->group1[0] = $2; 153 1.11 christos } 154 1.11 christos | T_CMD T_KEYSYM_VAR { 155 1.12 christos cur_mp->command = KS_Cmd; 156 1.12 christos cur_mp->group1[0] = $2; 157 1.9 phx } 158 1.1 hannken ; 159 1.1 hannken 160 1.9 phx keysym_list : /* empty */ 161 1.11 christos | keysym_var { 162 1.1 hannken cur_mp->group1[0] = $1; 163 1.1 hannken cur_mp->group1[1] = ksym_upcase(cur_mp->group1[0]); 164 1.1 hannken cur_mp->group2[0] = cur_mp->group1[0]; 165 1.1 hannken cur_mp->group2[1] = cur_mp->group1[1]; 166 1.1 hannken } 167 1.11 christos | keysym_var keysym_var { 168 1.1 hannken cur_mp->group1[0] = $1; 169 1.1 hannken cur_mp->group1[1] = $2; 170 1.1 hannken cur_mp->group2[0] = cur_mp->group1[0]; 171 1.1 hannken cur_mp->group2[1] = cur_mp->group1[1]; 172 1.1 hannken } 173 1.11 christos | keysym_var keysym_var keysym_var { 174 1.1 hannken cur_mp->group1[0] = $1; 175 1.1 hannken cur_mp->group1[1] = $2; 176 1.1 hannken cur_mp->group2[0] = $3; 177 1.1 hannken cur_mp->group2[1] = ksym_upcase(cur_mp->group2[0]); 178 1.1 hannken } 179 1.11 christos | keysym_var keysym_var keysym_var keysym_var { 180 1.1 hannken cur_mp->group1[0] = $1; 181 1.1 hannken cur_mp->group1[1] = $2; 182 1.1 hannken cur_mp->group2[0] = $3; 183 1.1 hannken cur_mp->group2[1] = $4; 184 1.1 hannken } 185 1.1 hannken ; 186 1.2 hannken 187 1.11 christos keysym_var : T_KEYSYM_VAR { 188 1.2 hannken $$ = $1; 189 1.2 hannken } 190 1.11 christos | T_NUMBER { 191 1.2 hannken char name[2]; 192 1.2 hannken int res; 193 1.2 hannken 194 1.2 hannken if ($1 < 0 || $1 > 9) 195 1.2 hannken yyerror("keysym expected"); 196 1.2 hannken name[0] = $1 + '0'; 197 1.2 hannken name[1] = '\0'; 198 1.2 hannken res = name2ksym(name); 199 1.2 hannken if (res < 0) 200 1.2 hannken yyerror("keysym expected"); 201 1.2 hannken $$ = res; 202 1.2 hannken }; 203 1.1 hannken %% 204 1.1 hannken 205 1.10 joerg __dead static void 206 1.5 christos yyerror(const char *msg) 207 1.1 hannken { 208 1.11 christos extern char *yytext; 209 1.11 christos extern int yyleng; 210 1.6 jmmv 211 1.11 christos errx(EXIT_FAILURE, "parse: %s [%.*s]", msg, yyleng, yytext); 212 1.1 hannken } 213