/* * Copyright (c) 1999 Matthias Elter * Copyright (c) 2004-2006 Adrian Page * * 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. * * 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. */ #ifndef KIS_CANVAS_H_ #define KIS_CANVAS_H_ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_GL #include #endif #include #include "kis_global.h" #include "kis_point.h" #include "kis_vec.h" #include "kis_input_device.h" #ifdef Q_MOC_RUN #define Q_WS_X11 #endif // Q_MOC_RUN #ifdef Q_WS_X11 // Irix has a different (and better) XInput tablet driver to // the XFree/xorg driver. TQt needs a separate code path for that // and so would we. #if defined(HAVE_XINPUTEXT) && !defined(Q_OS_IRIX) #define EXTENDED_X11_TABLET_SUPPORT #endif #include #include #if defined(EXTENDED_X11_TABLET_SUPPORT) #include #endif #endif // Q_WS_X11 class KisEvent; class KisMoveEvent; class KisButtonPressEvent; class KisButtonReleaseEvent; class KisDoubleClickEvent; class KisCanvasWidgetPainter; class KisCanvasWidget : public TQObject { TQ_OBJECT public: KisCanvasWidget(); virtual ~KisCanvasWidget(); // When enabled, the canvas may throw away move events if the application // is unable to keep up with them, i.e. intermediate move events in the event // queue are skipped. void enableMoveEventCompressionHint(bool enableMoveCompression) { m_enableMoveEventCompressionHint = enableMoveCompression; } virtual KisCanvasWidgetPainter *createPainter() = 0; #ifdef EXTENDED_X11_TABLET_SUPPORT static KisInputDevice findActiveInputDevice(); virtual void selectTabletDeviceEvents() = 0; static void selectTabletDeviceEvents(TQWidget *widget); #endif #ifdef Q_WS_X11 static void initX11Support(); #endif signals: void sigGotPaintEvent(TQPaintEvent*); void sigGotEnterEvent(TQEvent*); void sigGotLeaveEvent(TQEvent*); void sigGotMouseWheelEvent(TQWheelEvent*); void sigGotKeyPressEvent(TQKeyEvent*); void sigGotKeyReleaseEvent(TQKeyEvent*); void sigGotDragEnterEvent(TQDragEnterEvent*); void sigGotDropEvent(TQDropEvent*); void sigGotMoveEvent(KisMoveEvent *); void sigGotButtonPressEvent(KisButtonPressEvent *); void sigGotButtonReleaseEvent(KisButtonReleaseEvent *); void sigGotDoubleClickEvent(KisDoubleClickEvent *); protected: void widgetGotPaintEvent(TQPaintEvent *event); void widgetGotMousePressEvent(TQMouseEvent *event); void widgetGotMouseReleaseEvent(TQMouseEvent *event); void widgetGotMouseDoubleClickEvent(TQMouseEvent *event); void widgetGotMouseMoveEvent(TQMouseEvent *event); void widgetGotTabletEvent(TQTabletEvent *event); void widgetGotEnterEvent(TQEvent *event ); void widgetGotLeaveEvent(TQEvent *event); void widgetGotWheelEvent(TQWheelEvent *event); void widgetGotKeyPressEvent(TQKeyEvent *event); void widgetGotKeyReleaseEvent(TQKeyEvent *event); void widgetGotDragEnterEvent(TQDragEnterEvent *event); void widgetGotDropEvent(TQDropEvent *event); void moveEvent(KisMoveEvent *event); void buttonPressEvent(KisButtonPressEvent *event); void buttonReleaseEvent(KisButtonReleaseEvent *event); void doubleClickEvent(KisDoubleClickEvent *event); void translateTabletEvent(KisEvent *event); protected: bool m_enableMoveEventCompressionHint; double m_lastPressure; #ifdef Q_WS_X11 // On X11 systems, TQt throws away mouse move events if the application // is unable to keep up with them. We override this behaviour so that // we receive all move events, so that painting follows the mouse's motion // accurately. bool x11Event(XEvent *event, Display *x11Display, WId winId, TQPoint widgetOriginPos); static TQt::ButtonState translateX11ButtonState(int state); static TQt::ButtonState translateX11Button(unsigned int button); static bool X11SupportInitialised; // Modifier masks for alt/meta - detected at run-time static long X11AltMask; static long X11MetaMask; int m_lastRootX; int m_lastRootY; #ifdef EXTENDED_X11_TABLET_SUPPORT public: class X11TabletDevice { public: X11TabletDevice(); X11TabletDevice(const XDeviceInfo *deviceInfo); bool mightBeTabletDevice() const { return m_mightBeTabletDevice; } XID id() const { return m_deviceId; } XDevice *xDevice() const { return m_XDevice; } TQString name() const { return m_name; } KisInputDevice inputDevice() const { return m_inputDevice; } void setInputDevice(KisInputDevice inputDevice) { m_inputDevice = inputDevice; } void setEnabled(bool enabled); bool enabled() const; TQ_INT32 numAxes() const; void setXAxis(TQ_INT32 axis); void setYAxis(TQ_INT32 axis); void setPressureAxis(TQ_INT32 axis); void setXTiltAxis(TQ_INT32 axis); void setYTiltAxis(TQ_INT32 axis); void setWheelAxis(TQ_INT32 axis); void setToolIDAxis(TQ_INT32 axis); void setSerialNumberAxis(TQ_INT32 axis); static const TQ_INT32 NoAxis = -1; static const TQ_INT32 DefaultAxis = -2; TQ_INT32 xAxis() const; TQ_INT32 yAxis() const; TQ_INT32 pressureAxis() const; TQ_INT32 xTiltAxis() const; TQ_INT32 yTiltAxis() const; TQ_INT32 wheelAxis() const; TQ_INT32 toolIDAxis() const; TQ_INT32 serialNumberAxis() const; void readSettingsFromConfig(); void writeSettingsToConfig(); // These return -1 if the device does not support the event int buttonPressEvent() const { return m_buttonPressEvent; } int buttonReleaseEvent() const { return m_buttonReleaseEvent; } int motionNotifyEvent() const { return m_motionNotifyEvent; } int proximityInEvent() const { return m_proximityInEvent; } int proximityOutEvent() const { return m_proximityOutEvent; } void enableEvents(TQWidget *widget) const; class State { public: State() {} State(const KisPoint& pos, double pressure, const KisVector2D& tilt, double wheel, TQ_UINT32 toolID, TQ_UINT32 serialNumber); // Position, pressure and wheel are normalised to 0 - 1 KisPoint pos() const { return m_pos; } double pressure() const { return m_pressure; } // Tilt is normalised to -1->+1 KisVector2D tilt() const { return m_tilt; } double wheel() const { return m_wheel; } // Wacom tool id and serial number of device. TQ_UINT32 toolID() const { return m_toolID; } TQ_UINT32 serialNumber() const { return m_serialNumber; } private: KisPoint m_pos; double m_pressure; KisVector2D m_tilt; double m_wheel; TQ_UINT32 m_toolID; TQ_UINT32 m_serialNumber; }; State translateAxisData(const int *axisData) const; private: double translateAxisValue(int value, const XAxisInfo& axisInfo) const; XID m_deviceId; XDevice *m_XDevice; TQString m_name; bool m_mightBeTabletDevice; KisInputDevice m_inputDevice; bool m_enabled; TQ_INT32 m_xAxis; TQ_INT32 m_yAxis; TQ_INT32 m_pressureAxis; TQ_INT32 m_xTiltAxis; TQ_INT32 m_yTiltAxis; TQ_INT32 m_wheelAxis; TQ_INT32 m_toolIDAxis; TQ_INT32 m_serialNumberAxis; TQValueVector m_axisInfo; int m_motionNotifyEvent; int m_buttonPressEvent; int m_buttonReleaseEvent; int m_proximityInEvent; int m_proximityOutEvent; TQValueVector m_eventClassList; }; typedef std::map X11XIDTabletDeviceMap; static X11XIDTabletDeviceMap& tabletDeviceMap(); protected: static int X11DeviceMotionNotifyEvent; static int X11DeviceButtonPressEvent; static int X11DeviceButtonReleaseEvent; static int X11ProximityInEvent; static int X11ProximityOutEvent; static X11XIDTabletDeviceMap X11TabletDeviceMap; #endif // EXTENDED_X11_TABLET_SUPPORT #endif // Q_WS_X11 }; class KisCanvas : public TQObject { TQ_OBJECT public: KisCanvas(TQWidget *parent, const char *name); virtual ~KisCanvas(); // When enabled, the canvas may throw away move events if the application // is unable to keep up with them, i.e. intermediate move events in the event // queue are skipped. void enableMoveEventCompressionHint(bool enableMoveCompression); bool isOpenGLCanvas() const; /** * Returns true if the cursor is over the canvas. */ bool cursorIsOverCanvas() const; /** * Handle the given event (which must be a key event) as if the canvas * had received it directly. */ void handleKeyEvent(TQEvent *e); int width() const; int height() const; void update(); void update(const TQRect& r); void update(int x, int y, int width, int height); void repaint(); void repaint(bool erase); void repaint(int x, int y, int width, int height, bool erase = true); void repaint(const TQRect& r, bool erase = true); void repaint(const TQRegion& r, bool erase = true); void updateGeometry(); #if defined(EXTENDED_X11_TABLET_SUPPORT) void selectTabletDeviceEvents(); #endif signals: void sigGotPaintEvent(TQPaintEvent*); void sigGotEnterEvent(TQEvent*); void sigGotLeaveEvent(TQEvent*); void sigGotMouseWheelEvent(TQWheelEvent*); void sigGotKeyPressEvent(TQKeyEvent*); void sigGotKeyReleaseEvent(TQKeyEvent*); void sigGotDragEnterEvent(TQDragEnterEvent*); void sigGotDropEvent(TQDropEvent*); void sigGotMoveEvent(KisMoveEvent *); void sigGotButtonPressEvent(KisButtonPressEvent *); void sigGotButtonReleaseEvent(KisButtonReleaseEvent *); void sigGotDoubleClickEvent(KisDoubleClickEvent *); protected: // Allow KisView to render on the widget directly, but everything else // has restricted access. friend class KisView; friend class KisCanvasPainter; // One of these will be valid, the other null. In TQt3, using a TQPainter on // a TQGLWidget is not reliable. TQWidget *TQPaintDeviceWidget() const; #ifdef HAVE_GL TQGLWidget *OpenGLWidget() const; #endif void createTQPaintDeviceCanvas(); #ifdef HAVE_GL void createOpenGLCanvas(TQGLWidget *sharedContextWidget); #endif void show(); void hide(); void setGeometry(int x, int y, int width, int height); void setUpdatesEnabled(bool updatesEnabled); bool isUpdatesEnabled() const; void setFocusPolicy(TQ_FocusPolicy focusPolicy); const TQCursor& cursor() const; void setCursor(const TQCursor& cursor); KisCanvasWidgetPainter *createPainter(); KisCanvasWidget *canvasWidget() const; protected: #ifdef HAVE_GL void createCanvasWidget(bool useOpenGL, TQGLWidget *sharedContextWidget = 0); #else void createCanvasWidget(bool useOpenGL); #endif TQWidget *m_parent; TQString m_name; KisCanvasWidget *m_canvasWidget; bool m_enableMoveEventCompressionHint; bool m_useOpenGL; }; #endif // KIS_CANVAS_H_