1 /*
2  *  Copyright (c) 2014 Dmitry Kazakov <dimula73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "kis_tablet_debugger.h"
20 
21 #include <QEvent>
22 #include <QMessageBox>
23 
24 #include <kis_debug.h>
25 #include <kis_config.h>
26 
27 #include <QGlobalStatic>
28 
29 #include <klocalizedstring.h>
30 
Q_GLOBAL_STATIC(KisTabletDebugger,s_instance)31 Q_GLOBAL_STATIC(KisTabletDebugger, s_instance)
32 
33 
34 inline QString button(const QWheelEvent &ev) {
35     Q_UNUSED(ev);
36     return "-";
37 }
38 
39 template <class T>
button(const T & ev)40 QString button(const T &ev) {
41     return QString::number(ev.button());
42 }
43 
44 template <class T>
buttons(const T & ev)45 QString buttons(const T &ev) {
46     return QString::number(ev.buttons());
47 }
48 
49 template <class Event>
dumpBaseParams(QTextStream & s,const Event & ev,const QString & prefix)50     void dumpBaseParams(QTextStream &s, const Event &ev, const QString &prefix)
51 {
52     s << qSetFieldWidth(5)  << left << prefix << reset << " ";
53     s << qSetFieldWidth(17) << left << KisTabletDebugger::exTypeToString(ev.type()) << reset;
54 }
55 
56 template <class Event>
dumpMouseRelatedParams(QTextStream & s,const Event & ev)57     void dumpMouseRelatedParams(QTextStream &s, const Event &ev)
58 {
59     s << "btn: " << button(ev) << " ";
60     s << "btns: " << buttons(ev) << " ";
61     s << "pos: " << qSetFieldWidth(4) << ev.x() << qSetFieldWidth(0) << "," << qSetFieldWidth(4) << ev.y() << qSetFieldWidth(0) << " ";
62     s << "gpos: "  << qSetFieldWidth(4) << ev.globalX() << qSetFieldWidth(0) << "," << qSetFieldWidth(4) << ev.globalY() << qSetFieldWidth(0) << " ";
63 }
64 
exTypeToString(QEvent::Type type)65 QString KisTabletDebugger::exTypeToString(QEvent::Type type) {
66     return
67         type == QEvent::TabletEnterProximity ? "TabletEnterProximity" :
68         type == QEvent::TabletLeaveProximity ? "TabletLeaveProximity" :
69         type == QEvent::Enter ? "Enter" :
70         type == QEvent::Leave ? "Leave" :
71         type == QEvent::FocusIn ? "FocusIn" :
72         type == QEvent::FocusOut ? "FocusOut" :
73         type == QEvent::Wheel ? "Wheel" :
74         type == QEvent::KeyPress ? "KeyPress" :
75         type == QEvent::KeyRelease ? "KeyRelease" :
76         type == QEvent::ShortcutOverride ? "ShortcutOverride" :
77         type == QMouseEvent::MouseButtonPress ? "MouseButtonPress" :
78         type == QMouseEvent::MouseButtonRelease ? "MouseButtonRelease" :
79         type == QMouseEvent::MouseButtonDblClick ? "MouseButtonDblClick" :
80         type == QMouseEvent::MouseMove ? "MouseMove" :
81         type == QTabletEvent::TabletMove ? "TabletMove" :
82         type == QTabletEvent::TabletPress ? "TabletPress" :
83         type == QTabletEvent::TabletRelease ? "TabletRelease" :
84         type == QTouchEvent::TouchBegin ? "TouchBegin" :
85         type == QTouchEvent::TouchUpdate ? "TouchUpdate" :
86         type == QTouchEvent::TouchEnd ? "TouchEnd" :
87         type == QTouchEvent::TouchCancel ? "TouchCancel" :
88         "unknown";
89 }
90 
91 
KisTabletDebugger()92 KisTabletDebugger::KisTabletDebugger()
93     : m_debugEnabled(false)
94 {
95     KisConfig cfg(true);
96     m_shouldEatDriverShortcuts = cfg.shouldEatDriverShortcuts();
97 }
98 
instance()99 KisTabletDebugger* KisTabletDebugger::instance()
100 {
101     return s_instance;
102 }
103 
toggleDebugging()104 void KisTabletDebugger::toggleDebugging()
105 {
106     m_debugEnabled = !m_debugEnabled;
107     QMessageBox::information(0, i18nc("@title:window", "Krita"), m_debugEnabled ?
108                              i18n("Tablet Event Logging Enabled") :
109                              i18n("Tablet Event Logging Disabled"));
110     if (m_debugEnabled) {
111         dbgTablet << "vvvvvvvvvvvvvvvvvvvvvvv START TABLET EVENT LOG vvvvvvvvvvvvvvvvvvvvvvv";
112     }
113     else {
114         dbgTablet << "^^^^^^^^^^^^^^^^^^^^^^^ END TABLET EVENT LOG ^^^^^^^^^^^^^^^^^^^^^^^";
115     }
116 }
117 
debugEnabled() const118 bool KisTabletDebugger::debugEnabled() const
119 {
120     return m_debugEnabled;
121 }
122 
initializationDebugEnabled() const123 bool KisTabletDebugger::initializationDebugEnabled() const
124 {
125     // FIXME: make configurable!
126     return true;
127 }
128 
debugRawTabletValues() const129 bool KisTabletDebugger::debugRawTabletValues() const
130 {
131     // FIXME: make configurable!
132     return m_debugEnabled;
133 }
134 
shouldEatDriverShortcuts() const135 bool KisTabletDebugger::shouldEatDriverShortcuts() const
136 {
137     return m_shouldEatDriverShortcuts;
138 }
139 
eventToString(const QMouseEvent & ev,const QString & prefix)140 QString KisTabletDebugger::eventToString(const QMouseEvent &ev, const QString &prefix)
141 {
142     QString string;
143     QTextStream s(&string);
144 
145     dumpBaseParams(s, ev, prefix);
146     dumpMouseRelatedParams(s, ev);
147     s << "hires: " << qSetFieldWidth(8) << ev.screenPos().x() << qSetFieldWidth(0) << "," << qSetFieldWidth(8) << ev.screenPos().y() << qSetFieldWidth(0) << " ";
148     s << "Source:" << ev.source();
149 
150     return string;
151 }
152 
eventToString(const QKeyEvent & ev,const QString & prefix)153 QString KisTabletDebugger::eventToString(const QKeyEvent &ev, const QString &prefix)
154 {
155     QString string;
156     QTextStream s(&string);
157 
158     dumpBaseParams(s, ev, prefix);
159 
160     s << "key: 0x" << hex << ev.key() << reset << " ";
161     s << "mod: 0x" << hex << ev.modifiers() << reset << " ";
162     s << "text: " << (ev.text().isEmpty() ? "none" : ev.text());
163 
164     return string;
165 }
166 
eventToString(const QWheelEvent & ev,const QString & prefix)167 QString KisTabletDebugger::eventToString(const QWheelEvent &ev, const QString &prefix)
168 {
169     QString string;
170     QTextStream s(&string);
171 
172     dumpBaseParams(s, ev, prefix);
173     dumpMouseRelatedParams(s, ev);
174 
175     s << "delta: " << ev.delta() << " ";
176     s << "orientation: " << (ev.orientation() == Qt::Horizontal ? "H" : "V") << " ";
177 
178     return string;
179 }
180 
eventToString(const QTouchEvent & ev,const QString & prefix)181 QString KisTabletDebugger::eventToString(const QTouchEvent &ev, const QString &prefix)
182 {
183     QString string;
184     QTextStream s(&string);
185 
186     dumpBaseParams(s, ev, prefix);
187 
188     s << (ev.device()->type() ? "TouchPad" : "TouchScreen") << " ";
189     for (const auto& touchpoint: ev.touchPoints()) {
190         s << "id: " << touchpoint.id() << " ";
191         s << "hires: " << qSetFieldWidth(8) << touchpoint.screenPos().x() << qSetFieldWidth(0) << "," << qSetFieldWidth(8) << touchpoint.screenPos().y() << qSetFieldWidth(0) << " ";
192         s << "prs: " << touchpoint.pressure() << " ";
193         s << "rot: "<< touchpoint.rotation() << "; ";
194     }
195 
196     return string;
197 }
198 
eventToString(const QEvent & ev,const QString & prefix)199 QString KisTabletDebugger::eventToString(const QEvent &ev, const QString &prefix)
200 {
201     QString string;
202     QTextStream s(&string);
203 
204     dumpBaseParams(s, ev, prefix);
205 
206     return string;
207 }
208 
209 template <class Event>
tabletEventToString(const Event & ev,const QString & prefix)210     QString tabletEventToString(const Event &ev, const QString &prefix)
211 {
212     QString string;
213     QTextStream s(&string);
214 
215     dumpBaseParams(s, ev, prefix);
216     dumpMouseRelatedParams(s, ev);
217 
218     s << "hires: " << qSetFieldWidth(8) << ev.hiResGlobalX() << qSetFieldWidth(0) << "," << qSetFieldWidth(8) << ev.hiResGlobalY() << qSetFieldWidth(0) << " ";
219     s << "prs: " << qSetFieldWidth(4) << fixed << ev.pressure() << reset << " ";
220 
221     s << KisTabletDebugger::tabletDeviceToString((QTabletEvent::TabletDevice) ev.device()) << " ";
222     s << KisTabletDebugger::pointerTypeToString((QTabletEvent::PointerType) ev.pointerType()) << " ";
223     s << "id: " << ev.uniqueId() << " ";
224 
225     s << "xTilt: " << ev.xTilt() << " ";
226     s << "yTilt: " << ev.yTilt() << " ";
227     s << "rot: " << ev.rotation() << " ";
228     s << "z: " << ev.z() << " ";
229     s << "tp: " << ev.tangentialPressure() << " ";
230 
231     return string;
232 }
233 
eventToString(const QTabletEvent & ev,const QString & prefix)234 QString KisTabletDebugger::eventToString(const QTabletEvent &ev, const QString &prefix)
235 {
236     return tabletEventToString(ev, prefix);
237 }
238 
tabletDeviceToString(QTabletEvent::TabletDevice device)239 QString KisTabletDebugger::tabletDeviceToString(QTabletEvent::TabletDevice device)
240 {
241     return
242         device == QTabletEvent::NoDevice ? "NoDevice" :
243         device == QTabletEvent::Puck ? "Puck" :
244         device == QTabletEvent::Stylus ? "Stylus" :
245         device == QTabletEvent::Airbrush ? "Airbrush" :
246         device == QTabletEvent::FourDMouse ? "FourDMouse" :
247         device == QTabletEvent::XFreeEraser ? "XFreeEraser" :
248         device == QTabletEvent::RotationStylus ? "RotationStylus" :
249         "unknown";
250 }
251 
pointerTypeToString(QTabletEvent::PointerType pointer)252 QString KisTabletDebugger::pointerTypeToString(QTabletEvent::PointerType pointer) {
253     return
254         pointer == QTabletEvent::UnknownPointer ? "UnknownPointer" :
255         pointer == QTabletEvent::Pen ? "Pen" :
256         pointer == QTabletEvent::Cursor ? "Cursor" :
257         pointer == QTabletEvent::Eraser ? "Eraser" :
258         "unknown";
259 }
260 
261