Keymaps: Difference between revisions

From vice-emu
Jump to navigation Jump to search
mNo edit summary
 
(44 intermediate revisions by 2 users not shown)
Line 1: Line 1:
NOTE: i am working at this locally atm and updating the page while doing so. will commit when at least unix/sdl/win32 are working ok [[User:Gpz|Gpz]] ([[User talk:Gpz|talk]]) 01:29, 9 April 2015 (UTC)
Reason for this page: handling auf keymaps was a bit messy in some places in the past, unnecessary complex to maintain (eg hardcoded filenames in archdep code dont make updating a lot easier). It has been reworked to handle everything at one central place, with a minimum set of resources which are valid for all emulators. This will make both adding new keyboard types and updating the respective ports easier in the future. At the same time a somewhat more sane default behaviour that always works "as expected" automatically will be achived, based on the general assumption that the casual user never even wants to be bothered with setting up keymaps at all :)
 
Reason for this page: handling auf keymaps is currently a bit messy in some places, and seems unnecessary complex to maintain (eg hardcoded filenames in archdep code dont make updating a lot easier). The idea is to handle it at one central place, with a minimum set of resources which are valid for all emulators. This will make both adding new keyboard types and updating the respective ports easier in the future. At the same time a somewhat more sane default behaviour that always works "as expected" automatically will be achived, based on the general assumption that the casual user never even wants to be bothered with setting up keymaps at all :)


=== considerations ===
=== considerations ===
Line 22: Line 20:


* "KeyboardType" - (Integer) emulated keyboard type. (default:0)  
* "KeyboardType" - (Integer) emulated keyboard type. (default:0)  
** C128 0: International, 1: Finnish,French, 3: German, 4: Italian, 5: Norwegian, 6: Swedish
** C128 0: International, 1: Finnish,French, 3: German, 4: Italian, 5: Norwegian, 6: Swedish (not used by x128 yet)
** PET: (pet-resources.h) 0 "buus" 1: "buuk" 2: "bude" 3: "bujp" 4: "grus"
** PET: (pet-resources.h) 0 "buus" 1: "buuk" 2: "bude" 3: "bujp" 4: "grus"
** others: 0
** others: always 0
:: This resource will get updated when the machine model changes, and can be individually updated in the user interface.
:: This resource will get updated when the machine model changes, and can be individually updated in the user interface.


* "KeyboardMapping" - (integer) host keyboard type (default:0)  
NOTE: more info on local keyboard variants wanted, what about CBM2, C64... some VIC20 info [http://sleepingelephant.com/ipw-web/bulletin/bb/viewtopic.php?t=7388&p=79621#p79621 here]
** 0 "" (us mapping)
 
** 1 "uk"
* "KeyboardMapping" - (integer) host keyboard layout type (default:0)  
** 2 "de"
** 0 American (us) suffix: ""
** 3 "da"
** 1 British                "uk"
** 4 "no"
** 2 German                "de"
** 5 "fi"
** 3 Danish                "da"
** 6 "gr"
** 4 Norwegian              "no"
** 7 "it"
** 5 Finnish                "fi"
** 6 Italian                "it"
:: this list may be expanded as needed
:: this list may be expanded as needed
NOTE: suggestions for more languages that we should add as a default here wanted...


=== command line options ===
=== command line options ===
Line 48: Line 49:
=== defaults ===
=== defaults ===


* when the emulator starts the first time and finds "KeymapSymFile" and "KeymapPosFile" empty,  
* when the emulator starts and finds "KeymapSymFile" and "KeymapPosFile" empty,  
** an archdep function should be called which returns the type of keyboard connected -> src/arch/<port>/archdep*: kbd_arch_get_host_mapping() (done)
** an archdep function is called which returns the type of keyboard connected -> <tt>src/arch/<port>/archdep*: kbd_arch_get_host_mapping()</tt>
** "KeyboardMapping" is initialized with that value, and the resulting keymap loaded (done)
** "KeyboardMapping" is initialized with that value, and the resulting keymap loaded (done)
The goal is to automatically configure and load the right keyboard map for a given combination of host OS/language/layout and emulated system.


=== loading the keymap ===
=== loading the keymap ===


a central function which is called if any of "KeymapIndex", "KeyboardType", "KeyboardMapping" changed handles loading the new keymap.
a central function which is called if any of "KeymapIndex", "KeyboardType", "KeyboardMapping" changed handles loading the new keymap. -> <tt>keyboard.c:switch_keymap_file()</tt>


* if "KeymapIndex" is not 0 or 1, then load the respective user keymap and skip any further automatic actions
* if "KeymapIndex" is not 0 or 1, then load the respective user keymap and skip any further automatic actions
Line 68: Line 71:


=== constructing the filename ===
=== constructing the filename ===
-> <tt>keyboard.c:try_set_keymap_file()</tt>


generally the filename of a keymap will be constructed according to this scheme:
generally the filename of a keymap will be constructed according to this scheme:
Line 75: Line 80:
where:
where:


* <port> is a string constant defined in archdep code (eg "x11", "sdl", "win" etc) -> KBD_PORT_PREFIX in src/arch/<port>/kbd.h
* <port> is a string constant defined in archdep code (eg "x11", "sdl", "win" etc) -> <tt>KBD_PORT_PREFIX</tt> in <tt>src/arch/<port>/kbd.h</tt>
* <type> is a string returned by a machine specific function. this function should return NULL if the type string would be empty (the machine has no keyboard types) else eg "bkuk", "gkuk", "bkde" etc. (the returned string should be no more than 4 characters) -> machine_get_keyboard_type_name()
* <type> is a string returned by a machine specific function. this function should return NULL if the type string would be empty (the machine has no keyboard types) else eg "bkuk", "gkuk", "bkde" etc. (the returned string should be no more than 4 characters) -> <tt>machine_get_keyboard_type_name()</tt>
* <idx> is a string derived from "KeymapIndex", where 0 is "sym" and 1 is "pos"
* <idx> is a string derived from "KeymapIndex", where 0 is "sym" and 1 is "pos"
* <mapping> is a string derived from "KeyboardMapping", where 0 is an empty string and 1 is "de" (... 2: "fi" 3: "se" etc if needed)
* <mapping> is a string derived from "KeyboardMapping", where 0 is an empty string and 1 is "de" (... 2: "fi" 3: "se" etc if needed)
Line 90: Line 95:
**** <idx> is a string derived from "KeymapIndex", where 0 is "s" and 1 is "p"
**** <idx> is a string derived from "KeymapIndex", where 0 is "s" and 1 is "p"
**** use <port><type><idx><mapping>.vkm
**** use <port><type><idx><mapping>.vkm
----
----


== migrating the code ==
== migrating the code ==


=== menus ===
=== add ===
 
'''TODO:''' generate description for command line options at runtime (query available options in a similar way as the UIs)
 
* archdep function "<tt>int kbd_arch_get_host_mapping(void)</tt>" (query host keyboard mapping and return one of the KBD_MAPPING_xx constants defined in <tt>keyboard.h</tt>. If for whatever reason determining the layout is not possibly, always return KBD_MAPPING_US)
 
=== update menus ===


after the change, all user interfaces should have the following options:
after the change, all user interfaces should have the following options:


* "set keymapping" - select between "symbolic", "positional", "symbolic (user)", "positional (user) and change "KeymapIndex" accordingly
* "set keymapping" - select between "symbolic", "positional", "symbolic (user)", "positional (user) and change "KeymapIndex" accordingly (see <tt>keyboard.h</tt>)
* "set keyboard layout" - select between "us" and "de" and change "KeyboardMapping" accordingly
* "set keyboard layout" - available keyboard layouts can be queried by using <tt>keyboard.h:keyboard_get_num_mappings()</tt> and <tt>keyboard_get_info_list()</tt>. generate menu dynamically and set up "KeyboardMapping" accordingly (see <tt>keyboard.h</tt>)


* "define user-defined symbolic keymap" - set up "KeymapUserSymFile"
* "define user-defined symbolic keymap" - set up "KeymapUserSymFile"
* "define user-defined positional keymap" - set up "KeymapUserPosFile"
* "define user-defined positional keymap" - set up "KeymapUserPosFile"


additionally for machines which have more than one type of keyboard:
additionally for machines which have more than one type of keyboard (this should go into model selection somewhere):
 
* "set keyboard type" - select emulated keyboard (C128 0: International, 1: Finnish,French, 3: German, 4: Italian, 5: Norwegian, 6: Swedish - PET: 0 "bkuk" 1: "gkuk" 2: "bkde" - others: 0) and set up "KeyboardType" accordingly


=== change ===
* "set keyboard type" - available keyboard types can be queried using <tt>machine.h:machine_get_num_keyboard_types()</tt> and <tt>machine_get_keyboard_info_list()</tt>. generate menu dynamically set up "KeyboardType" accordingly. (this is currently only used by PET but may be used by others (C128, or even C64) later.)


* <strike>option -symkeymap <name> - set "KeymapUserSymFile" to <name></strike> (done)
To clearify: "KeymapSymFile" and "KeymapPosFile" should NOT get modified directly by the menu anymore, this is replaced by "KeymapIndex", "KeyboardMapping" and "KeyboardType" respectivly.
* <strike>option -poskeymap <name> - set "KeymapUserPosFile" to <name></strike> (done)
 
=== add ===


* option -keyboardtype - set "KeyboardType" (machine specific)
== misc ==
* option -keyboardmapping - set "KeyboardMapping" (host specific)


=== remove ===
* more keymaps should use !INCLUDE - eg probably all maps for C64DTV and SCPU64 can be blank files that simply include the respective C64 maps. also non US maps could include the US maps and then add/patch the few keys that are different. that way things should get more consistent and easier to maintain.


resources: KeymapSymDeFile, KeymapBusinessUKSymFile, KeymapBusinessUKPosFile, KeymapGraphicsSymFile, KeymapGraphicsPosFile, KeymapBusinessDESymFile, KeymapBusinessDEPosFile
* the virtual keyboard handling of the SDL port must be updated/fixed to support all PET keyboards


options: -symdekeymap, -buksymkeymap, -bukposkeymap, -grsymkeymap, -grposkeymap, -bdesymkeymap, -bdeposkeymap
[[Category:Developer]]
[[Category:DONE]]

Latest revision as of 18:30, 23 March 2023

Reason for this page: handling auf keymaps was a bit messy in some places in the past, unnecessary complex to maintain (eg hardcoded filenames in archdep code dont make updating a lot easier). It has been reworked to handle everything at one central place, with a minimum set of resources which are valid for all emulators. This will make both adding new keyboard types and updating the respective ports easier in the future. At the same time a somewhat more sane default behaviour that always works "as expected" automatically will be achived, based on the general assumption that the casual user never even wants to be bothered with setting up keymaps at all :)

considerations

  • host (pc) keyboards have a "machine" and "locale" type. the "machine" type is defined by the port (windows, x11, sdl etc) and the "locale" type by what type of keyboard the user has connected (we currently have different maps for US, DE, UK, FI, NO, DA etc... keyboards)
  • emulated keyboards have a "positional" and a "symbolic" type. the former referring to the actual hardware (keyboard matrix and key positions) and the later referring to what is actually written on the keycaps. (for example the localized c128 keyboards would all have the same "positional" type, but different "symbolic" types. fortunately the total combinations of these is small, so we can define one type per such combination.
  • we support two fundamentally different type of keyboard mappings, "symbolic" and "positional".

implementation

resources

  • "KeymapIndex" - (integer) selects active keymap (default:0) (0: symbolic, 1: positional, 2: user defined symbolic, 3: user defined positional)
  • "KeymapSymFile" - (string) name of the keymap to use for symbolic mapping (default:automatically set, see below)
  • "KeymapPosFile" - (string) name of the keymap to use for positional mapping (default:automatically set, see below)
  • "KeymapUserSymFile" - (string) name of user defined symbolic keymap (default: "<port>_sym.vkm")
  • "KeymapUserPosFile" - (string) name of user defined positional keymap (default: "<port>_pos.vkm")
  • "KeyboardType" - (Integer) emulated keyboard type. (default:0)
    • C128 0: International, 1: Finnish,French, 3: German, 4: Italian, 5: Norwegian, 6: Swedish (not used by x128 yet)
    • PET: (pet-resources.h) 0 "buus" 1: "buuk" 2: "bude" 3: "bujp" 4: "grus"
    • others: always 0
This resource will get updated when the machine model changes, and can be individually updated in the user interface.

NOTE: more info on local keyboard variants wanted, what about CBM2, C64... some VIC20 info here

  • "KeyboardMapping" - (integer) host keyboard layout type (default:0)
    • 0 American (us) suffix: ""
    • 1 British "uk"
    • 2 German "de"
    • 3 Danish "da"
    • 4 Norwegian "no"
    • 5 Finnish "fi"
    • 6 Italian "it"
this list may be expanded as needed

NOTE: suggestions for more languages that we should add as a default here wanted...

command line options

  • "-keymap" - sets "KeymapIndex" (and loads keymap indirectly)
  • "-keyboardtype" - sets "KeyboardType" (and loads keymap indirectly)
  • "-keyboardmapping" - sets "KeyboardMapping" (and loads keymap indirectly)
  • "-symkeymap" sets "KeymapUserSymFile" directly
  • "-poskeymap" sets "KeymapUserPosFile" directly

defaults

  • when the emulator starts and finds "KeymapSymFile" and "KeymapPosFile" empty,
    • an archdep function is called which returns the type of keyboard connected -> src/arch/<port>/archdep*: kbd_arch_get_host_mapping()
    • "KeyboardMapping" is initialized with that value, and the resulting keymap loaded (done)

The goal is to automatically configure and load the right keyboard map for a given combination of host OS/language/layout and emulated system.

loading the keymap

a central function which is called if any of "KeymapIndex", "KeyboardType", "KeyboardMapping" changed handles loading the new keymap. -> keyboard.c:switch_keymap_file()

  • if "KeymapIndex" is not 0 or 1, then load the respective user keymap and skip any further automatic actions
  • else try loading a keymap with the filename constructed as below.
  • if that fails, find a proper fallback:
    • if a positional map is not available, not much can be done other than switching to symbolic mapping instead, so do that...
    • remove the <mapping> part from the filename, ie try to load <port>_<type>_sym.vkm (for ports that have more than one emulated keyboard type, this MUST exist)
    • as last resort, always use <port>_sym.vkm (which MUST exist)
  • generally after loading update "KeymapIndex", "KeyboardType", "KeyboardMapping" and "KeymapSymFile"/"KeymapPosFile" to reflect the keymap that was actually loaded

constructing the filename

-> keyboard.c:try_set_keymap_file()

generally the filename of a keymap will be constructed according to this scheme:

<port>_<type>_<idx>_<mapping>.vkm

where:

  • <port> is a string constant defined in archdep code (eg "x11", "sdl", "win" etc) -> KBD_PORT_PREFIX in src/arch/<port>/kbd.h
  • <type> is a string returned by a machine specific function. this function should return NULL if the type string would be empty (the machine has no keyboard types) else eg "bkuk", "gkuk", "bkde" etc. (the returned string should be no more than 4 characters) -> machine_get_keyboard_type_name()
  • <idx> is a string derived from "KeymapIndex", where 0 is "sym" and 1 is "pos"
  • <mapping> is a string derived from "KeyboardMapping", where 0 is an empty string and 1 is "de" (... 2: "fi" 3: "se" etc if needed)

(this should in many cases not even require renaming any .vkm files)

  • a solution must be found for targets that only support 8.3 filenames, sth like
    • if "<type><idx><mapping>" is 4 characters (or less), use <port>_<type><idx><mapping>.vkm
      • else:
        • get short <port> string from constant defined in archdep code (max 2 characters, eg "md" for msdos)
        • get short <type> string from a machine specific function. this function should return an empty string if "KeyboardType" is 0 (else eg "buk", "guk", "bde" etc) (the returned string should be no more than 3 characters)
        • <idx> is a string derived from "KeymapIndex", where 0 is "s" and 1 is "p"
        • use <port><type><idx><mapping>.vkm

migrating the code

add

TODO: generate description for command line options at runtime (query available options in a similar way as the UIs)

  • archdep function "int kbd_arch_get_host_mapping(void)" (query host keyboard mapping and return one of the KBD_MAPPING_xx constants defined in keyboard.h. If for whatever reason determining the layout is not possibly, always return KBD_MAPPING_US)

update menus

after the change, all user interfaces should have the following options:

  • "set keymapping" - select between "symbolic", "positional", "symbolic (user)", "positional (user) and change "KeymapIndex" accordingly (see keyboard.h)
  • "set keyboard layout" - available keyboard layouts can be queried by using keyboard.h:keyboard_get_num_mappings() and keyboard_get_info_list(). generate menu dynamically and set up "KeyboardMapping" accordingly (see keyboard.h)
  • "define user-defined symbolic keymap" - set up "KeymapUserSymFile"
  • "define user-defined positional keymap" - set up "KeymapUserPosFile"

additionally for machines which have more than one type of keyboard (this should go into model selection somewhere):

  • "set keyboard type" - available keyboard types can be queried using machine.h:machine_get_num_keyboard_types() and machine_get_keyboard_info_list(). generate menu dynamically set up "KeyboardType" accordingly. (this is currently only used by PET but may be used by others (C128, or even C64) later.)

To clearify: "KeymapSymFile" and "KeymapPosFile" should NOT get modified directly by the menu anymore, this is replaced by "KeymapIndex", "KeyboardMapping" and "KeyboardType" respectivly.

misc

  • more keymaps should use !INCLUDE - eg probably all maps for C64DTV and SCPU64 can be blank files that simply include the respective C64 maps. also non US maps could include the US maps and then add/patch the few keys that are different. that way things should get more consistent and easier to maintain.
  • the virtual keyboard handling of the SDL port must be updated/fixed to support all PET keyboards