Linux - Wie Tastendruck an anderes Fenster?

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von theo »

mse hat geschrieben:Noch ein Tip:
Ich würde eine eigenes Testprogramm als Empfänger schreiben,


Zur Not tut's auch das Programm xev aus der Shell gestartet

_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_ »

xev kenn ich.
Aber ich hab es bis jetzt noch nicht geschafft überhaupt ne Taste zu Senden. :|

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:43, 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_ »

Ich kriegs nicht hin. :(
Beispielsource wäre hilfreich.

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 »

Ich werde versuchen, ein Beispiel zu schreiben, etwas Geduld bitte.

_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, ich werde warten.
Natürlich probier ich auch weiter.

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:45, 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 »

Untenstehender Code schickt auf buttonclick ein 'A' zum eigenen Fenster.

Code: Alles auswählen

procedure tmainfo.button1execute(const sender: TObject);
var
 event: txevent;
begin
 fillchar(event,sizeof(event),0);
 with event.xkey do begin
  _type:= keypress;
  window:= self.window.winid;
  root:= mserootwindow;
  keycode:= xkeysymtokeycode(msedisplay,ord('A'));
    //'A'..'Z' use ASCII numbers, see keysymdef.h
  state:= shiftmask;
    //simulate a pressed shift key, state is an ored combination
    //of Button1Mask, Button2Mask, Button3Mask, Button4Mask,
    //Button5Mask, ShiftMask, LockMask, ControlMask, Mod1Mask,
                     // Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
  xsendevent(msedisplay,window,true,keypressmask,@event);
  _type:= keyrelease;
  xsendevent(msedisplay,window,true,keyreleasemask,@event);
 end;
end;

Edit:
Für ein standalone Programm ohne laufende GUI eventloop braucht es noch XFlush.
Es wäre besser als timestamp eine mit dem Tastaturtreiber synchronisierte Zeit einzusetzen, keine Ahnung wie das gemacht werden könnte.
Zuletzt geändert von mse am So 1. Feb 2009, 09:23, 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_ »

Bei mir bring der Kompiler:

unit1.pas(35,16) Hint: Local variable "event" does not seem to be initialized
unit1.pas(37,19) Error: Wrong number of parameters specified for call to "KeyPress"
wincontrol.inc(4995,23) Hint: Found declaration: TWinControl.KeyPress(var Char)
unit1.pas(38,17) Error: identifier idents no member "window"
unit1.pas(39,23) Error: Identifier not found "mserootwindow"
unit1.pas(40,40) Error: Identifier not found "msedisplay"
unit1.pas(47,24) Error: Identifier not found "msedisplay"
unit1.pas(49,24) Error: Identifier not found "msedisplay"
unit1.pas(58) Fatal: There were 6 errors compiling module, stopping

msedisplay würde ich mit

Code: Alles auswählen

XOpenDisplay(nil);
setzen und mserootwindow mit

Code: Alles auswählen

XDefaultRootWindow(msedisplay);

Wie machst du das?
Wie ich den keypress-Fehler lösen soll weis ich nicht. Eigentlich ist ja gemeint das die Taste gedrückt werden soll.

mfg _X_
Zuletzt geändert von _X_ am So 16. Mai 2010, 19:45, 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 machst du das?

MSEgui stellt diese Werte zur Verfügung. Irgendwie solltest du auch unter Lazarus an die display connection des widgetset herankommen, da kann sicher ein Lazarus Spezialist mehr dazu sagen. KeyPress kommt scheinbar in twincontrol (welches in MSEgui nicht vorhanden ist) vor, die keypress Konstante ist in unit x, also:

Code: Alles auswählen

fillchar(event,sizeof(event),0);
 event._type:= x.keypress;
 with event.xkey do begin

x.keypress kann nicht im with statment geschrieben werden, da event.xkey ein "x" feld hat...
PS: habe gerade versucht auf ein fremdes Fenster zu schreiben, funktioniert. :-)

_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_ »

Ich zweifle nicht das es mit der MSEGui funktioniert, aber unter Lazarus bekomme ich es leider nicht zum laufen.

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

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von theo »

Für GTK2:

Code: Alles auswählen

unit Unit1;
 
{$MODE objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  xlib, x, gdk, StdCtrls;
 
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Edit1: TEdit;
    procedure Edit1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{ TForm1 }
 
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;
 
 
procedure TForm1.Edit1Click(Sender: TObject);
var winRoot, winFocus: TWindow;
  dpy: PDisplay;
  revert: integer;
  event: TXKeyEvent;
  KEYCODE: integer;
begin
  dpy := gdk_display;
  winRoot := XDefaultRootWindow(Pointer(dpy));
  XGetInputFocus(dpy, @winFocus, @revert);
  KEYCODE := ord('b');
  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;
 
initialization
{$I unit1.lrs}
 
end.
Zuletzt geändert von theo am Sa 31. Jan 2009, 23:08, 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_ »

Danke.
Damit ist mein Problem gelöst.
Vielen Dank. :D

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

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von theo »

Habe oben noch was in der uses geändert. Geht nämlich auch mit GTK1.

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
KeypressMask im zweiten XSendEvent sollte vermutlich KeyReleaseMask heissen. Da vermutlich alle potentiellen Empfänger sowohl KeypressMask als auch KeyReleaseMask gesetzt haben kommt es wohl nicht so sehr darauf an.

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von theo »

Da hast du wohl recht. Ich hab's ja auch nur bei dem da abgetippt: http://www.doctort.org/adam/nerd-notes/ ... event.html

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Linux - Wie Tastendruck an anderes Fenster?

Beitrag von mschnell »

Wäre natürlich schön, wenn es eine Library gäbe die solche Sachen Betriebssystem-unabhängig zur Verfügung stellt.

Gab es da nicht 'mal "Jedi" ( http://www.delphi-jedi.org/ ) zu genau diesem Zweck. Die wollten vor Jahren 'mal ihren Code Kylix- und FPC- kompatibel machen (von LCL ist aber wohl keine Rede).

Oder wäre es nicht eine vielleicht gute Sache solche Pascal-Funktionen (wie "sende Key-Event an Fenster") in Plattform-übergreifender Implementierung in eine zusätzliche Library oder die LCL selbst einzubringen ?

-Michael

Antworten