summaryrefslogtreecommitdiffstats
path: root/chalk/ui/kis_canvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chalk/ui/kis_canvas.cpp')
-rw-r--r--chalk/ui/kis_canvas.cpp1356
1 files changed, 1356 insertions, 0 deletions
diff --git a/chalk/ui/kis_canvas.cpp b/chalk/ui/kis_canvas.cpp
new file mode 100644
index 000000000..63ae4ab06
--- /dev/null
+++ b/chalk/ui/kis_canvas.cpp
@@ -0,0 +1,1356 @@
+/*
+ * Copyright (c) 1999 Matthias Elter <me@kde.org>
+ * Copyright (c) 2004-2006 Adrian Page <adrian@pagenet.plus.com>
+ *
+ * This program 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.
+ *
+ * This program 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.g
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+
+ Some of the X11-specific event handling code is based upon code from
+ src/kernel/qapplication_x11.cpp from the TQt GUI Toolkit and is subject
+ to the following license and copyright:
+
+ ****************************************************************************
+**
+**
+** Implementation of X11 startup routines and event handling
+**
+** Created : 931029
+**
+** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses for Unix/X11 may use this file in accordance with the TQt Commercial
+** License Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <tqcursor.h>
+
+#include "kis_canvas.h"
+#include "kis_cursor.h"
+#include "kis_move_event.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_double_click_event.h"
+#include "kis_config.h"
+#include "kis_qpaintdevice_canvas.h"
+#include "kis_opengl_canvas.h"
+#include "kis_config.h"
+#include "kis_input_device.h"
+#include "fixx11h.h"
+
+#ifdef Q_WS_X11
+
+#include <tqdesktopwidget.h>
+#include <tqapplication.h>
+
+#include <X11/XKBlib.h>
+#include <X11/keysym.h>
+
+bool KisCanvasWidget::X11SupportInitialised = false;
+long KisCanvasWidget::X11AltMask = 0;
+long KisCanvasWidget::X11MetaMask = 0;
+
+#if defined(EXTENDED_X11_TABLET_SUPPORT)
+
+int KisCanvasWidget::X11DeviceMotionNotifyEvent = -1;
+int KisCanvasWidget::X11DeviceButtonPressEvent = -1;
+int KisCanvasWidget::X11DeviceButtonReleaseEvent = -1;
+int KisCanvasWidget::X11ProximityInEvent = -1;
+int KisCanvasWidget::X11ProximityOutEvent = -1;
+
+//X11XIDTabletDeviceMap KisCanvasWidget::X11TabletDeviceMap;
+std::map<XID, KisCanvasWidget::X11TabletDevice> KisCanvasWidget::X11TabletDeviceMap;
+
+#endif // EXTENDED_X11_TABLET_SUPPORT
+
+#endif // Q_WS_X11
+
+KisCanvasWidget::KisCanvasWidget()
+{
+ m_enableMoveEventCompressionHint = false;
+ m_lastPressure = 0;
+
+#ifdef Q_WS_X11
+ if (!X11SupportInitialised) {
+ initX11Support();
+ }
+
+ m_lastRootX = -1;
+ m_lastRootY = -1;
+#endif
+}
+
+KisCanvasWidget::~KisCanvasWidget()
+{
+}
+
+void KisCanvasWidget::widgetGotPaintEvent(TQPaintEvent *e)
+{
+ emit sigGotPaintEvent(e);
+}
+
+void KisCanvasWidget::widgetGotMousePressEvent(TQMouseEvent *e)
+{
+ KisButtonPressEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
+ buttonPressEvent(&ke);
+}
+
+void KisCanvasWidget::widgetGotMouseReleaseEvent(TQMouseEvent *e)
+{
+ KisButtonReleaseEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
+ buttonReleaseEvent(&ke);
+}
+
+void KisCanvasWidget::widgetGotMouseDoubleClickEvent(TQMouseEvent *e)
+{
+ KisDoubleClickEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
+ doubleClickEvent(&ke);
+}
+
+void KisCanvasWidget::widgetGotMouseMoveEvent(TQMouseEvent *e)
+{
+ KisMoveEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->state());
+ moveEvent(&ke);
+}
+
+void KisCanvasWidget::widgetGotTabletEvent(TQTabletEvent *e)
+{
+ KisInputDevice device;
+
+ switch (e->device()) {
+ default:
+ case TQTabletEvent::NoDevice:
+ case TQTabletEvent::Stylus:
+ device = KisInputDevice::stylus();
+ break;
+ case TQTabletEvent::Puck:
+ device = KisInputDevice::puck();
+ break;
+ case TQTabletEvent::Eraser:
+ device = KisInputDevice::eraser();
+ break;
+ }
+
+ double pressure = e->pressure() / 255.0;
+
+ if (e->type() == TQEvent::TabletPress) {
+ KisButtonPressEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), Qt::LeftButton, Qt::NoButton);
+ translateTabletEvent(&ke);
+ }
+ else
+ if (e->type() == TQEvent::TabletRelease) {
+ KisButtonReleaseEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), Qt::LeftButton, Qt::NoButton);
+ translateTabletEvent(&ke);
+ }
+ else {
+ KisMoveEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), Qt::NoButton);
+ translateTabletEvent(&ke);
+#ifdef Q_WS_X11
+ // Fix the problem that when you change from using a tablet device to the mouse,
+ // the first mouse button event is not recognised. This is because we handle
+ // X11 core mouse move events directly so TQt does not get to see them. This breaks
+ // the tablet event accept/ignore mechanism, causing TQt to consume the first
+ // mouse button event it sees, instead of a mouse move. 'Ignoring' tablet move events
+ // stops TQt from stealing the next mouse button event. This does not affect the
+ // tablet aware tools as they do not care about mouse moves while the tablet device is
+ // drawing.
+ e->ignore();
+#endif
+ }
+}
+
+void KisCanvasWidget::widgetGotEnterEvent(TQEvent *e)
+{
+ emit sigGotEnterEvent(e);
+}
+
+void KisCanvasWidget::widgetGotLeaveEvent(TQEvent *e)
+{
+ emit sigGotLeaveEvent(e);
+}
+
+void KisCanvasWidget::widgetGotWheelEvent(TQWheelEvent *e)
+{
+ emit sigGotMouseWheelEvent(e);
+}
+
+void KisCanvasWidget::widgetGotKeyPressEvent(TQKeyEvent *e)
+{
+ emit sigGotKeyPressEvent(e);
+}
+
+void KisCanvasWidget::widgetGotKeyReleaseEvent(TQKeyEvent *e)
+{
+ emit sigGotKeyReleaseEvent(e);
+}
+
+void KisCanvasWidget::widgetGotDragEnterEvent(TQDragEnterEvent *e)
+{
+ emit sigGotDragEnterEvent(e);
+}
+
+void KisCanvasWidget::widgetGotDropEvent(TQDropEvent *e)
+{
+ emit sigGotDropEvent(e);
+}
+
+void KisCanvasWidget::moveEvent(KisMoveEvent *e)
+{
+ emit sigGotMoveEvent(e);
+}
+
+void KisCanvasWidget::buttonPressEvent(KisButtonPressEvent *e)
+{
+ TQWidget *widget = dynamic_cast<TQWidget *>(this);
+ Q_ASSERT(widget != 0);
+
+ if (widget) {
+ widget->setFocus();
+ }
+
+ emit sigGotButtonPressEvent(e);
+}
+
+void KisCanvasWidget::buttonReleaseEvent(KisButtonReleaseEvent *e)
+{
+ emit sigGotButtonReleaseEvent(e);
+}
+
+void KisCanvasWidget::doubleClickEvent(KisDoubleClickEvent *e)
+{
+ emit sigGotDoubleClickEvent(e);
+}
+
+void KisCanvasWidget::translateTabletEvent(KisEvent *e)
+{
+ bool checkThresholdOnly = false;
+
+ if (e->type() == KisEvent::ButtonPressEvent || e->type() == KisEvent::ButtonReleaseEvent) {
+ KisButtonEvent *b = static_cast<KisButtonEvent *>(e);
+
+ if (b->button() == Qt::MidButton || b->button() == Qt::RightButton) {
+
+ if (e->type() == KisEvent::ButtonPressEvent) {
+ buttonPressEvent(static_cast<KisButtonPressEvent *>(e));
+ } else {
+ buttonReleaseEvent(static_cast<KisButtonReleaseEvent *>(e));
+ }
+
+ checkThresholdOnly = true;
+ }
+ }
+
+ // Use pressure threshold to detect 'left button' press/release
+ if (e->pressure() >= PRESSURE_THRESHOLD && m_lastPressure < PRESSURE_THRESHOLD) {
+ KisButtonPressEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), Qt::LeftButton, e->state());
+ buttonPressEvent(&ke);
+ } else if (e->pressure() < PRESSURE_THRESHOLD && m_lastPressure >= PRESSURE_THRESHOLD) {
+ KisButtonReleaseEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), Qt::LeftButton, e->state());
+ buttonReleaseEvent(&ke);
+ } else {
+ if (!checkThresholdOnly) {
+ KisMoveEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->state());
+ moveEvent(&ke);
+ }
+ }
+
+ m_lastPressure = e->pressure();
+}
+
+#ifdef Q_WS_X11
+
+void KisCanvasWidget::initX11Support()
+{
+ if (X11SupportInitialised)
+ {
+ return;
+ }
+
+ X11SupportInitialised = true;
+
+ Display *x11Display = TQApplication::desktop()->x11Display();
+
+ // Look at the modifier mapping and get the correct masks for alt/meta
+ XModifierKeymap *map = XGetModifierMapping(x11Display);
+
+ if (map) {
+ int mapIndex = 0;
+
+ for (int maskIndex = 0; maskIndex < 8; maskIndex++) {
+ for (int i = 0; i < map->max_keypermod; i++) {
+ if (map->modifiermap[mapIndex]) {
+
+ KeySym sym = XkbKeycodeToKeysym(x11Display, map->modifiermap[mapIndex], 0, 0);
+
+ if (X11AltMask == 0 && (sym == XK_Alt_L || sym == XK_Alt_R)) {
+ X11AltMask = 1 << maskIndex;
+ }
+ if (X11MetaMask == 0 && (sym == XK_Meta_L || sym == XK_Meta_R)) {
+ X11MetaMask = 1 << maskIndex;
+ }
+ }
+
+ mapIndex++;
+ }
+ }
+
+ XFreeModifiermap(map);
+ }
+ else {
+ // Assume defaults
+ X11AltMask = Mod1Mask;
+ X11MetaMask = Mod4Mask;
+ }
+
+#if defined(EXTENDED_X11_TABLET_SUPPORT)
+
+ int numDevices = 0;
+ const XDeviceInfo *devices = XListInputDevices(x11Display, &numDevices);
+
+ if (devices != NULL) {
+ XID lastStylusSeen = 0;
+ XID lastEraserSeen = 0;
+ bool foundStylus = false;
+ bool foundEraser = false;
+
+ for (int i = 0; i < numDevices; i++) {
+
+ const XDeviceInfo *device = devices + i;
+ X11TabletDevice tabletDevice(device);
+
+ if (tabletDevice.mightBeTabletDevice()) {
+
+ tabletDevice.readSettingsFromConfig();
+
+ TQString lowerCaseName = tabletDevice.name().lower();
+
+ // Find the devices that TQt will use as its stylus and eraser devices.
+ if (!foundStylus || !foundEraser) {
+ if (lowerCaseName.startsWith("stylus") || lowerCaseName.startsWith("pen")) {
+ lastStylusSeen = device->id;
+ foundStylus = true;
+ }
+ else if (lowerCaseName.startsWith("eraser")) {
+ lastEraserSeen = device->id;
+ foundEraser = true;
+ }
+ }
+
+ X11TabletDeviceMap[device->id] = tabletDevice;
+
+ // Event types are device-independent. Store any
+ // the device supports.
+ if (tabletDevice.buttonPressEvent() >= 0) {
+ X11DeviceButtonPressEvent = tabletDevice.buttonPressEvent();
+ }
+ if (tabletDevice.buttonReleaseEvent() >= 0) {
+ X11DeviceButtonReleaseEvent = tabletDevice.buttonReleaseEvent();
+ }
+ if (tabletDevice.motionNotifyEvent() >= 0) {
+ X11DeviceMotionNotifyEvent = tabletDevice.motionNotifyEvent();
+ }
+ if (tabletDevice.proximityInEvent() >= 0) {
+ X11ProximityInEvent = tabletDevice.proximityInEvent();
+ }
+ if (tabletDevice.proximityOutEvent() >= 0) {
+ X11ProximityOutEvent = tabletDevice.proximityOutEvent();
+ }
+ }
+ }
+
+ // Allocate input devices.
+ for (X11XIDTabletDeviceMap::iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
+
+ X11TabletDevice& tabletDevice = (*it).second;
+
+ if (foundStylus && tabletDevice.id() == lastStylusSeen) {
+ tabletDevice.setInputDevice(KisInputDevice::stylus());
+ } else if (foundEraser && tabletDevice.id() == lastEraserSeen) {
+ tabletDevice.setInputDevice(KisInputDevice::eraser());
+ } else {
+ tabletDevice.setInputDevice(KisInputDevice::allocateInputDevice());
+ }
+ }
+
+ XFreeDeviceList(const_cast<XDeviceInfo *>(devices));
+ }
+#endif // EXTENDED_X11_TABLET_SUPPORT
+}
+
+TQt::ButtonState KisCanvasWidget::translateX11ButtonState(int state)
+{
+ int buttonState = 0;
+
+ if (state & Button1Mask)
+ buttonState |= Qt::LeftButton;
+ if (state & Button2Mask)
+ buttonState |= Qt::MidButton;
+ if (state & Button3Mask)
+ buttonState |= Qt::RightButton;
+ if (state & ShiftMask)
+ buttonState |= TQt::ShiftButton;
+ if (state & ControlMask)
+ buttonState |= TQt::ControlButton;
+ if (state & X11AltMask)
+ buttonState |= TQt::AltButton;
+ if (state & X11MetaMask)
+ buttonState |= TQt::MetaButton;
+
+ return static_cast<TQt::ButtonState>(buttonState);
+}
+
+TQt::ButtonState KisCanvasWidget::translateX11Button(unsigned int X11Button)
+{
+ TQt::ButtonState qtButton;
+
+ switch (X11Button) {
+ case Button1:
+ qtButton = Qt::LeftButton;
+ break;
+ case Button2:
+ qtButton = Qt::MidButton;
+ break;
+ case Button3:
+ qtButton = Qt::RightButton;
+ break;
+ default:
+ qtButton = Qt::NoButton;
+ }
+
+ return qtButton;
+}
+
+#if defined(EXTENDED_X11_TABLET_SUPPORT)
+
+KisCanvasWidget::X11TabletDevice::X11TabletDevice()
+{
+ m_mightBeTabletDevice = false;
+ m_inputDevice = KisInputDevice::unknown();
+ m_enabled = false;
+ m_xAxis = NoAxis;
+ m_yAxis = NoAxis;
+ m_pressureAxis = NoAxis;
+ m_xTiltAxis = NoAxis;
+ m_yTiltAxis = NoAxis;
+ m_wheelAxis = NoAxis;
+ m_toolIDAxis = NoAxis;
+ m_serialNumberAxis = NoAxis;
+ m_buttonPressEvent = -1;
+ m_buttonReleaseEvent = -1;
+ m_motionNotifyEvent = -1;
+ m_proximityInEvent = -1;
+ m_proximityOutEvent = -1;
+}
+
+KisCanvasWidget::X11TabletDevice::X11TabletDevice(const XDeviceInfo *deviceInfo)
+{
+ m_mightBeTabletDevice = false;
+ m_inputDevice = KisInputDevice::unknown();
+ m_enabled = false;
+ m_xAxis = NoAxis;
+ m_yAxis = NoAxis;
+ m_pressureAxis = NoAxis;
+ m_xTiltAxis = NoAxis;
+ m_yTiltAxis = NoAxis;
+ m_wheelAxis = NoAxis;
+ m_toolIDAxis = NoAxis;
+ m_serialNumberAxis = NoAxis;
+
+ m_deviceId = deviceInfo->id;
+ m_name = deviceInfo->name;
+
+ // Get the ranges of the valuators
+ XAnyClassPtr classInfo = const_cast<XAnyClassPtr>(deviceInfo->inputclassinfo);
+
+ for (int i = 0; i < deviceInfo->num_classes; i++) {
+
+ if (classInfo->c_class == ValuatorClass) {
+
+ const XValuatorInfo *valuatorInfo = reinterpret_cast<const XValuatorInfo *>(classInfo);
+
+ // Need at least x, y, and pressure.
+
+ if (valuatorInfo->num_axes >= 3) {
+
+ for (unsigned int axis = 0; axis < valuatorInfo->num_axes; axis++) {
+ m_axisInfo.append(valuatorInfo->axes[axis]);
+ }
+
+ m_mightBeTabletDevice = true;
+ }
+ }
+
+ classInfo = reinterpret_cast<XAnyClassPtr>(reinterpret_cast<char *>(classInfo) + classInfo->length);
+ }
+
+ // Determine the event types it supports. We're only interested in
+ // buttons and motion at the moment.
+ m_buttonPressEvent = -1;
+ m_buttonReleaseEvent = -1;
+ m_motionNotifyEvent = -1;
+ m_proximityInEvent = -1;
+ m_proximityOutEvent = -1;
+
+ m_XDevice = XOpenDevice(TQApplication::desktop()->x11Display(), m_deviceId);
+
+ if (m_XDevice != NULL) {
+ for (int i = 0; i < m_XDevice->num_classes; i++) {
+
+ XEventClass eventClass;
+
+ if (m_XDevice->classes[i].input_class == ButtonClass) {
+ DeviceButtonPress(m_XDevice, m_buttonPressEvent, eventClass);
+ m_eventClassList.append(eventClass);
+
+ DeviceButtonRelease(m_XDevice, m_buttonReleaseEvent, eventClass);
+ m_eventClassList.append(eventClass);
+ }
+ else
+ if (m_XDevice->classes[i].input_class == ValuatorClass) {
+ DeviceMotionNotify(m_XDevice, m_motionNotifyEvent, eventClass);
+ m_eventClassList.append(eventClass);
+ }
+ else
+ if (m_XDevice->classes[i].input_class == ProximityClass) {
+ ProximityIn(m_XDevice, m_proximityInEvent, eventClass);
+ m_eventClassList.append(eventClass);
+
+ ProximityOut(m_XDevice, m_proximityOutEvent, eventClass);
+ m_eventClassList.append(eventClass);
+ }
+ }
+
+ // Note: We don't XCloseXDevice() since TQt will have already opened
+ // it, and only one XCloseDevice() call closes it for all opens.
+ }
+
+ if (m_buttonPressEvent == -1 || m_buttonReleaseEvent == -1 || m_motionNotifyEvent == -1) {
+ m_mightBeTabletDevice = false;
+ }
+}
+
+void KisCanvasWidget::X11TabletDevice::setEnabled(bool enabled)
+{
+ m_enabled = enabled;
+}
+
+bool KisCanvasWidget::X11TabletDevice::enabled() const
+{
+ return m_enabled;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::numAxes() const
+{
+ return m_axisInfo.count();
+}
+
+void KisCanvasWidget::X11TabletDevice::setXAxis(TQ_INT32 axis)
+{
+ m_xAxis = axis;
+}
+
+void KisCanvasWidget::X11TabletDevice::setYAxis(TQ_INT32 axis)
+{
+ m_yAxis = axis;
+}
+
+void KisCanvasWidget::X11TabletDevice::setPressureAxis(TQ_INT32 axis)
+{
+ m_pressureAxis = axis;
+}
+
+void KisCanvasWidget::X11TabletDevice::setXTiltAxis(TQ_INT32 axis)
+{
+ m_xTiltAxis = axis;
+}
+
+void KisCanvasWidget::X11TabletDevice::setYTiltAxis(TQ_INT32 axis)
+{
+ m_yTiltAxis = axis;
+}
+
+void KisCanvasWidget::X11TabletDevice::setWheelAxis(TQ_INT32 axis)
+{
+ m_wheelAxis = axis;
+}
+
+void KisCanvasWidget::X11TabletDevice::setToolIDAxis(TQ_INT32 axis)
+{
+ m_toolIDAxis = axis;
+}
+
+void KisCanvasWidget::X11TabletDevice::setSerialNumberAxis(TQ_INT32 axis)
+{
+ m_serialNumberAxis = axis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::xAxis() const
+{
+ return m_xAxis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::yAxis() const
+{
+ return m_yAxis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::pressureAxis() const
+{
+ return m_pressureAxis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::xTiltAxis() const
+{
+ return m_xTiltAxis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::yTiltAxis() const
+{
+ return m_yTiltAxis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::wheelAxis() const
+{
+ return m_wheelAxis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::toolIDAxis() const
+{
+ return m_toolIDAxis;
+}
+
+TQ_INT32 KisCanvasWidget::X11TabletDevice::serialNumberAxis() const
+{
+ return m_serialNumberAxis;
+}
+
+void KisCanvasWidget::X11TabletDevice::readSettingsFromConfig()
+{
+ KisConfig cfg;
+
+ m_enabled = cfg.tabletDeviceEnabled(m_name);
+
+ m_xAxis = cfg.tabletDeviceAxis(m_name, "XAxis", DefaultAxis);
+ m_yAxis = cfg.tabletDeviceAxis(m_name, "YAxis", DefaultAxis);
+ m_pressureAxis = cfg.tabletDeviceAxis(m_name, "PressureAxis", DefaultAxis);
+ m_xTiltAxis = cfg.tabletDeviceAxis(m_name, "XTiltAxis", DefaultAxis);
+ m_yTiltAxis = cfg.tabletDeviceAxis(m_name, "YTiltAxis", DefaultAxis);
+ m_wheelAxis = cfg.tabletDeviceAxis(m_name, "WheelAxis", DefaultAxis);
+ m_toolIDAxis = cfg.tabletDeviceAxis(m_name, "ToolIDAxis", DefaultAxis);
+ m_serialNumberAxis = cfg.tabletDeviceAxis(m_name, "SerialNumberAxis", DefaultAxis);
+
+ if (!m_enabled && m_xAxis == DefaultAxis && m_yAxis == DefaultAxis && m_pressureAxis == DefaultAxis &&
+ m_xTiltAxis == DefaultAxis && m_yTiltAxis == DefaultAxis && m_wheelAxis == DefaultAxis &&
+ m_toolIDAxis == DefaultAxis && m_serialNumberAxis == DefaultAxis) {
+ // This is the first time this device has been seen. Set up default values, assuming
+ // it's a Wacom pad.
+ m_xAxis = 0;
+ m_yAxis = 1;
+ m_pressureAxis = 2;
+
+ if (m_axisInfo.count() >= 4) {
+ m_xTiltAxis = 3;
+ } else {
+ m_xTiltAxis = NoAxis;
+ }
+
+ if (m_axisInfo.count() >= 5) {
+ m_yTiltAxis = 4;
+ } else {
+ m_yTiltAxis = NoAxis;
+ }
+
+ if (m_axisInfo.count() >= 6) {
+ m_wheelAxis = 5;
+ } else {
+ m_wheelAxis = NoAxis;
+ }
+
+ // Available since driver version 0.7.2.
+ if (m_axisInfo.count() >= 7) {
+ m_toolIDAxis = 6;
+ } else {
+ m_toolIDAxis = NoAxis;
+ }
+
+ if (m_axisInfo.count() >= 8) {
+ m_serialNumberAxis = 7;
+ } else {
+ m_serialNumberAxis = NoAxis;
+ }
+ }
+}
+
+void KisCanvasWidget::X11TabletDevice::writeSettingsToConfig()
+{
+ KisConfig cfg;
+
+ cfg.setTabletDeviceEnabled(m_name, m_enabled);
+
+ cfg.setTabletDeviceAxis(m_name, "XAxis", m_xAxis);
+ cfg.setTabletDeviceAxis(m_name, "YAxis", m_yAxis);
+ cfg.setTabletDeviceAxis(m_name, "PressureAxis", m_pressureAxis);
+ cfg.setTabletDeviceAxis(m_name, "XTiltAxis", m_xTiltAxis);
+ cfg.setTabletDeviceAxis(m_name, "YTiltAxis", m_yTiltAxis);
+ cfg.setTabletDeviceAxis(m_name, "WheelAxis", m_wheelAxis);
+ cfg.setTabletDeviceAxis(m_name, "ToolIDAxis", m_toolIDAxis);
+ cfg.setTabletDeviceAxis(m_name, "SerialNumberAxis", m_serialNumberAxis);
+}
+
+void KisCanvasWidget::X11TabletDevice::enableEvents(TQWidget *widget) const
+{
+ if (!m_eventClassList.isEmpty()) {
+ int result = XSelectExtensionEvent(TQT_TQPAINTDEVICE(widget)->x11AppDisplay(), widget->handle(),
+ const_cast<XEventClass*>(&m_eventClassList[0]),
+ m_eventClassList.count());
+
+ if (result != Success) {
+ kdDebug(41001) << "Failed to select extension events for " << m_name << endl;
+ }
+ }
+}
+
+double KisCanvasWidget::X11TabletDevice::translateAxisValue(int value, const XAxisInfo& axisInfo) const
+{
+ int axisRange = axisInfo.max_value - axisInfo.min_value;
+ double translatedValue = 0;
+
+ if (axisRange != 0) {
+ translatedValue = (static_cast<double>(value) - axisInfo.min_value) / axisRange;
+ if (axisInfo.min_value < 0) {
+ translatedValue -= 0.5;
+ }
+ }
+
+ return translatedValue;
+}
+
+KisCanvasWidget::X11TabletDevice::State::State(const KisPoint& pos, double pressure, const KisVector2D& tilt, double wheel,
+ TQ_UINT32 toolID, TQ_UINT32 serialNumber)
+ : m_pos(pos),
+ m_pressure(pressure),
+ m_tilt(tilt),
+ m_wheel(wheel),
+ m_toolID(toolID),
+ m_serialNumber(serialNumber)
+{
+}
+
+KisCanvasWidget::X11TabletDevice::State KisCanvasWidget::X11TabletDevice::translateAxisData(const int *axisData) const
+{
+ KisPoint pos(0, 0);
+
+ if (m_xAxis != NoAxis && m_yAxis != NoAxis) {
+ pos = KisPoint(translateAxisValue(axisData[m_xAxis], m_axisInfo[m_xAxis]),
+ translateAxisValue(axisData[m_yAxis], m_axisInfo[m_yAxis]));
+ }
+
+ double pressure = PRESSURE_DEFAULT;
+
+ if (m_pressureAxis != NoAxis) {
+ pressure = translateAxisValue(axisData[m_pressureAxis], m_axisInfo[m_pressureAxis]);
+ }
+
+ KisVector2D tilt = KisVector2D(0, 0);
+ TQ_UINT32 toolID = 0;
+ TQ_UINT32 serialNumber = 0;
+
+ if (m_xTiltAxis != NoAxis) {
+ // Latest wacom driver returns the tool id and serial number in
+ // the upper 16 bits of the x and y tilts and wheel.
+ int xTiltAxisValue = (TQ_INT16)(axisData[m_xTiltAxis] & 0xffff);
+ toolID = ((TQ_UINT32)axisData[m_xTiltAxis] >> 16) & 0xffff;
+
+ tilt.setX(translateAxisValue(xTiltAxisValue, m_axisInfo[m_xTiltAxis]));
+ }
+
+ if (m_yTiltAxis != NoAxis) {
+ int yTiltAxisValue = (TQ_INT16)(axisData[m_yTiltAxis] & 0xffff);
+ serialNumber = (TQ_UINT32)axisData[m_yTiltAxis] & 0xffff0000;
+
+ tilt.setY(translateAxisValue(yTiltAxisValue, m_axisInfo[m_yTiltAxis]));
+ }
+
+ double wheel = 0;
+
+ if (m_wheelAxis != NoAxis) {
+ int wheelAxisValue = (TQ_INT16)(axisData[m_wheelAxis] & 0xffff);
+ serialNumber |= ((TQ_UINT32)axisData[m_wheelAxis] >> 16) & 0xffff;
+
+ wheel = translateAxisValue(wheelAxisValue, m_axisInfo[m_wheelAxis]);
+ }
+
+ //TQString ids;
+ //ids.sprintf("Tool ID: %8x Serial Number: %8x", toolID, serialNumber);
+
+ return State(pos, pressure, tilt, wheel, toolID, serialNumber);
+}
+
+KisCanvasWidget::X11XIDTabletDeviceMap& KisCanvasWidget::tabletDeviceMap()
+{
+ return X11TabletDeviceMap;
+}
+
+void KisCanvasWidget::selectTabletDeviceEvents(TQWidget *widget)
+{
+ for (X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
+
+ const X11TabletDevice& device = (*it).second;
+
+ if (device.enabled()) {
+ device.enableEvents(widget);
+ }
+ }
+}
+
+#endif // EXTENDED_X11_TABLET_SUPPORT
+
+bool KisCanvasWidget::x11Event(XEvent *event, Display *x11Display, WId winId, TQPoint widgetOriginPos)
+{
+ if (event->type == MotionNotify) {
+ // Mouse move
+ if (!m_enableMoveEventCompressionHint) {
+
+ XMotionEvent motion = event->xmotion;
+ TQPoint globalPos(motion.x_root, motion.y_root);
+
+ if (globalPos.x() != m_lastRootX || globalPos.y() != m_lastRootY) {
+
+ int state = translateX11ButtonState(motion.state);
+ TQPoint pos(motion.x, motion.y);
+ TQMouseEvent e(TQEvent::MouseMove, pos, globalPos, Qt::NoButton, state);
+
+ widgetGotMouseMoveEvent(&e);
+ }
+
+ m_lastRootX = globalPos.x();
+ m_lastRootY = globalPos.y();
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else
+#if defined(EXTENDED_X11_TABLET_SUPPORT)
+ if (event->type == X11DeviceMotionNotifyEvent || event->type == X11DeviceButtonPressEvent || event->type == X11DeviceButtonReleaseEvent) {
+ // Tablet event.
+ int deviceId;
+ const int *axisData;
+ TQt::ButtonState button;
+ TQt::ButtonState buttonState;
+
+ if (event->type == X11DeviceMotionNotifyEvent) {
+ // Tablet move
+ const XDeviceMotionEvent *motion = reinterpret_cast<const XDeviceMotionEvent *>(event);
+ XEvent mouseEvent;
+
+ // Look for an accompanying core event.
+ if (XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &mouseEvent)) {
+ if (motion->time == mouseEvent.xmotion.time) {
+ // Do nothing
+ } else {
+ XPutBackEvent(x11Display, &mouseEvent);
+ }
+ }
+
+ if (m_enableMoveEventCompressionHint) {
+ while (true) {
+ // Look for another motion notify in the queue and skip
+ // to that if found.
+ if (!XCheckTypedWindowEvent(x11Display, winId, X11DeviceMotionNotifyEvent, &mouseEvent)) {
+ break;
+ }
+
+ motion = reinterpret_cast<const XDeviceMotionEvent *>(&mouseEvent);
+
+ XEvent coreMotionEvent;
+
+ // Look for an accompanying core event.
+ if (!XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &coreMotionEvent)) {
+ // Do nothing
+ }
+ }
+ }
+
+ deviceId = motion->deviceid;
+ axisData = motion->axis_data;
+ button = Qt::NoButton;
+ buttonState = translateX11ButtonState(motion->state);
+ }
+ else
+ if (event->type == X11DeviceButtonPressEvent) {
+ // Tablet button press
+ const XDeviceButtonPressedEvent *buttonPressed = reinterpret_cast<const XDeviceButtonPressedEvent *>(event);
+ deviceId = buttonPressed->deviceid;
+ axisData = buttonPressed->axis_data;
+ button = translateX11Button(buttonPressed->button);
+ buttonState = translateX11ButtonState(buttonPressed->state);
+
+ if (TQApplication::activePopupWidget() == 0) {
+ XEvent mouseEvent;
+
+ // Look for and swallow an accompanying core event, but only if there's
+ // no active popup, as that needs to see it.
+ if (XCheckTypedWindowEvent(x11Display, winId, ButtonPress, &mouseEvent)) {
+ if (buttonPressed->time == mouseEvent.xbutton.time) {
+ // Do nothing
+ }
+ else {
+ XPutBackEvent(x11Display, &mouseEvent);
+ }
+ }
+ }
+ }
+ else {
+ // Tablet button release
+ const XDeviceButtonReleasedEvent *buttonReleased = reinterpret_cast<const XDeviceButtonReleasedEvent *>(event);
+ deviceId = buttonReleased->deviceid;
+ axisData = buttonReleased->axis_data;
+ button = translateX11Button(buttonReleased->button);
+ buttonState = translateX11ButtonState(buttonReleased->state);
+
+ if (TQApplication::activePopupWidget() == 0) {
+ XEvent mouseEvent;
+
+ // Look for and swallow an accompanying core event, but only if there's
+ // no active popup, as that needs to see it.
+ if (XCheckTypedWindowEvent(x11Display, winId, ButtonRelease, &mouseEvent)) {
+ if (buttonReleased->time == mouseEvent.xbutton.time) {
+ // Do nothing
+ }
+ else {
+ XPutBackEvent(x11Display, &mouseEvent);
+ }
+ }
+ }
+ }
+
+ X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.find(deviceId);
+
+ if (it != X11TabletDeviceMap.end()) {
+
+ const X11TabletDevice& tabletDevice = (*it).second;
+
+ if (tabletDevice.enabled()) {
+ X11TabletDevice::State deviceState = tabletDevice.translateAxisData(axisData);
+
+ // Map normalised position coordinates to screen coordinates
+ TQDesktopWidget *desktop = TQApplication::desktop();
+ KisPoint globalPos(deviceState.pos().x() * desktop->width(), deviceState.pos().y() * desktop->height());
+ // Convert screen coordinates to widget coordinates
+ KisPoint pos = globalPos - KoPoint( widgetOriginPos );
+
+ // Map tilt to -60 - +60 degrees
+ KisVector2D tilt(deviceState.tilt().x() * 60, deviceState.tilt().y() * 60);
+
+ if (event->type == X11DeviceMotionNotifyEvent) {
+ KisMoveEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), buttonState);
+ translateTabletEvent(&e);
+ }
+ else
+ if (event->type == X11DeviceButtonPressEvent) {
+ KisButtonPressEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState);
+ translateTabletEvent(&e);
+ }
+ else {
+ KisButtonReleaseEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState);
+ translateTabletEvent(&e);
+ }
+ }
+
+ // Consume the event even if the device is disabled otherwise TQt will
+ // process it and send a TQTabletEvent.
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else
+#endif // EXTENDED_X11_TABLET_SUPPORT
+ {
+ return false;
+ }
+}
+
+#if defined(EXTENDED_X11_TABLET_SUPPORT)
+
+KisInputDevice KisCanvasWidget::findActiveInputDevice()
+{
+ X11XIDTabletDeviceMap::const_iterator it;
+
+ for (it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
+ const X11TabletDevice& tabletDevice = (*it).second;
+
+ XDeviceState *deviceState = XQueryDeviceState(TQApplication::desktop()->x11Display(),
+ tabletDevice.xDevice());
+
+ // If your the laptop sleeps, and you remove the mouse from the usb
+ // port, then on wake-up Chalk can crash because the above call will
+ // return 0.
+ if (!deviceState) continue;
+
+ const XInputClass *inputClass = deviceState->data;
+ bool deviceIsInProximity = false;
+
+ for (int i = 0; i < deviceState->num_classes; i++) {
+
+ if (inputClass->c_class == ValuatorClass) {
+
+ const XValuatorState *valuatorState = reinterpret_cast<const XValuatorState *>(inputClass);
+
+ if ((valuatorState->mode & ProximityState) == InProximity) {
+ deviceIsInProximity = true;
+ break;
+ }
+ }
+
+ inputClass = reinterpret_cast<const XInputClass *>(reinterpret_cast<const char *>(inputClass) + inputClass->length);
+ }
+
+ XFreeDeviceState(deviceState);
+
+ if (deviceIsInProximity && tabletDevice.enabled()) {
+ return tabletDevice.inputDevice();
+ }
+ }
+
+ return KisInputDevice::mouse();
+}
+
+#endif // EXTENDED_X11_TABLET_SUPPORT
+
+
+#endif // Q_WS_X11
+
+/*************************************************************************/
+
+#define TQPAINTDEVICE_CANVAS_WIDGET false
+#define OPENGL_CANVAS_WIDGET true
+
+KisCanvas::KisCanvas(TQWidget *parent, const char *name)
+{
+ m_parent = parent;
+ m_name = name;
+ m_enableMoveEventCompressionHint = false;
+ m_canvasWidget = 0;
+ m_useOpenGL = false;
+ createCanvasWidget(TQPAINTDEVICE_CANVAS_WIDGET);
+}
+
+KisCanvas::~KisCanvas()
+{
+ delete m_canvasWidget;
+}
+
+#ifdef HAVE_GL
+void KisCanvas::createCanvasWidget(bool useOpenGL, TQGLWidget *sharedContextWidget)
+#else
+void KisCanvas::createCanvasWidget(bool useOpenGL)
+#endif
+{
+ delete m_canvasWidget;
+
+#ifndef HAVE_GL
+ useOpenGL = false;
+#else
+ if (useOpenGL && !TQGLFormat::hasOpenGL()) {
+ kdDebug(41001) << "Tried to create OpenGL widget when system doesn't have OpenGL\n";
+ useOpenGL = false;
+ }
+
+ if (useOpenGL) {
+ m_canvasWidget = new KisOpenGLCanvasWidget(m_parent, m_name.latin1(), sharedContextWidget);
+ } else
+#endif
+ {
+ m_canvasWidget = new KisTQPaintDeviceCanvasWidget(m_parent, m_name.latin1());
+ }
+
+ m_useOpenGL = useOpenGL;
+
+ TQ_CHECK_PTR(m_canvasWidget);
+ TQWidget *widget = dynamic_cast<TQWidget *>(m_canvasWidget);
+
+ widget->setBackgroundMode(TQWidget::NoBackground);
+ widget->setMouseTracking(true);
+ widget->setAcceptDrops(true);
+ m_canvasWidget->enableMoveEventCompressionHint(m_enableMoveEventCompressionHint);
+
+#if defined(EXTENDED_X11_TABLET_SUPPORT)
+ selectTabletDeviceEvents();
+#endif
+
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotPaintEvent(TQPaintEvent *)), TQT_SIGNAL(sigGotPaintEvent(TQPaintEvent *)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotEnterEvent(TQEvent*)), TQT_SIGNAL(sigGotEnterEvent(TQEvent*)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotLeaveEvent(TQEvent*)), TQT_SIGNAL(sigGotLeaveEvent(TQEvent*)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*)), TQT_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*)), TQT_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*)), TQT_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotDropEvent(TQDropEvent*)), TQT_SIGNAL(sigGotDropEvent(TQDropEvent*)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent *)), TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent *)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *)), TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *)), TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *)));
+ connect(m_canvasWidget, TQT_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *)), TQT_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *)));
+}
+
+void KisCanvas::createTQPaintDeviceCanvas()
+{
+ createCanvasWidget(TQPAINTDEVICE_CANVAS_WIDGET);
+}
+
+#ifdef HAVE_GL
+void KisCanvas::createOpenGLCanvas(TQGLWidget *sharedContextWidget)
+{
+ createCanvasWidget(OPENGL_CANVAS_WIDGET, sharedContextWidget);
+}
+#endif
+
+bool KisCanvas::isOpenGLCanvas() const
+{
+ return m_useOpenGL;
+}
+
+void KisCanvas::enableMoveEventCompressionHint(bool enableMoveCompression)
+{
+ m_enableMoveEventCompressionHint = enableMoveCompression;
+ if (m_canvasWidget != 0) {
+ m_canvasWidget->enableMoveEventCompressionHint(enableMoveCompression);
+ }
+}
+
+TQWidget *KisCanvas::TQPaintDeviceWidget() const
+{
+ if (m_useOpenGL) {
+ return 0;
+ } else {
+ return dynamic_cast<TQWidget *>(m_canvasWidget);
+ }
+}
+
+#ifdef HAVE_GL
+TQGLWidget *KisCanvas::OpenGLWidget() const
+{
+ if (m_useOpenGL) {
+ return dynamic_cast<TQGLWidget *>(m_canvasWidget);
+ } else {
+ return 0;
+ }
+}
+#endif
+
+KisCanvasWidgetPainter *KisCanvas::createPainter()
+{
+ Q_ASSERT(m_canvasWidget != 0);
+ return m_canvasWidget->createPainter();
+}
+
+KisCanvasWidget *KisCanvas::canvasWidget() const
+{
+ return m_canvasWidget;
+}
+
+void KisCanvas::setGeometry(int x, int y, int width, int height)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->setGeometry(x, y, width, height);
+}
+
+void KisCanvas::show()
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->show();
+}
+
+void KisCanvas::hide()
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->hide();
+}
+
+int KisCanvas::width() const
+{
+ Q_ASSERT(m_canvasWidget);
+ return dynamic_cast<TQWidget *>(m_canvasWidget)->width();
+}
+
+int KisCanvas::height() const
+{
+ Q_ASSERT(m_canvasWidget);
+ return dynamic_cast<TQWidget *>(m_canvasWidget)->height();
+}
+
+void KisCanvas::update()
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->update();
+}
+
+void KisCanvas::update(const TQRect& r)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->update(r);
+}
+
+void KisCanvas::update(int x, int y, int width, int height)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->update(x, y, width, height);
+}
+
+void KisCanvas::repaint()
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->repaint();
+}
+
+void KisCanvas::repaint(bool erase)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->repaint(erase);
+}
+
+void KisCanvas::repaint(int x, int y, int width, int height, bool erase)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->repaint(x, y, width, height, erase);
+}
+
+void KisCanvas::repaint(const TQRect& r, bool erase)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->repaint(r, erase);
+}
+
+void KisCanvas::repaint(const TQRegion& r, bool erase)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->repaint(r, erase);
+}
+
+bool KisCanvas::isUpdatesEnabled() const
+{
+ Q_ASSERT(m_canvasWidget);
+ return dynamic_cast<TQWidget *>(m_canvasWidget)->isUpdatesEnabled();
+}
+
+void KisCanvas::setUpdatesEnabled(bool updatesEnabled)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->setUpdatesEnabled(updatesEnabled);
+}
+
+void KisCanvas::updateGeometry()
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->updateGeometry();
+}
+
+void KisCanvas::setFocusPolicy(TQ_FocusPolicy focusPolicy)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->setFocusPolicy(focusPolicy);
+}
+
+const TQCursor& KisCanvas::cursor() const
+{
+ Q_ASSERT(m_canvasWidget);
+ return dynamic_cast<TQWidget *>(m_canvasWidget)->cursor();
+}
+
+void KisCanvas::setCursor(const TQCursor& cursor)
+{
+ Q_ASSERT(m_canvasWidget);
+ dynamic_cast<TQWidget *>(m_canvasWidget)->setCursor(cursor);
+}
+
+#if defined(EXTENDED_X11_TABLET_SUPPORT)
+void KisCanvas::selectTabletDeviceEvents()
+{
+ Q_ASSERT(m_canvasWidget);
+ m_canvasWidget->selectTabletDeviceEvents();
+}
+#endif
+
+bool KisCanvas::cursorIsOverCanvas() const
+{
+ if (TQApplication::activePopupWidget() != 0) {
+ return false;
+ }
+ if (TQApplication::activeModalWidget() != 0) {
+ return false;
+ }
+
+ TQWidget *canvasWidget = dynamic_cast<TQWidget *>(m_canvasWidget);
+ Q_ASSERT(canvasWidget != 0);
+
+ if (canvasWidget) {
+ if (TQApplication::widgetAt(TQCursor::pos(), true) == canvasWidget) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void KisCanvas::handleKeyEvent(TQEvent *e)
+{
+ TQKeyEvent *ke = dynamic_cast<TQKeyEvent *>(e);
+
+ Q_ASSERT(ke != 0);
+
+ if (ke) {
+ TQWidget *canvasWidget = dynamic_cast<TQWidget *>(m_canvasWidget);
+ Q_ASSERT(canvasWidget != 0);
+
+ if (canvasWidget) {
+ canvasWidget->setFocus();
+
+ if (e->type() == TQEvent::KeyPress) {
+ emit sigGotKeyPressEvent(ke);
+ } else {
+ emit sigGotKeyReleaseEvent(ke);
+ }
+ }
+ }
+}
+
+#include "kis_canvas.moc"
+