mirror of
https://github.com/bspeice/libcvautomation
synced 2025-07-02 06:16:49 -04:00
Integrate entering a key string from xautomation
This commit is contained in:
@ -17,6 +17,16 @@
|
||||
|
||||
#include <libcvautomation/libcvautomation-xtest.h>
|
||||
|
||||
/* The following includes are used only by the code brought in with xautomation.
|
||||
* As such, the rest of libcvautomation doesn't get access to them, which is why
|
||||
* they are included here, rather than in the header (so that all of libcvautomation
|
||||
* would end up including them). */
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
#include <libcvautomation/xautomation_kbd.h>
|
||||
#include <libcvautomation/xautomation_keysym_map.h>
|
||||
#include <libcvautomation/xautomation_multikey_map.h>
|
||||
|
||||
/* Note: The XLib documentation says that we shouldn't need to XFlush,
|
||||
* but I've found in testing that events don't get done correctly unless
|
||||
* we do. I've included the XFlush() calls. */
|
||||
@ -537,6 +547,125 @@ void xte_clickKey ( Display *displayLocation, char *key )
|
||||
XFlush( displayLocation );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* === FUNCTION ======================================================================
|
||||
* Name: xautomation_load_keycodes
|
||||
* Description: load_keycodes function from xte in xautomation
|
||||
* =====================================================================================
|
||||
*/
|
||||
void xautomation_load_keycodes ( Display *displayLocation )
|
||||
{
|
||||
int i_min_keycode, i_max_keycode, keysyms_per_keycode,keycode_index,wrap_key_index,num_modifiers;
|
||||
KeyCode min_keycode, max_keycode;
|
||||
char *str;
|
||||
KeySym *keysyms, keysym;
|
||||
KeyCode keycode;
|
||||
|
||||
XDisplayKeycodes( displayLocation, &i_min_keycode, &i_max_keycode);
|
||||
min_keycode = i_min_keycode;
|
||||
max_keycode = i_max_keycode;
|
||||
keysyms = XGetKeyboardMapping( displayLocation,
|
||||
min_keycode, max_keycode + 1 - min_keycode,
|
||||
&keysyms_per_keycode );
|
||||
|
||||
/* Clear tables */
|
||||
for( keysym=0; keysym<MAX_KEYSYM; keysym++ ) {
|
||||
keysym_to_modifier_map[keysym]=-1;
|
||||
keysym_to_keycode_map[keysym]=0;
|
||||
}
|
||||
|
||||
if( keysyms_per_keycode < NUM_KEY_MODIFIERS*2 ) {
|
||||
num_modifiers = keysyms_per_keycode;
|
||||
} else {
|
||||
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 );
|
||||
|
||||
if( keysym < MAX_KEYSYM &&
|
||||
keysym_to_modifier_map[ keysym ] == -1 ) {
|
||||
keysym_to_modifier_map[ keysym ] = wrap_key_index;
|
||||
keysym_to_keycode_map[ keysym ] = keycode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free storage */
|
||||
XFree(keysyms);
|
||||
|
||||
} /* ----- end of function xautomation_load_keycodes ----- */
|
||||
|
||||
|
||||
/*
|
||||
* === FUNCTION ======================================================================
|
||||
* Name: xautomation_send_char
|
||||
* Description:
|
||||
* =====================================================================================
|
||||
*/
|
||||
void xautomation_send_char ( Display *d, KeySym keysym )
|
||||
{
|
||||
/* The following code lovingly (and with full permission) ripped from
|
||||
* the 'xte' program as part of xautomation, and massaged to work with
|
||||
* libcvautomation. Find the original code at:
|
||||
* http://hoopajoo.net/projects/xautomation.html */
|
||||
|
||||
KeyCode keycode;
|
||||
char *wrap_key = NULL;
|
||||
int shift;
|
||||
|
||||
/* KeyCode and keyboard modifier lookup */
|
||||
keycode = keysym_to_keycode_map[keysym];
|
||||
shift = keysym_to_modifier_map[ keysym ]%2;
|
||||
wrap_key = key_modifiers[ (keysym_to_modifier_map[ keysym ]-shift)/2 ];
|
||||
|
||||
/* Generate key events */
|
||||
if( wrap_key != NULL )
|
||||
{
|
||||
KeySym wrap_keysym;
|
||||
wrap_keysym = XStringToKeysym(wrap_key);
|
||||
KeyCode wrap_keycode;
|
||||
wrap_keycode = XKeysymToKeycode( d, wrap_keysym);
|
||||
XTestFakeKeyEvent( d, wrap_keycode, True, CurrentTime );
|
||||
}
|
||||
if ( shift )
|
||||
{
|
||||
KeySym shift_keysym;
|
||||
shift_keysym = XStringToKeysym(shift_key);
|
||||
KeyCode shift_keycode;
|
||||
shift_keycode = XKeysymToKeycode( d, shift_keysym );
|
||||
XTestFakeKeyEvent( d, shift_keycode, True, CurrentTime );
|
||||
}
|
||||
XTestFakeKeyEvent( d, keycode, True, CurrentTime );
|
||||
XTestFakeKeyEvent( d, keycode, False, CurrentTime );
|
||||
if ( shift )
|
||||
{
|
||||
KeySym shift_keysym;
|
||||
shift_keysym = XStringToKeysym(shift_key);
|
||||
KeyCode shift_keycode;
|
||||
shift_keycode = XKeysymToKeycode( d, shift_keysym);
|
||||
XTestFakeKeyEvent( d, shift_keycode, False, CurrentTime );
|
||||
}
|
||||
if( wrap_key != NULL )
|
||||
{
|
||||
KeySym wrap_keysym;
|
||||
wrap_keysym = XStringToKeysym(wrap_key);
|
||||
KeyCode wrap_keycode;
|
||||
wrap_keycode = XKeysymToKeycode( d, wrap_keysym);
|
||||
XTestFakeKeyEvent( d, wrap_keycode, False, CurrentTime );
|
||||
}
|
||||
|
||||
/* Flushing after every key, thanks thorsten@staerk.de */
|
||||
XFlush( d );
|
||||
|
||||
} /* ----- end of function xautomation_send_char ----- */
|
||||
|
||||
/*
|
||||
* === FUNCTION ======================================================================
|
||||
* Name: xte_clickKeyStr
|
||||
@ -545,9 +674,81 @@ void xte_clickKey ( Display *displayLocation, char *key )
|
||||
*/
|
||||
void xte_clickKeyStr ( Display *displayLocation, char *string )
|
||||
{
|
||||
/* TODO: Write the code to implement a function that allows you to enter a string
|
||||
* at a time to X, rather than a single character.*/
|
||||
return;
|
||||
/* The following code lovingly (and with full permission) ripped from
|
||||
* the 'xte' program as part of xautomation, and massaged to work with
|
||||
* libcvautomation. Find the original code at:
|
||||
* http://hoopajoo.net/projects/xautomation.html */
|
||||
|
||||
static Bool didLoadKeyCodes = False;
|
||||
|
||||
if ( ! didLoadKeyCodes )
|
||||
{
|
||||
xautomation_load_keycodes( displayLocation );
|
||||
didLoadKeyCodes = True;
|
||||
}
|
||||
|
||||
int i,j;
|
||||
|
||||
KeySym keysym[2];
|
||||
|
||||
wchar_t string_s[ COMMAND_STR_LEN ];
|
||||
wchar_t wc_singlechar_str[2];
|
||||
|
||||
wmemset( string_s, L'\0', COMMAND_STR_LEN );
|
||||
mbstowcs( string_s, string, COMMAND_STR_LEN );
|
||||
wc_singlechar_str[ 1 ] = L'\0';
|
||||
i = 0;
|
||||
while( ( string[ i ] != L'\0' ) && ( i < COMMAND_STR_LEN ) ) {
|
||||
wc_singlechar_str[ 0 ] = string[ i ];
|
||||
|
||||
/* KeySym lookup */
|
||||
if (wc_singlechar_str[ 0] >= MAX_KEYSYM)
|
||||
keysym[0] = 0;
|
||||
else
|
||||
keysym[0] = wc_singlechar_str[ 0 ];
|
||||
keysym[1] = 0;
|
||||
if ( (keysym[0] == 0) || (keysym_to_keycode_map[keysym[0]] == 0) ) {
|
||||
// No keycode found -> try to find a Multi_key combination for this character
|
||||
keysym[0] = 0;
|
||||
for(j=0;j<MULTIKEY_MAP_SIZE;j++) {
|
||||
if (wc_singlechar_str[ 0 ] == multikey_map_char[ j ]) {
|
||||
/* Found */
|
||||
keysym[0] = multikey_map_first[j];
|
||||
keysym[1] = multikey_map_first[j];
|
||||
|
||||
if ((keysym_to_keycode_map[keysym[0]] == 0) || (keysym_to_keycode_map[keysym[1]] == 0)) {
|
||||
/* Character not supported */
|
||||
keysym[0] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym[0]) {
|
||||
if (keysym[1]) {
|
||||
/* Multi key sequence */
|
||||
XTestFakeKeyEvent( displayLocation,
|
||||
XKeysymToKeycode( displayLocation,
|
||||
XStringToKeysym( "Multi_key" )),
|
||||
True, CurrentTime );
|
||||
XTestFakeKeyEvent( displayLocation,
|
||||
XKeysymToKeycode( displayLocation,
|
||||
XStringToKeysym( "Multi_key" )),
|
||||
False, CurrentTime );
|
||||
|
||||
xautomation_send_char( displayLocation,keysym[0]);
|
||||
xautomation_send_char( displayLocation,keysym[1]);
|
||||
} else {
|
||||
/* Single key */
|
||||
xautomation_send_char( displayLocation,keysym[0]);
|
||||
}
|
||||
} else {
|
||||
fprintf( stderr, "Character '%ls' is not supported by your keyboard layout.\n", wc_singlechar_str );
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user