Linux - Wie Tastendruck an anderes Fenster?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mse »

theo hat geschrieben:Ich hab's ja auch nur bei dem da abgetippt:

Ich bin vorsichtig geworden mit dem Übernehmen von code Schnipseln. Meist ist es besser, die Sache selbst aufzubauen und aus den Beispielen lediglich Denkanstösse zu entnehmen.

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Code: Alles auswählen

function createKeyEvent(Display: Pdisplay; win: TWindow;
  winRoot: TWindow; press: Boolean;
  keycode: integer; modifiers: integer): TXKeyEvent;
var event: TXKeyEvent;
begin
  event.display := display;
  event.window := win;
  event.root := winRoot;
  event.subwindow := None;
  event.time := CurrentTime;
  event.x := 1;
  event.y := 1;
  event.x_root := 1;
  event.y_root := 1;
  event.same_screen := True;
  event.keycode := XKeysymToKeycode(display, keycode);
  event.state := modifiers;
 
  if press then
    event._type := KeyPress
  else
    event._type := KeyRelease;
 
  result := event;
end;
 
 
function SendKey(winFocus: TWindow; PKeyCode: integer): string;
var winRoot: TWindow;
  dpy: PDisplay;
  revert: integer;
  event: TXKeyEvent;
  KEYCODE: integer;
begin
  dpy := gdk_display;
  winRoot := XDefaultRootWindow(Pointer(dpy));
 
  //XGetInputFocus(dpy, @winFocus, @revert);
 
  KEYCODE := PKeyCode;
  event := createKeyEvent(dpy, winFocus, winRoot, true, KEYCODE, 0);
  XSendEvent(event.display, event.window, True, KeyPressMask, @event);
  event := createKeyEvent(dpy, winFocus, winRoot, false, KEYCODE, 0);
  XSendEvent(event.display, event.window, True, KeyPressMask, @event);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var ziel: integer;
begin
  ziel := 12345678; //ID von xev (geholt von xwininfo)
 
  SendKey(ziel, ord('h'));
  SendKey(ziel, ord('a'));
  SendKey(ziel, ord('l'));
  SendKey(ziel, ord('l'));
  SendKey(ziel, ord('o'));
end;
Funktioniert mit xev aber Wie kann ich an Firefox ne Taste senden.
Wenn ich mir die ID vom Firefox hohle, Bekomme ich ja nur die Fenster ID. Wie kann ich z.b. an ein Edit-Feld senden?
Ich Denke mal mit "xwininfo -tree" würde es gehen aber dann müsste ich ja jedes mal die ID suchen.

Gibt es eine andere Möglich mit der XLib?

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:41, insgesamt 1-mal geändert.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mse »

Ich sage ja es ist ein Murks! ;-)
Vermutlich wird ein edit widget die Tasten messages nur auswerten, wenn es den Eingabefocus hat. Also ist XGetInputFocus schon richtig. Nun ist das nächste Problem, dafür zu sorgen, dass das richtige widget den Focus hat. Besitzt denn Firefox keine Fernsteuerschnittstelle die du benützen könntest?

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Ob Firefox eine Schnittstelle zum Fernsteuern hat weiß ich nicht. Ich werde mal googeln! :wink:
Zu XGetInputFocus:
http://tronche.com/gui/x/xlib/input/XGetInputFocus.html
Wenn ich es so mache, wie es oben steht schreibt er immer ins eigene Fenster.
KA warum.

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:41, insgesamt 1-mal geändert.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mse »

_X_ hat geschrieben:Wenn ich es so mache, wie es oben steht schreibt er immer ins eigene Fenster.
KA warum.

Weil dein Fenster den Eingabefocus hat, du hast ja draufgeklickt.

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Ist schon klar. Ich habe ein sleep in den ganzen Code eingebaut und auf ein anderes Fenster geklickt, aber trotzdem sendet er ans eingene Fenster.

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:41, insgesamt 1-mal geändert.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mse »

Mach ein XFlush vor dem sleep. Die events sind erst in xlib zwischengespeichert, übertragen werden sie durch XFlush oder beim nächsten XNextEvent(). Durch das sleep Kommando wird XNextEvent() in der GUI event loop nicht mehr aufgerufen.

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Danke, funktioniert.

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:44, insgesamt 1-mal geändert.

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Wie krieg ich mit ord Großbuchstaben?

mfg _X_


edit:// Und was ist der Keycode für <tab>? Mit ord schreibt er einfach ins Feld einen Tab. Ich hätte aber gerne das er zum Nächsten Feld weiter springt.
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:42, insgesamt 1-mal geändert.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mse »

_X_ hat geschrieben:Wie krieg ich mit ord Großbuchstaben?

Setze die ShiftMask, siehe mein Beispiel.
Und was ist der Keycode für <tab>?

Schau in /usr/include/X11/keysymdef.h:

Code: Alles auswählen

/*
 * TTY function keys, cleverly chosen to map to ASCII, for convenience of
 * programming, but could have been arbitrary (at the cost of lookup
 * tables in client code).
 */

 
#define XK_BackSpace                     0xff08  /* Back space, back char */
#define XK_Tab                           0xff09
#define XK_Linefeed                      0xff0a  /* Linefeed, LF */
#define XK_Clear                         0xff0b
#define XK_Return                        0xff0d  /* Return, enter */
#define XK_Pause                         0xff13  /* Pause, hold */
#define XK_Scroll_Lock                   0xff14
#define XK_Sys_Req                       0xff15
#define XK_Escape                        0xff1b
#define XK_Delete                        0xffff  /* Delete, rubout */

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Den Tab krieg ich nicht hin!

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:42, insgesamt 1-mal geändert.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mse »

_X_ hat geschrieben:Den Tab krieg ich nicht hin!

Funktioniert bei mir. Zeig doch mal den code. Möglicherweise die ShiftMask angegeben?

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Code: Alles auswählen

unit afx;
 
interface
 
uses
  SysUtils, Process, StdCtrls, Classes, Forms, lclintf, xlib, x, gdk;
 
{$define XK_BackSpace                     0xff08}  // Back space, back char
{$define XK_Tab                           0xff09}
{$define XK_Linefeed                      0xff0a}  // Linefeed, LF
{$define XK_Clear                         0xff0b}
{$define XK_Return                        0xff0d}  // Return, enter
{$define XK_Pause                         0xff13}  // Pause, hold
{$define XK_Scroll_Lock                   0xff14}
{$define XK_Sys_Req                       0xff15}
{$define XK_Escape                        0xff1b}
{$define XK_Delete                        0xffff}  // Delete, rubout
 
procedure delay(msec:longint);
 
function createKeyEvent(Display: Pdisplay; win: TWindow; winRoot: TWindow; press: Boolean; keycode: integer; modifiers: string): TXKeyEvent;
function SendKey(winFocus: TWindow; PKeyCode: integer): string;
function SendKeyToActiveWindow(PTime: integer; PKeyCode: integer): string;
function SendStringToActiveWindow(PTime: integer; PString: string): string;
function DetectShiftState(ch: char): string;
 
 
implementation
 
procedure delay(msec:longint);
var
  start,stop:longint;
begin
  start := gettickcount;
  repeat
  stop := gettickcount;
  application.processmessages;
  until (stop - start ) >= msec;
end;
 
{=== Main ===}
 
function createKeyEvent(Display: Pdisplay; win: TWindow;
  winRoot: TWindow; press: Boolean;
  keycode: integer; modifiers: string): TXKeyEvent;
var event: TXKeyEvent;
begin
  event.display := display;
  event.window := win;
  event.root := winRoot;
  event.subwindow := None;
  event.time := CurrentTime;
  event.x := 1;
  event.y := 1;
  event.x_root := 1;
  event.y_root := 1;
  event.same_screen := True;
  event.keycode := XKeysymToKeycode(display, keycode);
  if modifiers = 'shift' then begin
      event.state := shiftmask;
  end
  else begin
      event.state := 0;
  end;
 
  if press then
    event._type := KeyPress
  else
    event._type := KeyRelease;
 
  result := event;
end;
 
 
function SendKey(winFocus: TWindow; PKeyCode: integer): string;
var winRoot: TWindow;
  dpy: PDisplay;
  revert: integer;
  event: TXKeyEvent;
  KEYCODE: integer;
  sh: string;
begin
  sh := DetectShiftState(chr(PKeyCode));
 
  dpy := gdk_display;
  winRoot := XDefaultRootWindow(Pointer(dpy));
 
  KEYCODE := PKeyCode;
  event := createKeyEvent(dpy, winFocus, winRoot, true, KEYCODE, sh);
  XSendEvent(event.display, event.window, True, KeyPressMask, @event);
  event := createKeyEvent(dpy, winFocus, winRoot, false, KEYCODE, sh);
  XSendEvent(event.display, event.window, True, KeyPressMask, @event);
end;
 
function SendKeyToActiveWindow(PTime: integer; PKeyCode: integer): string;
var winFocus, winRoot: TWindow;
  dpy: PDisplay;
  revert: integer;
  event: TXKeyEvent;
  KEYCODE: integer;
  sh: string;
begin
  sh := DetectShiftstate(chr(PKeyCode));
 
  dpy := gdk_display;
  winRoot := XDefaultRootWindow(Pointer(dpy));
 
  XFlush(dpy);
  delay(PTime);
 
  XGetInputFocus(dpy, @winFocus, @revert);
 
  KEYCODE := PKeyCode;
  event := createKeyEvent(dpy, winFocus, winRoot, true, KEYCODE, sh);
  XSendEvent(event.display, event.window, True, KeyPressMask, @event);
  event := createKeyEvent(dpy, winFocus, winRoot, false, KEYCODE, sh);
  XSendEvent(event.display, event.window, True, KeyPressMask, @event);
end;
 
function SendStringToActiveWindow(PTime: integer; PString: string): string;
var I: integer;
begin
 delay(PTime);
 
  for I:= 1 to length(PString) do begin
      SendKeyToActiveWindow(5, ord(PString[I]));
  end;
end;
 
function DetectShiftState(ch: char): string;
begin
  if ch in ['A'..'Z'] then begin
     result := 'shift';
  end
  else begin
     result := 'none';
  end;
end;
 
end.
So sieht's derzeit aus.
mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:44, insgesamt 1-mal geändert.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mse »

Den XK_TAB sehe ich nirgends in Verwendung?

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von _X_ »

Code: Alles auswählen

function DetectShiftState(ch: char): string;
begin
  if ch in ['A'..'Z'] then begin
     result := 'shift';
  end
  else begin
     result := 'none';
  end;
end;
Hier habe ich überhaupt Probleme, weil die ganzen Sonderzeichen auch noch erkannt werden müssen. ( ^°!"§$%&/()=? )
XK_Tab würde ich beim Aufruf verwenden

Code: Alles auswählen

SendStringToActiveWindow(5000, XK_TAB)

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:44, insgesamt 1-mal geändert.

Antworten