1#! /usr/bin/awk -f 2# $OpenBSD: makemap.awk,v 1.6 2005/05/23 21:33:03 miod Exp $ 3# 4# Copyright (c) 2005, Miodrag Vallat 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27# 28# This script attempts to convert, with minimal hacks and losses, the 29# regular PS/2 keyboard (pckbd) layout tables into USB keyboard (ukbd) 30# layout tables. 31# 32 33BEGIN { 34 rcsid = "$OpenBSD: makemap.awk,v 1.6 2005/05/23 21:33:03 miod Exp $" 35 ifdepth = 0 36 ignore = 0 37 declk = 0 38 haskeys = 0 39 kbfr = 0 40 41 # PS/2 id -> UKBD conversion table, or "sanity lossage 102" 42 # (101 is for GSC keyboards!) 43 for (i = 0; i < 256; i++) 44 conv[i] = -1 45 46 conv[1] = 41 47 conv[2] = 30 48 conv[3] = 31 49 conv[4] = 32 50 conv[5] = 33 51 conv[6] = 34 52 conv[7] = 35 53 conv[8] = 36 54 conv[9] = 37 55 conv[10] = 38 56 conv[11] = 39 57 conv[12] = 45 58 conv[13] = 46 59 conv[14] = 42 60 conv[15] = 43 61 conv[16] = 20 62 conv[17] = 26 63 conv[18] = 8 64 conv[19] = 21 65 conv[20] = 23 66 conv[21] = 28 67 conv[22] = 24 68 conv[23] = 12 69 conv[24] = 18 70 conv[25] = 19 71 conv[26] = 47 72 conv[27] = 48 73 conv[28] = 40 74 conv[29] = 224 75 conv[30] = 4 76 conv[31] = 22 77 conv[32] = 7 78 conv[33] = 9 79 conv[34] = 10 80 conv[35] = 11 81 conv[36] = 13 82 conv[37] = 14 83 conv[38] = 15 84 conv[39] = 51 85 conv[40] = 52 86 conv[41] = 53 87 conv[42] = 225 88 conv[43] = 50 89 conv[44] = 29 90 conv[45] = 27 91 conv[46] = 6 92 conv[47] = 25 93 conv[48] = 5 94 conv[49] = 17 95 conv[50] = 16 96 conv[51] = 54 97 conv[52] = 55 98 conv[53] = 56 99 conv[54] = 229 100 conv[55] = 85 101 conv[56] = 226 102 conv[57] = 44 103 conv[58] = 57 104 conv[59] = 58 105 conv[60] = 59 106 conv[61] = 60 107 conv[62] = 61 108 conv[63] = 62 109 conv[64] = 63 110 conv[65] = 64 111 conv[66] = 65 112 conv[67] = 66 113 conv[68] = 67 114 conv[69] = 83 115 conv[70] = 71 116 conv[71] = 95 117 conv[72] = 96 118 conv[73] = 97 119 conv[74] = 86 120 conv[75] = 92 121 conv[76] = 93 122 conv[77] = 94 123 conv[78] = 87 124 conv[79] = 89 125 conv[80] = 90M 126 conv[81] = 91 127 conv[82] = 98 128 conv[83] = 99 129 conv[86] = 100 130 conv[87] = 68 131 conv[88] = 69 132 conv[112] = 135 133 conv[115] = 136 134 conv[121] = 137 135 conv[123] = 138 136 conv[125] = 139 137 conv[127] = 72 138 conv[156] = 88 139 conv[157] = 228 140 conv[170] = 70 141 conv[181] = 84 142 conv[184] = 230 143 # 198 is #if 0 in the PS/2 map... 144 conv[199] = 74 145 conv[200] = 82 146 conv[201] = 75 147 conv[203] = 80 148 conv[205] = 79 149 conv[207] = 77 150 conv[208] = 81 151 conv[209] = 78 152 conv[210] = 73 153 conv[211] = 99 154 conv[219] = 227 155 conv[220] = 231 156 conv[221] = 101 157} 158NR == 1 { 159 VERSION = $0 160 gsub("\\$", "", VERSION) 161 gsub("\\$", "", rcsid) 162 163 printf("/*\t\$OpenBSD\$\t*/\n\n") 164 printf("/*\n") 165 printf(" * THIS FILE IS AUTOMAGICALLY GENERATED. DO NOT EDIT.\n") 166 printf(" *\n") 167 printf(" * generated by:\n") 168 printf(" *\t%s\n", rcsid) 169 printf(" * generated from:\n") 170 printf(" */\n") 171 print VERSION 172 173 next 174} 175 176# 177# A very limited #if ... #endif parser. We only want to correctly detect 178# ``#if 0'' constructs, so as not to process their contents. This is necessary 179# since our output is out-of-order from our input. 180# 181# Note that this does NOT handle ``#ifdef notyet'' correctly - please only use 182# ``#if 0'' constructs in the input. 183# 184 185/^#if/ { 186 ignores[ifdepth] = ignore 187 if ($2 == "0") 188 ignore = 1 189 else 190 ignore = 0 191 ifdepth++ 192 if (ignore) 193 next 194} 195/^#endif/ { 196 oldignore = ignore 197 ifdepth-- 198 ignore = ignores[ifdepth] 199 ignores[ifdepth] = 0 200 if (oldignore) 201 next 202} 203 204$1 == "#include" { 205 if (ignore) 206 next 207 if ($2 == "<dev/pckbc/wskbdmap_mfii.h>") 208 print "#include <dev/usb/usb_port.h>" 209 else 210 printf("#include %s\n", $2) 211 212 next 213} 214$1 == "#define" || $1 == "#undef" { 215 if (ignore) 216 next 217 print $0 218 next 219} 220 221# Don't bother converting the DEC LK layout. 222/declk\[/ { 223 declk = 1 224 next 225} 226/declk/ { 227 next 228} 229 230/pckbd/ { 231 gsub("pckbd", "ukbd", $0) 232 mapname = $4 233} 234 235/KC/ { 236 if (ignore) 237 next 238 239 if (declk) 240 next 241 242 haskeys = 1 243 244 sidx = substr($1, 4, length($1) - 5) 245 orig = int(sidx) 246 id = conv[orig] 247 248 # 183 is another Print Screen... 249 if (orig == 183) 250 next 251 252 if (id == -1) { 253 printf("/* initially KC(%d),", orig) 254 for (f = 2; f <= NF; f++) { 255 if ($f != "/*" && $f != "*/") 256 printf("\t%s", $f) 257 } 258 printf("\t*/\n") 259 } else { 260 lines[id] = sprintf(" KC(%d),\t", id) 261 # 262 # This makes sure that the non-comment part of the output 263 # ends up with a trailing comma. This is necessary since 264 # the last line of an input block might not have a trailing 265 # comma, but might not be the last line of an output block 266 # due to sorting. 267 # 268 comma = 0 269 for (f = 2; f <= NF; f++) { 270 l = length($f) 271 if ($f == "/*") 272 comma++ 273 if (comma == 0 && substr($f, l) != ",") { 274 lines[id] = sprintf("%s%s,", lines[id], $f) 275 l++ 276 } else { 277 lines[id] = sprintf("%s%s", lines[id], $f) 278 } 279 if (comma == 0 && f != NF) { 280 if (l < 2 * 8) 281 lines[id] = lines[id] "\t" 282 if (l < 8) 283 lines[id] = lines[id] "\t" 284 } 285 if ($f == "*/") 286 comma-- 287 } 288 } 289 290 next 291} 292/};/ { 293 if (ignore) 294 next 295 296 if (declk) { 297 declk = 0 298 next 299 } 300 301 if (haskeys) { 302 # Duplicate 42 (backspace) as 76 and 50 (backslash bar) as 49 303 if (!lines[76]) { 304 lines[76] = lines[42] 305 sub("42", "76", lines[76]) 306 } 307 if (!lines[49]) { 308 lines[49] = lines[50] 309 sub("50", "49", lines[49]) 310 } 311 312 for (i = 0; i < 256; i++) 313 if (lines[i]) { 314 print lines[i] 315 lines[i] = "" 316 } 317 318 haskeys = 0 319 320 # 321 # Apple black USB keyboards use a slightly different 322 # layout. We define them here. 323 # 324 if (mapname == "ukbd_keydesc_fr[]") { 325 print $0 326 print "\nstatic const keysym_t ukbd_keydesc_fr_apple[] = {" 327 print " KC(5),\tKS_b,\t\tKS_B,\t\tKS_ssharp," 328 print " KC(8),\tKS_e,\t\tKS_E,\t\tKS_ecircumflex,\tKS_Ecircumflex," 329 print " KC(11),\tKS_h,\t\tKS_H,\t\tKS_Igrave,\tKS_Icircumflex," 330 print " KC(12),\tKS_i,\t\tKS_I,\t\tKS_icircumflex,\tKS_idiaeresis," 331 print " KC(13),\tKS_j,\t\tKS_J,\t\tKS_Idiaeresis,\tKS_Iacute," 332 print " KC(14),\tKS_k,\t\tKS_K,\t\tKS_Egrave,\tKS_Ediaeresis," 333 print " KC(15),\tKS_l,\t\tKS_L,\t\tKS_voidSymbol,\tKS_bar," 334 print " KC(16),\tKS_comma,\tKS_question,\tKS_voidSymbol,\tKS_questiondown," 335 print " KC(17),\tKS_n,\t\tKS_N,\t\tKS_asciitilde," 336 print " KC(20),\tKS_a,\t\tKS_A,\t\tKS_ae,\t\tKS_AE," 337 print " KC(21),\tKS_r,\t\tKS_R,\t\tKS_registered,\tKS_comma," 338 print " KC(22),\tKS_s,\t\tKS_S,\t\tKS_Ograve," 339 print " KC(26),\tKS_z,\t\tKS_Z,\t\tKS_Acircumflex,\tKS_Aring," 340 print " KC(28),\tKS_y,\t\tKS_Y,\t\tKS_Uacute," 341 print " KC(31),\tKS_eacute,\tKS_2,\t\tKS_ediaeresis," 342 print " KC(32),\tKS_quotedbl,\tKS_3," 343 print " KC(33),\tKS_apostrophe,\tKS_4," 344 print " KC(34),\tKS_parenleft,\tKS_5,\t\tKS_braceleft,\tKS_bracketleft," 345 print " KC(35),\tKS_section,\tKS_6," 346 print " KC(36),\tKS_egrave,\tKS_7,\t\tKS_guillemotleft," 347 print "\t\t\t\t\t\tKS_guillemotright," 348 print " KC(37),\tKS_exclam,\tKS_8," 349 print " KC(38),\tKS_ccedilla,\tKS_9,\t\tKS_Ccedilla,\tKS_Aacute," 350 print " KC(37),\tKS_exclam,\tKS_8,\t\tKS_exclamdown,\tKS_Ucircumflex," 351 print " KC(39),\tKS_agrave,\tKS_0,\t\tKS_oslash,\tKS_Ooblique," 352 print " KC(45),\tKS_parenright,\tKS_degree,\tKS_braceright,\tKS_bracketright," 353 print " KC(46),\tKS_minus,\tKS_underscore," 354 print " KC(47),\tKS_dead_circumflex, KS_dead_diaeresis," 355 print "\t\t\t\t\t\tKS_ocircumflex,\tKS_Ocircumflex," 356 print " KC(48),\tKS_dollar,\tKS_asterisk,\tKS_cent,\tKS_yen," 357 print " KC(50),\tKS_grave,\tKS_sterling,\tKS_at,\t\tKS_numbersign," 358 print " KC(51),\tKS_m,\t\tKS_M,\t\tKS_mu,\t\tKS_Oacute," 359 print " KC(52),\tKS_ugrave,\tKS_percent,\tKS_Ugrave," 360 print " KC(53),\tKS_at,\t\tKS_numbersign," 361 print " KC(55),\tKS_colon,\tKS_slash,\tKS_voidSymbol,\tKS_backslash," 362 print " KC(56),\tKS_equal,\tKS_plus," 363 print " KC(103),\tKS_KP_Equal," 364 print " KC(231),\tKS_Mode_switch,\tKS_Multi_key," 365 } else 366 if (mapname == "ukbd_keydesc_pt[]") { 367 print $0 368 print "\nstatic const keysym_t ukbd_keydesc_pt_apple[] = {" 369 print "/* pos\t\tnormal\t\tshifted */" 370 print " KC(46),\tKS_plus,\tKS_asterisk," 371 print " KC(47),\tKS_masculine,\tKS_ordfeminine," 372 print " KC(50),\tKS_backslash,\tKS_bar," 373 print " KC(52),\tKS_dead_tilde,\tKS_dead_circumflex" 374 } 375 } 376} 377/KB_FR/ { 378 print $0 379 if (kbfr++ == 0) { 380 print "\tKBD_MAP(KB_FR | KB_APPLE,\tKB_FR,\tukbd_keydesc_fr_apple)," 381 } else { 382 print "\tKBD_MAP(KB_FR | KB_APPLE | KB_SWAPCTRLCAPS,\tKB_FR | KB_APPLE," 383 print "\t\tukbd_keydesc_swapctrlcaps)," 384 } 385 next 386} 387/KB_PT/ { 388 print $0 389 print "\tKBD_MAP(KB_PT | KB_APPLE,\tKB_PT,\tukbd_keydesc_pt_apple)," 390 next 391} 392{ 393 if (ignore) 394 next 395 if (declk) 396 next 397 print $0 398} 399