Individuare i tasti della tastiera intercettando i dati grezzi dal suo file-device

Da Gambas-it.org - Wikipedia.

E' possibile intercettare i dati grezzi provenienti dalla tastiera, per individuare di ciascun tasto pemuto il suo codice di scansione.


Per gestire direttamente i dati grezzi della tastiera, bisogna innanzitutto individuare il suo file-device. Sappiamo che esso è presente nel percorso /dev/input/, ed è rappresentato da uno dei file con il nome eventN; laddove "N" è un suffisso del nome rappresentato da un numero. nota 1 Per individuare precisamente quale sia il file-device associato alla tastiera, fra quelli che iniziano per event, bisognerà interrogare il file "/proc/bus/input/devices". Tale file mostra quali dispositivi e gestori di input sono attualmente attivi, ed all'interno del quale bisognerà individuare la riga che inizia per H:, e che rappresenta i driver gestore associati ad un determinato dispositivo. Pertanto, la riga "H:" che si riferisce alla tastiera si presenta visivamente come segue:

H: Handlers=sysrq kbd eventn

laddove n è in realtà un numero. nota 2

Individuato, dunque, il file-device associato alla tastiera, lo gestiremo con una variabile di tipo Process.

Ogni volta che è premuto un tasto della tastiera, vengono scritti nel file-device della tastiera alcuni dati, che potranno essere ovviamente letti dal programma gambas. Il 21° dati ci darà il Codice di Scansione del tasto premuto. Tale codice, identificando univocamente il tasto appena premuto o rilasciato, è dunque universale per tutti i calcolatori, e quindi tranquillamente utilizzabile nei nostri programmi Gambas.


Codice esemplificativo in ambiente grafico Gambas

Mostriamo di seguito un possibile codice esemplificativo per intercettare e ricavare in ambiente grafico di Gambas, per ciascun tasto premuto, il "codice di scansione"
Supponiamo, nell'esempio che segue, che sia stato già individuato il file-device corrispondente alla tastiera, e che sia stato già da noi privato della sua protezione.
I dati letti dal file-device saranno caricati in una variabile di tipo Stringa, dalla quale sarà estrapolato il 21° dato-valore.

Private fl As File


Public Sub Form_Open()
 
 fl = Open "/dev/input/event4" For Read Watch
  
End


Public Sub File_Read()
 
 TextArea1.Clear
 
 Read #fl, s, -256
 
 TextArea1.Text = "Codice di scansione del tasto premuto:  " & Asc(Mid(s, 21, 1))
    
End


Usando la funzione Exec e il comando bash cat

In quest'altro esempio è necessario attivare il componente gb.desktop ed aver installato xterm: si provvederà da codice ad individuare e successivamente a eliminare la protezione del file-device corrispondente alla tastiera.
Per ogni tasto che viene premuto, vengono intercettati dal file-device della tastiera ben 144 dati; il 21° ci darà il codice di scansione del tasto premuto della tastiera.

Private pr As Process
Private lett As New String[]


Public Sub Form_Open()

 Dim s As String
 Dim i As Integer
  
  s = File.Load("/proc/bus/input/devices")
  
' Individuiamo la riga contenente il testo "Handlers=sysrq"; ed individuiamo il nome del file-device della tastiera:
  s = Trim(Scan(s, "*Handlers=sysrq *\n*")[1])
  i = InStr(s, "event")
  s = Mid(s, i, 6)
  
' Per leggere il file-device individuato, bisogna avere i necessari permessi.
' Pertanto, se non sono stati modificati i permessi del file-device, allora vengono modificati
' (bisognerà inserire la propria password):
  If Stat("/dev/input" &/ s).Auth <> "rwsrwxrwx" Then
    Desktop.RunAsRoot("sudo -S chmod 4777 /dev/input" &/ s)
  Endif
  
' Poniamo un'attesa mediante un ciclo, fino a che i permessi del file-device non saranno mutati:
  Do
    Wait 0.01
  Loop Until Stat("/dev/input" &/ s).Auth = "rwsrwxrwx"
  
' Finalmente il file-device viene gestito mediante un "Processo":
  pr = Exec ["cat", "/dev/input" &/ s] For Read As "processo"
  
End


Public Sub processo_Read()

 Dim b As Byte
 
' Legge i dati provenienti dal file-device della tastiera:
  Read #pr, b
  
  lett.Add(CStr(b))
  
  If lett.Count = 144 Then
  
' Legge l'elemento di numero d'indice 20 della variabile array:
    Print "Codice scansione tasto:   "; lett[20]
    
    lett.Clear
    
  Endif
  
End


Codice esemplificativo in applicazione Gambas a riga di comando

Mostriamo di seguito un possibile codice esemplificativo per intercettare e ricavare nell'ambito di un'applicazione Gambas a riga di comando, per ciascun tasto premuto, il codice di scansione.

Private pr As Process
Private lett As New String[]


Public Sub Main()

 Dim s, pass As String
 Dim i As Integer
     
  s = File.Load("/proc/bus/input/devices")
   
' Individuiamo la riga contenente il testo "Handlers=sysrq"; ed individuiamo il nome del file-device della tastiera:
  s = Trim(Scan(s, "*Handlers=sysrq *\n*")[1])
  i = InStr(s, "event")
  s = Mid(s, i, 6)
    
' Per leggere il file-device individuato, bisogna avere i necessari permessi. Essi vengono quindi modificati.
' E' necessario inserire nell'apposito spazio sottostante la Console (o nel Terminale) la password personale dell'utente:
  Print "Inserire nello spazio sottostante la propria 'password'."
  Input pass
  Shell "echo " & pass & " | sudo -S chmod 4777 /dev/input" &/ s Wait
  Print  
 
' Finalmente il file-device viene gestito mediante un "Processo":
  pr = Exec ["cat", "/dev/input" &/ s] For Read As "processo"
  
End


Public Sub processo_Read()

 Dim b As Byte

  While Not Eof(pr)
' Legge i dati provenienti dal file-device della tastiera:
    Read #pr, b

    lett.Add(CStr(b))

    If lett.Count = 144 Then
' Legge l'elemento di numero d'indice 20 della variabile array:
      Print "Codice scansione tasto:   "; lett[20]
      lett.Clear
    Endif
  Wend
   
End




Note

[1] Il nome event è dato dalla circostanza che il rapporto tra i vari elementi del sottosistema di input - ossia gli ingressi principali, i driver e gestori di eventi - avviene attraverso eventi.

[2] In versioni di Mint superiori alla 17 dopo la parola "eventn" è presente anche la parola "leds". Pertanto, se ne dovrà tenere conto ai fini dell'individuazione della parola eventn.



Riferimenti