paul@tredysvr.Tredydev.Unisys.COM (Paul Siu) (01/11/91)
I have discovered the cause and a partial solution to the translation problem. The problem is related to the virtual binding as some usenet user suggested. I would like to go over the translation problem once again, this post will be a bit long, but people who are having problems with translation may want to read it. The translation manager allows user to modify behavior add new functionality to a widget. A typical translation entry looks something like this: <Key>q: quit() When the user press 'q' key, the action function quit() is called. The left side of the is the event that you want to trigger the action function. This event can be a button, a key, or other types of event. For this post, we will deal only with key events. The X-Window system represent the code generated by the keyboard as keycode, and represent the symbols on the keys as keysym. The association between keysym and keycode are store in the files "keysym.h", and "keysymdef.h". Both file can be found in the "/usr/include/X11" directory. A entry in the file looks something like this: #define XK_Return 0xFF0D Which basically means the keysym Return is defined as keycode 0xFF0D. When you press return, the keycode 0xFF0D is generated. Motif adds another layer of Keysym abstraction. Attempting to maintain some sort of programming consistancy among different keyboards, a number of virtual keysyms are define. The virtual keysym "osfHelp" for example is binded to the actual keysym "F1". The programmer use the virtual keysym in his or her program. When the program is run on a machine with no "F1", the user simply bind "osfHelp" to another key, running the program on the machine without any code changes. The binding entries can be store in a special file call ".motifbind", or it can be set in a resource "defaultVirtualBindings". There is also a default set of virtual bindings in case you do you want to change anything. You can find out more about this in P. I-89 of the Motif reference manual. A typical binding entry in ".motifbind" will look like this: osfHelp: <Key>F1 Note that virtually all the virtual binding keysym has the prefix "osf". What does this have to do with translation? When you specify a key event a translation entry, you will use the virtual keysym if they are available rather than using the actual keysym. Instead of specifying in your table: <Key>Delete: delete() You must instead specify: <Key>osfDelete: delete() This is because osfDelete is bind to the Delete key, and when you bind a virtual keysym to an actual keysym, the actual keysym disappear and can no longer be reference by the translation manager. I have no idea why this is so, and if it is a bug or not, but I find this very annoying. Additional problem develops when you attempt to rebind some of the keys. Assuming that your keyboard does not have a "F1" key, so you rebind "osfHelp" to "Escape". In the process of doing so, all of the default binding will become unbinded. Your "osfDelete" for example will no longer be bind to your "Delete" automatically. You must add entries to rebind every virtual keysym to an actual keysym. Virtual keysyms that are not rebind cannot be used. If rebinding "osfHelp" breaks the bind on "osfDelete", pressing the "osfDelete" key will not work until it is rebinded. It boils down to a few simple rules: 1. Motif binds virtual keysym to an actual keysym. After the binding, you can no longer reference the actual keysym directly in a translation entry, but you can reference the it indirectly through the virtual keysym. In any case, I think you are supposed to use the virtual keysym in place of the actual keysym 2. There exist a set of default virtual keysym which will become unbind if one or more virtual keysym are rebinded. When you rebind one keysym, you must rebind all. 3. There seems to be a problem with override. There are currently 3 methods to override the translation table. You can do this in the resource file, you can use XtSetArg(), and you can use XtOverrideTranslations(). According to definitioin, override is supposed to merge your tranlation table into the widget's translation table, overriding any overlaps. Unfortunately, the order after the merge seems a little rearranged. Let's look at an example of an override that failed. One of the text widget's translation entry is "KAny" (see XmText in Motif Ref), which basically stands for "<Key>" (see VirtualBindings in Motif Ref). Currently, "KAny" activates the action procedure self-insert(), it is placed as the last entry of the translation table, so it will not conflict with the other translation entries (It is a rule that you should always specify the more specific translation entry before the less specific.). Let say I override the "KAny" of the text widget by setting it to activate the function self-insert(), the text widget's behavior should remain unchanged because I simply override it with the same function. This does not happen, the text widget now self-inserts any key, as if it "KAny" had become the first entry in the text widget's translation table. This problem occur no matter which override method you choose. I have no idea of how to get around this short of using replacing the entire translation table. In any case, I said my 2 cents worth. All comments, and corrections will be welcome. Paul Siu paul@tredysvr.tredydev.unisys.com
ben@hpcvlx.cv.hp.com (Benjamin Ellsworth) (01/11/91)
> ... the text widget now self-inserts any key, as if it "KAny" had > become the first entry in the text widget's translation table. Because that is exactly what happened. > This problem occur no matter which override method you choose. I > have no idea of how to get around this short of using replacing the > entire translation table. Me neither.