How to read keypress from exclusive external USB keypad .

Post your Gambas programming questions here.
dinge
Posts: 12
Joined: Friday 5th June 2020 7:37pm

Re: How to read keypress from exclusive external USB keypad .

Post by dinge »

Dear Mr Vuott,
used your code as follow , also include a print result
Public Sub File_read()
Dim ev As New Input_event
Dim rd As Integer
rd = read_C(kfl.Handle, ev, Object.SizeOf(ev))
Print "ev: "; Str$(ev); " , sizeof ev: "; Object.SizeOf(ev); " , rd: "; rd; " ,time: "; ev.time_.tv_sec; " , type: "; ev.type; " , code: "; ev.code ; " , value: "; ev.value

End
  • output print gambas program code in quote
    ev: (input_event 0x187abb4) , sizeof ev: 24 , rd: 16 ,time: 1177329438085223 , type: 0 , code: 0 , value: 0
    ev: (input_event 0x187abb4) , sizeof ev: 24 , rd: 16 ,time: 1177329438085223 , type: 0 , code: 0 , value: 0
    ev: (input_event 0x187abb4) , sizeof ev: 24 , rd: 16 ,time: 1177329438085223 , type: 0 , code: 0 , value: 0
    ev: (input_event 0x187abb4) , sizeof ev: 24 , rd: 16 ,time: 1589663478370407 , type: 0 , code: 0 , value: 0
    ev: (input_event 0x187abb4) , sizeof ev: 24 , rd: 16 ,time: 1589663478370407 , type: 0 , code: 0 , value: 0
    ev: (input_event 0x187abb4) , sizeof ev: 24 , rd: 16 ,time: 1589663478370407 , type: 0 , code: 0 , value: 0
    ===========================================================================================================
    evtest output in terminal from same keyboard and same pressed key (not at same moment -time difference)
    Event: time 1592844255.880822, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7005d
    Event: time 1592844255.880822, type 1 (EV_KEY), code 76 (KEY_KP5), value 1
    Event: time 1592844255.880822, -------------- SYN_REPORT ------------
    5Event: time 1592844255.920823, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7005d
    Event: time 1592844255.920823, type 1 (EV_KEY), code 76 (KEY_KP5), value 0
    Event: time 1592844255.920823, -------------- SYN_REPORT ------------
This code gets a result , the time is available but no keypres type, code or values.
I believe the time are the first 16 bytes and the following 8 contain the keypressed type, value, code .
Do I only get 16 bytes as rd=16 ?
The sizeof ev is correct =24.
The number of lines produced by a keypress (5) is the samefor evtest and file_read
- so the third line and sixth lines (evtest - SYN_REPORT ) should give 0 values.
Do I have to read - approach- the ev.code on another way, i am stuck, can't still a good grip on it.
The implemented code for keyboard_name returns empty string and grab with iotcl still returns -1 .
What am I doing wrong.
Thanks a lot for your code it helps to evolve.
Greetings
vuott
Posts: 262
Joined: Wednesday 5th April 2017 6:07pm
Location: European Union

Re: How to read keypress from exclusive external USB keypad .

Post by vuott »

Try this:
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"
 
' int ioctl(int __fd, unsigned long int __request, ...)
' Perform the I/O control operation specified by REQUEST on FD.
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   ' We declare "Input_event" Structure instance as "Global"
Private kfl As File


Public Sub Main()

  Dim keyboard_name As New Byte[256]
  Dim rcode As Long

'' (In my system KEYBOARD event file-device is "event4"):
  kfl = Open "/dev/input/event4" For Read Watch
  If kfl.Handle < 0 Then
    kfl.Close
    Error.Raise("Error !")
  Endif
   
  rcode = 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))
 
  rcode = ioctl_grab(kfl.Handle, Eviocgrab(Asc("E"), &h90, SizeOf(gb.Integer)), 1)
  Print "\e[0mGetting exclusive access: "; IIf(rcode == 0, "\e[32mSUCCESS\e[0m", "\e[31mFAILURE\e[0m")
 
  Print

End

Public Sub File_Read()

  Dim rd As Integer

  rd = read_C(kfl.Handle, ke, Object.SizeOf(ke))
  
  If rd > -1 Then
    Print "\e[1m\e[31mev\e[0m: "; Str(ke); " , \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
  Endif
  
End
 
 
Private Function Eviocname(type As Long, nr As Long, size As Long) As Long
   
  Return Shl(_IOC_READ, CInt(_IOC_DIRSHIFT)) Or Shl(type, CInt(_IOC_TYPESHIFT)) Or Shl(nr, _IOC_NRSHIFT) Or Shl(size, CInt(_IOC_SIZESHIFT))

End

Private Function Eviocgrab(type As Long, nr As Long, size As Long) As Long
   
  Return Shl(_IOC_WRITE, CInt(_IOC_DIRSHIFT)) Or Shl(type, CInt(_IOC_TYPESHIFT)) Or Shl(nr, _IOC_NRSHIFT) Or Shl(size, CInt(_IOC_SIZESHIFT))
   
End
Last edited by vuott on Thursday 9th December 2021 7:46pm, edited 2 times in total.
Europaeus sum !

Amare memorentes atque deflentes ad mortem silenter labimur.
dinge
Posts: 12
Joined: Friday 5th June 2020 7:37pm

Re: How to read keypress from exclusive external USB keypad .

Post by dinge »

Hello, back in town.
I reworked my little program to grab exclusively input from touchpad or external wacompad, keypad and also Arduino serial input.
The program is named ExtraPadMini. Included in the zipped file is a Manual.odt and dpf file which shows how to use it. It is a minimal program but usable and can be productive.
I use my touchpad now which gives me 18 programmable virtual buttons. The Wacompad Volito2 i reuse now as a external 7x9= 63 extra programmable virtual buttons. With the Arduino i have written an arduino sketch to read IR remote control pulses and assign code to the remote buttons.
There are a lot of things that have to be worked out. The password permission behaves still sometimes strange.
Password using is a problem as different Linux Os use different permission protocol - gksu, kde, sudo, . The one i found seems to work with Ubuntu,Zorin,Bunsenlab. A lot of the code is gained from internet searching as I am not a programmer I am sure there are a lot of corrections and better code that can be used.
Please feel free to correct and let the gambaser enjoy your improvements.
It runs on 64bit linux os . Strangely 32bit does not work I gues it has to do with the 8bit and 16bit difference , I suppose.
That's why I struggled so long to get it working on 32bit and worked around it with xinput commands. To my surprise the ioclt commands worked on 64bit Linux Os. There is now that little program.
I am working on a ExtraPad program with scripting possibility's and 32bit compatible , I'll put it on the Project Forum
My special thanks to Mr Vuott for the ioctl gambas coding.
Greetings
Attachments
ExtraPadMini-0.0.7.tar.gz
(1.57 MiB) Downloaded 235 times
MANUAL.pdf
(855.38 KiB) Downloaded 245 times
Post Reply