Differenze tra le versioni di "Individuare i tasti della tastiera intercettando i dati grezzi dal suo file-device"
(36 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
− | E' possibile intercettare i dati ''grezzi'' provenienti dalla tastiera, per individuare di ciascun tasto | + | E' possibile intercettare i dati ''grezzi'' provenienti dalla tastiera, per individuare di ciascun tasto premuto il suo [http://xoomer.virgilio.it/ramsoft/scancode.html''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. | + | 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. <SUP>[[#Note|nota 1]]</sup> |
− | H: Handlers=sysrq kbd event | + | <BR>Per individuare precisamente quale sia il file-device associato alla tastiera, fra quelli che iniziano per ''event'', bisognerà ''interrogare'' il file: |
− | laddove | + | ''/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 event<FONT Color=#B22222 Size=2>n</font> | ||
+ | laddove <FONT Color=#B22222>n</font> è in realtà un numero. <SUP>[[#Note|nota 2]]</sup> | ||
Individuato, dunque, il file-device associato alla tastiera, lo gestiremo con una variabile di tipo ''Process''. | 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° dato ci darà il "''[http://spazioinwind.libero.it/ramsoft/scancode.htm 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 con le sole risorse di Gambas== | |
− | Mostriamo di seguito un possibile codice esemplificativo per intercettare e ricavare, per ciascun tasto premuto, il '' | + | Mostriamo di seguito un possibile codice esemplificativo per intercettare e ricavare in ambiente grafico di Gambas, per ciascun tasto premuto, il "''[http://spazioinwind.libero.it/ramsoft/scancode.htm Codice di Scansione]''" |
− | + | <BR>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. | |
− | + | <BR>Tale file-device sarà aperto in lettura e posto sotto ''osservazione'' con la parola-chiave ''Watch''. | |
+ | <BR>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() | '''Public''' Sub Form_Open() | ||
+ | |||
+ | fl = Open "/dev/input/event4" For Read Watch | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | '''Public''' Sub File_Read() | ||
+ | |||
Dim s As String | Dim s As String | ||
− | + | ||
− | + | TextArea1.Text &= gb.NewLine | |
+ | |||
+ | Read #fl, s, -256 | ||
+ | |||
+ | TextArea1.Text &= "Codice di scansione del tasto premuto: " & Asc(s, 21) | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | '''Public''' Sub Form_Close() | ||
+ | |||
+ | fl.Close | ||
+ | |||
+ | '''End''' | ||
+ | ====Come il precedente, ma in applicazione ''a riga di comando''==== | ||
+ | Private fl As File | ||
+ | |||
+ | |||
+ | '''Public''' Sub Main() | ||
+ | |||
+ | <FONT Color=gray>' ''Con questa riga di comando viene eliminata la protezione al file-device da leggere.'' | ||
+ | ' ''E' necessario porre la propria "password" di sistema al posto della parola "MIA_PASSWORD":''</font> | ||
+ | Shell "echo <FONT Color=#B22222>''MIA_PASSWORD''</font> | sudo -S chmod 666 /dev/" Wait | ||
+ | |||
+ | fl = Open "/dev/input/event4" For Read Watch | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | '''Public''' Sub File_Read() | ||
+ | |||
+ | Dim s As String | ||
+ | |||
+ | Read #fl, s, -256 | ||
+ | |||
+ | Print "Codice di scansione del tasto premuto: " & Asc(s, 21) | ||
− | + | '''End''' | |
+ | |||
+ | '''Public''' Sub Application_Read() <FONT Color=gray>' ''Se si preme il tasto "Invio" della tastiera, viene sollevato questo Evento</font> | ||
+ | |||
+ | fl.Close | ||
+ | |||
+ | <FONT Color=gray>' ''Avendo sollevato l'Evento "Application_Read()", per chiudere l'applicazione è necessario usare l'istruzione "Quit":</font> | ||
+ | Quit | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | ==Usando la funzione esterna "ioctl()"== | ||
+ | In questo secondo esempio useremo la funzione esterna ''ioctl( )'': | ||
+ | Library "libc:6" | ||
+ | |||
+ | Public Struct timeval | ||
+ | tv_sec As Long | ||
+ | tv_usec As Long | ||
+ | End Struct | ||
+ | |||
+ | Public Struct input_event | ||
+ | time_ As Struct Timeval | ||
+ | type As Short | ||
+ | code As Short | ||
+ | value As Integer | ||
+ | End Struct | ||
+ | |||
+ | Private Const _IOC_NRSHIFT As Integer = 0 | ||
+ | Private Const _IOC_NRBITS As Integer = 8 | ||
+ | Private _IOC_TYPESHIFT As Long = _IOC_NRSHIFT + _IOC_NRBITS | ||
+ | Private Const _IOC_TYPEBITS As Long = 8 | ||
+ | Private _IOC_SIZESHIFT As Long = _IOC_TYPESHIFT + _IOC_TYPEBITS | ||
+ | Private Const _IOC_SIZEBITS As Long = 14 | ||
+ | Private _IOC_DIRSHIFT As Long = _IOC_SIZESHIFT + _IOC_SIZEBITS | ||
+ | Private Const _IOC_WRITE As Long = 1 | ||
+ | Private Const _IOC_READ As Long = 2 | ||
+ | |||
+ | <FONT Color=gray>' ''int ioctl(int __fd, unsigned long int __request, ...)'' | ||
+ | ' ''Perform the I/O control operation specified by REQUEST on FD.''</font> | ||
+ | Private Extern ioctl_name(__fd As Integer, __request As Long, arg As Byte[]) As Integer Exec "ioctl" | ||
+ | |||
+ | Private Extern ioctl_grab(__fd As Integer, __request As Long, arg As Integer) As Integer Exec "ioctl" | ||
+ | |||
+ | <FONT Color=gray>' ''ssize_t read (int __fd, void *__buf, size_t __nbytes) | ||
+ | ' ''Read NBYTES into BUF from FD.''</font> | ||
+ | Private Extern read_C(__fd As Integer, __buf As Input_event, __nbytes As Long) As Long Exec "read" | ||
− | + | Private ke As New Input_event | |
+ | Private kfl As File | ||
− | |||
− | + | '''Public''' Sub Main() | |
− | <FONT | + | |
− | ' | + | Dim keyboard_name As New Byte[256] |
− | + | Dim rit As Long | |
− | + | ||
+ | <FONT Color=gray>' ''Supponendo che il file-device attinente alla tastiera sia "event4" (al quale dovrà essere ovviamente eliminata la protezione), lo si apre in "Lettura" e lo si pone in "osservazione":''</font> | ||
+ | kfl = Open "/dev/input/event4" For Read Watch | ||
+ | If kfl.Handle == -1 Then | ||
+ | kfl.Close | ||
+ | Error.Raise("Error !") | ||
+ | Endif | ||
+ | |||
+ | ioctl_name(kfl.Handle, Eviocname(Asc("E"), &h06, keyboard_name.Count), keyboard_name) | ||
+ | Print "Reading From: \e[34m"; keyboard_name.ToString(0, keyboard_name.Find(0)) | ||
+ | |||
+ | rit = ioctl_grab(kfl.Handle, Eviocgrab(Asc("E"), &h90, SizeOf(gb.Integer)), 1) | ||
+ | Print "\e[0mGetting exclusive access: "; IIf(rit == 0, "\e[32mSUCCESS\e[0m", "\e[31mFAILURE\e[0m") | ||
+ | |||
+ | Print | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | '''Public''' Sub File_Read() | ||
+ | |||
+ | Dim rit As Long | ||
+ | |||
+ | rit = read_C(kfl.Handle, ke, Object.SizeOf(ke)) | ||
+ | |||
+ | If rit > -1 Then | ||
+ | Print "\e[1mtime\e[0m: "; ke.time_.tv_sec; " , \e[1mtype\e[0m: "; ke.type & | ||
+ | " , \e[1mcode\e[0m: "; ke.code; " , \e[1mvalue\e[0m: "; ke.value | ||
+ | <FONT Color=gray>' ''Se viene premuto il tasto "Esc", il programma viene chiuso:''</font> | ||
+ | If (ke.type == 4) And (ke.code == 4) And (ke.value == 1) Then kfl.Close | ||
+ | Endif | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | '''Private''' Function Eviocname(type As Long, nr As Long, size As Long) As Long | ||
+ | |||
+ | Return Shl(_IOC_READ, _IOC_DIRSHIFT) Or Shl(type, _IOC_TYPESHIFT) Or Shl(nr, _IOC_NRSHIFT) Or Shl(size, _IOC_SIZESHIFT) | ||
+ | |||
+ | '''End''' | ||
− | + | '''Private''' Function Eviocgrab(type As Long, nr As Long, size As Long) As Long | |
− | + | ||
− | + | Return Shl(_IOC_WRITE, _IOC_DIRSHIFT) Or Shl(type, _IOC_TYPESHIFT) Or Shl(nr, _IOC_NRSHIFT) Or Shl(size, _IOC_SIZESHIFT) | |
+ | |||
+ | '''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. | ||
+ | <BR>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") | ||
+ | |||
+ | <FONT color=gray>' ''Individuiamo la riga contenente il testo "Handlers=sysrq"; ed individuiamo il nome del file-device della tastiera:''</font> | ||
+ | s = Trim(Scan(s, "*Handlers=sysrq *\n*")[1]) | ||
+ | i = InStr(s, "event") | ||
+ | s = Mid(s, i, 6) | ||
+ | |||
+ | <FONT color=gray>' ''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):''</font> | ||
+ | If Stat("/dev/input" &/ s).Auth <> "rwsrwxrwx" Then | ||
+ | Desktop.RunAsRoot("sudo -S chmod 4777 /dev/input" &/ s) | ||
+ | Endif | ||
+ | |||
+ | <FONT color=gray>' ''Poniamo un'attesa mediante un ciclo, fino a che i permessi del file-device non saranno mutati:''</font> | ||
+ | Do | ||
+ | Wait 0.01 | ||
+ | Loop Until Stat("/dev/input" &/ s).Auth = "rwsrwxrwx" | ||
+ | |||
+ | <FONT color=gray>' ''Finalmente il file-device viene gestito mediante un "Processo":''</font> | ||
+ | pr = Exec ["cat", "/dev/input" &/ s] For Read As "processo" | ||
+ | |||
'''End''' | '''End''' | ||
Riga 54: | Riga 208: | ||
Dim b As Byte | Dim b As Byte | ||
− | + | ||
+ | <FONT color=gray>' ''Legge i dati provenienti dal file-device della tastiera:''</font> | ||
+ | Read #pr, b | ||
+ | |||
+ | lett.Add(CStr(b)) | ||
+ | |||
+ | If lett.Count = 144 Then | ||
+ | |||
+ | <FONT color=gray>' ''Legge l'elemento di numero d'indice 20 della variabile array:''</font> | ||
+ | Print "Codice scansione tasto: "; lett[20] | ||
+ | |||
+ | lett.Clear | ||
+ | |||
+ | Endif | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | ====Come il precedente, ma in applicazione ''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") | ||
+ | |||
+ | <FONT color=gray>' ''Individuiamo la riga contenente il testo "Handlers=sysrq"; ed individuiamo il nome del file-device della tastiera:''</font> | ||
+ | s = Trim(Scan(s, "*Handlers=sysrq *\n*")[1]) | ||
+ | i = InStr(s, "event") | ||
+ | s = Mid(s, i, 6) | ||
+ | |||
+ | <FONT color=gray>' ''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:''</font> | ||
+ | Print "Inserire nello spazio sottostante la propria 'password'." | ||
+ | Input pass | ||
+ | Shell "echo " & pass & " | sudo -S chmod 4777 /dev/input" &/ s Wait | ||
+ | Print | ||
+ | |||
+ | <FONT color=gray>' ''Finalmente il file-device viene gestito mediante un "Processo":''</font> | ||
+ | pr = Exec ["cat", "/dev/input" &/ s] For Read As "processo" | ||
+ | |||
+ | '''End''' | ||
− | |||
− | + | '''Public''' Sub processo_Read() | |
− | + | ||
+ | Dim b As Byte | ||
− | + | While Not Eof(pr) | |
+ | <FONT color=gray>' ''Legge i dati provenienti dal file-device della tastiera:''</font> | ||
+ | Read #pr, b | ||
− | + | lett.Add(CStr(b)) | |
− | + | ||
+ | If lett.Count = 144 Then | ||
+ | <FONT color=gray>' ''Legge l'elemento di numero d'indice 20 della variabile array:''</font> | ||
+ | Print "Codice scansione tasto: "; lett[20] | ||
+ | lett.Clear | ||
+ | Endif | ||
+ | Wend | ||
+ | |||
'''End''' | '''End''' | ||
+ | |||
Riga 78: | Riga 281: | ||
=Note= | =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''. | [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 "event<FONT Size=2>n</font>" è presente anche la parola "''leds''". Pertanto, se ne dovrà tenere conto ai fini dell'individuazione della parola ''event<FONT Size=2>n</font>''. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | =Riferimenti= | ||
+ | * https://www.win.tue.nl/~aeb/linux/kbd/scancodes.html |
Versione delle 06:30, 20 mar 2023
E' possibile intercettare i dati grezzi provenienti dalla tastiera, per individuare di ciascun tasto premuto 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° dato 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.
Indice
Codice esemplificativo in ambiente grafico con le sole risorse di 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.
Tale file-device sarà aperto in lettura e posto sotto osservazione con la parola-chiave Watch.
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() Dim s As String TextArea1.Text &= gb.NewLine Read #fl, s, -256 TextArea1.Text &= "Codice di scansione del tasto premuto: " & Asc(s, 21) End Public Sub Form_Close() fl.Close End
Come il precedente, ma in applicazione a riga di comando
Private fl As File Public Sub Main() ' Con questa riga di comando viene eliminata la protezione al file-device da leggere. ' E' necessario porre la propria "password" di sistema al posto della parola "MIA_PASSWORD": Shell "echo MIA_PASSWORD | sudo -S chmod 666 /dev/" Wait fl = Open "/dev/input/event4" For Read Watch End Public Sub File_Read() Dim s As String Read #fl, s, -256 Print "Codice di scansione del tasto premuto: " & Asc(s, 21) End Public Sub Application_Read() ' Se si preme il tasto "Invio" della tastiera, viene sollevato questo Evento fl.Close ' Avendo sollevato l'Evento "Application_Read()", per chiudere l'applicazione è necessario usare l'istruzione "Quit": Quit End
Usando la funzione esterna "ioctl()"
In questo secondo esempio useremo la funzione esterna ioctl( ):
Library "libc:6" Public Struct timeval tv_sec As Long tv_usec As Long End Struct Public Struct input_event time_ As Struct Timeval type As Short code As Short value As Integer End Struct Private Const _IOC_NRSHIFT As Integer = 0 Private Const _IOC_NRBITS As Integer = 8 Private _IOC_TYPESHIFT As Long = _IOC_NRSHIFT + _IOC_NRBITS Private Const _IOC_TYPEBITS As Long = 8 Private _IOC_SIZESHIFT As Long = _IOC_TYPESHIFT + _IOC_TYPEBITS Private Const _IOC_SIZEBITS As Long = 14 Private _IOC_DIRSHIFT As Long = _IOC_SIZESHIFT + _IOC_SIZEBITS Private Const _IOC_WRITE As Long = 1 Private Const _IOC_READ As Long = 2 ' int ioctl(int __fd, unsigned long int __request, ...) ' Perform the I/O control operation specified by REQUEST on FD. Private Extern ioctl_name(__fd As Integer, __request As Long, arg As Byte[]) As Integer Exec "ioctl" Private Extern ioctl_grab(__fd As Integer, __request As Long, arg As Integer) As Integer Exec "ioctl" ' ssize_t read (int __fd, void *__buf, size_t __nbytes) ' Read NBYTES into BUF from FD. Private Extern read_C(__fd As Integer, __buf As Input_event, __nbytes As Long) As Long Exec "read" Private ke As New Input_event Private kfl As File Public Sub Main() Dim keyboard_name As New Byte[256] Dim rit As Long ' Supponendo che il file-device attinente alla tastiera sia "event4" (al quale dovrà essere ovviamente eliminata la protezione), lo si apre in "Lettura" e lo si pone in "osservazione": kfl = Open "/dev/input/event4" For Read Watch If kfl.Handle == -1 Then kfl.Close Error.Raise("Error !") Endif ioctl_name(kfl.Handle, Eviocname(Asc("E"), &h06, keyboard_name.Count), keyboard_name) Print "Reading From: \e[34m"; keyboard_name.ToString(0, keyboard_name.Find(0)) rit = ioctl_grab(kfl.Handle, Eviocgrab(Asc("E"), &h90, SizeOf(gb.Integer)), 1) Print "\e[0mGetting exclusive access: "; IIf(rit == 0, "\e[32mSUCCESS\e[0m", "\e[31mFAILURE\e[0m") Print End Public Sub File_Read() Dim rit As Long rit = read_C(kfl.Handle, ke, Object.SizeOf(ke)) If rit > -1 Then Print "\e[1mtime\e[0m: "; ke.time_.tv_sec; " , \e[1mtype\e[0m: "; ke.type & " , \e[1mcode\e[0m: "; ke.code; " , \e[1mvalue\e[0m: "; ke.value ' Se viene premuto il tasto "Esc", il programma viene chiuso: If (ke.type == 4) And (ke.code == 4) And (ke.value == 1) Then kfl.Close Endif End Private Function Eviocname(type As Long, nr As Long, size As Long) As Long Return Shl(_IOC_READ, _IOC_DIRSHIFT) Or Shl(type, _IOC_TYPESHIFT) Or Shl(nr, _IOC_NRSHIFT) Or Shl(size, _IOC_SIZESHIFT) End Private Function Eviocgrab(type As Long, nr As Long, size As Long) As Long Return Shl(_IOC_WRITE, _IOC_DIRSHIFT) Or Shl(type, _IOC_TYPESHIFT) Or Shl(nr, _IOC_NRSHIFT) Or Shl(size, _IOC_SIZESHIFT) 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
Come il precedente, ma in applicazione 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.