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. |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.

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

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 della tastiera. 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. E' necessario attivare il componente gb.desktop ed aver installato xterm.

Private pr As Process
Private lett As New String[]


Public Sub Form_Open()

 Dim s As String
 Dim ss As New String[]
 Dim j As Short

   
   s = File.Load("/proc/bus/input/devices")

   s = Replace$(s, "\n", " ")

   ss = Split(s, " ", "", True)


' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Questa prima parte, volendo, può essere sostituita dalle seguenti righe con "Input":
   Dim fl As File

   fl = Open "/proc/bus/input/devices" For Input
  
   While Not Eof(fl)
     Input #fl, s
     ss.Add(s)
   Wend
' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


   For j = 0 To ss.Max
' Individuiamo la riga contenente il testo "Handlers=sysrq",
' e quindi raccogliamo l'ultima parola della riga medesima. Tale parola sarà in nome del file-device della tastiera:
     If ss[j] = "Handlers=sysrq" Then s = ss[j + 2]
   Next

' 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
 Dim s As String


' 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 Form_Open()

 Dim s As String
 Dim ss As New String[]
 Dim j As Short

   
   s = File.Load("/proc/bus/input/devices")

   s = Replace$(s, "\n", " ")

   ss = Split(s, " ", "", True)


' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Questa prima parte, volendo, può essere sostituita dalle seguenti righe con "Input":
   Dim fl As File

   fl = Open "/proc/bus/input/devices" For Input
  
   While Not Eof(fl)
     Input #fl, s
     ss.Add(s)
   Wend
' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


   For j = 0 To ss.Max
' Individuiamo la riga contenente il testo "Handlers=sysrq",
' e quindi raccogliamo l'ultima parola della riga medesima. Tale parola sarà in nome del file-device della tastiera:
     If ss[j] = "Handlers=sysrq" Then s = ss[j + 2]
   Next

' Per leggere il file-device individuato, bisogna avere i necessari permessi. Essi vengono quindi modificati.
' La parola "mia_password" della riga seguente è la password personale dell'utente:
   Shell "echo mia_password | sudo -S chmod 4777 /dev/input" &/ s Wait
 
 
' 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
 Dim s As String


' 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




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.