chalk

kis_canvas.h
1/*
2 * Copyright (c) 1999 Matthias Elter <me@kde.org>
3 * Copyright (c) 2004-2006 Adrian Page <adrian@pagenet.plus.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#ifndef KIS_CANVAS_H_
21#define KIS_CANVAS_H_
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <tqwidget.h>
28#ifdef HAVE_GL
29#include <tqgl.h>
30#endif
31#include <tqpainter.h>
32
33#include "kis_global.h"
34#include "kis_point.h"
35#include "kis_vec.h"
36#include "kis_input_device.h"
37
38#ifdef Q_MOC_RUN
39#define TQ_WS_X11
40#endif // Q_MOC_RUN
41
42#ifdef TQ_WS_X11
43
44#if defined(HAVE_XINPUTEXT)
45#define EXTENDED_X11_TABLET_SUPPORT
46#endif
47
48#include <map>
49#include <X11/Xlib.h>
50
51#if defined(EXTENDED_X11_TABLET_SUPPORT)
52#include <X11/extensions/XInput.h>
53#endif
54
55#endif // TQ_WS_X11
56
57class KisEvent;
58class KisMoveEvent;
59class KisButtonPressEvent;
60class KisButtonReleaseEvent;
61class KisDoubleClickEvent;
62class KisCanvasWidgetPainter;
63
64class KisCanvasWidget : public TQObject {
65 TQ_OBJECT
66
67
68public:
69 KisCanvasWidget();
70 virtual ~KisCanvasWidget();
71
72 // When enabled, the canvas may throw away move events if the application
73 // is unable to keep up with them, i.e. intermediate move events in the event
74 // queue are skipped.
75 void enableMoveEventCompressionHint(bool enableMoveCompression) { m_enableMoveEventCompressionHint = enableMoveCompression; }
76
77 virtual KisCanvasWidgetPainter *createPainter() = 0;
78
79#ifdef EXTENDED_X11_TABLET_SUPPORT
80 static KisInputDevice findActiveInputDevice();
81 virtual void selectTabletDeviceEvents() = 0;
82
83 static void selectTabletDeviceEvents(TQWidget *widget);
84#endif
85
86#ifdef TQ_WS_X11
87 static void initX11Support();
88#endif
89
90signals:
91 void sigGotPaintEvent(TQPaintEvent*);
92 void sigGotEnterEvent(TQEvent*);
93 void sigGotLeaveEvent(TQEvent*);
94 void sigGotMouseWheelEvent(TQWheelEvent*);
95 void sigGotKeyPressEvent(TQKeyEvent*);
96 void sigGotKeyReleaseEvent(TQKeyEvent*);
97 void sigGotDragEnterEvent(TQDragEnterEvent*);
98 void sigGotDropEvent(TQDropEvent*);
99 void sigGotMoveEvent(KisMoveEvent *);
100 void sigGotButtonPressEvent(KisButtonPressEvent *);
101 void sigGotButtonReleaseEvent(KisButtonReleaseEvent *);
102 void sigGotDoubleClickEvent(KisDoubleClickEvent *);
103
104protected:
105 void widgetGotPaintEvent(TQPaintEvent *event);
106 void widgetGotMousePressEvent(TQMouseEvent *event);
107 void widgetGotMouseReleaseEvent(TQMouseEvent *event);
108 void widgetGotMouseDoubleClickEvent(TQMouseEvent *event);
109 void widgetGotMouseMoveEvent(TQMouseEvent *event);
110 void widgetGotTabletEvent(TQTabletEvent *event);
111 void widgetGotEnterEvent(TQEvent *event );
112 void widgetGotLeaveEvent(TQEvent *event);
113 void widgetGotWheelEvent(TQWheelEvent *event);
114 void widgetGotKeyPressEvent(TQKeyEvent *event);
115 void widgetGotKeyReleaseEvent(TQKeyEvent *event);
116 void widgetGotDragEnterEvent(TQDragEnterEvent *event);
117 void widgetGotDropEvent(TQDropEvent *event);
118 void moveEvent(KisMoveEvent *event);
119 void buttonPressEvent(KisButtonPressEvent *event);
120 void buttonReleaseEvent(KisButtonReleaseEvent *event);
121 void doubleClickEvent(KisDoubleClickEvent *event);
122 void translateTabletEvent(KisEvent *event);
123
124protected:
125
126 bool m_enableMoveEventCompressionHint;
127 double m_lastPressure;
128
129#ifdef TQ_WS_X11
130 // On X11 systems, TQt throws away mouse move events if the application
131 // is unable to keep up with them. We override this behaviour so that
132 // we receive all move events, so that painting follows the mouse's motion
133 // accurately.
134 bool x11Event(XEvent *event, Display *x11Display, WId winId, TQPoint widgetOriginPos);
135 static TQt::ButtonState translateX11ButtonState(int state);
136 static TQt::ButtonState translateX11Button(unsigned int button);
137
138 static bool X11SupportInitialised;
139
140 // Modifier masks for alt/meta - detected at run-time
141 static long X11AltMask;
142 static long X11MetaMask;
143
144 int m_lastRootX;
145 int m_lastRootY;
146
147#ifdef EXTENDED_X11_TABLET_SUPPORT
148
149public:
150 class X11TabletDevice
151 {
152 public:
153 X11TabletDevice();
154 X11TabletDevice(const XDeviceInfo *deviceInfo);
155
156 bool mightBeTabletDevice() const { return m_mightBeTabletDevice; }
157
158 XID id() const { return m_deviceId; }
159 XDevice *xDevice() const { return m_XDevice; }
160 TQString name() const { return m_name; }
161
162 KisInputDevice inputDevice() const { return m_inputDevice; }
163 void setInputDevice(KisInputDevice inputDevice) { m_inputDevice = inputDevice; }
164
165 void setEnabled(bool enabled);
166 bool enabled() const;
167
168 TQ_INT32 numAxes() const;
169
170 void setXAxis(TQ_INT32 axis);
171 void setYAxis(TQ_INT32 axis);
172 void setPressureAxis(TQ_INT32 axis);
173 void setXTiltAxis(TQ_INT32 axis);
174 void setYTiltAxis(TQ_INT32 axis);
175 void setWheelAxis(TQ_INT32 axis);
176 void setToolIDAxis(TQ_INT32 axis);
177 void setSerialNumberAxis(TQ_INT32 axis);
178
179 static const TQ_INT32 NoAxis = -1;
180 static const TQ_INT32 DefaultAxis = -2;
181
182 TQ_INT32 xAxis() const;
183 TQ_INT32 yAxis() const;
184 TQ_INT32 pressureAxis() const;
185 TQ_INT32 xTiltAxis() const;
186 TQ_INT32 yTiltAxis() const;
187 TQ_INT32 wheelAxis() const;
188 TQ_INT32 toolIDAxis() const;
189 TQ_INT32 serialNumberAxis() const;
190
191 void readSettingsFromConfig();
192 void writeSettingsToConfig();
193
194 // These return -1 if the device does not support the event
195 int buttonPressEvent() const { return m_buttonPressEvent; }
196 int buttonReleaseEvent() const { return m_buttonReleaseEvent; }
197 int motionNotifyEvent() const { return m_motionNotifyEvent; }
198 int proximityInEvent() const { return m_proximityInEvent; }
199 int proximityOutEvent() const { return m_proximityOutEvent; }
200
201 void enableEvents(TQWidget *widget) const;
202
203 class State
204 {
205 public:
206 State() {}
207 State(const KisPoint& pos, double pressure, const KisVector2D& tilt, double wheel,
208 TQ_UINT32 toolID, TQ_UINT32 serialNumber);
209
210 // Position, pressure and wheel are normalised to 0 - 1
211 KisPoint pos() const { return m_pos; }
212 double pressure() const { return m_pressure; }
213 // Tilt is normalised to -1->+1
214 KisVector2D tilt() const { return m_tilt; }
215 double wheel() const { return m_wheel; }
216 // Wacom tool id and serial number of device.
217 TQ_UINT32 toolID() const { return m_toolID; }
218 TQ_UINT32 serialNumber() const { return m_serialNumber; }
219
220 private:
221 KisPoint m_pos;
222 double m_pressure;
223 KisVector2D m_tilt;
224 double m_wheel;
225 TQ_UINT32 m_toolID;
226 TQ_UINT32 m_serialNumber;
227 };
228
229 State translateAxisData(const int *axisData) const;
230
231 private:
232 double translateAxisValue(int value, const XAxisInfo& axisInfo) const;
233
234 XID m_deviceId;
235 XDevice *m_XDevice;
236
237 TQString m_name;
238
239 bool m_mightBeTabletDevice;
240 KisInputDevice m_inputDevice;
241
242 bool m_enabled;
243
244 TQ_INT32 m_xAxis;
245 TQ_INT32 m_yAxis;
246 TQ_INT32 m_pressureAxis;
247 TQ_INT32 m_xTiltAxis;
248 TQ_INT32 m_yTiltAxis;
249 TQ_INT32 m_wheelAxis;
250 TQ_INT32 m_toolIDAxis;
251 TQ_INT32 m_serialNumberAxis;
252
253 TQValueVector<XAxisInfo> m_axisInfo;
254
255 int m_motionNotifyEvent;
256 int m_buttonPressEvent;
257 int m_buttonReleaseEvent;
258 int m_proximityInEvent;
259 int m_proximityOutEvent;
260
261 TQValueVector<XEventClass> m_eventClassList;
262 };
263
264 typedef std::map<XID, X11TabletDevice> X11XIDTabletDeviceMap;
265 static X11XIDTabletDeviceMap& tabletDeviceMap();
266
267protected:
268 static int X11DeviceMotionNotifyEvent;
269 static int X11DeviceButtonPressEvent;
270 static int X11DeviceButtonReleaseEvent;
271 static int X11ProximityInEvent;
272 static int X11ProximityOutEvent;
273
274 static X11XIDTabletDeviceMap X11TabletDeviceMap;
275
276#endif // EXTENDED_X11_TABLET_SUPPORT
277
278#endif // TQ_WS_X11
279};
280
281class KisCanvas : public TQObject {
282 TQ_OBJECT
283
284
285public:
286 KisCanvas(TQWidget *parent, const char *name);
287 virtual ~KisCanvas();
288
289 // When enabled, the canvas may throw away move events if the application
290 // is unable to keep up with them, i.e. intermediate move events in the event
291 // queue are skipped.
292 void enableMoveEventCompressionHint(bool enableMoveCompression);
293
294 bool isOpenGLCanvas() const;
295
299 bool cursorIsOverCanvas() const;
300
305 void handleKeyEvent(TQEvent *e);
306
307 int width() const;
308 int height() const;
309
310 void update();
311 void update(const TQRect& r);
312 void update(int x, int y, int width, int height);
313 void repaint();
314 void repaint(bool erase);
315 void repaint(int x, int y, int width, int height, bool erase = true);
316 void repaint(const TQRect& r, bool erase = true);
317 void repaint(const TQRegion& r, bool erase = true);
318
319 void updateGeometry();
320
321#if defined(EXTENDED_X11_TABLET_SUPPORT)
322 void selectTabletDeviceEvents();
323#endif
324
325signals:
326 void sigGotPaintEvent(TQPaintEvent*);
327 void sigGotEnterEvent(TQEvent*);
328 void sigGotLeaveEvent(TQEvent*);
329 void sigGotMouseWheelEvent(TQWheelEvent*);
330 void sigGotKeyPressEvent(TQKeyEvent*);
331 void sigGotKeyReleaseEvent(TQKeyEvent*);
332 void sigGotDragEnterEvent(TQDragEnterEvent*);
333 void sigGotDropEvent(TQDropEvent*);
334 void sigGotMoveEvent(KisMoveEvent *);
335 void sigGotButtonPressEvent(KisButtonPressEvent *);
336 void sigGotButtonReleaseEvent(KisButtonReleaseEvent *);
337 void sigGotDoubleClickEvent(KisDoubleClickEvent *);
338
339protected:
340 // Allow KisView to render on the widget directly, but everything else
341 // has restricted access.
342 friend class KisView;
343 friend class KisCanvasPainter;
344
345 // One of these will be valid, the other null. In TQt3, using a TQPainter on
346 // a TQGLWidget is not reliable.
347 TQWidget *TQPaintDeviceWidget() const;
348#ifdef HAVE_GL
349 TQGLWidget *OpenGLWidget() const;
350#endif
351 void createTQPaintDeviceCanvas();
352#ifdef HAVE_GL
353 void createOpenGLCanvas(TQGLWidget *sharedContextWidget);
354#endif
355 void show();
356 void hide();
357 void setGeometry(int x, int y, int width, int height);
358
359 void setUpdatesEnabled(bool updatesEnabled);
360 bool isUpdatesEnabled() const;
361
362 void setFocusPolicy(TQWidget::FocusPolicy focusPolicy);
363
364 const TQCursor& cursor() const;
365 void setCursor(const TQCursor& cursor);
366
367 KisCanvasWidgetPainter *createPainter();
368 KisCanvasWidget *canvasWidget() const;
369
370protected:
371#ifdef HAVE_GL
372 void createCanvasWidget(bool useOpenGL, TQGLWidget *sharedContextWidget = 0);
373#else
374 void createCanvasWidget(bool useOpenGL);
375#endif
376 TQWidget *m_parent;
377 TQString m_name;
378 KisCanvasWidget *m_canvasWidget;
379 bool m_enableMoveEventCompressionHint;
380 bool m_useOpenGL;
381};
382
383#endif // KIS_CANVAS_H_
384