symulacje klawiszy

Potrzebujesz pomocy z C, C++, perl, python, itp.
Chodak
Posty: 12
Rejestracja: 28 października 2007, 11:17

symulacje klawiszy

Post 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
db
Beginner
Posty: 185
Rejestracja: 25 czerwca 2006, 15:23

Post 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.
Chodak
Posty: 12
Rejestracja: 28 października 2007, 11:17

Post autor: Chodak »

OK pobawie sie. Wielkie dzieki :)

pozdrawiam
czarnymurzyn
Posty: 8
Rejestracja: 04 sierpnia 2009, 11:51
Lokalizacja: WLKP

Post 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).
Awatar użytkownika
grzesiek
Junior Member
Posty: 932
Rejestracja: 06 stycznia 2008, 10:41
Lokalizacja: Białystok

Post 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ć.
czarnymurzyn
Posty: 8
Rejestracja: 04 sierpnia 2009, 11:51
Lokalizacja: WLKP

Post 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.
Awatar użytkownika
grzesiek
Junior Member
Posty: 932
Rejestracja: 06 stycznia 2008, 10:41
Lokalizacja: Białystok

Post autor: grzesiek »

zamień
#define BUFLEN 64
na
#define BUFLEN 128
czarnymurzyn
Posty: 8
Rejestracja: 04 sierpnia 2009, 11:51
Lokalizacja: WLKP

Post 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 :-(
Awatar użytkownika
grzesiek
Junior Member
Posty: 932
Rejestracja: 06 stycznia 2008, 10:41
Lokalizacja: Białystok

Post 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ś.
czarnymurzyn
Posty: 8
Rejestracja: 04 sierpnia 2009, 11:51
Lokalizacja: WLKP

Post 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.)
ODPOWIEDZ