[BACK]Return to wskbdutil.c CVS log [TXT][DIR] Up to [local] / sys / dev / wscons

Annotation of sys/dev/wscons/wskbdutil.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb