The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/wscons/wskbdutil.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: d56553f716af08fb268c0c9e2de2a9ba


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.