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