Hi again,
I have rethought this matter and I have to revise the statements I've
made earlier. There are two different issues:
1) The implementation of the key-modifiers in load_keycodes() and
send_string() (which I have introduced originally...) is wrong.
Characters which require the use of the group modifier (AltGr) don't
work in the current version of xte. This is probably the problem the bug
reporter is experiencing.
2) Characters which can only be typed using the compose (Multi_key) are
currently not supported. Implementing this feature is not trivial. It
would require to look up the key combination somewhere (e.g. in
/usr/share/X11/locale/en_US.UTF-8/Compose). As mentioned earlier, using
the Multi_key explicitly is a workaround which should work in most
cases. In any case, there should be printed a proper warning/error when
such characters are encountered.
The attached patch addresses these issues and replaces the patch I have
submitted two days ago. I suggest to apply the patch to the upstream
version, as it is not Debian specific. The patch contains the following
changes:
1) All characters that can be typed using a group modifier (Mode_switch
or ISO_Level3_Shift [AltGr]) and/or the Shift key are supported now.
E.g. AltGr+2 = @ or AltGr+Shift+1 = ¡ with a Swiss German keyboard.
2) The following warning is displayed, when an unsupported character is
encountered (this prevents the reported 'BadValue' Xlib error):
Character '%ls' is currently not supported. Using key 'Multi_key'
could be a workaround.
3) The limitation regarding composed characters is now mentioned in the
manpage of xte and an example of a workaround is given:
BUGS
Special characters, which can only be typed using the compose key
(Multi_key), are currently not supported and can't be used in the
argument of the str command. A workaround is to split the string
in two parts and insert 'key Multi_key' in between. For example,
the command sequence
str na
key Multi_key
str "ive
will print 'naïve'.
Cheers,
Marco
--- kbd.h 2008-02-06 19:55:07.000000000 +0100
+++ kbd.h 2009-04-09 23:38:24.000000000 +0200
@@ -21,7 +21,8 @@
#define NUM_KEY_MODIFIERS 3
// ISO_Level3_Shift = AltGr
-char *key_modifiers[] = { NULL, "Shift_L", "ISO_Level3_Shift" };
+char *key_modifiers[] = { NULL, "Mode_switch", "ISO_Level3_Shift" };
+char *shift_key = "Shift_L";
#define MAX_KEYSYM 65536
// this maps what keysyms need a modifier pushed
--- xte.c 2008-03-17 16:12:49.000000000 +0100
+++ xte.c 2009-04-11 14:26:39.000000000 +0200
@@ -61,7 +61,7 @@ KeyCode thing_to_keycode( Display *d, ch
* except the special character 'Tab'. */
void send_string( Display *d, char *thing_in ) {
char *wrap_key = NULL;
- int i;
+ int i,shift;
KeyCode keycode;
KeySym keysym;
@@ -82,25 +82,34 @@ void send_string( Display *d, char *thin
/* keysym = wchar value */
keysym = wc_singlechar_str[ 0 ];
if( keysym >= MAX_KEYSYM ) {
- fprintf( stderr, "Special character '%ls' is currently not supported.\n", thing );
+ fprintf( stderr, "Special character '%ls' is currently not supported.\n", wc_singlechar_str );
}else{
/* Keyboard modifier and KeyCode lookup */
- wrap_key = key_modifiers[ keysym_to_modifier_map[ keysym ] ];
+ shift = keysym_to_modifier_map[ keysym ]%2;
+ wrap_key = key_modifiers[ (keysym_to_modifier_map[ keysym ]-shift)/2 ];
keycode = keysym_to_keycode_map[keysym];
-
- dmsg( 1, "Keycode: %d\n",
- keycode );
-
- if( wrap_key != NULL )
- XTestFakeKeyEvent( d, thing_to_keycode( d, wrap_key ), True, CurrentTime );
- XTestFakeKeyEvent( d, keycode, True, CurrentTime );
- XTestFakeKeyEvent( d, keycode, False, CurrentTime );
- if( wrap_key != NULL )
- XTestFakeKeyEvent( d, thing_to_keycode( d, wrap_key ), False, CurrentTime );
-
- /* Not flushing after every key like we need to, thanks
- * thors...@staerk.de */
- XFlush( d );
+ if ( keycode == 0 ) {
+ fprintf( stderr, "Character '%ls' is currently not supported. Using key 'Multi_key' could be a workaround.\n", wc_singlechar_str );
+ } else {
+
+ dmsg( 1, "Keycode: %d, Wrap key: %s, Shift: %d\n",
+ keycode, wrap_key, shift );
+
+ if( wrap_key != NULL )
+ XTestFakeKeyEvent( d, thing_to_keycode( d, wrap_key ), True, CurrentTime );
+ if ( shift )
+ XTestFakeKeyEvent( d, thing_to_keycode( d, shift_key ), True, CurrentTime );
+ XTestFakeKeyEvent( d, keycode, True, CurrentTime );
+ XTestFakeKeyEvent( d, keycode, False, CurrentTime );
+ if ( shift )
+ XTestFakeKeyEvent( d, thing_to_keycode( d, shift_key ), False, CurrentTime );
+ if( wrap_key != NULL )
+ XTestFakeKeyEvent( d, thing_to_keycode( d, wrap_key ), False, CurrentTime );
+
+ /* Not flushing after every key like we need to, thanks
+ * thors...@staerk.de */
+ XFlush( d );
+ }
}
i++;
@@ -203,23 +212,22 @@ void load_keycodes( Display *d ) {
keysym_to_keycode_map[keysym]=0;
}
- if( keysyms_per_keycode < NUM_KEY_MODIFIERS ) {
+ if( keysyms_per_keycode < NUM_KEY_MODIFIERS*2 ) {
num_modifiers = keysyms_per_keycode;
} else {
- num_modifiers = NUM_KEY_MODIFIERS;
+ num_modifiers = NUM_KEY_MODIFIERS*2;
}
for( keycode_index = 0; keycode_index < ( max_keycode + 1 - min_keycode ); keycode_index++ ) {
+ keycode = keycode_index + min_keycode;
for( wrap_key_index = 0; wrap_key_index < num_modifiers; wrap_key_index++ ) {
str = XKeysymToString( keysyms[ keycode_index * keysyms_per_keycode + wrap_key_index ] );
if( str != NULL ) {
keysym = XStringToKeysym( str );
- /* keycode = XKeysymToKeycode( d, keysym ); */
- keycode = keycode_index + min_keycode;
- dmsg( 2, "i=%d (keysym %lld), j=%d (keycode %d): %s\n",
- keycode_index, (long long int)keysym,
- wrap_key_index, keycode, str );
-
+ dmsg( 2, "keycode=%d + mod=%d => %s (keysym %lld)\n",
+ keycode, wrap_key_index,
+ str,(long long int)keysym );
+
if( keysym < MAX_KEYSYM &&
keysym_to_modifier_map[ keysym ] == -1 ) {
keysym_to_modifier_map[ keysym ] = wrap_key_index;
@@ -228,6 +236,9 @@ void load_keycodes( Display *d ) {
}
}
}
+
+ /* Free storage */
+ XFree(keysyms);
}
int main( int argc, char *argv[] ) {
--- xte.1 2008-02-06 19:55:07.000000000 +0100
+++ xte.1 2009-04-11 14:22:49.000000000 +0200
@@ -122,6 +122,8 @@
Alt_L
.br
Alt_R
+.br
+Multi_key
.SH SEE ALSO
.BR pat2ppm (1),
@@ -133,3 +135,18 @@
.SH AUTHOR
.B xte
was written by Steve Slaven <b...@hoopajoo.net>.
+
+.SH BUGS
+.PP
+Special characters, which can only be typed using the compose key
+(Multi_key), are currently not supported and can't be used in the
+argument of the \fBstr\fP command. A workaround is to split the
+string in two parts and insert '\fBkey\fP Multi_key' in between. For
+example, the command sequence
+
+ str na
+ key Multi_key
+ str "ive
+
+will print 'naïve'.
+