root/dev/wscons/wskbdutil.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. compose_tab_cmp
  2. wskbd_compose_value
  3. ksym_upcase
  4. fillmapentry
  5. wskbd_get_mapentry
  6. wskbd_init_keymap
  7. wskbd_load_keymap

    1 /*      $OpenBSD: wskbdutil.c,v 1.6 2006/12/17 22:04:04 miod Exp $      */
    2 /*      $NetBSD: wskbdutil.c,v 1.7 1999/12/21 11:59:13 drochner Exp $   */
    3 
    4 /*-
    5  * Copyright (c) 1997 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Juergen Hannken-Illjes.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/types.h>
   42 #include <sys/cdefs.h>
   43 #include <sys/errno.h>
   44 #include <sys/systm.h>
   45 #include <sys/malloc.h>
   46 #include <dev/wscons/wsksymdef.h>
   47 #include <dev/wscons/wsksymvar.h>
   48 
   49 static struct compose_tab_s {
   50         keysym_t elem[2];
   51         keysym_t result;
   52 } compose_tab[] = {
   53         { { KS_plus,                    KS_plus },              KS_numbersign },
   54         { { KS_a,                       KS_a },                 KS_at },
   55         { { KS_parenleft,               KS_parenleft },         KS_bracketleft },
   56         { { KS_slash,                   KS_slash },             KS_backslash },
   57         { { KS_parenright,              KS_parenright },        KS_bracketright },
   58         { { KS_parenleft,               KS_minus },             KS_braceleft },
   59         { { KS_slash,                   KS_minus },             KS_bar },
   60         { { KS_parenright,              KS_minus },             KS_braceright },
   61         { { KS_exclam,                  KS_exclam },            KS_exclamdown },
   62         { { KS_c,                       KS_slash },             KS_cent },
   63         { { KS_l,                       KS_minus },             KS_sterling },
   64         { { KS_y,                       KS_minus },             KS_yen },
   65         { { KS_s,                       KS_o },                 KS_section },
   66         { { KS_x,                       KS_o },                 KS_currency },
   67         { { KS_c,                       KS_o },                 KS_copyright },
   68         { { KS_less,                    KS_less },              KS_guillemotleft },
   69         { { KS_greater,                 KS_greater },           KS_guillemotright },
   70         { { KS_question,                KS_question },          KS_questiondown },
   71         { { KS_dead_acute,              KS_space },             KS_apostrophe },
   72         { { KS_dead_grave,              KS_space },             KS_grave },
   73         { { KS_dead_tilde,              KS_space },             KS_asciitilde },
   74         { { KS_dead_circumflex,         KS_space },             KS_asciicircum },
   75         { { KS_dead_diaeresis,          KS_space },             KS_quotedbl },
   76         { { KS_dead_cedilla,            KS_space },             KS_comma },
   77         { { KS_dead_circumflex,         KS_A },                 KS_Acircumflex },
   78         { { KS_dead_diaeresis,          KS_A },                 KS_Adiaeresis },
   79         { { KS_dead_grave,              KS_A },                 KS_Agrave },
   80         { { KS_dead_abovering,          KS_A },                 KS_Aring },
   81         { { KS_dead_tilde,              KS_A },                 KS_Atilde },
   82         { { KS_dead_cedilla,            KS_C },                 KS_Ccedilla },
   83         { { KS_dead_acute,              KS_E },                 KS_Eacute },
   84         { { KS_dead_circumflex,         KS_E },                 KS_Ecircumflex },
   85         { { KS_dead_diaeresis,          KS_E },                 KS_Ediaeresis },
   86         { { KS_dead_grave,              KS_E },                 KS_Egrave },
   87         { { KS_dead_acute,              KS_I },                 KS_Iacute },
   88         { { KS_dead_circumflex,         KS_I },                 KS_Icircumflex },
   89         { { KS_dead_diaeresis,          KS_I },                 KS_Idiaeresis },
   90         { { KS_dead_grave,              KS_I },                 KS_Igrave },
   91         { { KS_dead_tilde,              KS_N },                 KS_Ntilde },
   92         { { KS_dead_acute,              KS_O },                 KS_Oacute },
   93         { { KS_dead_circumflex,         KS_O },                 KS_Ocircumflex },
   94         { { KS_dead_diaeresis,          KS_O },                 KS_Odiaeresis },
   95         { { KS_dead_grave,              KS_O },                 KS_Ograve },
   96         { { KS_dead_tilde,              KS_O },                 KS_Otilde },
   97         { { KS_dead_acute,              KS_U },                 KS_Uacute },
   98         { { KS_dead_circumflex,         KS_U },                 KS_Ucircumflex },
   99         { { KS_dead_diaeresis,          KS_U },                 KS_Udiaeresis },
  100         { { KS_dead_grave,              KS_U },                 KS_Ugrave },
  101         { { KS_dead_acute,              KS_Y },                 KS_Yacute },
  102         { { KS_dead_acute,              KS_a },                 KS_aacute },
  103         { { KS_dead_circumflex,         KS_a },                 KS_acircumflex },
  104         { { KS_dead_diaeresis,          KS_a },                 KS_adiaeresis },
  105         { { KS_dead_grave,              KS_a },                 KS_agrave },
  106         { { KS_dead_abovering,          KS_a },                 KS_aring },
  107         { { KS_dead_tilde,              KS_a },                 KS_atilde },
  108         { { KS_dead_cedilla,            KS_c },                 KS_ccedilla },
  109         { { KS_dead_acute,              KS_e },                 KS_eacute },
  110         { { KS_dead_circumflex,         KS_e },                 KS_ecircumflex },
  111         { { KS_dead_diaeresis,          KS_e },                 KS_ediaeresis },
  112         { { KS_dead_grave,              KS_e },                 KS_egrave },
  113         { { KS_dead_acute,              KS_i },                 KS_iacute },
  114         { { KS_dead_circumflex,         KS_i },                 KS_icircumflex },
  115         { { KS_dead_diaeresis,          KS_i },                 KS_idiaeresis },
  116         { { KS_dead_grave,              KS_i },                 KS_igrave },
  117         { { KS_dead_tilde,              KS_n },                 KS_ntilde },
  118         { { KS_dead_acute,              KS_o },                 KS_oacute },
  119         { { KS_dead_circumflex,         KS_o },                 KS_ocircumflex },
  120         { { KS_dead_diaeresis,          KS_o },                 KS_odiaeresis },
  121         { { KS_dead_grave,              KS_o },                 KS_ograve },
  122         { { KS_dead_tilde,              KS_o },                 KS_otilde },
  123         { { KS_dead_acute,              KS_u },                 KS_uacute },
  124         { { KS_dead_circumflex,         KS_u },                 KS_ucircumflex },
  125         { { KS_dead_diaeresis,          KS_u },                 KS_udiaeresis },
  126         { { KS_dead_grave,              KS_u },                 KS_ugrave },
  127         { { KS_dead_acute,              KS_y },                 KS_yacute },
  128         { { KS_dead_diaeresis,          KS_y },                 KS_ydiaeresis },
  129         { { KS_quotedbl,                KS_A },                 KS_Adiaeresis },
  130         { { KS_quotedbl,                KS_E },                 KS_Ediaeresis },
  131         { { KS_quotedbl,                KS_I },                 KS_Idiaeresis },
  132         { { KS_quotedbl,                KS_O },                 KS_Odiaeresis },
  133         { { KS_quotedbl,                KS_U },                 KS_Udiaeresis },
  134         { { KS_quotedbl,                KS_a },                 KS_adiaeresis },
  135         { { KS_quotedbl,                KS_e },                 KS_ediaeresis },
  136         { { KS_quotedbl,                KS_i },                 KS_idiaeresis },
  137         { { KS_quotedbl,                KS_o },                 KS_odiaeresis },
  138         { { KS_quotedbl,                KS_u },                 KS_udiaeresis },
  139         { { KS_quotedbl,                KS_y },                 KS_ydiaeresis },
  140         { { KS_acute,                   KS_A },                 KS_Aacute },
  141         { { KS_asciicircum,             KS_A },                 KS_Acircumflex },
  142         { { KS_grave,                   KS_A },                 KS_Agrave },
  143         { { KS_asterisk,                KS_A },                 KS_Aring },
  144         { { KS_asciitilde,              KS_A },                 KS_Atilde },
  145         { { KS_cedilla,                 KS_C },                 KS_Ccedilla },
  146         { { KS_acute,                   KS_E },                 KS_Eacute },
  147         { { KS_asciicircum,             KS_E },                 KS_Ecircumflex },
  148         { { KS_grave,                   KS_E },                 KS_Egrave },
  149         { { KS_acute,                   KS_I },                 KS_Iacute },
  150         { { KS_asciicircum,             KS_I },                 KS_Icircumflex },
  151         { { KS_grave,                   KS_I },                 KS_Igrave },
  152         { { KS_asciitilde,              KS_N },                 KS_Ntilde },
  153         { { KS_acute,                   KS_O },                 KS_Oacute },
  154         { { KS_asciicircum,             KS_O },                 KS_Ocircumflex },
  155         { { KS_grave,                   KS_O },                 KS_Ograve },
  156         { { KS_asciitilde,              KS_O },                 KS_Otilde },
  157         { { KS_acute,                   KS_U },                 KS_Uacute },
  158         { { KS_asciicircum,             KS_U },                 KS_Ucircumflex },
  159         { { KS_grave,                   KS_U },                 KS_Ugrave },
  160         { { KS_acute,                   KS_Y },                 KS_Yacute },
  161         { { KS_acute,                   KS_a },                 KS_aacute },
  162         { { KS_asciicircum,             KS_a },                 KS_acircumflex },
  163         { { KS_grave,                   KS_a },                 KS_agrave },
  164         { { KS_asterisk,                KS_a },                 KS_aring },
  165         { { KS_asciitilde,              KS_a },                 KS_atilde },
  166         { { KS_cedilla,                 KS_c },                 KS_ccedilla },
  167         { { KS_acute,                   KS_e },                 KS_eacute },
  168         { { KS_asciicircum,             KS_e },                 KS_ecircumflex },
  169         { { KS_grave,                   KS_e },                 KS_egrave },
  170         { { KS_acute,                   KS_i },                 KS_iacute },
  171         { { KS_asciicircum,             KS_i },                 KS_icircumflex },
  172         { { KS_grave,                   KS_i },                 KS_igrave },
  173         { { KS_asciitilde,              KS_n },                 KS_ntilde },
  174         { { KS_acute,                   KS_o },                 KS_oacute },
  175         { { KS_asciicircum,             KS_o },                 KS_ocircumflex },
  176         { { KS_grave,                   KS_o },                 KS_ograve },
  177         { { KS_asciitilde,              KS_o },                 KS_otilde },
  178         { { KS_acute,                   KS_u },                 KS_uacute },
  179         { { KS_asciicircum,             KS_u },                 KS_ucircumflex },
  180         { { KS_grave,                   KS_u },                 KS_ugrave },
  181         { { KS_acute,                   KS_y },                 KS_yacute }
  182 };
  183 
  184 #define COMPOSE_SIZE    sizeof(compose_tab)/sizeof(compose_tab[0])
  185 
  186 static int compose_tab_inorder = 0;
  187 
  188 inline int compose_tab_cmp(struct compose_tab_s *,
  189                                 struct compose_tab_s *);
  190 keysym_t ksym_upcase(keysym_t);
  191 void fillmapentry(const keysym_t *, int, struct wscons_keymap *);
  192 
  193 inline int
  194 compose_tab_cmp(i, j)
  195         struct compose_tab_s *i, *j;
  196 {
  197         if (i->elem[0] == j->elem[0])
  198                 return(i->elem[1] - j->elem[1]);
  199         else
  200                 return(i->elem[0] - j->elem[0]);
  201 }
  202 
  203 keysym_t
  204 wskbd_compose_value(compose_buf)
  205         keysym_t *compose_buf;
  206 {
  207         int i, j, r;
  208         struct compose_tab_s v;
  209 
  210         if (! compose_tab_inorder) {
  211                 /* Insertion sort. */
  212                 for (i = 1; i < COMPOSE_SIZE; i++) {
  213                         v = compose_tab[i];
  214                         /* find correct slot, moving others up */
  215                         for (j = i; --j >= 0 && compose_tab_cmp(& v, & compose_tab[j]) < 0; )
  216                                 compose_tab[j + 1] = compose_tab[j];
  217                         compose_tab[j + 1] = v;
  218                 }
  219                 compose_tab_inorder = 1;
  220         }
  221 
  222         for (j = 0, i = COMPOSE_SIZE; i != 0; i /= 2) {
  223                 if (compose_tab[j + i/2].elem[0] == compose_buf[0]) {
  224                         if (compose_tab[j + i/2].elem[1] == compose_buf[1])
  225                                 return(compose_tab[j + i/2].result);
  226                         r = compose_tab[j + i/2].elem[1] < compose_buf[1];
  227                 } else
  228                         r = compose_tab[j + i/2].elem[0] < compose_buf[0];
  229                 if (r) {
  230                         j += i/2 + 1;
  231                         i--;
  232                 }
  233         }
  234 
  235         return(KS_voidSymbol);
  236 }
  237 
  238 static const u_char latin1_to_upper[256] = {
  239 /*      0  8  1  9  2  a  3  b  4  c  5  d  6  e  7  f               */
  240         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 0 */
  241         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 0 */
  242         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 1 */
  243         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 1 */
  244         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 2 */
  245         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 2 */
  246         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 3 */
  247         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 3 */
  248         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 4 */
  249         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 4 */
  250         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 5 */
  251         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 5 */
  252         0x00,  'A',  'B',  'C',  'D',  'E',  'F',  'G',         /* 6 */
  253          'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',         /* 6 */
  254          'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',         /* 7 */
  255          'X',  'Y',  'Z', 0x00, 0x00, 0x00, 0x00, 0x00,         /* 7 */
  256         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 8 */
  257         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 8 */
  258         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 9 */
  259         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* 9 */
  260         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* a */
  261         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* a */
  262         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* b */
  263         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* b */
  264         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* c */
  265         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* c */
  266         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* d */
  267         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* d */
  268         0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,         /* e */
  269         0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,         /* e */
  270         0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00,         /* f */
  271         0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00,         /* f */
  272 };
  273 
  274 keysym_t
  275 ksym_upcase(ksym)
  276         keysym_t ksym;
  277 {
  278         if (ksym >= KS_f1 && ksym <= KS_f20)
  279                 return(KS_F1 - KS_f1 + ksym);
  280 
  281         if (KS_GROUP(ksym) == KS_GROUP_Ascii && ksym <= 0xff &&
  282             latin1_to_upper[ksym] != 0x00)
  283                 return(latin1_to_upper[ksym]);
  284 
  285         return(ksym);
  286 }
  287 
  288 void
  289 fillmapentry(kp, len, mapentry)
  290         const keysym_t *kp;
  291         int len;
  292         struct wscons_keymap *mapentry;
  293 {
  294         switch (len) {
  295         case 0:
  296                 mapentry->group1[0] = KS_voidSymbol;
  297                 mapentry->group1[1] = KS_voidSymbol;
  298                 mapentry->group2[0] = KS_voidSymbol;
  299                 mapentry->group2[1] = KS_voidSymbol;
  300                 break;
  301 
  302         case 1:
  303                 mapentry->group1[0] = kp[0];
  304                 mapentry->group1[1] = ksym_upcase(kp[0]);
  305                 mapentry->group2[0] = mapentry->group1[0];
  306                 mapentry->group2[1] = mapentry->group1[1];
  307                 break;
  308 
  309         case 2:
  310                 mapentry->group1[0] = kp[0];
  311                 mapentry->group1[1] = kp[1];
  312                 mapentry->group2[0] = mapentry->group1[0];
  313                 mapentry->group2[1] = mapentry->group1[1];
  314                 break;
  315 
  316         case 3:
  317                 mapentry->group1[0] = kp[0];
  318                 mapentry->group1[1] = kp[1];
  319                 mapentry->group2[0] = kp[2];
  320                 mapentry->group2[1] = ksym_upcase(kp[2]);
  321                 break;
  322 
  323         case 4:
  324                 mapentry->group1[0] = kp[0];
  325                 mapentry->group1[1] = kp[1];
  326                 mapentry->group2[0] = kp[2];
  327                 mapentry->group2[1] = kp[3];
  328                 break;
  329 
  330         }
  331 }
  332 
  333 void
  334 wskbd_get_mapentry(mapdata, kc, mapentry)
  335         const struct wskbd_mapdata *mapdata;
  336         int kc;
  337         struct wscons_keymap *mapentry;
  338 {
  339         kbd_t cur;
  340         const keysym_t *kp;
  341         const struct wscons_keydesc *mp;
  342         int l;
  343         keysym_t ksg;
  344 
  345         mapentry->command = KS_voidSymbol;
  346         mapentry->group1[0] = KS_voidSymbol;
  347         mapentry->group1[1] = KS_voidSymbol;
  348         mapentry->group2[0] = KS_voidSymbol;
  349         mapentry->group2[1] = KS_voidSymbol;
  350 
  351         for (cur = mapdata->layout & ~KB_HANDLEDBYWSKBD; cur != 0; ) {
  352                 mp = mapdata->keydesc;
  353                 while (mp->map_size > 0) {
  354                         if (mp->name == cur)
  355                                 break;
  356                         mp++;
  357                 }
  358 
  359                 /* If map not found, return */
  360                 if (mp->map_size <= 0)
  361                         return;
  362 
  363                 for (kp = mp->map; kp < mp->map + mp->map_size; kp++) {
  364                         ksg = KS_GROUP(*kp);
  365                         if (ksg == KS_GROUP_Keycode &&
  366                             KS_VALUE(*kp) == kc) {
  367                                 /* First skip keycode and possible command */
  368                                 kp++;
  369                                 if (KS_GROUP(*kp) == KS_GROUP_Command ||
  370                                     *kp == KS_Cmd || *kp == KS_Cmd1 || *kp == KS_Cmd2)
  371                                         mapentry->command = *kp++;
  372 
  373                                 for (l = 0; kp + l < mp->map + mp->map_size;
  374                                     l++) {
  375                                         ksg = KS_GROUP(kp[l]);
  376                                         if (ksg == KS_GROUP_Keycode)
  377                                                 break;
  378                                 }
  379                                 if (l > 4)
  380                                         panic("wskbd_get_mapentry: %d(%d): bad entry",
  381                                               mp->name, *kp);
  382                                 fillmapentry(kp, l, mapentry);
  383                                 return;
  384                         }
  385                 }
  386 
  387                 cur = mp->base;
  388         }
  389 }
  390 
  391 void
  392 wskbd_init_keymap(newlen, map, maplen)
  393         int newlen;
  394         struct wscons_keymap **map;
  395         int *maplen;
  396 {
  397         int i;
  398 
  399         if (newlen != *maplen) {
  400                 if (*maplen > 0)
  401                         free(*map, M_TEMP);
  402                 *maplen = newlen;
  403                 *map = malloc(newlen*sizeof(struct wscons_keymap),
  404                               M_TEMP, M_WAITOK);
  405         }
  406 
  407         for (i = 0; i < *maplen; i++) {
  408                 (*map)[i].command = KS_voidSymbol;
  409                 (*map)[i].group1[0] = KS_voidSymbol;
  410                 (*map)[i].group1[1] = KS_voidSymbol;
  411                 (*map)[i].group2[0] = KS_voidSymbol;
  412                 (*map)[i].group2[1] = KS_voidSymbol;
  413         }
  414 }
  415 
  416 int
  417 wskbd_load_keymap(mapdata, map, maplen)
  418         const struct wskbd_mapdata *mapdata;
  419         struct wscons_keymap **map;
  420         int *maplen;
  421 {
  422         int i, s, kc, stack_ptr;
  423         const keysym_t *kp;
  424         const struct wscons_keydesc *mp, *stack[10];
  425         kbd_t cur;
  426         keysym_t ksg;
  427 
  428         for (cur = mapdata->layout & ~KB_HANDLEDBYWSKBD, stack_ptr = 0;
  429              cur != 0; stack_ptr++) {
  430                 mp = mapdata->keydesc;
  431                 while (mp->map_size > 0) {
  432                         if (cur == 0 || mp->name == cur) {
  433                                 break;
  434                         }
  435                         mp++;
  436                 }
  437 
  438                 if (stack_ptr == sizeof(stack)/sizeof(stack[0]))
  439                         panic("wskbd_load_keymap: %d: recursion too deep",
  440                               mapdata->layout);
  441                 if (mp->map_size <= 0)
  442                         return(EINVAL);
  443 
  444                 stack[stack_ptr] = mp;
  445                 cur = mp->base;
  446         }
  447 
  448         for (i = 0, s = stack_ptr - 1; s >= 0; s--) {
  449                 mp = stack[s];
  450                 for (kp = mp->map; kp < mp->map + mp->map_size; kp++) {
  451                         ksg = KS_GROUP(*kp);
  452                         if (ksg == KS_GROUP_Keycode && KS_VALUE(*kp) > i)
  453                                 i = KS_VALUE(*kp);
  454                 }
  455         }
  456 
  457         wskbd_init_keymap(i + 1, map, maplen);
  458 
  459         for (s = stack_ptr - 1; s >= 0; s--) {
  460                 mp = stack[s];
  461                 for (kp = mp->map; kp < mp->map + mp->map_size; ) {
  462                         ksg = KS_GROUP(*kp);
  463                         if (ksg != KS_GROUP_Keycode)
  464                                 panic("wskbd_load_keymap: %d(%d): bad entry",
  465                                       mp->name, *kp);
  466 
  467                         kc = KS_VALUE(*kp);
  468                         kp++;
  469 
  470                         if (KS_GROUP(*kp) == KS_GROUP_Command ||
  471                             *kp == KS_Cmd || *kp == KS_Cmd1 || *kp == KS_Cmd2) {
  472                                 (*map)[kc].command = *kp;
  473                                 kp++;
  474                         }
  475 
  476                         for (i = 0; kp + i < mp->map + mp->map_size; i++) {
  477                                 ksg = KS_GROUP(kp[i]);
  478                                 if (ksg == KS_GROUP_Keycode)
  479                                         break;
  480                         }
  481 
  482                         if (i > 4)
  483                                 panic("wskbd_load_keymap: %d(%d): bad entry",
  484                                       mp->name, *kp);
  485 
  486                         fillmapentry(kp, i, &(*map)[kc]);
  487                         kp += i;
  488                 }
  489         }
  490 
  491         return(0);
  492 }

/* [<][>][^][v][top][bottom][index][help] */