Customizing key mapping for menu shortcuts
This topic includes the following sections:
- Files and environment variables used for key mapping
- Customizing with the key mapping utility (UNIX and OpenVMS)
- Modifying shortcut identifiers for menu entries defined in a script
- Redefining identifiers for shortcuts specified with MB_ENTRY
- Using keys.dbl to test shortcuts (UNIX and OpenVMS)
- Example
- Customizing reserved keys
Toolkit enables you to create menu shortcuts by mapping keys and key sequences to menu entries. As distributed, Toolkit contains default key mappings for most terminal types, but you can create custom mappings for individual keys and key sequences, and you can create sets of mappings (called key maps) for terminals and for users.
Key mappings are fixed on Windows. Only the text for a key map can be changed (the text that’s displayed next to the menu entry) because function codes on Windows are mapped to a native Windows accelerator table. If you use the key mapping utility to view the key map for Windows, you’ll see both the shortcuts and the shortcut text, but only the shortcut text can be changed. |
When a user presses a nonstandard key or key sequence during an input routine, Toolkit consults the key map, which is a set of shortcuts for the terminal or user, to see if there’s a mapping for the escape sequence it received. This is referred to as runtime terminal binding. If a mapping is found, Toolkit then looks at the menu definitions created by MB_ENTRY or .ENTRY to find a match. If there is a match, Toolkit loads the menu entry name into the g_entnam global variable and returns control to your application. If there is no key mapping for the escape sequence or match for the key mapping, Toolkit rings the keyboard bell and ignores the escape sequence.
Because of runtime terminal binding, your application can be made to handle input from various types of terminals and keyboards. In addition, you can enable your users to create their own shortcuts by including a call to the U_EDITKEYS routine in your application.
You can create shortcuts by doing the following:
- Specifying shortcuts in menu entry definitions. If you use .ENTRY or MB_ENTRY and use the ^key form to specify a shortcut, your shortcut is complete. On UNIX and OpenVMS, however, if you use .ENTRY and specify an arrow key or use the f# form for a shortcut, you must make sure the function code is mapped to a key or key sequence in the key map(s) that will be used with the application. (On Windows, functions codes are automatically mapped to a native Windows accelerator table.)
- Mapping keys in key maps. A key map is a set of shortcuts for a terminal or keyboard type. Key maps are stored in a Synergy database called a key map file (which is dtkmap.ism by default). The key map file as it’s distributed includes several key maps, but you can use the key mapping utility to add your own key maps, modify key maps, and delete key maps. See Customizing with the key mapping utility (UNIX and OpenVMS) for more information.
- Defining identifiers in the key mapping script file. Identifiers defined in the key mapping script file (which is keymap.ctl by default) can be used as the shortcut argument in .ENTRY definitions. This can make shortcut definitions in script files easier to understand. See Modifying shortcut identifiers for menu entries defined in a script for more information.
Note the following:
- Some keys and key sequences are reserved. Ctrl+M, for example, is reserved for carriage return, and it can’t be mapped to any other function. The other reserved keys and key sequences, which are listed in Customizing reserved keys can be mapped to other functions.
- If there are conflicts, entries in key maps override entries in the key mapping script file and shortcuts specified with .ENTRY or MB_ENTRY. Shortcuts specified with .ENTRY must not conflict with entries in the key mapping script file. If they do, errors will be generated when you generate the window libraries.
- Shortcut text (text displayed next to a menu entry) can be specified only in key maps. (Shortcut text specified with MB_ENTRY or the key mapping script file is ignored.)
Files and environment variables used for key mapping
The following files are used for key mapping.
File |
Purpose |
---|---|
inpctl.def |
Defines identifiers passed as the shortcut argument to MB_ENTRY. |
key map file |
Associates keys (escape sequences) with internal function codes. To locate this file, Toolkit looks first for the file and directory specified by DTKMAPFIL if that environment variable is set. Toolkit then looks for dtkmap.ism in the directory specified by DTKMAP if that’s set. If the file isn’t there or can’t be opened, Toolkit looks in the WND directory. |
key mapping script file |
As distributed, this file contains a copy of keymap.msw or keymap.vt depending on the operating system or terminal type. (See Modifying shortcut identifiers for menu entries defined in a script.) To locate the key mapping script file, Toolkit looks first for the directory and filename specified by DTKKEYCTLFIL if it’s set. If DTKKEYCTLFIL isn’t set, Toolkit looks for keymap.ctl in the current working directory. And if the file isn’t there, Toolkit looks for keymap.ctl in the WND directory. If Toolkit can’t find a key mapping script file, the only shortcuts supported by scripts are “F1” through “F63”. |
keymap.msw |
Contains shortcut identifier definitions for Windows systems. On Windows, keymap.ctl is a copy of this file. |
keymap.vt |
Contains shortcut identifier definitions for VT-style keyboards. On UNIX and OpenVMS, keymap.ctl is a copy of this file. |
keys.dbl |
Enables you to test menu shortcuts. See Using keys.dbl to test shortcuts (UNIX and OpenVMS). |
script file |
Assigns shortcuts or function codes to menu entries. (You create this. See Window Scripts for information.) |
window library |
Contains the shortcuts for menu entries. Proto and Script generate this from the script file and keymap.ctl. |
The following environment variables are used in key mapping:
Environment variable |
Purpose |
---|---|
Defines the location and name of the key mapping script file. If DTKKEYCTLFIL is not set, Toolkit looks for the default key mapping script file (keymap.ctl) in the current working directory or, if it’s not there, in the WND directory. To specify a different name or location, set DTKKEYCTLFIL to the full path and name of the file. |
|
Defines the location of the default key map file, dtkmap.ism. Use this environment variable if you want to change the location (but not the name) of the key map file. This setting is ignored if DTKMAPFIL is set. |
|
Defines the location and name of the key map file. By default, the key mapping file is named dtkmap.ism and is located in the WND directory. To specify a key map file with a different name or location, set DTKMAPFIL to the path and name of the file. This environment variable overrides DTKMAP. |
|
Specifies a key map for a terminal. The value of DTKTERM is used as the database key to locate the appropriate key map in the key map file (which is a database). For this purpose, DTKTERM overrides TERM. (It doesn’t override TERM as a setting for terminal capabilities on UNIX systems.) |
|
Specifies a key map for a terminal if DTKTERM is not defined. |
|
Specifies the default location of dtkmap.ism and keymap.ctl, among other things. |
a. If neither DTKTERM nor TERM is defined, Toolkit uses MSWINDOWS in Windows environments and VT100 elsewhere.
As distributed, the key map file (dtkmap.ism) includes the following key maps:
Key map name |
Terminal type |
---|---|
ANSI |
UNIX console |
GENERIC |
Unknown terminal type |
HFT |
IBM high-function terminal |
IBMPC |
PC |
MSWINDOWS |
Windows |
VT100 |
VTxxx terminal |
WY60 |
Wyse-60 and compatibles |
XTERM |
X-Windows terminals |
Customizing with the key mapping utility (UNIX and OpenVMS)
Because the key mapping utility modifies key maps for all Toolkit applications on UNIX and OpenVMS, including the key map utility itself, we recommend saving a copy of the original default key map file (WND:dtkmap.ism) with a different name before you open the key map utility or modify a key map. Then, if you make unwanted changes that you can’t undo, you can go back to the original key maps and start again. |
Running the key mapping utility
Open the key mapping utility by doing one of the following:
- Run Proto and select General > Key mapping.
- Run the Synergy UI Toolkit Control Panel and select Preferences > Key mapping.
You can also run this utility from your application by calling U_EDITKEYS.
Adding a key map for a terminal or user
Most terminals on UNIX and OpenVMS systems can emulate VT-style keyboards. If you use a terminal that doesn’t, you need to create a key map for that specific terminal type. You can also create a key map for a specific user.
You can create a key map from scratch (see below), or you can copy an existing key map, customize it, and then save it with a new name. (See Creating a new key map from an existing key map.)
Creating a key map from scratch
1. | Set the DTKTERM environment variable to the GENERIC key map. For example, |
SET DTKTERM=GENERIC
2. | Open the key mapping utility. (See Running the key mapping utility.) |
If you set DTKTERM for an environment, rather than setting it for the system, open the key mapping utility in the same environment. |
3. | The GENERIC (blank) key map is displayed. Select Key mapping> Add or change terminal type. |
5. | If a key map with that name doesn’t exist, enter Y at the “Do you wish to add it?” prompt, and press Enter. An empty key map layout is displayed. |
6. | If a key map with that name already exists, it is displayed. Select General > Exit. Then select Key mapping from the General or Preferences menu and start again at step 3. |
7. | Highlight the entry you want to modify. (Use the arrow keys to move around the key map and highlight key map entries.) Then press Enter. |
8. | In the Key Definition window, enter key map information. All fields are optional. |
- If the key map is for a keyboard type that is different than the type you are using, use the Codes fields to enter the ASCII code(s) for the key or key sequence you want to associate with the function.
- If the key map is for the type of keyboard you are now using, select Key mapping > Accept key sequence. This moves you to fields above the Codes fields. Here you can define the entry by pressing the actual key sequence (rather than by entering the ASCII code for the key sequence).
- To clear an entry in one of the Codes fields, press the spacebar when the entry is highlighted, and then press Enter to move to the next field.
- To clear an entry in the Key Sequence, Alternate #1, or Alternate #2 fields, press Enter when the entry is highlighted.
- To cancel changes in this window, select Key mapping > Cancel current changes.
Key Sequence/Codes
If you are on the Key Sequence line (rather than Codes), press the key or key sequence you want to associate with the function. (The key mapping utility automatically fills the Codes field with the characters for the corresponding ASCII codes.) Otherwise, in the Codes field, enter the ASCII code(s) for the key or key sequence you want to associate with the function.
Alternate #1/Codes
If you are on the Alternate #1 line (rather than Codes), press the key or key sequence you want to use as the alternate for the function. (The key mapping utility fills the Codes field with the characters for the corresponding ASCII codes.) Otherwise, in the Codes field, enter the ASCII code(s) for an alternate key or key sequence you want associated with the function.
Alternate #2/Codes
If you are on the Alternate #2 line (rather than Codes), press the key or key sequence you want to use as the second alternate for the function. (The key mapping utility fills the Codes field with the characters for the corresponding ASCII codes.) Otherwise, in the Codes field, enter the ASCII code(s) for a second alternate key or key sequence you want associated with the function.
Menu Shortcut Text
Enter the text you want to display in the menu column for the shortcut.
Note that for the Submenu Flag entry, you can edit only the Menu Shortcut Text field. This is because this entry defines the characters on UNIX and OpenVMS systems that mark a menu entry as having submenus. By default, the submenu flag is set to a dash and a greater-than symbol (->). (On Windows, this setting has no effect. Windows has its own, fixed submenu indicator.)
9. | Close the Key Definition window by selecting General > Exit or by pressing Enter while you are on the Menu Shortcut Text field. |
10. | Continue mapping key sequences to functions by repeating step 7 through step 9. When you’re finished assigning function codes, exit the key mapping utility by selecting General > Exit. |
11. | Enter Y at the “Save current changes to …?” prompt to save the key map with the specified name, or enter N to save it with a different name. Note that you can’t cancel changes at this point; you must save the key map. If you don’t want the key map, go ahead and save it; then follow the instructions in Deleting a key map for a terminal or user to delete it. |
12. | Test the key map by setting DTKTERM to the key map name (specified in step 4) and then running your application from a machine with a keyboard that the key map was designed for. |
If you created a key map for a specific user, set DTKTERM in the user’s environment before you test.
Creating a new key map from an existing key map
1. | Open the key mapping utility. (See Running the key mapping utility.) |
2. | Select Key mapping > Add or change terminal type. |
3. | Enter a name (with a maximum of 10 characters) for the new key map at the “Enter New Terminal Type to Modify” prompt. |
For example, if you are creating a key map for the IBM 3151 terminal, you could enter IBM3151. If you’re creating a key map for a specific user, you could enter something like SMITH_W_H.
4. | If a key map with that name doesn’t exist, enter Y at the “Do you wish to add it?” prompt, and press Enter. An empty key map layout is displayed. |
5. | If a key map with that name already exists, it is displayed. Unless you want to overwrite this key map, select General > Exit, and then select Key mapping from the General or Preferences menu and start again at step 2. |
6. | Select Key mapping > Copy terminal definition. |
7. | At the “Enter terminal type to copy from:” prompt, enter the name of the key map you want to use as the basis for the key map you are creating. |
The key map is displayed.
8. | Highlight an entry you want to modify. (Use the arrow keys to move around the key map and highlight key map entries.) Then press Enter. |
9. | In the Key Definition window, enter key map information. See step 8 in Creating a key map from scratch for details on entering data in these fields. |
10. | Close the Key Definition window by selecting General > Exit or by pressing Enter while you’re on the Menu Shortcut Text field. |
11. | Continue mapping key sequences to functions by repeating step 8 through step 10. When you’re finished assigning function codes, exit the key mapping utility by selecting General > Exit. |
12. | Enter N at the “Save current changes to …?” prompt. Then, enter a name for your new key map at the “Enter name of terminal to save current changes” prompt. You can use up to 10 characters. |
13. | Test the key map by setting DTKTERM to the key map name (specified in step 12) and then running your application from a machine with a keyboard that the key map was designed for. |
If you created a key map for a specific user, set DTKTERM in the user’s environment before you test.
Modifying an entry in a key map
1. | Open the key mapping utility. (See Running the key mapping utility.) |
2. | The default key map for your operating system or terminal is displayed. If you want to modify an entry in another key map, select Key mapping > Add or change terminal type. Then, at the “Enter New Terminal Type to Modify” prompt, enter the name of the key map you want to modify. |
3. | Highlight the entry you want to modify. (Use the arrow keys to move around the key map and highlight key map entries.) Then, press Enter. |
4. | In the Key Definition window, enter key map information. See step 8 in Creating a key map from scratch for details on entering data in these fields. |
5. | Close the Key Definition window by selecting General > Exit or by pressing Enter while you’re on the Menu Shortcut Text field. |
6. | Continue mapping key sequences to functions by repeating step 3 through step 5. When you’re finished assigning function codes, exit the key mapping utility by selecting General > Exit. |
7. | Enter Y at the “Save current changes to …?” prompt to save the key map with the specified name, or enter N to save it with a different name. You can’t cancel changes at this point; you must save the key map. If you don’t want the key map, go ahead and save it; then follow the instructions in Deleting a key map for a terminal or user below to delete it. |
8. | Test the key map by setting DTKTERM to the key map you specified in step 3 and then running your application from a machine with a keyboard that the key map was designed for. |
Deleting a key map for a terminal or user
1. | Open the key mapping utility. (See Running the key mapping utility.) |
2. | If you want to delete a key map other than the one that’s displayed in the Select Functions for… window, select Key mapping > Add or change terminal type. Then, at the “Enter New Terminal Type to Modify” prompt, enter the name of the key map you want to modify. |
3. | Select Key mapping > Delete terminal definition. |
4. | Enter Y at the “Delete key map for” prompt to delete the current key map or N to cancel. |
5. | To exit the “Enter New Terminal Type to Modify” prompt, select General > Exit. Select General > Exit a second time to exit the Key mapping utility. |
Customizing the submenu flag
By default on UNIX and OpenVMS systems, a right arrow symbol (->) is displayed next to menu entries that have submenu columns. (On Windows, the submenu flag setting has no effect. Windows has its own, fixed submenu indicator.)
1. | Open the key mapping utility. (See Running the key mapping utility.) |
2. | Use the arrow keys to move to the “Submenu Flag” entry and then press Enter. |
3. | In the Key Definition input window, enter the menu text you want to use for the submenu flag, and press Enter. |
4. | Select General > Exit to exit the Key mapping utility. |
Modifying shortcut identifiers for menu entries defined in a script
If you use script files to create menus, you can customize the way shortcuts for menu entries are defined in scripts by adding, deleting, or changing shortcut identifiers, which are defined in keymap.ctl. For example, to specify the Ctrl+I key combination as a shortcut, you use KEY(^i) because it adheres to one of the forms for shortcut definitions for KEY (listed in the .ENTRY Discussion). But what if you wanted to use KEY(inv) instead because the shortcut was for a menu entry that opened an inventory listing? You could do this by adding an identifier for the shortcut to keymap.ctl. In this case, you would add ^i=inv.
Note that if an identifier is defined for a shortcut in keymap.ctl, you can’t use that shortcut, rather than the identifier, in a KEY(shortcut) definition. For example, if you add ^i=inv to keymap.ctl, you can’t use KEY(^i) in a script; you must use KEY(inv) instead to assign the Ctrl+I key combination as a menu entry shortcut.
If you change keymap.ctl and leave it in the synergy\toolkit directory, be sure to make a copy of it with a different name or in a different location. UI Toolkit distributions install a keymap.ctl file to this directory, so installing a new version of Toolkit will overwrite any keymap.ctl file in this directory. |
1. | Open the keymap.* file you want to modify in a text editor. You can modify keymap.ctl directly, or you can modify keymap.msw (for Windows) or keymap.vt (for UNIX and OpenVMS) and then save the file as keymap.ctl or another name of your choosing (in step 3). |
2. | Add, change, or delete entries as needed. If you add or change entries, use the following format: |
shortcut=identifier
where shortcut is the internal function code and identifier is the identifier to use in KEY(shortcut) definitions for .ENTRY. Identifier must be unique and have no more than five characters.
As distributed, keymap.* files also contain definitions with the following formats:
Deprecated format |
Example |
---|---|
shortcut=(identifier) |
f1=(PF1) |
shortcut=identifier(text) |
f31=alt_q(“Alt-Q”) |
where text is ignored by Toolkit. (In early versions of Toolkit, text was used as shortcut text, which is the text that appears next to the menu entry. But now shortcut text can be defined only in key maps. For the first deprecated format above, identifier doubled as the shortcut text and the shortcut identifier.)
The following are true of all three formats:
- If you place multiple specifications on a single line, you must separate them with commas.
- Blank lines and lines that begin with a semicolon are ignored.
- If an identifier specification contains a blank or non-alphanumeric character, you must enclose identifier in quotation marks.
Redefining identifiers for shortcuts specified with MB_ENTRY
You can customize the way shortcuts for menu entries are defined in MB_ENTRY calls by creating and including a .def file that redefines and/or adds to the shortcut identifiers defined in inpctl.def. For example, if you use only the distributed version of inpctl.def and want to specify the Ctrl+I key combination as a shortcut, you must pass CTRL_I_KEY as the shortcut argument for MB_ENTRY, because that’s the identifier defined in inpctl.def for this key combination. But what if you are assigning this key combination to a menu entry that opens an inventory list, for example, and for more readable code you want to instead pass “INVENTORY_KEY” as the shortcut argument? You can do this by creating a .def file that includes the following definition and which could, in turn, include inpctl.def.
.define INVENTORY_KEY, CTRL_I_KEY
Note that on UNIX and OpenVMS, identifiers defined in inpctl.def must be set to function values defined in a key map file (dtkmap.ism by default). On Windows, use only the function values used in the distributed version of inpctl.def. These correspond to function values defined in the accelerator table for Toolkit on Windows.
Using keys.dbl to test shortcuts (UNIX and OpenVMS)
To verify that your key mapping is working correctly, use the keys.dbl file. Keys.dbl enables you to test your key mapping. To create the test program,
1. | Compile keys.dbl, and link the resulting file with tklib.elb (TKLIB_SH.EXE on OpenVMS). |
2. | If you made changes to keymap.ctl, make the same shortcut changes vtkeys.wsc. |
3. | Run Script to create a file called keys.ism from vtkeys.wsc. |
4. | Run the keys program by entering the following at the command prompt: |
dbr keys
Each menu entry in this program has a different shortcut key, and all 98 shortcuts are represented. You can use this program to test each shortcut.
Example
If your application runs on VT-style terminals, your script file could assign the HELP key to the menu entry O_HELP as follows:
.entry o_help, Help, key(help)
Keymap.ctl defines the following function code for the HELP key:
f15=Help
When you process the script file with Proto, Script, or Composer, the menu column is stored in a window library. The menu entry O_HELP is associated with the function code f15.
Because your application runs on VT-style terminals, you’ve set the DTKTERM environment variable to VT100. When your application calls the U_START subroutine, Toolkit opens the key map file and loads the key map for VT-style keyboards.
When you press the Help key during UI Toolkit input, the escape sequence ^[[28~ is generated. Toolkit searches the VT100 key map for this escape sequence. The key map associates this sequence with f15. Toolkit then looks through its list of placed menu entries to see if any of them use f15 (Help) as a shortcut. The shortcut for O_HELP matches, and O_HELP is returned in g_entnam. Figure 1 illustrates how the Help key would be mapped.
|
Customizing reserved keys
This section explains how to assign reserved keys to other functions and how to assign new keys for reserved functions.
UI Toolkit’s input processing uses four reserved functions. Each of these functions is tied to a specific key, as shown in the table below.
Function |
Key |
---|---|
Process Menu |
Ctrl+P or Alt (Windows) |
Screen Redraw |
Ctrl+R |
Delete Character |
Backspace (Ctrl+H) or Delete |
End of File |
Ctrl+D (UNIX) or Ctrl+Z (OpenVMS) |
Assigning reserved keys to other functions
You can use a reserved key for some other function either by assigning it directly as a shortcut or by entering it as the sequence for the function code in the key map. However, you will need to assign a new key to the reserved function.
Assigning new keys for reserved functions
If you want to use a different key for a reserved function, you need to write your own version of the EFKEY_METHOD subroutine. This subroutine enables you to remap any function codes, and you can name the subroutine anything you want. After you register it with the E_METHOD subroutine, UI Toolkit will call your subroutine whenever the user presses a function key or control character. (See Overloading UI Toolkit routines for more information on overloading a user-overloadable subroutine.)
The distributed include file inpctl.def defines the function codes for key mapping. EFKEY_METHOD is passed the function code that resulted from any interpretation of the key map. You can modify this function code and change it to any other code defined in inpctl.def. At the end of the list of defined codes, you may notice definitions for DELETE_KEY, PROCESS_MENU, SCREEN_REDRAW, and EOF_KEY. To assign these functions to a different key, you need to change the usual code generated by the desired keystroke to one of these codes in your EFKEY_METHOD subroutine.
For example, to make the F10 key process the menu and Ctrl+L redraw the screen, you’d write EFKEY_METHOD as follows:
subroutine efkey_method a_sts ,n ;Function code (incoming and returned) .include "WND:inpctl.def" proc case a_sts of begincase F10_KEY: a_sts = PROCESS_MENU ;Make F10 process the menu CTRL_L_KEY: a_sts = SCREEN_REDRAW ;Make ^L redraw the screen endcase xreturn endsubroutine