Re: [PATCH 2/2] elantech: Report multitouch with proper ABS_MT messages

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Op 05-05-10 21:06, Henrik Rydberg schreef:
> Éric Piel wrote:
>>
>> BTW, does anyone know a graphical app which reads the MT events from a
>> /dev/input/eventX device and displays them as points in a window? That
>> would be rather helpful to reverse-engineer/debug multitouch hardwares.
> 
> Something like fingermgmt in OSX? Not to my knowledge. The touchd project
> includes some graphics via python, but is not based on MT events. Maybe our
> friends at ENAC has something cooking?

Thanks a lot for the tips.
I've hacked up an app which does just this, based on touchd and
pyinputevent.

Apparently when there are two fingers, the hardware doesn't report
really the finger coordinates but the lowest and highest points of the
rectangle defined by the two fingers.

For those who want to tinker too, attached is the source code of my
hack. Note that the synaptics driver grabs the event device so normally
you cannot receive anything. So you need to disable it, for instance
with a HAL rule like this:
 <?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
  <device>
    <match key="info.capabilities" contains="input.touchpad">
       <match key="info.product" contains="ETPS/2 Elantech Touchpad">
        <merge key="input.x11_driver" type="string">mult</merge>
       </match>
    </match>
  </device>
</deviceinfo>

Then a rmmod psmouse; modprobe psmouse should free the device. You also
need pyinputevent.py in the same directory.

See you,
Eric
# Copyright 2010, Eric Piel <eric.piel@xxxxxxxxxxxxxxxx>

# This file contains part of touchd - 2008, Scott Shawcroft, scott.shawcroft@xxxxxxxxx
# This file uses pyinputevent available http://github.com/rmt/pyinputevent/ by Robert Thomson and individual contributors.

# FingerViewer is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.

# FingerViewer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with FingerViewer.  If not, see <http://www.gnu.org/licenses/>.

# Runs the finger view window.
# use a command like:
# sudo python fingerviewer.py /dev/input/event1

import pygtk
import gtk
import math
import time
import threading, thread
from pyinputevent import *

gtk.gdk.threads_init()


class MouseDevice(SimpleDevice):
    """
    Report Multitouch events
    """
    def __init__(self, viewer, *args, **kwargs):
        SimpleDevice.__init__(self, *args, **kwargs)
        self.viewer = viewer
        self.x = 0
        self.y = 0
        self.num = 0
    def receive(self, event):
        etype, ecode, evalue = (
            event.etype,
            event.ecode,
            event.evalue,
        )
        #print "%s" % event
        if etype == 3:
            if ecode == 53:
                self.x = evalue
            elif ecode == 54:
                self.y = evalue
        elif etype == 0:
            if ecode == 2:
               viewer.got_finger(self.num, self.x, self.y, 0, 0, 10)
               self.num += 1
            elif ecode == 0:
               self.num = 0
            

class FingerViewer:
	def __init__(self):
		self.window = gtk.Window()
		self.window.set_title("Fingers")
		self.width = 400
		self.height = 200
		self.window.width = self.width
		self.window.height = self.height
		
		self.window.connect("destroy",self.hide)
		self.window.show()
		
		self.image = gtk.Image()
		self.image.show()
		self.window.add(self.image)
		
		pixmap = gtk.gdk.Pixmap(None,self.width,self.height,24)
		self.image.set_from_pixmap(pixmap,None)
		self.context = pixmap.cairo_create()
		self.context.rectangle(0,0,self.width,self.height)
		self.context.set_source_rgb(1,1,1)
		self.context.fill()
		
		self.context.set_line_width(2)
		
		self.fingers = []
	
	def got_finger(self,num,x,y,dx,dy,p):
		if num==0:
			# update the image
			self.draw_all()
		
		self.fingers.append((num,x,y,dx,dy,p))

	def draw_all(self):
		self.context.rectangle(0,0,self.width,self.height) # fill with white
		self.context.set_source_rgb(1,1,1)
		self.context.fill()
		
		for i in range(len(self.fingers)):
			num,x,y,dx,dy,p = self.fingers[i]
			self.draw_finger(num,x,y,dx,dy,p)
		
		self.image.queue_draw()
		self.fingers = []

	def draw_finger(self,num,x,y,dx,dy,p):
		dy*=-1
		
		# draw the finger
		tx = self.translate_x(x)
		ty = self.translate_y(y)
		self.context.arc(tx,ty,10+p/500.0*20,0,2*math.pi)
		self.context.set_source_rgba(0,0,1)
		self.context.fill()
		
		# draw the velocity
		VRES = 500
		VSCALE = 100
		self.context.set_source_rgb(0,0,0)
		self.context.move_to(tx,ty)
		self.context.line_to(tx+(float(dx)/VRES)*VSCALE,ty-(float(dy)/VRES)*VSCALE)
		self.context.stroke()
		
		# draw number label
		self.context.set_source_rgb(1,1,1)
		self.context.move_to(tx-5,ty+5)
		self.context.set_font_size(15)
		self.context.show_text(str(num+1))
	
	def num_fingers(self,i):
		if i==0:
			self._wipe()
	
	# translate to the graphical coordinates
	def translate_x(self,v):
		XRES = 1152
		return ((float(v)/XRES)*(self.width))
	
	# translate to the graphical coordinates
	def translate_y(self,v):
		YRES = 768
		YOFF = 0
		return ((float(v+YOFF)/YRES)*(self.height))
	
	def hide(self,widget):
		#self.window.hide()
                gtk.main_quit()

	def readValues(self, args):
            import select
            controller = Controller("Controller")
            fds = {}
            poll = select.poll()
            dev = args
            print dev
            dev = MouseDevice(self, dev)
            fds[dev.fileno()] = dev
            poll.register(dev, select.POLLIN | select.POLLPRI)
            while True:
                for x,e in poll.poll():
                    dev = fds[x]
                    dev.read()

if __name__ == "__main__":
    viewer = FingerViewer()
    threading.Thread(target=viewer.readValues, args=sys.argv[1:]).start()
    gtk.main()


# vim:shiftwidth=4:expandtab:spelllang=en_gb:spell:         

[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux