Knowledge Base Nr: 00158 sendkeyslin.cpp - http://www.swe-kaiser.de
Downloads:
linux: relaykarte abfragen und auf eingänge mit programmaufrufen reagieren
z.b. tastendrücke an X schicken oder programme/scripte starten
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "CDIO.h"
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
#include <signal.h>
//sample call:
// .sendkeys 100 500 "./xte 100 500 'key A'" "./xte 'key B'" "./xte 'key X'" "./xte 'key Return'"
Display* ourXDisplay = 0;
Display* getXDisplay(const char* appName)
{
int ourEvent, ourError, ourMajor, ourMinor;
Display* ourDisplay = XOpenDisplay(0);
if (! ourDisplay) {
printf("\n ERROR: This program is made to be run in X Windows.\n\n");
exit(1);
}
if (! XTestQueryExtension(ourDisplay, &ourEvent, &ourError, &ourMajor, &ourMinor) )
{
printf("%s: ", appName);
printf("XServer %s doesn't support the Xtest extensions we need...\n", DisplayString(ourDisplay));
XCloseDisplay(ourDisplay);
exit(1);
}
printf("\nServer %s supports XTest (version %d.%d). Good.\n\n", DisplayString(ourDisplay), ourMajor, ourMinor);
XSync( ourDisplay, True);
return ourDisplay;
}
void doXKey(Display* ourDisplay, const int keyToSend)
{
printf("Taste '%d' senden\n", keyToSend);
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, True, CurrentTime);
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, False, CurrentTime);
}
void doShiftXKey(Display* ourDisplay, const int keyToSend)
{
printf("Taste Shift+'%d' senden\n", keyToSend);
KeySym ks = XStringToKeysym("Shift_L");
if( ks == NoSymbol )
{
printf("Unable to resolve keysym for 'Shift_L'\n");
return;
}
KeyCode kc = XKeysymToKeycode(ourXDisplay, ks );
printf("'Shift_L' maps to keysym '%d' / keycode '%d'\n", ks, kc);
XTestFakeKeyEvent(ourDisplay, (unsigned int)kc, True, CurrentTime); //Shift_L
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, True, CurrentTime);
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, False, CurrentTime);
XTestFakeKeyEvent(ourDisplay, (unsigned int)kc, False, CurrentTime); //Shift_L
}
void doAltXKey(Display* ourDisplay, const int keyToSend)
{
printf("Taste Alt+'%d' senden\n", keyToSend);
KeySym ks = XStringToKeysym("Alt_L");
if( ks == NoSymbol )
{
printf("Unable to resolve keysym for 'Alt_L'\n");
return;
}
KeyCode kc = XKeysymToKeycode(ourXDisplay, ks );
printf("'Alt_L' maps to keysym '%d' / keycode '%d'\n", ks, kc);
XTestFakeKeyEvent(ourDisplay, (unsigned int)kc, True, CurrentTime); //Alt_L
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, True, CurrentTime);
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, False, CurrentTime);
XTestFakeKeyEvent(ourDisplay, (unsigned int)kc, False, CurrentTime); //Alt_L
}
void doCtrlXKey(Display* ourDisplay, const int keyToSend)
{
printf("Taste Control+'%d' senden\n", keyToSend);
KeySym ks = XStringToKeysym("Control_L");
if( ks == NoSymbol )
{
printf("Unable to resolve keysym for 'Control_L'\n");
return;
}
KeyCode kc = XKeysymToKeycode(ourXDisplay, ks );
printf("'Control_L' maps to keysym '%d' / keycode '%d'\n", ks, kc);
XTestFakeKeyEvent(ourDisplay, (unsigned int)kc, True, CurrentTime); //Control_L
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, True, CurrentTime);
XTestFakeKeyEvent(ourDisplay, (unsigned int)keyToSend, False, CurrentTime);
XTestFakeKeyEvent(ourDisplay, (unsigned int)kc, False, CurrentTime); //Control_L
}
void cleanup(const int signal)
{
XCloseDisplay(ourXDisplay);
printf("\nExiting on signal.\n");
exit(0);
}
void sendKeyToX(char* szKeyCmd)
{
char szKeysym[50];
bool bAltKey = false;
bool bShiftKey = false;
bool bControlKey = false;
if (strstr(szKeyCmd, "Alt+") != 0)
{
strcpy(szKeysym, szKeyCmd+4);
bAltKey = true;
}
else if (strstr(szKeyCmd, "Shift+") != 0)
{
strcpy(szKeysym, szKeyCmd+6);
bShiftKey = true;
}
else if (strstr(szKeyCmd, "Control+") != 0)
{
strcpy(szKeysym, szKeyCmd+8);
bControlKey = true;
}
else
{
strcpy(szKeysym, szKeyCmd);
}
KeyCode kc;
KeySym ks;
ks = XStringToKeysym(szKeysym);
if( ks == NoSymbol )
{
printf("Unable to resolve keysym for '%s'\n", szKeysym);
return;
}
kc = XKeysymToKeycode(ourXDisplay, ks );
printf("String '%s' maps to keysym '%d' / keycode '%d'\n", szKeysym, ks, kc);
if (bAltKey)
doAltXKey(ourXDisplay, kc);
else if (bShiftKey)
doShiftXKey(ourXDisplay, kc);
else if (bControlKey)
doCtrlXKey(ourXDisplay, kc);
else
doXKey(ourXDisplay, kc);
}
int main(int argc, char **argv)
{
signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
if (argc < 3)
{
printf("usage: sendkeys entprellzeitinms tastaturwiederholrateinms \"cmd1 param1\" \"cmd2 param2\" ...\n"
"cmd kann z.b. sein:\n"
" key="Alt+F4\n"
" repkey=Up\n"
" cmd=xterm&\n"
"tastaturwiederholrateinms <= 0: keine wiederholfunktion\n\n");
return 0;
}
unsigned long nEntprellzeit = atoi(argv[1]);
unsigned long nWiederholzeit = atoi(argv[2]);
bool bKeyRepeat = (nWiederholzeit>0) ? true : false;
CDIO dio;
char szCmd[20][100] = { 0 };
printf("Entprellzeit: %d ms Wiederholzeit: %d ms\n", nEntprellzeit, nWiederholzeit);
nEntprellzeit *= 1000ul;
nWiederholzeit *= 1000ul;
int n;
for (n=3; n<=18; n++)
{
if (n<argc)
strcpy(szCmd[n-2], argv[n]);
else
strcpy(szCmd[n-2], "action_not_defined");
printf("szCmd[%d] = %s\n", n-2, szCmd[n-2]);
}
strcpy(szCmd[0], "input not mapped!");
int nRet = dio.InitCard();
if (nRet < 0)
{
printf("dio.InitCard() failed!");
}
ourXDisplay = getXDisplay(argv[0]);
while (1)
{
int nValue = dio.GetPort();
usleep(nEntprellzeit); //us
if (nValue>0)
{
int nValue2 = dio.GetPort();
usleep(nEntprellzeit); //usleep(nEntprellzeit); //us
int nValue3 = dio.GetPort();
usleep(nEntprellzeit); //usleep(nEntprellzeit); //us
//printf("values: %d %d %d\n", nValue, nValue2, nValue3);
if ((nValue == nValue2) && (nValue2 == nValue3))
{
printf("input: %d\n", nValue);
int nCmd = 0;
switch (nValue)
{
case 1: nCmd = 1; break;
case 2: nCmd = 2; break;
case 4: nCmd = 3; break;
case 8: nCmd = 4; break;
case 16: nCmd = 5; break;
case 32: nCmd = 6; break;
case 64: nCmd = 7; break;
case 128: nCmd = 8; break;
case 256: nCmd = 9; break;
case 512: nCmd = 10; break;
case 1024: nCmd = 11; break;
case 2048: nCmd = 12; break;
case 4096: nCmd = 13; break;
case 8192: nCmd = 14; break;
case 16384: nCmd = 15; break;
case 32768: nCmd = 16; break;
default: nCmd = 0;
}
if (nCmd>0)
{
if (strstr(szCmd[nCmd], "cmd=") != 0)
{
printf("command: <%s>\n", &szCmd[nCmd][4]);
system(&szCmd[nCmd][4]);
}
else if ((strstr(szCmd[nCmd], "key=") != 0) || (strstr(szCmd[nCmd], "repkey=") != 0))
{
bKeyRepeat = (strstr(szCmd[nCmd], "repkey=") != 0) ? true : false;
//file erzeugen für forms
char szFile[50];
sprintf(szFile, "/tmp/~key_%d", nCmd);
FILE* fp = fopen(szFile, "w");
if (fp)
{
fprintf(fp, "temp. file von sendkeys erzeugt.");
fclose(fp);
}
//key an X schicken
//key an X schicken
if (bKeyRepeat)
{
printf("key schicken: <%s>\n", &szCmd[nCmd][7]);
sendKeyToX(&szCmd[nCmd][7]);
}
else
{
printf("key schicken: <%s>\n", &szCmd[nCmd][4]);
sendKeyToX(&szCmd[nCmd][4]);
}
XFlush(ourXDisplay);
}
else
{
printf("illegal command (key=/cmd=): <%s>\n", szCmd[nCmd]);
}
}
if (bKeyRepeat)
{
usleep(nWiederholzeit); //us
}
else //warten bis losgelassen
{
while (nValue == nValue2)
{
nValue = dio.GetPort();
usleep(500*1000); //us
}
}
}
}
}
XCloseDisplay(ourXDisplay);
return 0;
}