]>
git.proxmox.com Git - pve-qemu.git/blob - keycodemapdb/tools/keymap-gen
4 # Keycode Map Generator
6 # Copyright (C) 2009-2017 Red Hat, Inc.
8 # This file is dual license under the terms of the GPLv2 or later
9 # and 3-clause BSD licenses.
13 from __future__
import print_function
20 sys
.path
.append(os
.path
.join(os
.path
.dirname(__file__
), "../thirdparty"))
28 # Linux: linux/input.h
31 # OS-X: Carbon/HIToolbox/Events.h
34 # AT Set 1: linux/drivers/input/keyboard/atkbd.c
35 # (atkbd_set2_keycode + atkbd_unxlate_table)
38 # AT Set 2: linux/drivers/input/keyboard/atkbd.c
39 # (atkbd_set2_keycode)
42 # AT Set 3: linux/drivers/input/keyboard/atkbd.c
43 # (atkbd_set3_keycode)
46 # Linux RAW: linux/drivers/char/keyboard.c (x86_keycodes)
49 # USB HID: linux/drivers/hid/usbhid/usbkbd.c (usb_kbd_keycode)
52 # Win32: mingw32/winuser.h
55 # XWin XT: xorg-server/hw/xwin/{winkeybd.c,winkeynames.h}
56 # (xt + manually transcribed)
59 # X11: http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
62 # XKBD XT: xf86-input-keyboard/src/at_scancode.c
63 # (xt + manually transcribed)
66 # Xorg with evdev: linux + an offset
67 MAP_XORGEVDEV
= "xorgevdev"
69 # Xorg with kbd: xkbdxt + an offset
70 MAP_XORGKBD
= "xorgkbd"
72 # Xorg with OS-X: osx + an offset
73 MAP_XORGXQUARTZ
= "xorgxquartz"
75 # Xorg + Cygwin: xwinxt + an offset
76 MAP_XORGXWIN
= "xorgxwin"
78 # QEMU key numbers: xtkbd + special re-encoding of high bit
90 # Sun / Sparc scan codes
91 # Reference: "SPARC International Keyboard Spec 1", page 7 "US scan set"
95 # Reference: http://www.archive.org/stream/apple-guide-macintosh-family-hardware/Apple_Guide_to_the_Macintosh_Family_Hardware_2e#page/n345/mode/2up
115 # These are derived from maps above
156 MAP_QCODE
: "Q_KEY_CODE__MAX",
164 self
.mapchecksum
= None
166 for name
in self
.MAP_LIST
:
167 # Key is a MAP_LINUX, value is a MAP_XXX
168 self
.mapto
[name
] = {}
169 # key is a MAP_XXX, value is a MAP_LINUX
170 self
.mapfrom
[name
] = {}
172 for name
in self
.NAME_COLUMNS
.keys():
173 # key is a MAP_LINUX, value is a string
174 self
.mapname
[name
] = {}
176 def _generate_checksum(self
, filename
):
177 hash = hashlib
.sha256()
178 with
open(filename
, "rb") as f
:
179 for chunk
in iter(lambda: f
.read(4096), b
""):
181 self
.mapchecksum
= hash.hexdigest()
183 def load(self
, filename
):
184 self
._generate
_checksum
(filename
)
186 with
open(filename
, 'r') as f
:
187 reader
= csv
.reader(f
)
192 # Discard column headings
197 # We special case MAP_LINUX since that is out
198 # master via which all other mappings are done
199 linux
= self
.load_linux(row
)
201 # Now load all the remaining master data values
202 self
.load_data(row
, linux
)
204 # Then load all the keycode names
205 self
.load_names(row
, linux
)
207 # Finally calculate derived key maps
208 self
.derive_data(row
, linux
)
210 def load_linux(self
, row
):
211 col
= self
.CODE_COLUMNS
[self
.MAP_LINUX
]
214 if linux
.startswith("0x"):
215 linux
= int(linux
, 16)
217 linux
= int(linux
, 10)
219 self
.mapto
[self
.MAP_LINUX
][linux
] = linux
220 self
.mapfrom
[self
.MAP_LINUX
][linux
] = linux
225 def load_data(self
, row
, linux
):
226 for mapname
in self
.CODE_COLUMNS
:
227 if mapname
== self
.MAP_LINUX
:
230 col
= self
.CODE_COLUMNS
[mapname
]
236 if val
.startswith("0x"):
241 self
.mapto
[mapname
][linux
] = val
242 self
.mapfrom
[mapname
][val
] = linux
244 def load_names(self
, row
, linux
):
245 for mapname
in self
.NAME_COLUMNS
:
246 col
= self
.NAME_COLUMNS
[mapname
]
252 self
.mapname
[mapname
][linux
] = val
255 def derive_data(self
, row
, linux
):
256 # Linux RAW is XT scan codes with special encoding of the
258 if linux
in self
.mapto
[self
.MAP_ATSET1
]:
259 at1
= self
.mapto
[self
.MAP_ATSET1
][linux
]
261 assert((at1
& ~
0x7f) == 0xe000)
262 xtkbd
= 0x100 |
(at1
& 0x7f)
265 self
.mapto
[self
.MAP_XTKBD
][linux
] = xtkbd
266 self
.mapfrom
[self
.MAP_XTKBD
][xtkbd
] = linux
268 # Xorg KBD is XKBD XT offset by 8
269 if linux
in self
.mapto
[self
.MAP_XKBDXT
]:
270 xorgkbd
= self
.mapto
[self
.MAP_XKBDXT
][linux
] + 8
271 self
.mapto
[self
.MAP_XORGKBD
][linux
] = xorgkbd
272 self
.mapfrom
[self
.MAP_XORGKBD
][xorgkbd
] = linux
274 # Xorg evdev is Linux offset by 8
275 self
.mapto
[self
.MAP_XORGEVDEV
][linux
] = linux
+ 8
276 self
.mapfrom
[self
.MAP_XORGEVDEV
][linux
+ 8] = linux
278 # Xorg XQuartx is OS-X offset by 8
279 if linux
in self
.mapto
[self
.MAP_OSX
]:
280 xorgxquartz
= self
.mapto
[self
.MAP_OSX
][linux
] + 8
281 self
.mapto
[self
.MAP_XORGXQUARTZ
][linux
] = xorgxquartz
282 self
.mapfrom
[self
.MAP_XORGXQUARTZ
][xorgxquartz
] = linux
284 # Xorg Xwin (aka Cygwin) is XWin XT offset by 8
285 if linux
in self
.mapto
[self
.MAP_XWINXT
]:
286 xorgxwin
= self
.mapto
[self
.MAP_XWINXT
][linux
] + 8
287 self
.mapto
[self
.MAP_XORGXWIN
][linux
] = xorgxwin
288 self
.mapfrom
[self
.MAP_XORGXWIN
][xorgxwin
] = linux
290 # QNUM keycodes are XT scan codes with a slightly
291 # different encoding of 0xe0 scan codes
292 if linux
in self
.mapto
[self
.MAP_ATSET1
]:
293 at1
= self
.mapto
[self
.MAP_ATSET1
][linux
]
295 assert((at1
& ~
0x7f) == 0xe000)
296 qnum
= 0x80 |
(at1
& 0x7f)
299 self
.mapto
[self
.MAP_QNUM
][linux
] = qnum
300 self
.mapfrom
[self
.MAP_QNUM
][qnum
] = linux
302 # Hack for compatibility with previous mistakes in handling
303 # Print/SysRq. The preferred qnum for Print/SysRq is 0x54,
304 # but QEMU previously allowed 0xb7 too
306 self
.mapfrom
[self
.MAP_QNUM
][0xb7] = self
.mapfrom
[self
.MAP_QNUM
][0x54]
308 if linux
in self
.mapname
[self
.MAP_QCODE
]:
309 qcodeenum
= self
.mapname
[self
.MAP_QCODE
][linux
]
310 qcodeenum
= "Q_KEY_CODE_" + qcodeenum
.upper()
311 self
.mapto
[self
.MAP_QCODE
][linux
] = qcodeenum
312 self
.mapfrom
[self
.MAP_QCODE
][qcodeenum
] = linux
314 class LanguageGenerator(object):
316 def _boilerplate(self
, lines
):
317 raise NotImplementedError()
319 def generate_header(self
, database
, args
):
320 today
= time
.strftime("%Y-%m-%d %H:%M")
322 "This file is auto-generated from keymaps.csv on %s" % today
,
323 "Database checksum sha256(%s)" % database
.mapchecksum
,
324 "To re-generate, run:",
328 class LanguageSrcGenerator(LanguageGenerator
):
331 TYPE_STRING
= "string"
334 def _array_start(self
, varname
, length
, defvalue
, fromtype
, totype
):
335 raise NotImplementedError()
337 def _array_end(self
, fromtype
, totype
):
338 raise NotImplementedError()
340 def _array_entry(self
, index
, value
, comment
, fromtype
, totype
):
341 raise NotImplementedError()
343 def generate_code_map(self
, varname
, database
, frommapname
, tomapname
):
344 if frommapname
not in database
.mapfrom
:
345 raise Exception("Unknown map %s, expected one of %s" % (
346 frommapname
, ", ".join(database
.mapfrom
.keys())))
347 if tomapname
not in database
.mapto
:
348 raise Exception("Unknown map %s, expected one of %s" % (
349 tomapname
, ", ".join(database
.mapto
.keys())))
351 tolinux
= database
.mapfrom
[frommapname
]
352 fromlinux
= database
.mapto
[tomapname
]
355 varname
= "code_map_%s_to_%s" % (frommapname
, tomapname
)
357 if frommapname
in database
.ENUM_COLUMNS
:
358 fromtype
= self
.TYPE_ENUM
359 elif type(tolinux
.keys()[0]) == str:
360 fromtype
= self
.TYPE_STRING
362 fromtype
= self
.TYPE_INT
364 if tomapname
in database
.ENUM_COLUMNS
:
365 totype
= self
.TYPE_ENUM
366 elif type(fromlinux
.values()[0]) == str:
367 totype
= self
.TYPE_STRING
369 totype
= self
.TYPE_INT
371 keys
= tolinux
.keys()
373 if fromtype
== self
.TYPE_INT
:
374 keys
= range(keys
[-1] + 1)
376 if fromtype
== self
.TYPE_ENUM
:
377 keymax
= database
.ENUM_BOUND
[frommapname
]
381 defvalue
= fromlinux
.get(0, None)
382 if fromtype
== self
.TYPE_ENUM
:
383 self
._array
_start
(varname
, keymax
, defvalue
, fromtype
, totype
)
385 self
._array
_start
(varname
, keymax
, None, fromtype
, totype
)
388 linux
= tolinux
.get(src
, None)
392 dst
= fromlinux
.get(linux
, defvalue
)
394 comment
= "%s -> %s -> %s" % (self
._label
(database
, frommapname
, src
, linux
),
395 self
._label
(database
, Database
.MAP_LINUX
, linux
, linux
),
396 self
._label
(database
, tomapname
, dst
, linux
))
397 self
._array
_entry
(src
, dst
, comment
, fromtype
, totype
)
398 self
._array
_end
(fromtype
, totype
)
400 def generate_code_table(self
, varname
, database
, mapname
):
401 if mapname
not in database
.mapto
:
402 raise Exception("Unknown map %s, expected one of %s" % (
403 mapname
, ", ".join(database
.mapto
.keys())))
405 keys
= database
.mapto
[Database
.MAP_LINUX
].keys()
407 names
= [database
.mapname
[Database
.MAP_LINUX
].get(key
, "unnamed") for key
in keys
]
410 varname
= "code_table_%s" % mapname
412 if mapname
in database
.ENUM_COLUMNS
:
413 totype
= self
.TYPE_ENUM
414 elif type(database
.mapto
[mapname
].values()[0]) == str:
415 totype
= self
.TYPE_STRING
417 totype
= self
.TYPE_INT
419 self
._array
_start
(varname
, len(keys
), None, self
.TYPE_INT
, totype
)
421 defvalue
= database
.mapto
[mapname
].get(0, None)
422 for i
in range(len(keys
)):
424 dst
= database
.mapto
[mapname
].get(key
, defvalue
)
425 self
._array
_entry
(i
, dst
, names
[i
], self
.TYPE_INT
, totype
)
427 self
._array
_end
(self
.TYPE_INT
, totype
)
429 def generate_name_map(self
, varname
, database
, frommapname
, tomapname
):
430 if frommapname
not in database
.mapfrom
:
431 raise Exception("Unknown map %s, expected one of %s" % (
432 frommapname
, ", ".join(database
.mapfrom
.keys())))
433 if tomapname
not in database
.mapname
:
434 raise Exception("Unknown map %s, expected one of %s" % (
435 tomapname
, ", ".join(database
.mapname
.keys())))
437 tolinux
= database
.mapfrom
[frommapname
]
438 fromlinux
= database
.mapname
[tomapname
]
441 varname
= "name_map_%s_to_%s" % (frommapname
, tomapname
)
443 keys
= tolinux
.keys()
445 if type(keys
[0]) == int:
446 keys
= range(keys
[-1] + 1)
448 if type(keys
[0]) == int:
449 fromtype
= self
.TYPE_INT
451 fromtype
= self
.TYPE_STRING
453 self
._array
_start
(varname
, len(keys
), None, fromtype
, self
.TYPE_STRING
)
456 linux
= tolinux
.get(src
, None)
460 dst
= fromlinux
.get(linux
, None)
462 comment
= "%s -> %s -> %s" % (self
._label
(database
, frommapname
, src
, linux
),
463 self
._label
(database
, Database
.MAP_LINUX
, linux
, linux
),
464 self
._label
(database
, tomapname
, dst
, linux
))
465 self
._array
_entry
(src
, dst
, comment
, fromtype
, self
.TYPE_STRING
)
466 self
._array
_end
(fromtype
, self
.TYPE_STRING
)
468 def generate_name_table(self
, varname
, database
, mapname
):
469 if mapname
not in database
.mapname
:
470 raise Exception("Unknown map %s, expected one of %s" % (
471 mapname
, ", ".join(database
.mapname
.keys())))
473 keys
= database
.mapto
[Database
.MAP_LINUX
].keys()
475 names
= [database
.mapname
[Database
.MAP_LINUX
].get(key
, "unnamed") for key
in keys
]
478 varname
= "name_table_%s" % mapname
480 self
._array
_start
(varname
, len(keys
), None, self
.TYPE_INT
, self
.TYPE_STRING
)
482 for i
in range(len(keys
)):
484 dst
= database
.mapname
[mapname
].get(key
, None)
485 self
._array
_entry
(i
, dst
, names
[i
], self
.TYPE_INT
, self
.TYPE_STRING
)
487 self
._array
_end
(self
.TYPE_INT
, self
.TYPE_STRING
)
489 def _label(self
, database
, mapname
, val
, linux
):
490 if mapname
in database
.mapname
:
491 return "%s:%s (%s)" % (mapname
, val
, database
.mapname
[mapname
].get(linux
, "unnamed"))
493 return "%s:%s" % (mapname
, val
)
495 class LanguageDocGenerator(LanguageGenerator
):
497 def _array_start_name_doc(self
, varname
, namemap
):
498 raise NotImplementedError()
500 def _array_start_code_doc(self
, varname
, namemap
, codemap
):
501 raise NotImplementedError()
503 def _array_end(self
):
504 raise NotImplementedError()
506 def _array_name_entry(self
, value
, name
):
507 raise NotImplementedError()
509 def _array_code_entry(self
, value
, name
):
510 raise NotImplementedError()
512 def generate_name_docs(self
, varname
, database
, mapname
):
513 if mapname
not in database
.mapname
:
514 raise Exception("Unknown map %s, expected one of %s" % (
515 mapname
, ", ".join(database
.mapname
.keys())))
517 keys
= database
.mapto
[Database
.MAP_LINUX
].keys()
519 names
= [database
.mapname
[Database
.MAP_LINUX
].get(key
, "unnamed") for key
in keys
]
524 self
._array
_start
_name
_doc
(varname
, mapname
)
526 for i
in range(len(keys
)):
528 dst
= database
.mapname
[mapname
].get(key
, None)
529 self
._array
_name
_entry
(key
, dst
)
534 def generate_code_docs(self
, varname
, database
, mapname
):
535 if mapname
not in database
.mapfrom
:
536 raise Exception("Unknown map %s, expected one of %s" % (
537 mapname
, ", ".join(database
.mapfrom
.keys())))
539 tolinux
= database
.mapfrom
[mapname
]
540 keys
= tolinux
.keys()
542 if mapname
in database
.mapname
:
543 names
= database
.mapname
[mapname
]
546 names
= database
.mapname
[Database
.MAP_LINUX
]
547 namemap
= Database
.MAP_LINUX
552 self
._array
_start
_code
_doc
(varname
, mapname
, namemap
)
554 for i
in range(len(keys
)):
556 self
._array
_code
_entry
(key
, names
.get(tolinux
[key
], "unnamed"))
560 class CLanguageGenerator(LanguageSrcGenerator
):
562 def __init__(self
, inttypename
, strtypename
, lentypename
):
563 self
.inttypename
= inttypename
564 self
.strtypename
= strtypename
565 self
.lentypename
= lentypename
567 def _boilerplate(self
, lines
):
570 print(" * %s" % line
)
573 def _array_start(self
, varname
, length
, defvalue
, fromtype
, totype
):
574 self
._varname
= varname
;
575 totypename
= self
.strtypename
if totype
== self
.TYPE_STRING
else self
.inttypename
576 if fromtype
in (self
.TYPE_INT
, self
.TYPE_ENUM
):
577 if type(length
) == str:
578 print("const %s %s[%s] = {" % (totypename
, varname
, length
))
580 print("const %s %s[%d] = {" % (totypename
, varname
, length
))
582 print("const struct _%s {" % varname
)
583 print(" const %s from;" % self
.strtypename
)
584 print(" const %s to;" % totypename
)
585 print("} %s[] = {" % varname
)
588 if totype
== self
.TYPE_ENUM
:
589 if type(length
) == str:
590 print(" [0 ... %s-1] = %s," % (length
, defvalue
))
592 print(" [0 ... 0x%x-1] = %s," % (length
, defvalue
))
594 if type(length
) == str:
595 print(" [0 ... %s-1] = 0x%x," % (length
, defvalue
))
597 print(" [0 ... 0x%x-1] = 0x%x," % (length
, defvalue
))
599 def _array_end(self
, fromtype
, totype
):
601 print("const %s %s_len = sizeof(%s)/sizeof(%s[0]);" %
602 (self
.lentypename
, self
._varname
, self
._varname
, self
._varname
))
604 def _array_entry(self
, index
, value
, comment
, fromtype
, totype
):
607 if fromtype
== self
.TYPE_INT
:
609 elif fromtype
== self
.TYPE_ENUM
:
614 if totype
== self
.TYPE_INT
:
616 elif totype
== self
.TYPE_ENUM
:
621 if fromtype
!= self
.TYPE_STRING
:
622 print((" [" + indexfmt
+ "] = " + valuefmt
+ ", /* %s */") % (index
, value
, comment
))
624 print((" {" + indexfmt
+ ", " + valuefmt
+ "}, /* %s */") % (index
, value
, comment
))
626 class CppLanguageGenerator(CLanguageGenerator
):
628 def _array_start(self
, varname
, length
, defvalue
, fromtype
, totype
):
629 if fromtype
== self
.TYPE_ENUM
:
630 raise NotImplementedError("Enums not supported as source in C++ generator")
631 totypename
= "const " + self
.strtypename
if totype
== self
.TYPE_STRING
else self
.inttypename
632 if fromtype
== self
.TYPE_INT
:
633 print("#include <vector>")
634 print("const std::vector<%s> %s = {" % (totypename
, varname
))
636 print("#include <map>")
637 print("#include <string>")
638 print("const std::map<const std::string, %s> %s = {" % (totypename
, varname
))
640 def _array_end(self
, fromtype
, totype
):
643 # designated initializers not available in C++
644 def _array_entry(self
, index
, value
, comment
, fromtype
, totype
):
645 if fromtype
== self
.TYPE_STRING
:
646 return super(CppLanguageGenerator
, self
)._array
_entry
(index
, value
, comment
, fromtype
, totype
)
649 print(" 0, /* %s */" % comment
)
650 elif totype
== self
.TYPE_INT
:
651 print(" 0x%x, /* %s */" % (value
, comment
))
652 elif totype
== self
.TYPE_ENUM
:
653 print(" %s, /* %s */" % (value
, comment
))
655 print(" \"%s\", /* %s */" % (value
, comment
))
657 class StdCLanguageGenerator(CLanguageGenerator
):
660 super(StdCLanguageGenerator
, self
).__init
__("unsigned short", "char *", "unsigned int")
662 class StdCppLanguageGenerator(CppLanguageGenerator
):
665 super(StdCppLanguageGenerator
, self
).__init
__("unsigned short", "char *", "unsigned int")
667 class GLib2LanguageGenerator(CLanguageGenerator
):
670 super(GLib2LanguageGenerator
, self
).__init
__("guint16", "gchar *", "guint")
672 class PythonLanguageGenerator(LanguageSrcGenerator
):
674 def _boilerplate(self
, lines
):
680 def _array_start(self
, varname
, length
, defvalue
, fromtype
, totype
):
681 if fromtype
== self
.TYPE_ENUM
:
682 raise NotImplementedError("Enums not supported as source in Python generator")
684 if fromtype
!= self
.TYPE_STRING
:
685 print("%s = [" % varname
)
687 print("%s = {" % varname
)
689 def _array_end(self
, fromtype
, totype
):
690 if fromtype
!= self
.TYPE_STRING
:
695 def _array_entry(self
, index
, value
, comment
, fromtype
, totype
):
696 if fromtype
== self
.TYPE_INT
:
698 print(" None, # %s" % (comment
))
699 elif totype
== self
.TYPE_INT
:
700 print(" 0x%x, # %s" % (value
, comment
))
701 elif totype
== self
.TYPE_ENUM
:
702 print(" %s, # %s" % (value
, comment
))
704 print(" \"%s\", # %s" % (value
, comment
))
707 print(" \"%s\": None, # %s" % (index
, comment
))
708 elif totype
== self
.TYPE_INT
:
709 print(" \"%s\": 0x%x, # %s" % (index
, value
, comment
))
710 elif totype
== self
.TYPE_ENUM
:
711 print(" \"%s\": %s, # %s" % (index
, value
, comment
))
713 print(" \"%s\": \"%s\", # %s" % (index
, value
, comment
))
715 class PerlLanguageGenerator(LanguageSrcGenerator
):
717 def _boilerplate(self
, lines
):
723 def _array_start(self
, varname
, length
, defvalue
, fromtype
, totype
):
724 if fromtype
== self
.TYPE_ENUN
:
725 raise NotImplementedError("Enums not supported as source in Python generator")
726 if fromtype
== self
.TYPE_INT
:
727 print("my @%s = (" % varname
)
729 print("my %%%s = (" % varname
)
731 def _array_end(self
, fromtype
, totype
):
734 def _array_entry(self
, index
, value
, comment
, fromtype
, totype
):
735 if fromtype
== self
.TYPE_INT
:
737 print(" undef, # %s" % (comment
))
738 elif totype
== self
.TYPE_INT
:
739 print(" 0x%x, # %s" % (value
, comment
))
740 elif totype
== self
.TYPE_ENUM
:
741 print(" %s, # %s" % (value
, comment
))
743 print(" \"%s\", # %s" % (value
, comment
))
746 print(" \"%s\", undef, # %s" % (index
, comment
))
747 elif totype
== self
.TYPE_INT
:
748 print(" \"%s\", 0x%x, # %s" % (index
, value
, comment
))
749 elif totype
== self
.TYPE_ENUM
:
750 print(" \"%s\", 0x%x, # %s" % (index
, value
, comment
))
752 print(" \"%s\", \"%s\", # %s" % (index
, value
, comment
))
754 class JavaScriptLanguageGenerator(LanguageSrcGenerator
):
756 def _boilerplate(self
, lines
):
759 print(" * %s" % line
)
762 def _array_start(self
, varname
, length
, defvalue
, fromtype
, totype
):
763 print("export default {")
765 def _array_end(self
, fromtype
, totype
):
768 def _array_entry(self
, index
, value
, comment
, fromtype
, totype
):
772 if fromtype
== self
.TYPE_INT
:
774 elif fromtype
== self
.TYPE_ENUM
:
779 if totype
== self
.TYPE_INT
:
781 elif totype
== self
.TYPE_ENUM
:
786 print((" " + fromfmt
+ ": " + tofmt
+ ", /* %s */") % (index
, value
, comment
))
788 class PodLanguageGenerator(LanguageDocGenerator
):
790 def _boilerplate(self
, lines
):
796 def _array_start_name_doc(self
, varname
, namemap
):
797 print("=head1 %s" % varname
)
799 print("List of %s key code names, with corresponding key code values" % namemap
)
804 def _array_start_code_doc(self
, varname
, codemap
, namemap
):
805 print("=head1 %s" % varname
)
807 print("List of %s key code values, with corresponding %s key code names" % (codemap
, namemap
))
812 def _array_end(self
):
816 def _array_name_entry(self
, value
, name
):
817 print("=item %s" % name
)
819 print("Key value %d (0x%x)" % (value
, value
))
822 def _array_code_entry(self
, value
, name
):
823 print("=item %d (0x%x)" % (value
, value
))
825 print("Key name %s" % name
)
829 "stdc": StdCLanguageGenerator(),
830 "stdc++": StdCppLanguageGenerator(),
831 "glib2": GLib2LanguageGenerator(),
832 "python2": PythonLanguageGenerator(),
833 "python3": PythonLanguageGenerator(),
834 "perl": PerlLanguageGenerator(),
835 "js": JavaScriptLanguageGenerator(),
838 "pod": PodLanguageGenerator(),
842 database
= Database()
843 database
.load(args
.keymaps
)
845 cliargs
= ["keymap-gen", "--lang=%s" % args
.lang
]
846 if args
.varname
is not None:
847 cliargs
.append("--varname=%s" % args
.varname
)
848 cliargs
.extend(["code-map", "keymaps.csv", args
.frommapname
, args
.tomapname
])
849 SRC_GENERATORS
[args
.lang
].generate_header(database
, " ".join(cliargs
))
851 SRC_GENERATORS
[args
.lang
].generate_code_map(args
.varname
, database
, args
.frommapname
, args
.tomapname
)
853 def code_table(args
):
854 database
= Database()
855 database
.load(args
.keymaps
)
857 cliargs
= ["keymap-gen", "--lang=%s" % args
.lang
]
858 if args
.varname
is not None:
859 cliargs
.append("--varname=%s" % args
.varname
)
860 cliargs
.extend(["code-table", "keymaps.csv", args
.mapname
])
861 SRC_GENERATORS
[args
.lang
].generate_header(database
, " ".join(cliargs
))
863 SRC_GENERATORS
[args
.lang
].generate_code_table(args
.varname
, database
, args
.mapname
)
866 database
= Database()
867 database
.load(args
.keymaps
)
869 cliargs
= ["keymap-gen", "--lang=%s" % args
.lang
]
870 if args
.varname
is not None:
871 cliargs
.append("--varname=%s" % args
.varname
)
872 cliargs
.extend(["name-map", "keymaps.csv", args
.frommapname
, args
.tomapname
])
873 SRC_GENERATORS
[args
.lang
].generate_header(database
, " ".join(cliargs
))
875 SRC_GENERATORS
[args
.lang
].generate_name_map(args
.varname
, database
, args
.frommapname
, args
.tomapname
)
877 def name_table(args
):
878 database
= Database()
879 database
.load(args
.keymaps
)
882 cliargs
= ["keymap-gen", "--lang=%s" % args
.lang
]
883 if args
.varname
is not None:
884 cliargs
.append("--varname=%s" % args
.varname
)
885 cliargs
.extend(["name-table", "keymaps.csv", args
.mapname
])
886 SRC_GENERATORS
[args
.lang
].generate_header(database
, " ".join(cliargs
))
888 SRC_GENERATORS
[args
.lang
].generate_name_table(args
.varname
, database
, args
.mapname
)
891 database
= Database()
892 database
.load(args
.keymaps
)
895 cliargs
= ["keymap-gen", "--lang=%s" % args
.lang
]
896 if args
.varname
is not None:
897 cliargs
.append("--varname=%s" % args
.varname
)
898 cliargs
.extend(["code-docs", "keymaps.csv", args
.mapname
])
899 DOC_GENERATORS
[args
.lang
].generate_header(database
, " ".join(cliargs
))
901 DOC_GENERATORS
[args
.lang
].generate_code_docs(args
.varname
, database
, args
.mapname
)
904 database
= Database()
905 database
.load(args
.keymaps
)
908 cliargs
= ["keymap-gen", "--lang=%s" % args
.lang
]
909 if args
.varname
is not None:
910 cliargs
.append("--varname=%s" % args
.varname
)
911 cliargs
.extend(["name-docs", "keymaps.csv", args
.mapname
])
912 DOC_GENERATORS
[args
.lang
].generate_header(database
, " ".join(cliargs
))
914 DOC_GENERATORS
[args
.lang
].generate_name_docs(args
.varname
, database
, args
.mapname
)
917 print ("Please select a command:")
918 print (" 'code-map', 'code-table', 'name-map', 'name-table', 'docs'")
922 parser
= argparse
.ArgumentParser()
924 parser
.add_argument("--lang", default
="stdc",
925 help="Output language, (src=%s, doc=%s)" % (
926 ",".join(SRC_GENERATORS
.keys()),
927 ",".join(DOC_GENERATORS
.keys())))
928 parser
.add_argument("--varname", default
=None,
929 help="Data variable name")
931 subparsers
= parser
.add_subparsers(help="sub-command help")
933 codemapparser
= subparsers
.add_parser("code-map", help="Generate a mapping between code tables")
934 codemapparser
.add_argument("keymaps", help="Path to keymap CSV data file")
935 codemapparser
.add_argument("frommapname", help="Source code table name")
936 codemapparser
.add_argument("tomapname", help="Target code table name")
937 codemapparser
.set_defaults(func
=code_map
)
939 codetableparser
= subparsers
.add_parser("code-table", help="Generate a flat code table")
940 codetableparser
.add_argument("keymaps", help="Path to keymap CSV data file")
941 codetableparser
.add_argument("mapname", help="Code table name")
942 codetableparser
.set_defaults(func
=code_table
)
944 namemapparser
= subparsers
.add_parser("name-map", help="Generate a mapping to names")
945 namemapparser
.add_argument("keymaps", help="Path to keymap CSV data file")
946 namemapparser
.add_argument("frommapname", help="Source code table name")
947 namemapparser
.add_argument("tomapname", help="Target name table name")
948 namemapparser
.set_defaults(func
=name_map
)
950 nametableparser
= subparsers
.add_parser("name-table", help="Generate a flat name table")
951 nametableparser
.add_argument("keymaps", help="Path to keymap CSV data file")
952 nametableparser
.add_argument("mapname", help="Name table name")
953 nametableparser
.set_defaults(func
=name_table
)
955 codedocsparser
= subparsers
.add_parser("code-docs", help="Generate code documentation")
956 codedocsparser
.add_argument("keymaps", help="Path to keymap CSV data file")
957 codedocsparser
.add_argument("mapname", help="Code table name")
958 codedocsparser
.set_defaults(func
=code_docs
)
960 namedocsparser
= subparsers
.add_parser("name-docs", help="Generate name documentation")
961 namedocsparser
.add_argument("keymaps", help="Path to keymap CSV data file")
962 namedocsparser
.add_argument("mapname", help="Name table name")
963 namedocsparser
.set_defaults(func
=name_docs
)
965 args
= parser
.parse_args()
966 if hasattr(args
, "func"):