Aktuelle Zeit: 18.08.2019 04:49

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 16:37 
Offline
Benutzeravatar

Registriert: 06.08.2005 22:56
Wohnort: Gernsbach
In meinem aktuellen PB Projekt Keyboard Mapper moechte ich implementieren, dass Tastatureingaben in das aktuell aktive Fenster einer fremden Anwendung gesendet werden. Unter Windows funktioniert das mit keybd_event_() aus der WinAPI. Gibt es unter Linux eine vergleichbare Funktion?

Ich moechte zwei Varianten implementieren: Senden von einfachen Tastatureingaben und Senden eines kompletten Strings (z.B. per Clipboard + Ctrl+V im aktiven Fenster).

Hat jemand eine Idee wie man das in PB unter Linux implementieren kann?

_________________
BildBildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 16:48 
Offline
Admin
Benutzeravatar

Registriert: 05.10.2006 18:55
Wohnort: Deutschland::Berlin()
Es gibt gdk_event_put_(). Damit kannst du auch Keycodes simulieren. Leider konnte ich in diesem Forum kein Beispielcode finden.

_________________
BildBildBildBild(Update: 17.08.2019 (+196 Dateien, +1392 MB)) BildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 16:49 
Offline
Benutzeravatar

Registriert: 06.08.2005 22:56
Wohnort: Gernsbach
OK, danke. Mal schauen ob ich damit weiter komme.

_________________
BildBildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 19:27 
Offline

Registriert: 25.03.2013 09:59
Hi Programie,

da Linux hier sehr widerborstig ist, schau Dir vielleicht mal wmctrl oder (vielleicht noch geeigneter) xdotool für Linux X11 an.
Kann sein dass Du hier schneller ans Ziel kommst.
Code:
;Ein paar Links zu xdotool ...
;http://manpages.ubuntu.com/manpages/xenial/man1/xdotool.1.html
;https://www.linux.org/threads/xdotool-keyboard.10528/
;http://xmodulo.com/simulate-key-press-mouse-movement-linux.html

Delay(2000)
;Klicke auf ein Fremdfenster ...
; Debug RunProgram ("xdotool", "getactivewindow key ctrl+Q", "");     schließt (meist) das aktive Fenster
Debug RunProgram ("xdotool", "getactivewindow key ctrl+Down", "");   scrollt (meist) das aktive Fenster nach unten
Gruß, Charly

_________________
PureBasic Linux-API-Library: http://www.chabba.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 19:36 
Offline
Benutzeravatar

Registriert: 06.08.2005 22:56
Wohnort: Gernsbach
OK, einen Aufruf von xdotool oder so mit RunProgram() wollte ich verhindern. Da kann man auch gleich alles mit einem Shell Script erschlagen. :mrgreen:

Ich hab da in der Zwischenzeit auch ein bischen mit gdk_event_put() experimentiert. Aber das Event wird wohl nur an die eigenen Fenster gesendet: https://mail.gnome.org/archives/gtk-app ... 00226.html

Hab da auch den Hinweis auf Xlib gefunden und mal damit experimentiert. Allerdings hab ich es noch nicht soweit geschafft, dass irgendein Fenster irgendetwas macht (nichtmal meine eigenen), stattdessen crasht meine Test Anwendung immer mit einem Invalid Memory Access. :cry:

_________________
BildBildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 21:13 
Offline
Benutzeravatar

Registriert: 06.08.2005 22:56
Wohnort: Gernsbach
So, habe es jetzt zumindest mal geschafft, dass mein Programm nicht mehr durch einen Invalid Memory Access crashed. Aber es funktioniert einfach nicht. Es kommen keine Tastatureingaben an (auch nicht in den StringGadgets von dem Programm selbst)...

Hier ist mein aktueller Stand:

Code:
EnableExplicit

ImportC ""
  gdk_screen_get_active_window(*screen)
  gdk_screen_get_default()
  gdk_x11_window_get_xid(*window)
EndImport

ImportC "-lX11"
  XOpenDisplay(*display)
  XSendEvent(display, xWindow, propagate, event_mask, event_send)
  XStringToKeysym(string.p-utf8)
  XFlush(display)
EndImport

Structure XKeyEvent
  type.i       ; KeyPress or KeyRelease
  serial.l     ; # of last request processed by server
  send_event.i ; true if this came from a SendEvent request
  *display     ; Display the event was read from
  window.i     ; ''event'' window it is reported relative to
  root.i       ; root window that the event occurred on
  subwindow.i  ; child window
  time.i       ; milliseconds
  x.i          ; pointer x coordinate in event window
  y.i          ; pointer y coordinate in event window
  x_root.i     ; x coordinate relative to root
  y_root.i     ; y coordinate relative to root
  state.i      ; key or button mask
  keycode.i    ; detail
  same_screen.i; same screen flag
EndStructure

Structure charcodemap
  key.w
  code.a
  symbol.l
  group.i
  modmask.i
  needs_binding.i
EndStructure

#KeyPressMask = 1
#KeyPress = 2
#KeyRelease = 3

Procedure SendKey(*display, *key.charcodemap, modstate)
  Protected *gdkWindow = gdk_screen_get_active_window(gdk_screen_get_default())
  Debug *gdkWindow
 
  Protected xWindow = gdk_x11_window_get_xid(*gdkWindow)
  Debug xWindow
 
  Protected mask = modstate | *key\modmask

  Protected keyEvent.XKeyEvent
  keyEvent\display = *display
  keyEvent\subwindow = 0
  keyEvent\time = 0
  keyEvent\same_screen = #True
 
  keyEvent\window = xWindow
  keyEvent\keycode = *key\code
  keyEvent\state = mask | *key\group << 13
 
  keyEvent\type = #KeyPress
  XSendEvent(*display, keyEvent\window, #True, #KeyPressMask, keyEvent)
  XFlush(*display)
 
  Delay(100)
 
  keyEvent\type = #KeyRelease
  XSendEvent(*display, keyEvent\window, #True, #KeyPressMask, keyEvent)
  XFlush(*display)
EndProcedure

Procedure SendKeyLoop(param)
  Protected *display = XOpenDisplay(0)
 
  Repeat
    Protected symbol = XStringToKeysym("A")
    Debug symbol
   
    Protected key.charcodemap
    key\code = 0
    key\symbol = symbol
    key\needs_binding = 1
    SendKey(*display, key, 0)
   
    Delay(1000)
  ForEver
EndProcedure

If OpenWindow(0, 0, 0, 500, 130, "Test", #PB_Window_ScreenCentered)
  StringGadget(0, 10, 10, 480, 30, "")
  StringGadget(1, 10, 50, 480, 30, "")
  StringGadget(2, 10, 90, 480, 30, "")
  SetActiveGadget(0)
  CreateThread(@SendKeyLoop(), 0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf


Einiges davon habe ich mir aus dem Code vom xdotool zusammengebastelt.

_________________
BildBildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 22:21 
Offline
Benutzeravatar

Registriert: 06.08.2005 22:56
Wohnort: Gernsbach
Habe es jetzt geschafft Tastatureingaben an das aktive Fenster zu senden. :D

Ganz einfach: mit XTestFakeKeyEvent (so macht es auch xdotool wenn das Zielfenster den Fokus hat)

Code:
EnableExplicit

ImportC "-lX11"
  XOpenDisplay(*display)
  XStringToKeysym(string.p-utf8)
  XKeysymToKeycode(*display, keysym)
  XFlush(display)
EndImport

ImportC "/usr/lib/x86_64-linux-gnu/libXtst.so.6"
  XTestFakeKeyEvent(display, keycode, is_press, delay)
EndImport

Procedure SendKeyLoop(param)
  Protected *display = XOpenDisplay(0)
 
  Repeat
    Protected symbol = XStringToKeysym("A")
    Protected code = XKeysymToKeycode(*display, symbol)
    Debug symbol
    Debug code
   
    XTestFakeKeyEvent(*display, code, #True, 0)
    XTestFakeKeyEvent(*display, code, #False, 0)
    XFlush(*display)
   
    Delay(1000)
  ForEver
EndProcedure

If OpenWindow(0, 0, 0, 500, 130, "Test", #PB_Window_ScreenCentered)
  StringGadget(0, 10, 10, 480, 30, "")
  StringGadget(1, 10, 50, 480, 30, "")
  StringGadget(2, 10, 90, 480, 30, "")
  SetActiveGadget(0)
  CreateThread(@SendKeyLoop(), 0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf


Was mich an dem Code aktuell noch stoert: Der absolute Pfad zur libXtst.so.6. Wenn ich nur den Dateiname ohne Pfad beim Import angebe bekomme ich einen Linker Error (gcc: error: libXtst.so.6: No such file or directory).

Allerdings funktioniert es mit OpenLibrary ohne absoluten Pfad. Eventuell werde ich einfach die Funktion mit einem Prototype + GetFunction ansprechen.

_________________
BildBildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 22:48 
Offline

Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge
@Programie

Klasse!

Nicht schlecht!

Programie hat geschrieben:
Was mich an dem Code aktuell noch stoert: Der absolute Pfad zur libXtst.so.6. Wenn ich nur den Dateiname ohne Pfad beim Import angebe bekomme ich einen Linker Error (gcc: error: libXtst.so.6: No such file or directory).


Ähm! Schon mal:

ImportC "-lXtst"
XTestFakeKeyEvent(display, keycode, is_press, delay)
EndImport

probiert ?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 22:51 
Offline
Benutzeravatar

Registriert: 06.08.2005 22:56
Wohnort: Gernsbach
ccode_new hat geschrieben:
Ähm! Schon mal:

ImportC "-lXtst"
XTestFakeKeyEvent(display, keycode, is_press, delay)
EndImport

probiert ?


Ah... soweit hab ich nicht gedacht. Aber damit funktioniert es, danke!

Was genau macht denn das "-l" beim Import? Das andere mit "-lX11" hab ich auch nur im englischen Forum gefunden.

_________________
BildBildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tastatureingaben an aktives Fenster senden
BeitragVerfasst: 02.12.2018 22:54 
Offline

Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge
Das -l ist Präfix für lib.

Ist eine C-Linker-Anweisung für den gcc-Linker (ld).


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye