Strona 1 z 1

symulacje klawiszy

: 28 października 2007, 11:33
autor: Chodak
Witam. Musze napisac program w C++ symulujacy naciskanie odpowiednich przyciskow na klawiaturze. Znalazlem XSendEvent() ale nie bardzo umiem go wykorzystac, potrzebuje czegos jak 'keybd_event' na windows. Jesli ktos wie jak to zrobic to prosze o przykladowy kod (np klawisze ALT+TAB).

pozdrawiam

: 29 października 2007, 19:21
autor: db

Kod: Zaznacz cały

#include <stdio.h>

#include <X11/Xlib.h>

#include <X11/Xutil.h>

#include <X11/Xresource.h>

#include <X11/cursorfont.h>

#include <X11/Xos.h>

#include <X11/keysym.h>

#define BUFLEN 64

int isModifier(KeySym k) {

switch (k) {

case XK_Shift_L:

case XK_Shift_R:

case XK_Control_L:

case XK_Control_R:

case XK_Caps_Lock:

case XK_Shift_Lock:

case XK_Meta_L:

case XK_Meta_R:

case XK_Alt_L:

case XK_Alt_R:

case XK_Super_L:

case XK_Super_R:

case XK_Hyper_L:

case XK_Hyper_R:

return -1;

default:

break;

}

return 0;

}

 

int getModifierMask(KeySym k) {

switch (k) {

case XK_Shift_L:

case XK_Shift_R:

return ShiftMask;

case XK_Control_L:

case XK_Control_R:

return ControlMask;

case XK_Alt_L:

case XK_Alt_R:

return Mod1Mask;

case XK_Caps_Lock:

case XK_Shift_Lock:

case XK_Meta_L:

case XK_Meta_R:

case XK_Super_L:

case XK_Super_R:

case XK_Hyper_L:

case XK_Hyper_R:

default:

break;

}

return 0;

}

int main(int argc, char* argv[]) {

Display *display;

Window window;

int xerr;

XEvent xkey;

char ksBuf[BUFLEN];

KeySym keysym;

int statemask = 0;

if (argc != 3) {

fprintf(stderr, "Usage: %s windowId keySym\n", argv[0]);

exit(2);

}

if (sscanf(argv[1], "%lx", &window) != 1) {

fprintf(stderr, "Invalid windowId %s\n", argv[1]);

exit(2);

}

if ((display = XOpenDisplay(":0")) == NULL) {

printf("failed to open display\n");

exit(2);

}

char sepchar[2]=" +";

char *curkey = strtok(argv[2], sepchar);

do {

keysym = XStringToKeysym(curkey);

if (keysym == NoSymbol) {

fprintf(stderr, "Invalid keysym %s\n", curkey);

XCloseDisplay(display);

exit(2);

} else {

if(isModifier(keysym) == -1) {

xkey.xkey.state = getModifierMask(keysym);

} else {

xkey.xkey.keycode = XKeysymToKeycode(display, keysym);

}

}

} while( ( curkey = strtok(NULL, sepchar)) != NULL ) ;

xkey.xkey.state |= statemask;

xkey.type = KeyPress;

xkey.xkey.type = KeyPress;

xkey.xkey.display = display;

xkey.xkey.window = window;

xkey.xkey.subwindow = None;

xkey.xkey.x = xkey.xkey.y = xkey.xkey.x_root = xkey.xkey.y_root = 0;

xkey.xkey.same_screen = True;

xkey.xkey.root = DefaultRootWindow(display);

if ((xerr = XSendEvent(display, window, 0, False, &xkey)) == 0) {

printf("%s: failed to send (return code %d).\n", argv[0], xerr);

exit(1);

}

xkey.type = KeyRelease;

xkey.xkey.type = KeyRelease;

if ((xerr = XSendEvent(display, window, 0, False, &xkey)) == 0) {

printf("%s: failed to send (return code %d).\n", argv[0], xerr);

exit(1);

}

XFlush(display);

XCloseDisplay(display);

} 
Znalezione w otchłaniach dysku. Kompiluj z -lX11.

Numery okien pięknie podaje xwininfo.

: 31 października 2007, 22:18
autor: Chodak
OK pobawie sie. Wielkie dzieki :)

pozdrawiam

: 19 sierpnia 2009, 16:01
autor: czarnymurzyn
Witam potrzebuje dokładnie taki sam program jak Chodak. Problem polega na tym, że nie można tego zrobić w Bashu a ja nie znam C++ :-/ Znalazlem opis kompilacji w internecie (przez polecenie g++ plik.cpp) przy próbie skompilowania wystepowały błedy wiec dodałem jescze include: cstring oraz cstdlib. Liczba błędów zmalala obecnie wyswietla:

Kod: Zaznacz cały

plik.cpp: In function ‘int main(int, char**)’:
plik.cpp:155: error: initializer-string for array of chars is too long
Co muszę zrobić by ten błąd zniknął? Z góry dziękuje za pomoc.

PS. Chodzi mi o taki pogram niestety ten nie jest na Linuxa, a Wine odpada (na architekturze Power PC).

: 20 sierpnia 2009, 08:33
autor: grzesiek
To znaczy, że do tablicy napisów został przypisany ciąg znaków dłuższy niż przewiduje to deklaracja tablicy. Ma to miejsce w kodzie jeszcze przed kompilacją. Pokaż kod to zobaczymy jak to rozwiązać.

: 20 sierpnia 2009, 11:42
autor: czarnymurzyn
Kod skopiowałem z góry tzn. ten napisany przez użytkownika db aby dodać include: cstring oraz cstdlib, czyli po prostu tak teraz wygląda:

Kod: Zaznacz cały

#include <cstring>

#include <cstdlib>

#include <stdio.h>

#include <X11/Xlib.h>

#include <X11/Xutil.h>

#include <X11/Xresource.h>

#include <X11/cursorfont.h>

#include <X11/Xos.h>

#include <X11/keysym.h>

#define BUFLEN 64

int isModifier(KeySym k) {

switch (k) {

case XK_Shift_L:

case XK_Shift_R:

case XK_Control_L:

case XK_Control_R:

case XK_Caps_Lock:

case XK_Shift_Lock:

case XK_Meta_L:

case XK_Meta_R:

case XK_Alt_L:

case XK_Alt_R:

case XK_Super_L:

case XK_Super_R:

case XK_Hyper_L:

case XK_Hyper_R:

return -1;

default:

break;

}

return 0;

}

 

int getModifierMask(KeySym k) {

switch (k) {

case XK_Shift_L:

case XK_Shift_R:

return ShiftMask;

case XK_Control_L:

case XK_Control_R:

return ControlMask;

case XK_Alt_L:

case XK_Alt_R:

return Mod1Mask;

case XK_Caps_Lock:

case XK_Shift_Lock:

case XK_Meta_L:

case XK_Meta_R:

case XK_Super_L:

case XK_Super_R:

case XK_Hyper_L:

case XK_Hyper_R:

default:

break;

}

return 0;

}

int main(int argc, char* argv[]) {

Display *display;

Window window;

int xerr;

XEvent xkey;

char ksBuf[BUFLEN];

KeySym keysym;

int statemask = 0;

if (argc != 3) {

fprintf(stderr, "Usage: %s windowId keySym\n", argv[0]);

exit(2);

}

if (sscanf(argv[1], "%lx", &window) != 1) {

fprintf(stderr, "Invalid windowId %s\n", argv[1]);

exit(2);

}

if ((display = XOpenDisplay(":0")) == NULL) {

printf("failed to open display\n");

exit(2);

}

char sepchar[2]=" +";

char *curkey = strtok(argv[2], sepchar);

do {

keysym = XStringToKeysym(curkey);

if (keysym == NoSymbol) {

fprintf(stderr, "Invalid keysym %s\n", curkey);

XCloseDisplay(display);

exit(2);

} else {

if(isModifier(keysym) == -1) {

xkey.xkey.state = getModifierMask(keysym);

} else {

xkey.xkey.keycode = XKeysymToKeycode(display, keysym);

}

}

} while( ( curkey = strtok(NULL, sepchar)) != NULL ) ;

xkey.xkey.state |= statemask;

xkey.type = KeyPress;

xkey.xkey.type = KeyPress;

xkey.xkey.display = display;

xkey.xkey.window = window;

xkey.xkey.subwindow = None;

xkey.xkey.x = xkey.xkey.y = xkey.xkey.x_root = xkey.xkey.y_root = 0;

xkey.xkey.same_screen = True;

xkey.xkey.root = DefaultRootWindow(display);

if ((xerr = XSendEvent(display, window, 0, False, &xkey)) == 0) {

printf("%s: failed to send (return code %d).\n", argv[0], xerr);

exit(1);

}

xkey.type = KeyRelease;

xkey.xkey.type = KeyRelease;

if ((xerr = XSendEvent(display, window, 0, False, &xkey)) == 0) {

printf("%s: failed to send (return code %d).\n", argv[0], xerr);

exit(1);

}

XFlush(display);

XCloseDisplay(display);

} 
Szczerze mówiąc nie bardzo wiem o co w nim chodzi i jak będzie wyglądał ten program. C++? Znam tylko powierzchownie ale jeśli chodzi o deklaracje wielkości tablicy to może wystarczy aby ją powiększyć? Niestety nie mogę znaleźć tej deklaracji w kodzie, więc nie wiem jak rozwiązać ten problem.

: 20 sierpnia 2009, 13:57
autor: grzesiek
zamień
#define BUFLEN 64
na
#define BUFLEN 128

: 20 sierpnia 2009, 15:18
autor: czarnymurzyn
Przepraszam za błędy, dobrze będę sprawdzał pisownie. Niestety program ma nadal ten błąd zmieniałem #define BUFLEN na 128 później wpisałem 512 i 1024 nadal to samo :-(

: 20 sierpnia 2009, 15:28
autor: grzesiek
a usuń
char ksBuf[BUFLEN];
i
#define BUFLEN 64
bo coś mi się zdaje, że to nigdzie indziej nie jest używane poza tym plikiem co podałeś.

: 20 sierpnia 2009, 15:38
autor: czarnymurzyn
Dzięki grzesiek, za zainteresowanie. Udało mi sie skompilować ten program, wystarczyło zmienić:

Kod: Zaznacz cały

char sepchar[2]=" +"; 
na:

Kod: Zaznacz cały

char sepchar[3]=" +";
Ten program ma małe możliwości, nie obsługuje kombinacji klawiszy itp. Już mam inny - lepszy :mrgreen:
Gdyby ktoś szukał coś takiego to gotowy program o nazwie xvkbd jest w repozytorium ( można go obsługiwać również z poziomu konsoli.)