Individuare i tasti premuti della tastiera mediante le risorse esterne dichiarate in termios.h

Da Gambas-it.org - Wikipedia.

Utilizzando alcune risorse dichiarate nel file header "/usr/include/termios.h", è possibile intercettare ed individuare i tasti premuti della tastiera.

E' necessario richiamare in Gambas la libreria condivisa: "libc.so.6 ".

Mostriamo un esempio pratico:

Library "libc:6"

Public Struct termios
  c_iflag As Integer
  c_oflag As Integer
  c_cflag As Integer
  c_lflag As Integer
  c_line As Byte
  c_cc[32] As Byte
  c_ispeed As Integer
  c_ospeed As Integer
End Struct

Private Const TCSANOW As Integer = 0
Private Const TCSADRAIN As Integer = 1
Private Const ICANON As Integer = 2
Private Const VTIME As Integer = 5
Private Const VMIN As Integer = 6
Private Const ECHO As Integer = 16
 
' int tcgetattr (int __fd, struct termios *__termios_p)
' Put the state of FD into *TERMIOS_P.
Private Extern tcgetattr(__fd As Integer, __termios_p As Termios) As Integer

' int tcsetattr (int __fd, int __optional_actions, const struct termios *__termios_p)
' Set the state of FD to *TERMIOS_P.
Private Extern tcsetattr(__fd As Integer, __optional_actions As Integer, __termios_p As Termios) As Integer


Public Sub Main()

  Dim b As Byte

' Avvia un ciclo infinito:
  Do
    b = Getchar()
    Print "\rPremuto il tasto: " & Chr(b); "  -  Codice ASCII: "; b
  Loop

End

Private Function Getchar() As Byte
 
  Dim trm As New Termios
  Dim b As Byte
  Dim i As Integer
  Dim fl As File

  i = tcgetattr(0, trm)
  If i < 0 Then Error.Raise("Errore alla funzione 'tcgetattr()' !")
  
  With trm
    .c_lflag = .c_lflag And (Not ICANON)
    .c_lflag = .c_lflag And (Not ECHO)
    .c_cc[VMIN] = 1
    .c_cc[VTIME] = 0
  End With
  
  i = tcsetattr(0, TCSANOW, trm)
  If i < 0 Then Error.Raise("Errore alla funzione 'tcsetattr()' !")
  
  fl = Open "/proc/self/fd/0"
  Read #fl, b
  fl.Close
  
  With trm
    .c_lflag = .c_lflag Or ICANON
    .c_lflag = .c_lflag Or ECHO
  End With
   
  i = tcsetattr(0, TCSADRAIN, trm)
  If i < 0 Then Error.Raise("Errore alla funzione 'tcsetattr()' !")
  
  Return b
   
End


Un altro esempio:

Library "libc:6"

Public Struct termios
  c_iflag As Integer
  c_oflag As Integer
  c_cflag As Integer
  c_lflag As Integer
  c_line As Byte
  c_cc[32] As Byte
  c_ispeed As Integer
  c_ospeed As Integer
End Struct

Private Const STDIN_FILENO As Integer = 0
Private Const TCSANOW As Integer = 0
Private Const ICANON As Integer = 2
Private Const ECHO As Integer = 16
 
' int tcgetattr (int __fd, struct termios *__termios_p)
' Put the state of FD into *TERMIOS_P.
Private Extern tcgetattr(__fd As Integer, __termios_p As Termios) As Integer

' int tcsetattr (int __fd, int __optional_actions, const struct termios *__termios_p)
' Set the state of FD to *TERMIOS_P.
Private Extern tcsetattr(__fd As Integer, __optional_actions As Integer, __termios_p As Termios) As Integer


Public Sub Main()
 
  Dim t As Byte
 
  Do
    set_mode(1)
    While Not t
      t = get_key()
    Wend
    Print "\rTasto "; t;; Chr(t)
    t = 0
  Loop
  
End

Private Procedure set_mode(wk As Integer)
 
  Dim vet, nov As New Termios
 
  If 0 == wk Then
    With vet
      .c_lflag = .c_lflag Or ICANON
      .c_lflag = .c_lflag Or ECHO
    End With
    Return
  Endif
  
  tcgetattr(STDIN_FILENO, vet)
  nov = vet
  nov.c_lflag = nov.c_lflag And (Not (ICANON Or ECHO))
  tcsetattr(STDIN_FILENO, TCSANOW, nov)
  
End

Private Function get_key() As Byte
 
  Dim fl As File
  Dim b As Byte
  
  fl = Open "/dev/stdin"
  Read #fl, b
  fl.Close
  
  set_mode(0)
  
  Return b
  
End