213 lines
5.3 KiB
Plaintext
213 lines
5.3 KiB
Plaintext
/* $NetBSD: map_parse.y,v 1.12 2012/10/23 15:30:45 christos Exp $ */
|
|
|
|
/*-
|
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
|
* by Juergen Hannken-Illjes.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/* Parse a keyboard map. Statements are one of
|
|
*
|
|
* keysym sym1 = sym2 Assign the key containing `sym2' to
|
|
* the key containing `sym1'. This is a copy
|
|
* from the old to the new map. Therefore it
|
|
* is possible to exchange keys.
|
|
*
|
|
* keycode pos = sym ... assign the symbols to key `pos'.
|
|
* The first symbol may be a command.
|
|
* The following symbols are assigned
|
|
* to the normal and altgr groups.
|
|
* Missing symbols are generated automatically
|
|
* as either the upper case variant or the
|
|
* normal group.
|
|
*/
|
|
|
|
%{
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <dev/wscons/wsksymdef.h>
|
|
#include <dev/wscons/wsconsio.h>
|
|
|
|
#include <err.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "wsconsctl.h"
|
|
|
|
extern struct wskbd_map_data kbmap; /* from keyboard.c */
|
|
|
|
static struct wscons_keymap mapdata[KS_NUMKEYCODES];
|
|
struct wskbd_map_data newkbmap; /* used in util.c */
|
|
static struct wscons_keymap *cur_mp;
|
|
|
|
static size_t ksym_lookup(keysym_t);
|
|
|
|
static size_t
|
|
ksym_lookup(keysym_t ksym)
|
|
{
|
|
size_t i;
|
|
struct wscons_keymap *mp;
|
|
|
|
for (i = 0; i < kbmap.maplen; i++) {
|
|
mp = kbmap.map + i;
|
|
if (mp->command == ksym ||
|
|
mp->group1[0] == ksym || mp->group1[1] == ksym ||
|
|
mp->group2[0] == ksym || mp->group2[1] == ksym)
|
|
return(i);
|
|
}
|
|
|
|
errx(EXIT_FAILURE, "keysym %s not found", ksym2name(ksym));
|
|
}
|
|
|
|
%}
|
|
|
|
%union {
|
|
keysym_t kval;
|
|
int ival;
|
|
}
|
|
|
|
%token T_KEYSYM T_KEYCODE T_CMD
|
|
%token <kval> T_KEYSYM_VAR T_KEYSYM_CMD_VAR
|
|
%token <ival> T_NUMBER
|
|
|
|
%type <kval> keysym_var
|
|
|
|
%%
|
|
|
|
program : {
|
|
int i;
|
|
struct wscons_keymap *mp;
|
|
|
|
for (i = 0; i < KS_NUMKEYCODES; i++) {
|
|
mp = mapdata + i;
|
|
mp->command = KS_voidSymbol;
|
|
mp->group1[0] = KS_voidSymbol;
|
|
mp->group1[1] = KS_voidSymbol;
|
|
mp->group2[0] = KS_voidSymbol;
|
|
mp->group2[1] = KS_voidSymbol;
|
|
}
|
|
|
|
newkbmap.maplen = 0;
|
|
newkbmap.map = mapdata;
|
|
} expr_list
|
|
;
|
|
|
|
expr_list : expr
|
|
| expr_list expr
|
|
;
|
|
|
|
expr : keysym_expr
|
|
| keycode_expr
|
|
;
|
|
|
|
keysym_expr : T_KEYSYM keysym_var "=" keysym_var {
|
|
size_t src, dst;
|
|
|
|
dst = ksym_lookup($2);
|
|
src = ksym_lookup($4);
|
|
newkbmap.map[dst] = kbmap.map[src];
|
|
if (dst >= newkbmap.maplen)
|
|
newkbmap.maplen = dst + 1;
|
|
}
|
|
;
|
|
|
|
keycode_expr : T_KEYCODE T_NUMBER "=" {
|
|
if ($2 >= KS_NUMKEYCODES)
|
|
errx(EXIT_FAILURE, "%d: keycode too large", $2);
|
|
if ((unsigned int)$2 >= newkbmap.maplen)
|
|
newkbmap.maplen = $2 + 1;
|
|
cur_mp = mapdata + $2;
|
|
} keysym_cmd keysym_list
|
|
;
|
|
|
|
keysym_cmd : /* empty */
|
|
| T_KEYSYM_CMD_VAR {
|
|
cur_mp->command = $1;
|
|
}
|
|
| T_CMD T_KEYSYM_CMD_VAR {
|
|
cur_mp->command = KS_Cmd;
|
|
cur_mp->group1[0] = $2;
|
|
}
|
|
| T_CMD T_KEYSYM_VAR {
|
|
cur_mp->command = KS_Cmd;
|
|
cur_mp->group1[0] = $2;
|
|
}
|
|
;
|
|
|
|
keysym_list : /* empty */
|
|
| keysym_var {
|
|
cur_mp->group1[0] = $1;
|
|
cur_mp->group1[1] = ksym_upcase(cur_mp->group1[0]);
|
|
cur_mp->group2[0] = cur_mp->group1[0];
|
|
cur_mp->group2[1] = cur_mp->group1[1];
|
|
}
|
|
| keysym_var keysym_var {
|
|
cur_mp->group1[0] = $1;
|
|
cur_mp->group1[1] = $2;
|
|
cur_mp->group2[0] = cur_mp->group1[0];
|
|
cur_mp->group2[1] = cur_mp->group1[1];
|
|
}
|
|
| keysym_var keysym_var keysym_var {
|
|
cur_mp->group1[0] = $1;
|
|
cur_mp->group1[1] = $2;
|
|
cur_mp->group2[0] = $3;
|
|
cur_mp->group2[1] = ksym_upcase(cur_mp->group2[0]);
|
|
}
|
|
| keysym_var keysym_var keysym_var keysym_var {
|
|
cur_mp->group1[0] = $1;
|
|
cur_mp->group1[1] = $2;
|
|
cur_mp->group2[0] = $3;
|
|
cur_mp->group2[1] = $4;
|
|
}
|
|
;
|
|
|
|
keysym_var : T_KEYSYM_VAR {
|
|
$$ = $1;
|
|
}
|
|
| T_NUMBER {
|
|
char name[2];
|
|
int res;
|
|
|
|
if ($1 < 0 || $1 > 9)
|
|
yyerror("keysym expected");
|
|
name[0] = $1 + '0';
|
|
name[1] = '\0';
|
|
res = name2ksym(name);
|
|
if (res < 0)
|
|
yyerror("keysym expected");
|
|
$$ = res;
|
|
};
|
|
%%
|
|
|
|
__dead static void
|
|
yyerror(const char *msg)
|
|
{
|
|
extern char *yytext;
|
|
extern int yyleng;
|
|
|
|
errx(EXIT_FAILURE, "parse: %s [%.*s]", msg, yyleng, yytext);
|
|
}
|