-
Notifications
You must be signed in to change notification settings - Fork 0
/
mtif.lisp
135 lines (109 loc) · 3.93 KB
/
mtif.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
;;;; MTIF
;;;; [email protected]
;;;;
;;;; User API and FFI driver
(in-package :mtif)
(defvar *mtif-started* nil
"Whether we have started using a device or not")
(defvar *mtif-handle* nil
"Handle to the MT device, used for stopping/starting")
(defvar *mtif-callback* nil
"User callback to call with the touchpad data")
(defvar *init-complete* nil
"Signal whether things have been setup")
(defvar *frame-count* 0
"The number of frames received since last call to `start'")
(defvar *frame-limit* 0
"Maximum number of frames to process (ignored if nil)")
(define-condition err-not-started (simple-error)
())
(define-condition err-already-started (simple-error)
())
(defstruct finger
"Finger data"
(id "Numeric identifier for this finger")
(state "The finger state")
(size "Measure of the area covered by the finger")
(pos-x "Normalised X position")
(pos-y "Normalised Y position")
(vel-x "Normalised X velocity")
(vel-y "Normalised Y velocity")
(ellipse-angle "Angle of the finger ellipsoid")
(ellipse-major-axis "Major axis of the finger ellipsoid")
(ellipse-minor-axis "Minor axis of the finger ellipsoid"))
(defun get-readout (mtReadout slot1 slot2)
(getf (getf mtReadout slot1) slot2))
(defmethod translate-from-foreign (ptr (type c-finger))
"`ptr' is to c-finger type"
(with-foreign-slots
((path-id state size normalized angle major-axis minor-axis)
ptr (:struct Finger))
(make-finger
:id path-id
:state state
:size size
:ellipse-angle angle
:ellipse-major-axis major-axis
:ellipse-minor-axis minor-axis
:pos-x (get-readout normalized 'position 'x)
:pos-y (get-readout normalized 'position 'y)
:vel-x (get-readout normalized 'velocity 'x)
:vel-y (get-readout normalized 'velocity 'y))))
;; call (reset) before you redefine this!
(defcallback mtcallback :int
((device :int)
(data (:pointer (:struct Finger)))
(nFingers :int)
(timestamp :double)
(frame :int))
(declare (ignore device))
(prog1 0
(when (or (not (numberp *frame-limit*))
(< *frame-count* *frame-limit*))
(incf *frame-count*)
(unless (null *mtif-callback*)
(let ((finger-data (loop for i from 0 to (1- nFingers)
collect (mem-aref data '(:struct Finger) i))))
;; User defined callback:
(restart-case
(funcall (symbol-value '*mtif-callback*)
finger-data timestamp frame)
(ignore-it ()
:report "Ignore the MT callback error"
t)
(kill-mtif ()
:report "Stop MTIF"
(stop))))))))
(defun print-all-touches (finger-data timestamp frame)
"Example callback which just prints all touches to *standard-output*"
(format t "~A [~{~A~% ~}]~%" (length finger-data) finger-data))
(defun init-device ()
"Initial setup - create device, register callback"
(setf *mtif-handle* (mtdevicecreatedefault))
(mtregistercontactframecallback *mtif-handle*
(get-callback 'mtcallback))
(setf *init-complete* t))
(defun start (callback &optional frame-limit)
"Start the MT interface with `callback' receiving the data"
(unless *init-complete* (init-device))
(if *mtif-started* (error 'err-already-started))
(setf *mtif-callback* callback)
(setf *frame-count* 0)
(setf *frame-limit* frame-limit)
(mtdevicestart *mtif-handle* 0)
(setf *mtif-started* t))
(defun stop ()
"Stop the MT interface"
(unless *mtif-started* (error 'err-not-started))
(setf *mtif-started* nil)
(mtdevicestop *mtif-handle*))
(defun reset ()
"Reset the device"
(if *init-complete*
(progn (handler-case
(stop)
(err-not-started ()))
(mtunregistercontactframecallback *mtif-handle*
(get-callback 'mtcallback))
(setf *init-complete* nil))
(warn "Not initialised")))