From 345f8d5ff5fe7e909e8e9aae6a7d02981263ff91 Mon Sep 17 00:00:00 2001 From: Marco Gerards Date: Sun, 6 Mar 2011 17:45:44 -0300 Subject: Add XKB parser and implementation. * console-client/xkb/Compose: New file. * console-client/xkb/MISSING-FEATURES: Likewise. * console-client/xkb/README: Likewise. * console-client/xkb/TODO: Likewise. * console-client/xkb/compose.c: Likewise. * console-client/xkb/default.xkb: Likewise. * console-client/xkb/keysymdef.h: Likewise. * console-client/xkb/ks_tables.h: Likewise. * console-client/xkb/kstoucs.c: Likewise. * console-client/xkb/lex.l: Likewise. * console-client/xkb/makeconf.sh: Likewise. * console-client/xkb/parser.y: Likewise. * console-client/xkb/symname.c: Likewise. * console-client/xkb/xkb-data/keymap/hurd: Likewise. * console-client/xkb/xkb-data/symbols/hurd: Likewise. * console-client/xkb/xkb-data/types/hurd: Likewise. * console-client/xkb/xkb.c: Likewise. * console-client/xkb/xkb.h: Likewise. * console-client/xkb/xkbdata.c: Likewise. * console-client/xkb/xkbdefaults.c: Likewise. * console-client/xkb/xkbtimer.c: Likewise. --- console-client/xkb/xkbdata.c | 456 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 console-client/xkb/xkbdata.c (limited to 'console-client/xkb/xkbdata.c') diff --git a/console-client/xkb/xkbdata.c b/console-client/xkb/xkbdata.c new file mode 100644 index 00000000..97545e52 --- /dev/null +++ b/console-client/xkb/xkbdata.c @@ -0,0 +1,456 @@ +/* xkbdata.c -- Manage XKB datastructures. + + Copyright (C) 2003 Marco Gerards + + Written by Marco Gerards + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. */ + +/* Generate a key for the string S. XXX: The are many more effecient + algoritms, this one should be replaced by one of those. */ + +#include +#include +#include +#include "xkb.h" + +static int +name_hash (char *s) +{ + int i = 0; + while (*s) + i += *(s++); + return i; +} + + +/* A keyname with a keycode and realmodifier bound to it. */ +struct keyname +{ + int keycode; + int rmods; +}; + +static struct hurd_ihash kn_mapping; + +/* Initialize the keyname hashtable. */ +static void +keyname_init () +{ + hurd_ihash_init (&kn_mapping, HURD_IHASH_NO_LOCP); + debug_printf ("Kn_mapping init"); + /* XXX: error. */ +} + +/* Assign the name KEYNAME to the keycode KEYCODE. */ +error_t +keyname_add (char *keyname, int keycode) +{ + struct keyname *kn; + int kn_int; + + kn = malloc (sizeof (struct keyname)); + if (!kn) + return ENOMEM; + + /* XXX: 4 characters can be mapped into a int, it is safe to assume + this will not be changed. */ + if (strlen (keyname) > 4) + { + debug_printf ("The keyname `%s' consist of more than 4 characters;" + " 4 characters is the maximum.\n", keyname); + /* XXX: Abort? */ + return 0; + } + + kn->keycode = keycode; + kn->rmods = 0; + + kn_int = keyname[0] + (keyname[1] << 8) + (keyname[2] << 16) + (keyname[3] << 24); + debug_printf ("add : %d\n", kn_mapping.locp_offset); + hurd_ihash_add (&kn_mapping, kn_int, kn); + + return 0; +} + +/* Find the numberic representation of the keycode with the name + KEYNAME. */ +int +keyname_find (char *keyname) +{ + struct keyname *kn; + int kn_int; + + /* XXX: 4 characters can be mapped into a int, it is safe to assume + this will not be changed. */ + if (strlen (keyname) > 4) + { + debug_printf ("The keyname `%s' consist of more than 4 characters;" + " 4 characters is the maximum.\n", keyname); + /* XXX: Abort? */ + return 0; + } + kn_int = keyname[0] + (keyname[1] << 8) + (keyname[2] << 16) + (keyname[3] << 24); + + kn = hurd_ihash_find (&kn_mapping, kn_int); + if (kn) + return kn->keycode; +/* int h = name_hash (keyname); */ +/* struct keyname *kn; */ +/* for (kn = knhash[KNHASH(h)]; kn; kn = kn->hnext) */ +/* { */ +/* if (strcmp (kn->keyname, keyname)) */ +/* continue; */ + +/* return kn->keycode; */ +/* } */ + + /* XXX: Is 0 an invalid keycode? */ + return 0; +} + + +/* Keytypes and keytype maps. */ + +/* The dummy gets used when the original may not be overwritten. */ +static struct keytype dummy_keytype; + +#define KTHSZ 16 +#if ((KTHSZ&(KTHSZ-1)) == 0) +#define KTHASH(ktttl) ((ktttl)&(KTHSZ-1)) +#else +#define KTHASH(ktttl) (((unsigned)(kt))%KTHSZ) +#endif + +/* All keytypes. */ +struct keytype *kthash[KTHSZ]; + +/* Initialize the keytypes hashtable. */ +static void +keytype_init () +{ + int n; + for (n = 0; n < KTHSZ; n++) + kthash[n] = 0; +} + +/* Search the keytype with the name NAME. */ +struct keytype * +keytype_find (char *name) +{ + int nhash = name_hash (name); + struct keytype *kt; + + for (kt = kthash[KTHASH(nhash)]; kt; kt = kt->hnext) + if (!strcmp (name, kt->name)) + return kt; + return NULL; +} + +/* Remove the keytype KT. */ +void +keytype_delete (struct keytype *kt) +{ + struct typemap *map; + + + *kt->prevp = kt->hnext; + if (kt->hnext) + kt->hnext->prevp = kt->prevp; + + map = kt->maps; + while (map) + { + struct typemap *nextmap = map->next; + free (map); + map = nextmap; + } + +} + +/* Create a new keytype with the name NAME. */ +error_t +keytype_new (char *name, struct keytype **new_kt) +{ + struct keytype *kt; + struct keytype *ktlist; + int nhash; + + nhash = name_hash (name); + debug_printf ("New: %s\n", name); + + kt = keytype_find (name); + + if (kt) + { + /* If the merge mode is augement don't replace it. */ + if (merge_mode == augment) + { + *new_kt = &dummy_keytype; + return 0; + } + else /* This keytype should replace the old one, remove the old one. */ + keytype_delete (kt); + } + + ktlist = kthash[KTHASH(nhash)]; + kt = calloc (1, sizeof (struct keytype)); + if (kt == NULL) + return ENOMEM; + + kt->hnext = ktlist; + kt->name = strdup (name); + kt->prevp = &kthash[KTHASH(nhash)]; + kt->maps = NULL; + if (kthash[KTHASH(nhash)]) + kthash[KTHASH(nhash)]->prevp = &(kt->hnext); + kthash[KTHASH(nhash)] = kt; + + *new_kt = kt; + return 0; +} + +/* Add a level (LEVEL) to modifiers (MODS) mapping to the current + keytype. */ +error_t +keytype_mapadd (struct keytype *kt, modmap_t mods, int level) +{ + struct typemap *map; + modmap_t nulmap = {0, 0}; + + map = malloc (sizeof (struct typemap)); + if (!map) + return ENOMEM; + + map->level = level; + map->mods = mods; + map->preserve = nulmap; + /* By default modifiers shouldn't be preserved. */ + map->next = kt->maps; + + kt->maps = map; + + return 0; +} + +/* For the current keytype the modifiers PRESERVE should be preserved + when the modifiers MODS are pressed. */ +error_t +keytype_preserve_add (struct keytype *kt, modmap_t mods, modmap_t preserve) +{ + error_t err; + struct typemap *map; + + map = kt->maps; + while (map) + { + if (mods.rmods == map->mods.rmods && mods.vmods == map->mods.vmods) + { + map->preserve = preserve; + return 0; + } + map = map->next; + } + + /* No map has been found, add the default map. */ + err = keytype_mapadd (kt, mods, 0); + if (err) + return err; + + keytype_preserve_add (kt, mods, preserve); + + return 0; +} + + +/* Interpretations. */ + +struct xkb_interpret *last_interp; +struct xkb_interpret default_interpretation; + + +/* Add a new interpretation. */ +error_t +interpret_new (xkb_interpret_t **new_interpret, symbol ks) +{ + struct xkb_interpret *new_interp; + + new_interp = malloc (sizeof (struct xkb_interpret)); + if (!new_interp) + return ENOMEM; + + memcpy (new_interp, &default_interpretation, sizeof (struct xkb_interpret)); + new_interp->symbol = ks; + + if (ks) + { + new_interp->next = interpretations; + interpretations = new_interp; + + if (!last_interp) + last_interp = new_interp; + } + else + { + if (last_interp) + last_interp->next = new_interp; + + last_interp = new_interp; + + if (!interpretations) + interpretations = new_interp; + } + + *new_interpret = new_interp; + + return 0; +} + + +/* XXX: Dead code!? */ +/* Virtual modifiers name to number mapping. */ +/* Last number assigned to a virtual modifier. */ +static int lastvmod = 0; + +/* One virtual modifiername -> vmod number mapping. */ +struct vmodname +{ + char *name; + struct vmodname *next; +}; + +/* A list of virtualmodifier names and its numberic representation. */ +static struct vmodname *vmodnamel; + +/* Get the number assigned to the virtualmodifier with the name + VMODNAME. */ +int +vmod_find (char *vmodname) +{ + int i = 0; + struct vmodname *vmn = vmodnamel; + + while (vmn) + { + if (!strcmp (vmn->name, vmodname)) + return (lastvmod - i); + vmn = vmn->next; + i++; + } + + return 0; +} + +/* Give the virtualmodifier VMODNAME a number and add it to the + hashtable. */ +error_t +vmod_add (char *vmodname) +{ + struct vmodname *vmn; + + if (vmod_find (vmodname)) + return 0; + + vmn = malloc (sizeof (struct vmodname)); + if (vmn == NULL) + return ENOMEM; + + vmn->name = vmodname; + vmn->next = vmodnamel; + vmodnamel = vmn; + + lastvmod++; + + return 0; +} + + +/* XXX: Use this, no pointers. */ +struct ksrm +{ + symbol ks; + + int rmods; +}; +static struct hurd_ihash ksrm_mapping; + +/* Initialize the list for keysyms to realmodifiers mappings. */ +void +ksrm_init () +{ + hurd_ihash_init (&ksrm_mapping, HURD_IHASH_NO_LOCP); + debug_printf ("KSRM MAP IHASH CREATED \n"); +} + +/* Add keysym to realmodifier mapping. */ +error_t +ksrm_add (symbol ks, int rmod) +{ + hurd_ihash_add (&ksrm_mapping, ks, (void *) rmod); + + return 0; +} + +/* Apply the rkms (realmods to keysyms) table to all keysyms. */ +void +ksrm_apply (void) +{ + keycode_t kc; + for (kc = 0; kc < max_keys; kc++) + { + int group; + for (group = 0; group < 4; group++) + { + int cursym; + for (cursym = 0; cursym < keys[kc].groups[group].width; cursym++) + { + symbol ks = keys[kc].groups[group].symbols[cursym]; + int rmods = (int) hurd_ihash_find (&ksrm_mapping, ks); + struct ksrm *ksrm; + + if (rmods) + { + keys[kc].mods.rmods = rmods; + debug_printf ("kss %d = %d\n", kc, ksrm->rmods); + } + } + } + } +} + + +/* void */ +/* indicator_new (xkb_indicator_t **, */ + + +/* Keycode to realmodifier mapping. */ + +/* Set the current rmod for the key with keyname KEYNAME. */ +/* XXX: It shouldn't be applied immediatly because the key can be + replaced. */ +void +set_rmod_keycode (char *keyname, int rmod) +{ + keycode_t kc = keyname_find (keyname); + keys[kc].mods.rmods = rmod; + debug_printf ("kc %d = %d\n", kc, rmod); +} + +/* Initialize XKB data structures. */ +error_t +xkb_data_init (void) +{ + keyname_init (); + keytype_init (); + ksrm_init (); + + return 0; +} -- cgit v1.2.3