can't get the mouse move event from /dev/input/event* - linux

I can't get the mouse move event when using the evtest tools to test the input events .
I just get three mouse events:
left click event: type = EV_KEY, code = 272 (LeftBtn), value=1/0
right click event: type = EV_KEY, code = 273 (RightBtn), value = 1/0
mouse wheel event: type = EV_REL, code = 8 (Wheel), value = -1
No mouse move event. So where my mouse move event and how to capture it?
ps: Tested on Ubuntu 11.04 and Gentoo in VirtualBox-4 with virtualBox-addition installed.

If not on an embedded linux system I prefer to use the input-utils tools rather than evtest (and if I'm on Android I use cat /proc/bus/input/devices and getevent )
Install input-utils via:
$ sudo apt-get install input-utils
List all my input devices
$ sudo lsinput
/dev/input/event0
bustype : BUS_HOST
vendor : 0x0
product : 0x5
version : 0
name : "Lid Switch"
..
..
phys : "isa0060/serio1/input0"
bits ev : EV_SYN EV_KEY EV_ABS
/dev/input/event12
bustype : BUS_I8042
vendor : 0x2
product : 0xa
version : 0
name : "TPPS/2 IBM TrackPoint"
phys : "synaptics-pt/serio0/input0"
bits ev : EV_SYN EV_KEY EV_REL
Then I read events on my laptop's trackpoint (don't forget to move the it around after starting input-events)
$ sudo input-events 12
/dev/input/event12
bustype : BUS_I8042
vendor : 0x2
product : 0xa
version : 0
name : "TPPS/2 IBM TrackPoint"
phys : "synaptics-pt/serio0/input0"
bits ev : EV_SYN EV_KEY EV_REL
waiting for events
16:43:46.516075: EV_REL REL_Y -1
16:43:46.516090: EV_SYN code=0 value=0
16:43:46.539642: EV_REL REL_X -1
16:43:46.539656: EV_REL REL_Y -1
16:43:46.539660: EV_SYN code=0 value=0
16:43:46.704385: EV_REL REL_Y -1
16:43:46.704401: EV_SYN code=0 value=0

Have you tried actually moving the mouse rather than evtest?
I don't get anything on /dev/input/event* when I move my mouse but do on /dev/input/by-path/platform-i8042-serio-1-event-mouse. I also don't get anything when I use /dev/input/by-path/platform-i8042-serio-1-event-mouse and move the mouse across Synergy, I have to physically move the mouse.
Sach

Related

Gammu - Entry is empty, cannot set SMSC

Short description:
when I try to send a SMS I receive the error: "Failed to get SMSC number from phone."
so I try to set the SMSC number and I receive the error: "Entry is empty."
Commnads are:
root#mail:/home/victor# echo "Dragon Ball super is Awsome!" | gammu --sendsms TEXT +40740863629
Failed to get SMSC number from phone.
root#mail:/home/victor# gammu setsmsc 1 "+40748438759"
Entry is empty.
Result of command gammu identify is:
root#mail:/home/victor# gammu identify
Device : /dev/ttyUSB0
Manufacturer : Qualcomm
Model : unknown (HSDPA Modem)
Firmware : 01.02.04 1 [Nov 27 2015 14:33:39]
SIM IMSI : +CIMI:226102317883481
Maybe my device is not supported by gammu?
This is my configuration file ... I tried different configuration:
[gammu]
port = /dev/ttyUSB0
model =
connection = at19200
synchronizetime = no
logfile = /var/log/gammu.log
logformat = textall
use_locking =
gammuloc =
I used my Ubuntu gammu version 1.37.
I just read the manual of the device, the solution is to load the right driver:
modprobe usbserial vendor=0x5c6 product=0x6000
After this the SMS can be send, no need to set SMSC manualy

VM entry (vmlaunch) with invalid control field

I am learning Intel VMX with a Linux based VMM.
I found 'vmlaunch' instruction failed with vm instruction error of 7.
I checked Intel's SDM, it means 'VM entry with invalid control field'.
I double checked the VM_entry_control, VM_exit_control, VM_exec_control, but could NOT find anything wrong.
I am using EPTP for VM execution (VM is in real mode).
Below is the control fields, and VMX capabilities.
Host CPU info is as follows.
Linux kernel is 3.10, and 4.4.0.
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 63
model name : Intel(R) Xeon(R) CPU E5-2620 v3 # 2.40GHz
stepping : 2
microcode : 0x37
cpu MHz : 2391.223
cache size : 15360 KB
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
<pre>
0x0000001F = control_VMX_pin_based
0xA50061F2 = control_VMX_cpu_based
0x00000082 = control_VMX_proc2_based
0x00000000 = control_exception_bitmap
0x00000000 = control_pagefault_errorcode_mask
0xFFFFFFFF = control_pagefault_errorcode_match
0x00000002 = control_CR3_target_count
0x00036FFB = control_VM_exit_controls
0x000011FB = control_VM_entry_controls
0x00000000 = control_VM_entry_interruption_information
0x00000000 = control_VM_entry_exception_errorcode
0x00000000 = control_VM_entry_instruction_length
0x0000000000000020 = control_CR0_mask
0x0000000000002000 = control_CR4_mask
0x0000000000000020 = control_CR0_shadow
0x0000000000002000 = control_CR4_shadow
0x0000000000000000 = control_CR3_target0
0x0000000124FCE000 = control_CR3_target1
0x0000000000000000 = control_CR3_target2
0x0000000000000000 = control_CR3_target3
Host VMX capabilities are as follows,
VMX-Capability Model-Specific Registers
00D8100000000001 = IA32_VMX_BASIC_MSR
0000003F00000016 = IA32_VMX_PINBASED_CTLS_MSR
FFF9FFFE0401E172 = IA32_VMX_PROCBASED_CTLS_MSR
0033FFFF00036DFF = IA32_VMX_EXIT_CTLS_MSR
0000B3FF000011FF = IA32_VMX_ENTRY_CTLS_MSR
00000000000401E0 = IA32_VMX_MISC_MSR
0000000080000021 = IA32_VMX_CR0_FIXED0_MSR
00000000FFFFFFFF = IA32_VMX_CR0_FIXED1_MSR
0000000000002000 = IA32_VMX_CR4_FIXED0_MSR
00000000000427FF = IA32_VMX_CR4_FIXED1_MSR
000000000000005A = IA32_VMX_VMCS_ENUM_MSR
000000EE00000000 = IA32_VMX_PROCBASED_CTLS2
00000F0106114041 = IA32_VMX_EPT_VPID_CAP
0000003F00000016 = IA32_VMX_TRUE_PINBASED_CTLS
FFF9FFFE04006172 = IA32_VMX_TRUE_PROCBASED_CTLS
0033FFFF00036DFB = IA32_VMX_TRUE_EXIT_CTLS
0000B3FF000011FB = IA32_VMX_TRUE_ENTRY_CTLS
I don’t see anything wrong in the fields you provided, but there are more checks on fields you haven’t listed. For example, Use MSR bitmap is 1, but you don’t show the value of the MSR bitmap address.
You should go through all the checks in section 26.2.1.
I suggest also looking at any checks related to unrestricted-guest. It is recommended that you set the controls to save and restore EFER in the exit and entry controls.
By checking the VMCS fields, i found the invalid control came from the EPTP.
In that CPU, it does NOT support 'dirty/access' bit to be 1 in EPTP (bit 6).
After set that bit to 0, there is NO 'invalid control fields' error.

How to send commands to smart card reader (and not to the smart card) while no card present?

Preface:
I have a dual interface smart card reader that has some extended capabilities (other than sending APDU commands to card and receiving APDU responses).
For example in its document it is mentioned that you can get firmware version of your reader using following command:
GET_FIRMWARE_VERSION: FF 69 44 42 05 68 92 00 05 00
In its tool, there is a button for this function and it works fine:
I even sniffed USB port to see what exactly exchanged in the connection between my PC and my reader for this function:
Command:
Response:
Problem:
I want to get my reader version (and maybe send other extended commands) using other tools or via code, but I must insert a card in the card reader to be able sending commands, otherwise I receive No Card Present exception, while I don't want to send commands to card! (The reader tool answers successfully to GET_FIRMWARE_VERSION without any card available in the reader's slots)
What I did so far:
1.I tried some tools, including OpenSCTool , PyAPDUTool, and another reader's tool.
2.I wrote following python script to send extended commands.
#--- Importing required modules.
import sys
import time
sys.path.append("D:\\PythonX\\Lib\\site-packages")
from smartcard.scard import *
import smartcard.util
from smartcard.System import readers
#---This is the list of commands that we want to send device
cmds =[[,0xFF,0x69,0x44,0x42,0x05,0x68,0x92,0x00,0x04,0x00],]
#--- Let's to make a connection to the card reader
r=readers()
print "Available Readers :",r
print
target_reader = input("--- Select Reader (0, 1 , ...): ")
print
while(True):
try:
print "Using :",r[target_reader]
reader = r[target_reader]
connection=reader.createConnection()
connection.connect()
break
except:
print "--- Exception occured! (Wrong reader or No card present)"
ans = raw_input("--- Try again? (0:Exit/1:Again/2:Change Reader)")
if int(ans)==0:
exit()
elif int(ans)==2:
target_reader = input("Select Reader (0, 1 , ...): ")
#--- An struct for APDU responses consist of Data, SW1 and SW2
class stru:
def __init__(self):
self.data = list()
self.sw1 = 0
self.sw2 = 0
resp = stru()
def send(cmds):
for cmd in cmds:
#--- Following 5 line added to have a good format of command in the output.
temp = stru() ;
temp.data[:]=cmd[:]
temp.sw1=12
temp.sw2=32
modifyFormat(temp)
print "req: ", temp.data
resp.data,resp.sw1,resp.sw2 = connection.transmit(cmd)
modifyFormat(resp)
printResponse(resp)
def modifyFormat(resp):
resp.sw1=hex(resp.sw1)
resp.sw2=hex(resp.sw2)
if (len(resp.sw2)<4):
resp.sw2=resp.sw2[0:2]+'0'+resp.sw2[2]
for i in range(0,len(resp.data)):
resp.data[i]=hex(resp.data[i])
if (len(resp.data[i])<4):
resp.data[i]=resp.data[i][0:2]+'0'+resp.data[i][2]
def printResponse(resp):
print "res: ", resp.data,resp.sw1,resp.sw2
send(cmds)
connection.disconnect()
Output:
>>> ================================ RESTART ================================
Available Readers : ['CREATOR CRT-603 (CZ1) CCR RF 0', 'CREATOR CRT-603 (CZ1) CCR SAM 0']
--- Select Reader (0, 1 , ...): 0
Using : CREATOR CRT-603 (CZ1) CCR RF 0
--- Exception occured! (Wrong reader or No card present)
--- Try again? (0:Exit/1:Again/2:Change Reader)
>>> ================================ RESTART ================================
Available Readers : ['CREATOR CRT-603 (CZ1) CCR RF 0', 'CREATOR CRT-603 (CZ1) CCR SAM 0']
--- Select Reader (0, 1 , ...): 1
Using : CREATOR CRT-603 (CZ1) CCR SAM 0
--- Exception occured! (Wrong reader or No card present)
--- Try again? (0:Exit/1:Again/2:Change Reader)
But both have the mentioned problem!
Questions:
1- How to send extended commands to reader while there is no card available?
2- Why I can't see command header in the sniffed data? (Note that, as Header is a pre-designated fixed value for all extended commands, I think the reader tool doesn't send the header with GET_FIRMWARE_VERSION command and it send only the data! but how does it works?)
Update:
Using trial and error I found something useful.
Assumptions:
Pseudo-APDUs fixed header = FF 69 44 42
Pseudo-APDU data field for GET_READER_FIRMWARE_VERSION = 68 92 00 04 00
Pseudo-APDU data field for CHANGE_SAM_SLOT = 68 92 01 00 03 XX 00 00
(My reader has two SAM slots, so XX can be 01 or 02)
SELECT APDU command = 00 A4 04 00 00
Ok, I wrote the following Java Program:
import java.util.List;
import java.util.Scanner;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
import javax.smartcardio.TerminalFactory;
import javax.xml.bind.DatatypeConverter;
public class TestPCSC {
public static void main(String[] args) throws CardException {
TerminalFactory tf = TerminalFactory.getDefault();
List< CardTerminal> terminals = tf.terminals().list();
System.out.println("Available Readers:");
System.out.println(terminals + "\n");
Scanner scanner = new Scanner(System.in);
System.out.print("Which reader do you want to send your commands to? (0 or 1 or ...): ");
String input = scanner.nextLine();
int readerNum = Integer.parseInt(input);
CardTerminal cardTerminal = (CardTerminal) terminals.get(readerNum);
Card connection = cardTerminal.connect("DIRECT");
CardChannel cardChannel = connection.getBasicChannel();
System.out.println("Write your commands in Hex form, without '0x' or Space charaters.");
System.out.println("\n---------------------------------------------------");
System.out.println("Pseudo-APDU Mode:");
System.out.println("---------------------------------------------------");
while (true) {
System.out.println("Pseudo-APDU command: (Enter 0 to send APDU command)");
String cmd = scanner.nextLine();
if (cmd.equals("0")) {
break;
}
System.out.println("Command : " + cmd);
byte[] cmdArray = hexStringToByteArray(cmd);
byte[] resp = connection.transmitControlCommand(CONTROL_CODE(), cmdArray);
String hex = DatatypeConverter.printHexBinary(resp);
System.out.println("Response : " + hex + "\n");
}
System.out.println("\n---------------------------------------------------");
System.out.println("APDU Mode:");
System.out.println("---------------------------------------------------");
while (true) {
System.out.println("APDU command: (Enter 0 to exit)");
String cmd = scanner.nextLine();
if (cmd.equals("0")) {
break;
}
System.out.println("Command : " + cmd);
byte[] cmdArray = hexStringToByteArray(cmd);
ResponseAPDU resp = cardChannel.transmit(new CommandAPDU(cmdArray));
byte[] respB = resp.getBytes();
String hex = DatatypeConverter.printHexBinary(respB);
System.out.println("Response : " + hex + "\n");
}
connection.disconnect(true);
}
public static int CONTROL_CODE() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.indexOf("windows") > -1) {
/* Value used by both MS' CCID driver and SpringCard's CCID driver */
return (0x31 << 16 | 3500 << 2);
} else {
/* Value used by PCSC-Lite */
return 0x42000000 + 1;
}
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}
In the above program, I can send commands to my reader using both connection.transmitControlCommand and cardChannel.transmit() methods. The point is that, all the commands that send to the reader using first method, are assumed as Pseudo-APDU command and I should not use the Psedo-APDU header for them! And all the commands that send to the reader using second method, are assumed as regular APDU commands, so if I need to send Pseudo-APDU commands via second method, I must add the Pseudo-APDU header to it.
Let see output for the contact-less reader:
run:
Available Readers:
[PC/SC terminal ACS ACR122 0,
PC/SC terminal CREATOR CRT-603 (CZ1) CCR RF 0,
PC/SC terminal CREATOR CRT-603 (CZ1) CCR SAM 0]
Which reader do you want to send your commands to? (0 or 1 or ...): 1
Write your commands in Hex form, without '0x' or Space charaters.
---------------------------------------------------
Pseudo-APDU Mode:
---------------------------------------------------
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
//Based on reader's documents, 0x6800 means "Class byte is not correct"
//As I have a regular java card in the RF field of my reader, I conclude that
//this response is Reader's response (and not card response)
Pseudo-APDU command: (Enter 0 to send APDU command)
6892000400
Command : 6892000400
Response : 433630335F435A375F425F31353038323100039000
Pseudo-APDU command: (Enter 0 to send APDU command)
FF694442056892000400
Command : FF694442056892000400
Response : 6800
//Pseudo-APDU commands doesn't work in Pseudo-APDU mode if I add the Pseudo-APDU header to them.
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
0
---------------------------------------------------
APDU Mode:
---------------------------------------------------
APDU command: (Enter 0 to exit)
00A4040000
Command : 00A4040000
Response : 6F198408A000000018434D00A50D9F6E061291921101009F6501FF9000
APDU command: (Enter 0 to exit)
6892000400
Command : 6892000400
Response : 6E00
//This is the response of my card. I can't receive Firmware version in APDU mode using this command without Pseudo-APDU header.
APDU command: (Enter 0 to exit)
FF694442056892000400
Command : FF694442056892000400
Response : 433630335F435A375F425F31353038323100099000
//I successfully received Firmware version in APDU mode using the fixed Pseudo-APDU header.
APDU command: (Enter 0 to exit)
00A4040000
Command : 00A4040000
Response : 6F198408A000000018434D00A50D9F6E061291921101009F6501FF9000
APDU command: (Enter 0 to exit)
0
BUILD SUCCESSFUL (total time: 1 minute 36 seconds)
Is there any problem still?
Yes, two problems!:
1-the above program works fine only for its first run. I mean, if I stop running and rerun it, the second method throw an exception:
run:
Available Readers:
[PC/SC terminal ACS ACR122 0, PC/SC terminal CREATOR CRT-603 (CZ1) CCR RF 0, PC/SC terminal CREATOR CRT-603 (CZ1) CCR SAM 0]
Which reader do you want to send your commands to? (0 or 1 or ...): 1
Write your commands in Hex form, without '0x' or Space charaters.
---------------------------------------------------
Pseudo-APDU Mode:
---------------------------------------------------
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
FF694442056892000400
Command : FF694442056892000400
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
6892000400
Command : 6892000400
Response : 433630335F435A375F425F31353038323100049000
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
0
---------------------------------------------------
APDU Mode:
---------------------------------------------------
APDU command: (Enter 0 to exit)
00A4040000
Command : 00A4040000
Exception in thread "main" javax.smartcardio.CardException: sun.security.smartcardio.PCSCException: Unknown error 0x16
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:219)
at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:90)
at TestPCSC.main(TestPCSC.java:58)
Caused by: sun.security.smartcardio.PCSCException: Unknown error 0x16
at sun.security.smartcardio.PCSC.SCardTransmit(Native Method)
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:188)
... 2 more
Java Result: 1
BUILD SUCCESSFUL (total time: 39 seconds)
As you see above, I can't use second method anymore and I need to power-off the reader and power on it again to make it work fine again.
2-The contact interface (I mean the SAM reader) throw previous exception always! I mean the second method doesn`t work at all (neither first run, nor second and third .... )
Note that I tried different readers, it seems that this is not limited only ti this reader. Some ACS readers also have a similar or exactly the same problem with rerun
Does anyone have any idea?
And as a side question, does Python have any equal methods for sending Pseudo-APDU like Java?
And finally, from the view of Reader, what's the difference between connection.transmitControlCommand and cardChannel.transmit() methods?
When you stop "Smart Card" service, does the tool still return a firmware version? If yes, then the tool might use raw IOCTL commands (DeviceIoControl) to communicate with the driver.
Also take a look at this question. The author says you have to set SCARD_PROTOCOL_UNDEFINED as protocol parameter:
SCardConnect(hSC,
readerState.szReader,
SCARD_SHARE_DIRECT,
SCARD_PROTOCOL_UNDEFINED,
&hCH,
&dwAP
);
I just tried it and it seems to work for Windows 10 at least. Communication was possible with no card inserted. I did not test for other Windows versions though.
readers() is array index of available readers
reader = r[target_reader]
convert
reader = r[int(target_reader)]
output
Available Readers : ['JAVACOS Virtual Contact Reader 0', 'JAVACOS Virtual Contactless Reader 1', 'OMNIKEY CardMan 3x21 0']
--- Select Reader (0, 1 , ...): 2
Using : OMNIKEY CardMan 3x21 0
ATR : 3B 9E 94 80 1F 47 80 31 A0 73 BE 21 13 66 86 88 02 14 4B 10 19

Qt 5.4 Linux Touchscreen Input with Tslib on Raspberry Pi failing with LinuxFB QPA Platform Plugin

I bought a Tontec 2.4 Inch Touchscreen ( http://elinux.org/MZTX-PI-EXT ) for my Raspberry Pi. The touchscreen controller requires the "tsc2007.ko" and "tsp_raspi.ko" kernel modules as described in the elinux post. The tsc2007.ko module is in the Raspbian Kernel tree but the tsp_raspi.ko can be found here: https://github.com/osandov/raspi/tree/master/tsc2007.
I've cross compiled a new Kernel for the Pi with those modules and they load fine and create a /dev/input/event0 device in Raspbian. If I 'evtest' that device and touch the screen, I get output so I know the events are being delivered in Linux:
pi#raspberry /dev/input $ evtest
Available devices:
/dev/input/event0: TSC2007 Touchscreen
Select the device event number [0-0]: 0
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "TSC2007 Touchscreen"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 1922
Min 0
Max 4095
Fuzz 64
Event code 1 (ABS_Y)
Value 2221
Min 0
Max 4095
Fuzz 64
Event code 24 (ABS_PRESSURE)
Value 0
Min 0
Max 4095
Fuzz 64
Properties:
Testing ... (interrupt to exit)
Event: time 1425521704.199489, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1425521704.199489, type 3 (EV_ABS), code 1 (ABS_Y), value 2085
Event: time 1425521704.199489, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 538
Event: time 1425521704.199489, -------------- SYN_REPORT ------------
Event: time 1425521704.209174, type 3 (EV_ABS), code 0 (ABS_X), value 1455
...
I installed tslib and ran a quick ts_calibrate. I also made sure that ts_test spit out data when I touched the screen.
I added the following environment variables to /etc/profile for tslib support in Qt5:
## For Qt5 Touchscreen Support
export QT_DEBUG_PLUGINS=1
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/arm-linux-gnueabihf/
export QT_PLUGIN_PATH=/usr/lib/plugins
export QT_QPA_FONTDIR=/usr/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/plugins/platforms
export QT_QPA_PLATFORM=linuxfb
export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event0
export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0
export TSLIB_TSEVENTTYPE='INPUT'
export TSLIB_CALIBFILE='/etc/pointercal'
export TSLIB_CONFFILE='/etc/ts.conf'
export TSLIB_CONSOLEDEVICE='none'
export TSLIB_FBDEVICE='/dev/fb0'
export TSLIB_PLUGINDIR='/usr/lib/ts'
export TSLIB_TSDEVICE='/dev/input/event0'
I read up on the Qt5 docs and how to get touch events in my app. I have a main Widget and set the appropriate flags in the constructor:
MainWidget::MainWidget(QLabel *parent)
: QLabel(parent)
{
qDebug() << "Setting WA_AcceptTouchEvents on MainWidget...";
// Accept touch events
setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_StaticContents);
}
I setup an event filter to try to catch the touch events:
bool MainWidget::eventFilter( QObject* target, QEvent* e )
{
qDebug() << "Event Type: " << e->type();
return false;
return QLabel::eventFilter(target, e);
}
I launch my app like this:
myapp -platform linuxfb:fb=/dev/fb0 -plugin tslib:/dev/input/event0
I also uncommented a single printf in Qt's source code for the qtslib.cpp:
void QTsLibMouseHandler::readMouseData()
{
ts_sample sample;
while (get_sample(m_dev, &sample, m_rawMode)) {
bool pressed = sample.pressure;
int x = sample.x;
int y = sample.y;
// work around missing coordinates on mouse release
if (sample.pressure == 0 && sample.x == 0 && sample.y == 0) {
x = m_x;
y = m_y;
}
if (!m_rawMode) {
//filtering: ignore movements of 2 pixels or less
int dx = x - m_x;
int dy = y - m_y;
if (dx*dx <= 4 && dy*dy <= 4 && pressed == m_pressed)
continue;
}
QPoint pos(x, y);
//printf("handleMouseEvent %d %d %d %ld\n", m_x, m_y, pressed, sample.tv.tv_usec);
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
m_x = x;
m_y = y;
m_pressed = pressed;
}
}
When I launch my Qt app I see the plugins are loading OK ( even shows the correct event0 file ). I also see that the qt tslib plugin is receiving touch events when I touch the screen. The problem is that the event filter is NEVER called!
Here is the app being launched:
Got keys from plugin meta data ("tslib", "tslibraw")
QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/generic" ...
loaded library "/usr/lib/qt/plugins/generic/libqtslibplugin.so"
QTsLibMouseHandler "tslib" ""
QTsLibMouseHandler "tslib" "/dev/input/event0"
QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/qt/plugins/styles" ...
QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/styles" ...
Setting WA_AcceptTouchEvents on MainWidget...
-----------------------------------------
Waiting for data now...
-----------------------------------------
handleMouseEvent 0 0 1 751196
handleMouseEvent 0 0 1 751196
handleMouseEvent 1696 1615 1 771075
handleMouseEvent 1696 1615 1 771075
handleMouseEvent 1679 1622 1 781368
handleMouseEvent 1671 1638 1 781368
handleMouseEvent 1679 1622 1 781368
handleMouseEvent 1671 1638 1 781368
...
I found a few forum posts where people are having problems with touch input with the linuxfb platform plugin:
http://comments.gmane.org/gmane.comp.lib.qt.user/5686
http://qt-project.org/forums/viewthread/35757
http://qt-project.org/forums/viewthread/36120/
I've tried all their suggestions and still have the problem - no touch events are received by my app even though the Qt tslib plugin says it is receiving them.
It seems that the tslib plugin is having problems injecting the event it receives into my app's event loop with this:
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
I also tried the Qt5.4 touch fingerpaint example and see the same behavior - no touch events are received.
I'm not sure where to go from here. I would greatly appreciate any help solving this issue. Thanks!
UPDATE:
I changed my event filter so it looks like this:
bool MainWidget::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "Event received" << obj->metaObject()->className() << event->type();
switch (event->type()) {
case QEvent::TouchBegin:
qDebug() << "TouchBegin";
case QEvent::TouchUpdate:
qDebug() << "TouchUpdate";
case QEvent::TouchEnd:
qDebug() << "TouchEnd";
{
// QTouchEvent *touch = static_cast<QTouchEvent *>(event);
// QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
// foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
// switch (touchPoint.state()) {
// case Qt::TouchPointStationary:
// // don't do anything if this touch point hasn't moved
// continue;
// default:
// {
// }
// break;
// }
// }
// break;
}
//default:
//return QLabel::event(event);
}
//return true;
}
Now I can see 'socket notifier' events intermingled with Qt Tslib Plugin's prints whenever I touch the screen. Any ideas as to why Event Type 50 but no Touch Events?
Event received QSocketNotifier 50
handleMouseEvent 2702 2618 0 557715
Event received QSocketNotifier 50
handleMouseEvent 2698 2612 1 547758
Event received QSocketNotifier 50
handleMouseEvent 2706 2802 1 759928
Event received QSocketNotifier 50
Event received QSocketNotifier 50
UPDATE #2:
I installed the event filter only to try to catch any events. I'm not sure in Qt5 what translates an event type 50 ( QSocketNotifier ) to a QTouch* or QMouse* event.
Here is some more information:
When I run evtest, I see that the screen resolution is huge ( ~2500 x
~2500 ) and the actual screen is 320x240. I tried changed the
/dev/fb0 framebuffer size in /boot/config.txt to 320x240 and
rebooted. But the evtest and ts_calibrate steps still show the huge
resolution.
Because of the large resolution, I tried making my main widget
10000x10000 to see if I would get a touch or mouse event - but I
still only get the QSocketNotifier
I then tried to force the tslib plugin to always inject events at
screen position X=50 Y=50, but I still only get the event type 50
QSocketNotifier.
The problem was solved by making sure the tslib plugins were installed on the RasbperryPi.
TSLIB_PLUGINDIR=/usr/lib/ts
The directory /usr/lib/ts was not present on the Pi.

TinyX shows display using builtin fbtft touchscreen driver but touch doesn't work

I'm using an "adafruitts" touchscreen with a raspi to control a usb peripheral.
The full raspbian kernel takes forever to boot (50 seconds), and part of that is due to the touchscreen driver loading (by modprobe/udev) and initializing.
During the first 20-30 seconds of boot, the display is not loaded, so it is blank. I need this to be a user-friendly item that cannot be blank for 30 seconds each time it is turned on, so I've used buildroot to build a small kernel with the touchscreen driver built-in. (I am on a steep learning curve with buildroot and kernel building in general).
The display driver is fbtft_device.c patched to include the adafruitts display. This patch defines the "touch" half:
/* Touch device spi-half of adafruit touchscreen */
.name = "adafruitts",
.spi = &(struct spi_board_info) {
.modalias = "stmpe610",
.max_speed_hz = 500000,
.mode = SPI_MODE_0,
.chip_select = 1,
.platform_data = &(struct stmpe_platform_data) {
.blocks = STMPE_BLOCK_TOUCHSCREEN | STMPE_BLOCK_GPIO,
.irq_over_gpio = 1,
.irq_gpio = 24,
.irq_trigger = IRQF_TRIGGER_FALLING,
.irq_base = GPIO_IRQ_START + GPIO_IRQS,
.ts = &(struct stmpe_ts_platform_data) {
.sample_time = 4,
.mod_12b = 1,
.ref_sel = 0,
.adc_freq = 2,
.ave_ctrl = 3,
.touch_det_delay = 4,
.settling = 2,
.fraction_z = 7,
.i_drive = 0,
},
}
},
.is_support = 1,
.gpio_settings = (struct gpio_setting []) {
{
.gpio = 24,
.pull = pull_up,
}
},
.gpio_num_settings = 1,
},
and the LCD half:
}, {
/* LCD component of adafruit touchscreen */
.name = "adafruitts",
.spi = &(struct spi_board_info) {
.modalias = "fb_ili9340",
.max_speed_hz = 16000000,
.mode = SPI_MODE_0,
.chip_select = 0,
.platform_data = &(struct fbtft_platform_data) {
.display = {
.buswidth = 8,
.backlight = 1,
},
.bgr = true,
.gpios = (const struct fbtft_gpio []) {
{ "dc", 25 },
{},
},
}
}
}, {
by including:
fbtft_device.name=adafruitts
in the cmdline.txt for the boot loader, I've gotten the display half of the system to work (it boots in ~ 5 seconds :) ) with tinyX/matchbox desktop showing the desktop, but I cannot get the touchscreen part to work (the cursor does not move when I touch the screeen).
Somehow I have to bind the touch part of the touchscreen to tinyX, but I have not been able to figure out how to do this.
I have tried to specify the keyboard (and mouse) when launching tinyX:
X -keybd smpte610 (for example)
but X reports it cannot find the driver.
How can I verify the touch screen input device was successfully loaded?
The boot log has these messages about fbtft_device:
fbtft_device: SPI devices registered:
fbtft_device: spidev spi0.0 500kHz 8 bits mode=0x00
fbtft_device: spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device: 'fb' Platform devices registered:
fbtft_device: bcm2708_fb id=-1 pdata? no
fbtft_device: Deleting spi0.1 (spi0.1)
fbtft_device: Looking at item 0
fbtft_device: Setting pin 24 to 2
stmpe-spi: probe of spi0.1 failed with error -22
fbtft_device: Deleting spi0.0 (spi0.0)
Console: switching to colour frame buffer device 40x30
graphics fb0: fb_ili9340 frame buffer, 320x240, 150 KiB video memory, 16 KiB buffer memory, fps=20, spi0.0 at 16 MHz
fbtft_device: GPIOS used by 'adafruitts':
fbtft_device: 'dc' = GPIO25
fbtft_device: SPI devices registered:
fbtft_device: stmpe610 spi0.1 48000kHz 8 bits mode=0x00
fbtft_device: fb_ili9340 spi0.0 16000kHz 8 bits mode=0x00
kgdb: Registered I/O driver kgdboc.
Is the kgdb message associated with fbtft_device or something else?
If I look in /dev/input I see: event0, event1, and mice. event0 and event1 are associated with an attached keyboard (according to the boot log) and I have no mouse attached. Should there be some other items in input?
If the touch screen input device IS loaded, how to I specify the correct driver for tinyX?
Thanks
What I learned:
By comparing the boot messages in my modprobe/udev/module loading kernel with the fast built-in kernel, it shows:
stmpe-spi: probe of spi0.1 failed with error -22
is a "bad" thing.
A successful driver load will say (something like):
bcm2708_spi.0: registered child spi0.0
and then later:
input: stmpe-ts as /devices/virtual/input/input0
I fixed the "probe" failure by making these changes to my kernel configuration file. (Sorry, I don't want to include the whole thing, so these are the changes from when I had the issue to when the driver successfully loaded according to the syslog):
< Touch Did Not respond > Touch Did respond
> CONFIG_INPUT_FF_MEMLESS=y
< CONFIG_INPUT_POLLDEV=m > CONFIG_INPUT_POLLDEV=y
< CONFIG_INPUT_EVDEV=m > CONFIG_INPUT_EVDEV=y
< CONFIG_TOUCHSCREEN_STMPE=m > CONFIG_TOUCHSCREEN_STMPE=y
> CONFIG_KEYBOARD_STMPE=y
< CONFIG_SERIO=m > CONFIG_SERIO_SERPORT=m
> CONFIG_SPI_DEBUG=y
< CONFIG_SPI_SPIDEV=y
> CONFIG_SPI_GPIO=y
My main objective with these changes was to try to make sure that the dependent drivers were also built-in, and I enabled the debug. (Some of these were magically set by menuconfig, and this is diff from the "non-default" values from buildroot, so the diff is - different)
With this config, I now have event0, event1, event2, mice, and mouse0. The syslog says event1 and event2 are associated with the usb keyboard I have attached. I have no extra mouse attached.
I could use "evtest" to see events from /dev/input/event0 whenever I touched the display. evtest'ing /dev/input/mouse0 threw "Inappropriate ioctl for device"
I restarted X (tinyX) using:
X -mouse mouse,,/dev/input/mouse0
and touches worked, but the touch axis is rotated from the display axis.
I could not figure out a way to fix this in tinyX, so I'm going with a full blown Xorg implementation.
Make sure you have enabled the evdev input support in tinyx (BR2_PACKAGE_XSERVER_XORG_SERVER_KDRIVE_EVDEV) and use the syntax specified in hw/kdrive/src/kinput.c:
/*
* You can call your kdriver server with something like:
* $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
* evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
*/

Resources