Aprire un Terminale e passargli una riga di comando mediante le funzioni esterne del API di X11

Da Gambas-it.org - Wikipedia.

Per passare ad un Terminale un comando, o comunque dei caratteri, con un'applicazione Gambas non in ambiente grafico (ma a riga di comando), si può far uso di alcune risorse del API della libreria di X11.

E' necessario richiamare inGambas ed avere installate nel sistema le librerie dinamiche condivise:

  • "libX11.so.6.4.0 "
  • "libXtst.so.6.1.0 "


Mostriamo un semplice esempio, nel quale si invierà ad un Terminale già aperto i due caratteri "l" e "s", così a formare il comando bash "ls". Tale riga potrà essere efficacemente utilizzata nel Terminale medesimo cliccando come di consueto sul tasto "Invio" della tastiera, e vederne così il risultato.

Library "libX11:6.4.0"

Private Const XK_l As Integer = &6C
Private Const XK_s As Integer = &73

' Display *XOpenDisplay(char *display_name)
' Opens a connection to the X server that controls a display.
Private Extern XOpenDisplay(display_name As Pointer) As Pointer

' KeyCode XKeysymToKeycode(Display *display, KeySym keysym)
' Uses internal Xlib tables and returns the KeyCode defined for the specified KeySym.
Private Extern XKeysymToKeycode(display As Pointer, keysym As Integer) As Integer

' int XCloseDisplay(Display *display)
' Closes the connection to the X server for the display specified in the Display structure and destroys all windows.
Private Extern XCloseDisplay(display As Pointer) As Integer


Library "libXtst:6.1.0"

' int XTestFakeKeyEvent(Display *display, unsigned int keycode, Bool is_press, unsigned long delay)
' Requests the server to simulate either a KeyPress (if is_press is True) or a KeyRelease of the key with the specified keycode.
Private Extern XTestFakeKeyEvent(display As Pointer, keycode As Integer, is_press As Boolean, delay As Long) As Integer

' XSync(Display *display, Bool discard)
' Flushes the output buffer.
Private Extern XSync(display As Pointer, discard As Boolean)


Public Sub Main()
 
 Dim disp As Pointer
 
' Abbiamo 3 secondi per dare il "focus" manualmente al Terminale:
 Wait 3
  
' Connessione al server X ed impostazione predefinita:
 disp = XOpenDisplay(0)
 If disp == 0 Then Error.Raise("Errore !")
 
 InviaCarattere(disp, XK_l)
 InviaCarattere(disp, XK_s)
  
' Chiude la libreria:
 XCloseDisplay(disp)
  
End

Private Procedure InviaCarattere(ds As Pointer, keysym As Integer)
 
 Dim keycode As Integer
  
 keycode = XKeysymToKeycode(ds, keysym)
  
 If keycode == 0 Then Return
  
' Genera il regolare effetto del tasto premuto e di quello rilasciato:
 XTestFakeKeyEvent(ds, keycode, True, 0)
 XTestFakeKeyEvent(ds, keycode, False, 0)
  
 XSync(ds, False)
  
End


Riferimenti