63#include "kis_canvas.h"
64#include "kis_cursor.h"
65#include "kis_move_event.h"
66#include "kis_button_press_event.h"
67#include "kis_button_release_event.h"
68#include "kis_double_click_event.h"
69#include "kis_config.h"
70#include "kis_qpaintdevice_canvas.h"
71#include "kis_opengl_canvas.h"
72#include "kis_config.h"
73#include "kis_input_device.h"
78#include <tqdesktopwidget.h>
79#include <tqapplication.h>
81#include <X11/XKBlib.h>
82#include <X11/keysym.h>
84bool KisCanvasWidget::X11SupportInitialised =
false;
85long KisCanvasWidget::X11AltMask = 0;
86long KisCanvasWidget::X11MetaMask = 0;
88#if defined(EXTENDED_X11_TABLET_SUPPORT)
90int KisCanvasWidget::X11DeviceMotionNotifyEvent = -1;
91int KisCanvasWidget::X11DeviceButtonPressEvent = -1;
92int KisCanvasWidget::X11DeviceButtonReleaseEvent = -1;
93int KisCanvasWidget::X11ProximityInEvent = -1;
94int KisCanvasWidget::X11ProximityOutEvent = -1;
97std::map<XID, KisCanvasWidget::X11TabletDevice> KisCanvasWidget::X11TabletDeviceMap;
103KisCanvasWidget::KisCanvasWidget()
105 m_enableMoveEventCompressionHint =
false;
109 if (!X11SupportInitialised) {
118KisCanvasWidget::~KisCanvasWidget()
122void KisCanvasWidget::widgetGotPaintEvent(TQPaintEvent *e)
124 emit sigGotPaintEvent(e);
127void KisCanvasWidget::widgetGotMousePressEvent(TQMouseEvent *e)
129 KisButtonPressEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
130 buttonPressEvent(&ke);
133void KisCanvasWidget::widgetGotMouseReleaseEvent(TQMouseEvent *e)
135 KisButtonReleaseEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
136 buttonReleaseEvent(&ke);
139void KisCanvasWidget::widgetGotMouseDoubleClickEvent(TQMouseEvent *e)
141 KisDoubleClickEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
142 doubleClickEvent(&ke);
145void KisCanvasWidget::widgetGotMouseMoveEvent(TQMouseEvent *e)
147 KisMoveEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->state());
151void KisCanvasWidget::widgetGotTabletEvent(TQTabletEvent *e)
153 KisInputDevice device;
155 switch (e->device()) {
157 case TQTabletEvent::NoDevice:
158 case TQTabletEvent::Stylus:
159 device = KisInputDevice::stylus();
161 case TQTabletEvent::Puck:
162 device = KisInputDevice::puck();
164 case TQTabletEvent::Eraser:
165 device = KisInputDevice::eraser();
169 double pressure = e->pressure() / 255.0;
171 if (e->type() == TQEvent::TabletPress) {
172 KisButtonPressEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), TQt::LeftButton, TQt::NoButton);
173 translateTabletEvent(&ke);
176 if (e->type() == TQEvent::TabletRelease) {
177 KisButtonReleaseEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), TQt::LeftButton, TQt::NoButton);
178 translateTabletEvent(&ke);
181 KisMoveEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), TQt::NoButton);
182 translateTabletEvent(&ke);
197void KisCanvasWidget::widgetGotEnterEvent(TQEvent *e)
199 emit sigGotEnterEvent(e);
202void KisCanvasWidget::widgetGotLeaveEvent(TQEvent *e)
204 emit sigGotLeaveEvent(e);
207void KisCanvasWidget::widgetGotWheelEvent(TQWheelEvent *e)
209 emit sigGotMouseWheelEvent(e);
212void KisCanvasWidget::widgetGotKeyPressEvent(TQKeyEvent *e)
214 emit sigGotKeyPressEvent(e);
217void KisCanvasWidget::widgetGotKeyReleaseEvent(TQKeyEvent *e)
219 emit sigGotKeyReleaseEvent(e);
222void KisCanvasWidget::widgetGotDragEnterEvent(TQDragEnterEvent *e)
224 emit sigGotDragEnterEvent(e);
227void KisCanvasWidget::widgetGotDropEvent(TQDropEvent *e)
229 emit sigGotDropEvent(e);
232void KisCanvasWidget::moveEvent(KisMoveEvent *e)
234 emit sigGotMoveEvent(e);
237void KisCanvasWidget::buttonPressEvent(KisButtonPressEvent *e)
239 TQWidget *widget =
dynamic_cast<TQWidget *
>(
this);
240 Q_ASSERT(widget != 0);
246 emit sigGotButtonPressEvent(e);
249void KisCanvasWidget::buttonReleaseEvent(KisButtonReleaseEvent *e)
251 emit sigGotButtonReleaseEvent(e);
254void KisCanvasWidget::doubleClickEvent(KisDoubleClickEvent *e)
256 emit sigGotDoubleClickEvent(e);
259void KisCanvasWidget::translateTabletEvent(KisEvent *e)
261 bool checkThresholdOnly =
false;
263 if (e->type() == KisEvent::ButtonPressEvent || e->type() == KisEvent::ButtonReleaseEvent) {
264 KisButtonEvent *b =
static_cast<KisButtonEvent *
>(e);
266 if (b->button() == TQt::MidButton || b->button() == TQt::RightButton) {
268 if (e->type() == KisEvent::ButtonPressEvent) {
269 buttonPressEvent(
static_cast<KisButtonPressEvent *
>(e));
271 buttonReleaseEvent(
static_cast<KisButtonReleaseEvent *
>(e));
274 checkThresholdOnly =
true;
279 if (e->pressure() >= PRESSURE_THRESHOLD && m_lastPressure < PRESSURE_THRESHOLD) {
280 KisButtonPressEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), TQt::LeftButton, e->state());
281 buttonPressEvent(&ke);
282 }
else if (e->pressure() < PRESSURE_THRESHOLD && m_lastPressure >= PRESSURE_THRESHOLD) {
283 KisButtonReleaseEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), TQt::LeftButton, e->state());
284 buttonReleaseEvent(&ke);
286 if (!checkThresholdOnly) {
287 KisMoveEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->state());
292 m_lastPressure = e->pressure();
297void KisCanvasWidget::initX11Support()
299 if (X11SupportInitialised)
304 X11SupportInitialised =
true;
306 Display *x11Display = TQApplication::desktop()->x11Display();
309 XModifierKeymap *map = XGetModifierMapping(x11Display);
314 for (
int maskIndex = 0; maskIndex < 8; maskIndex++) {
315 for (
int i = 0; i < map->max_keypermod; i++) {
316 if (map->modifiermap[mapIndex]) {
318 KeySym sym = XkbKeycodeToKeysym(x11Display, map->modifiermap[mapIndex], 0, 0);
320 if (X11AltMask == 0 && (sym == XK_Alt_L || sym == XK_Alt_R)) {
321 X11AltMask = 1 << maskIndex;
323 if (X11MetaMask == 0 && (sym == XK_Meta_L || sym == XK_Meta_R)) {
324 X11MetaMask = 1 << maskIndex;
332 XFreeModifiermap(map);
336 X11AltMask = Mod1Mask;
337 X11MetaMask = Mod4Mask;
340#if defined(EXTENDED_X11_TABLET_SUPPORT)
343 const XDeviceInfo *devices = XListInputDevices(x11Display, &numDevices);
345 if (devices != NULL) {
346 XID lastStylusSeen = 0;
347 XID lastEraserSeen = 0;
348 bool foundStylus =
false;
349 bool foundEraser =
false;
351 for (
int i = 0; i < numDevices; i++) {
353 const XDeviceInfo *device = devices + i;
354 X11TabletDevice tabletDevice(device);
356 if (tabletDevice.mightBeTabletDevice()) {
358 tabletDevice.readSettingsFromConfig();
360 TQString lowerCaseName = tabletDevice.name().lower();
363 if (!foundStylus || !foundEraser) {
364 if (lowerCaseName.startsWith(
"stylus") || lowerCaseName.startsWith(
"pen")) {
365 lastStylusSeen = device->id;
368 else if (lowerCaseName.startsWith(
"eraser")) {
369 lastEraserSeen = device->id;
374 X11TabletDeviceMap[device->id] = tabletDevice;
378 if (tabletDevice.buttonPressEvent() >= 0) {
379 X11DeviceButtonPressEvent = tabletDevice.buttonPressEvent();
381 if (tabletDevice.buttonReleaseEvent() >= 0) {
382 X11DeviceButtonReleaseEvent = tabletDevice.buttonReleaseEvent();
384 if (tabletDevice.motionNotifyEvent() >= 0) {
385 X11DeviceMotionNotifyEvent = tabletDevice.motionNotifyEvent();
387 if (tabletDevice.proximityInEvent() >= 0) {
388 X11ProximityInEvent = tabletDevice.proximityInEvent();
390 if (tabletDevice.proximityOutEvent() >= 0) {
391 X11ProximityOutEvent = tabletDevice.proximityOutEvent();
397 for (X11XIDTabletDeviceMap::iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
399 X11TabletDevice& tabletDevice = (*it).second;
401 if (foundStylus && tabletDevice.id() == lastStylusSeen) {
402 tabletDevice.setInputDevice(KisInputDevice::stylus());
403 }
else if (foundEraser && tabletDevice.id() == lastEraserSeen) {
404 tabletDevice.setInputDevice(KisInputDevice::eraser());
406 tabletDevice.setInputDevice(KisInputDevice::allocateInputDevice());
410 XFreeDeviceList(
const_cast<XDeviceInfo *
>(devices));
415TQt::ButtonState KisCanvasWidget::translateX11ButtonState(
int state)
419 if (state & Button1Mask)
420 buttonState |= TQt::LeftButton;
421 if (state & Button2Mask)
422 buttonState |= TQt::MidButton;
423 if (state & Button3Mask)
424 buttonState |= TQt::RightButton;
425 if (state & ShiftMask)
426 buttonState |= TQt::ShiftButton;
427 if (state & ControlMask)
428 buttonState |= TQt::ControlButton;
429 if (state & X11AltMask)
430 buttonState |= TQt::AltButton;
431 if (state & X11MetaMask)
432 buttonState |= TQt::MetaButton;
434 return static_cast<TQt::ButtonState
>(buttonState);
437TQt::ButtonState KisCanvasWidget::translateX11Button(
unsigned int X11Button)
439 TQt::ButtonState qtButton;
443 qtButton = TQt::LeftButton;
446 qtButton = TQt::MidButton;
449 qtButton = TQt::RightButton;
452 qtButton = TQt::NoButton;
458#if defined(EXTENDED_X11_TABLET_SUPPORT)
460KisCanvasWidget::X11TabletDevice::X11TabletDevice()
462 m_mightBeTabletDevice =
false;
463 m_inputDevice = KisInputDevice::unknown();
467 m_pressureAxis = NoAxis;
468 m_xTiltAxis = NoAxis;
469 m_yTiltAxis = NoAxis;
470 m_wheelAxis = NoAxis;
471 m_toolIDAxis = NoAxis;
472 m_serialNumberAxis = NoAxis;
473 m_buttonPressEvent = -1;
474 m_buttonReleaseEvent = -1;
475 m_motionNotifyEvent = -1;
476 m_proximityInEvent = -1;
477 m_proximityOutEvent = -1;
480KisCanvasWidget::X11TabletDevice::X11TabletDevice(
const XDeviceInfo *deviceInfo)
482 m_mightBeTabletDevice =
false;
483 m_inputDevice = KisInputDevice::unknown();
487 m_pressureAxis = NoAxis;
488 m_xTiltAxis = NoAxis;
489 m_yTiltAxis = NoAxis;
490 m_wheelAxis = NoAxis;
491 m_toolIDAxis = NoAxis;
492 m_serialNumberAxis = NoAxis;
494 m_deviceId = deviceInfo->id;
495 m_name = deviceInfo->name;
498 XAnyClassPtr classInfo =
const_cast<XAnyClassPtr
>(deviceInfo->inputclassinfo);
500 for (
int i = 0; i < deviceInfo->num_classes; i++) {
502 if (classInfo->c_class == ValuatorClass) {
504 const XValuatorInfo *valuatorInfo =
reinterpret_cast<const XValuatorInfo *
>(classInfo);
508 if (valuatorInfo->num_axes >= 3) {
510 for (
unsigned int axis = 0; axis < valuatorInfo->num_axes; axis++) {
511 m_axisInfo.append(valuatorInfo->axes[axis]);
514 m_mightBeTabletDevice =
true;
518 classInfo =
reinterpret_cast<XAnyClassPtr
>(
reinterpret_cast<char *
>(classInfo) + classInfo->length);
523 m_buttonPressEvent = -1;
524 m_buttonReleaseEvent = -1;
525 m_motionNotifyEvent = -1;
526 m_proximityInEvent = -1;
527 m_proximityOutEvent = -1;
529 m_XDevice = XOpenDevice(TQApplication::desktop()->x11Display(), m_deviceId);
531 if (m_XDevice != NULL) {
532 for (
int i = 0; i < m_XDevice->num_classes; i++) {
534 XEventClass eventClass;
536 if (m_XDevice->classes[i].input_class == ButtonClass) {
537 DeviceButtonPress(m_XDevice, m_buttonPressEvent, eventClass);
538 m_eventClassList.append(eventClass);
540 DeviceButtonRelease(m_XDevice, m_buttonReleaseEvent, eventClass);
541 m_eventClassList.append(eventClass);
544 if (m_XDevice->classes[i].input_class == ValuatorClass) {
545 DeviceMotionNotify(m_XDevice, m_motionNotifyEvent, eventClass);
546 m_eventClassList.append(eventClass);
549 if (m_XDevice->classes[i].input_class == ProximityClass) {
550 ProximityIn(m_XDevice, m_proximityInEvent, eventClass);
551 m_eventClassList.append(eventClass);
553 ProximityOut(m_XDevice, m_proximityOutEvent, eventClass);
554 m_eventClassList.append(eventClass);
562 if (m_buttonPressEvent == -1 || m_buttonReleaseEvent == -1 || m_motionNotifyEvent == -1) {
563 m_mightBeTabletDevice =
false;
567void KisCanvasWidget::X11TabletDevice::setEnabled(
bool enabled)
572bool KisCanvasWidget::X11TabletDevice::enabled()
const
577TQ_INT32 KisCanvasWidget::X11TabletDevice::numAxes()
const
579 return m_axisInfo.count();
582void KisCanvasWidget::X11TabletDevice::setXAxis(TQ_INT32 axis)
587void KisCanvasWidget::X11TabletDevice::setYAxis(TQ_INT32 axis)
592void KisCanvasWidget::X11TabletDevice::setPressureAxis(TQ_INT32 axis)
594 m_pressureAxis = axis;
597void KisCanvasWidget::X11TabletDevice::setXTiltAxis(TQ_INT32 axis)
602void KisCanvasWidget::X11TabletDevice::setYTiltAxis(TQ_INT32 axis)
607void KisCanvasWidget::X11TabletDevice::setWheelAxis(TQ_INT32 axis)
612void KisCanvasWidget::X11TabletDevice::setToolIDAxis(TQ_INT32 axis)
617void KisCanvasWidget::X11TabletDevice::setSerialNumberAxis(TQ_INT32 axis)
619 m_serialNumberAxis = axis;
622TQ_INT32 KisCanvasWidget::X11TabletDevice::xAxis()
const
627TQ_INT32 KisCanvasWidget::X11TabletDevice::yAxis()
const
632TQ_INT32 KisCanvasWidget::X11TabletDevice::pressureAxis()
const
634 return m_pressureAxis;
637TQ_INT32 KisCanvasWidget::X11TabletDevice::xTiltAxis()
const
642TQ_INT32 KisCanvasWidget::X11TabletDevice::yTiltAxis()
const
647TQ_INT32 KisCanvasWidget::X11TabletDevice::wheelAxis()
const
652TQ_INT32 KisCanvasWidget::X11TabletDevice::toolIDAxis()
const
657TQ_INT32 KisCanvasWidget::X11TabletDevice::serialNumberAxis()
const
659 return m_serialNumberAxis;
662void KisCanvasWidget::X11TabletDevice::readSettingsFromConfig()
666 m_enabled = cfg.tabletDeviceEnabled(m_name);
668 m_xAxis = cfg.tabletDeviceAxis(m_name,
"XAxis", DefaultAxis);
669 m_yAxis = cfg.tabletDeviceAxis(m_name,
"YAxis", DefaultAxis);
670 m_pressureAxis = cfg.tabletDeviceAxis(m_name,
"PressureAxis", DefaultAxis);
671 m_xTiltAxis = cfg.tabletDeviceAxis(m_name,
"XTiltAxis", DefaultAxis);
672 m_yTiltAxis = cfg.tabletDeviceAxis(m_name,
"YTiltAxis", DefaultAxis);
673 m_wheelAxis = cfg.tabletDeviceAxis(m_name,
"WheelAxis", DefaultAxis);
674 m_toolIDAxis = cfg.tabletDeviceAxis(m_name,
"ToolIDAxis", DefaultAxis);
675 m_serialNumberAxis = cfg.tabletDeviceAxis(m_name,
"SerialNumberAxis", DefaultAxis);
677 if (!m_enabled && m_xAxis == DefaultAxis && m_yAxis == DefaultAxis && m_pressureAxis == DefaultAxis &&
678 m_xTiltAxis == DefaultAxis && m_yTiltAxis == DefaultAxis && m_wheelAxis == DefaultAxis &&
679 m_toolIDAxis == DefaultAxis && m_serialNumberAxis == DefaultAxis) {
686 if (m_axisInfo.count() >= 4) {
689 m_xTiltAxis = NoAxis;
692 if (m_axisInfo.count() >= 5) {
695 m_yTiltAxis = NoAxis;
698 if (m_axisInfo.count() >= 6) {
701 m_wheelAxis = NoAxis;
705 if (m_axisInfo.count() >= 7) {
708 m_toolIDAxis = NoAxis;
711 if (m_axisInfo.count() >= 8) {
712 m_serialNumberAxis = 7;
714 m_serialNumberAxis = NoAxis;
719void KisCanvasWidget::X11TabletDevice::writeSettingsToConfig()
723 cfg.setTabletDeviceEnabled(m_name, m_enabled);
725 cfg.setTabletDeviceAxis(m_name,
"XAxis", m_xAxis);
726 cfg.setTabletDeviceAxis(m_name,
"YAxis", m_yAxis);
727 cfg.setTabletDeviceAxis(m_name,
"PressureAxis", m_pressureAxis);
728 cfg.setTabletDeviceAxis(m_name,
"XTiltAxis", m_xTiltAxis);
729 cfg.setTabletDeviceAxis(m_name,
"YTiltAxis", m_yTiltAxis);
730 cfg.setTabletDeviceAxis(m_name,
"WheelAxis", m_wheelAxis);
731 cfg.setTabletDeviceAxis(m_name,
"ToolIDAxis", m_toolIDAxis);
732 cfg.setTabletDeviceAxis(m_name,
"SerialNumberAxis", m_serialNumberAxis);
735void KisCanvasWidget::X11TabletDevice::enableEvents(TQWidget *widget)
const
737 if (!m_eventClassList.isEmpty()) {
738 int result = XSelectExtensionEvent(widget->x11AppDisplay(), widget->handle(),
739 const_cast<XEventClass*
>(&m_eventClassList[0]),
740 m_eventClassList.count());
742 if (result != Success) {
743 kdDebug(41001) <<
"Failed to select extension events for " << m_name << endl;
748double KisCanvasWidget::X11TabletDevice::translateAxisValue(
int value,
const XAxisInfo& axisInfo)
const
750 int axisRange = axisInfo.max_value - axisInfo.min_value;
751 double translatedValue = 0;
753 if (axisRange != 0) {
754 translatedValue = (
static_cast<double>(value) - axisInfo.min_value) / axisRange;
755 if (axisInfo.min_value < 0) {
756 translatedValue -= 0.5;
760 return translatedValue;
763KisCanvasWidget::X11TabletDevice::State::State(
const KisPoint& pos,
double pressure,
const KisVector2D& tilt,
double wheel,
764 TQ_UINT32 toolID, TQ_UINT32 serialNumber)
766 m_pressure(pressure),
770 m_serialNumber(serialNumber)
774KisCanvasWidget::X11TabletDevice::State KisCanvasWidget::X11TabletDevice::translateAxisData(
const int *axisData)
const
778 if (m_xAxis != NoAxis && m_yAxis != NoAxis) {
779 pos =
KisPoint(translateAxisValue(axisData[m_xAxis], m_axisInfo[m_xAxis]),
780 translateAxisValue(axisData[m_yAxis], m_axisInfo[m_yAxis]));
783 double pressure = PRESSURE_DEFAULT;
785 if (m_pressureAxis != NoAxis) {
786 pressure = translateAxisValue(axisData[m_pressureAxis], m_axisInfo[m_pressureAxis]);
789 KisVector2D tilt = KisVector2D(0, 0);
790 TQ_UINT32 toolID = 0;
791 TQ_UINT32 serialNumber = 0;
793 if (m_xTiltAxis != NoAxis) {
796 int xTiltAxisValue = (TQ_INT16)(axisData[m_xTiltAxis] & 0xffff);
797 toolID = ((TQ_UINT32)axisData[m_xTiltAxis] >> 16) & 0xffff;
799 tilt.setX(translateAxisValue(xTiltAxisValue, m_axisInfo[m_xTiltAxis]));
802 if (m_yTiltAxis != NoAxis) {
803 int yTiltAxisValue = (TQ_INT16)(axisData[m_yTiltAxis] & 0xffff);
804 serialNumber = (TQ_UINT32)axisData[m_yTiltAxis] & 0xffff0000;
806 tilt.setY(translateAxisValue(yTiltAxisValue, m_axisInfo[m_yTiltAxis]));
811 if (m_wheelAxis != NoAxis) {
812 int wheelAxisValue = (TQ_INT16)(axisData[m_wheelAxis] & 0xffff);
813 serialNumber |= ((TQ_UINT32)axisData[m_wheelAxis] >> 16) & 0xffff;
815 wheel = translateAxisValue(wheelAxisValue, m_axisInfo[m_wheelAxis]);
821 return State(pos, pressure, tilt, wheel, toolID, serialNumber);
824KisCanvasWidget::X11XIDTabletDeviceMap& KisCanvasWidget::tabletDeviceMap()
826 return X11TabletDeviceMap;
829void KisCanvasWidget::selectTabletDeviceEvents(TQWidget *widget)
831 for (X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
833 const X11TabletDevice& device = (*it).second;
835 if (device.enabled()) {
836 device.enableEvents(widget);
843bool KisCanvasWidget::x11Event(XEvent *event, Display *x11Display, WId winId, TQPoint widgetOriginPos)
845 if (event->type == MotionNotify) {
847 if (!m_enableMoveEventCompressionHint) {
849 XMotionEvent motion =
event->xmotion;
850 TQPoint globalPos(motion.x_root, motion.y_root);
852 if (globalPos.x() != m_lastRootX || globalPos.y() != m_lastRootY) {
854 int state = translateX11ButtonState(motion.state);
855 TQPoint pos(motion.x, motion.y);
856 TQMouseEvent e(TQEvent::MouseMove, pos, globalPos, TQt::NoButton, state);
858 widgetGotMouseMoveEvent(&e);
861 m_lastRootX = globalPos.x();
862 m_lastRootY = globalPos.y();
871#if defined(EXTENDED_X11_TABLET_SUPPORT)
872 if (event->type == X11DeviceMotionNotifyEvent || event->type == X11DeviceButtonPressEvent || event->type == X11DeviceButtonReleaseEvent) {
876 TQt::ButtonState button;
877 TQt::ButtonState buttonState;
879 if (event->type == X11DeviceMotionNotifyEvent) {
881 const XDeviceMotionEvent *motion =
reinterpret_cast<const XDeviceMotionEvent *
>(event);
885 if (XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &mouseEvent)) {
886 if (motion->time == mouseEvent.xmotion.time) {
889 XPutBackEvent(x11Display, &mouseEvent);
893 if (m_enableMoveEventCompressionHint) {
897 if (!XCheckTypedWindowEvent(x11Display, winId, X11DeviceMotionNotifyEvent, &mouseEvent)) {
901 motion =
reinterpret_cast<const XDeviceMotionEvent *
>(&mouseEvent);
903 XEvent coreMotionEvent;
906 if (!XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &coreMotionEvent)) {
912 deviceId = motion->deviceid;
913 axisData = motion->axis_data;
914 button = TQt::NoButton;
915 buttonState = translateX11ButtonState(motion->state);
918 if (event->type == X11DeviceButtonPressEvent) {
920 const XDeviceButtonPressedEvent *buttonPressed =
reinterpret_cast<const XDeviceButtonPressedEvent *
>(event);
921 deviceId = buttonPressed->deviceid;
922 axisData = buttonPressed->axis_data;
923 button = translateX11Button(buttonPressed->button);
924 buttonState = translateX11ButtonState(buttonPressed->state);
926 if (TQApplication::activePopupWidget() == 0) {
931 if (XCheckTypedWindowEvent(x11Display, winId, ButtonPress, &mouseEvent)) {
932 if (buttonPressed->time == mouseEvent.xbutton.time) {
936 XPutBackEvent(x11Display, &mouseEvent);
943 const XDeviceButtonReleasedEvent *buttonReleased =
reinterpret_cast<const XDeviceButtonReleasedEvent *
>(event);
944 deviceId = buttonReleased->deviceid;
945 axisData = buttonReleased->axis_data;
946 button = translateX11Button(buttonReleased->button);
947 buttonState = translateX11ButtonState(buttonReleased->state);
949 if (TQApplication::activePopupWidget() == 0) {
954 if (XCheckTypedWindowEvent(x11Display, winId, ButtonRelease, &mouseEvent)) {
955 if (buttonReleased->time == mouseEvent.xbutton.time) {
959 XPutBackEvent(x11Display, &mouseEvent);
965 X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.find(deviceId);
967 if (it != X11TabletDeviceMap.end()) {
969 const X11TabletDevice& tabletDevice = (*it).second;
971 if (tabletDevice.enabled()) {
972 X11TabletDevice::State deviceState = tabletDevice.translateAxisData(axisData);
975 TQDesktopWidget *desktop = TQApplication::desktop();
976 KisPoint globalPos(deviceState.pos().x() * desktop->width(), deviceState.pos().y() * desktop->height());
978 KisPoint pos = globalPos - KoPoint( widgetOriginPos );
981 KisVector2D tilt(deviceState.tilt().x() * 60, deviceState.tilt().y() * 60);
983 if (event->type == X11DeviceMotionNotifyEvent) {
984 KisMoveEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), buttonState);
985 translateTabletEvent(&e);
988 if (event->type == X11DeviceButtonPressEvent) {
989 KisButtonPressEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState);
990 translateTabletEvent(&e);
993 KisButtonReleaseEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState);
994 translateTabletEvent(&e);
1013#if defined(EXTENDED_X11_TABLET_SUPPORT)
1015KisInputDevice KisCanvasWidget::findActiveInputDevice()
1017 X11XIDTabletDeviceMap::const_iterator it;
1019 for (it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
1020 const X11TabletDevice& tabletDevice = (*it).second;
1022 XDeviceState *deviceState = XQueryDeviceState(TQApplication::desktop()->x11Display(),
1023 tabletDevice.xDevice());
1028 if (!deviceState)
continue;
1030 const XInputClass *inputClass = deviceState->data;
1031 bool deviceIsInProximity =
false;
1033 for (
int i = 0; i < deviceState->num_classes; i++) {
1035 if (inputClass->c_class == ValuatorClass) {
1037 const XValuatorState *valuatorState =
reinterpret_cast<const XValuatorState *
>(inputClass);
1039 if ((valuatorState->mode & ProximityState) == InProximity) {
1040 deviceIsInProximity =
true;
1045 inputClass =
reinterpret_cast<const XInputClass *
>(
reinterpret_cast<const char *
>(inputClass) + inputClass->length);
1048 XFreeDeviceState(deviceState);
1050 if (deviceIsInProximity && tabletDevice.enabled()) {
1051 return tabletDevice.inputDevice();
1055 return KisInputDevice::mouse();
1065#define TQPAINTDEVICE_CANVAS_WIDGET false
1066#define OPENGL_CANVAS_WIDGET true
1068KisCanvas::KisCanvas(TQWidget *parent,
const char *name)
1072 m_enableMoveEventCompressionHint =
false;
1074 m_useOpenGL =
false;
1075 createCanvasWidget(TQPAINTDEVICE_CANVAS_WIDGET);
1078KisCanvas::~KisCanvas()
1080 delete m_canvasWidget;
1084void KisCanvas::createCanvasWidget(
bool useOpenGL, TQGLWidget *sharedContextWidget)
1086void KisCanvas::createCanvasWidget(
bool useOpenGL)
1089 delete m_canvasWidget;
1094 if (useOpenGL && !TQGLFormat::hasOpenGL()) {
1095 kdDebug(41001) <<
"Tried to create OpenGL widget when system doesn't have OpenGL\n";
1100 m_canvasWidget =
new KisOpenGLCanvasWidget(m_parent, m_name.latin1(), sharedContextWidget);
1104 m_canvasWidget =
new KisTQPaintDeviceCanvasWidget(m_parent, m_name.latin1());
1107 m_useOpenGL = useOpenGL;
1109 TQ_CHECK_PTR(m_canvasWidget);
1110 TQWidget *widget =
dynamic_cast<TQWidget *
>(m_canvasWidget);
1112 widget->setBackgroundMode(TQWidget::NoBackground);
1113 widget->setMouseTracking(
true);
1114 widget->setAcceptDrops(
true);
1115 m_canvasWidget->enableMoveEventCompressionHint(m_enableMoveEventCompressionHint);
1117#if defined(EXTENDED_X11_TABLET_SUPPORT)
1118 selectTabletDeviceEvents();
1121 connect(m_canvasWidget, TQ_SIGNAL(sigGotPaintEvent(TQPaintEvent *)), TQ_SIGNAL(sigGotPaintEvent(TQPaintEvent *)));
1122 connect(m_canvasWidget, TQ_SIGNAL(sigGotEnterEvent(TQEvent*)), TQ_SIGNAL(sigGotEnterEvent(TQEvent*)));
1123 connect(m_canvasWidget, TQ_SIGNAL(sigGotLeaveEvent(TQEvent*)), TQ_SIGNAL(sigGotLeaveEvent(TQEvent*)));
1124 connect(m_canvasWidget, TQ_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*)), TQ_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*)));
1125 connect(m_canvasWidget, TQ_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), TQ_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)));
1126 connect(m_canvasWidget, TQ_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*)), TQ_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*)));
1127 connect(m_canvasWidget, TQ_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*)), TQ_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*)));
1128 connect(m_canvasWidget, TQ_SIGNAL(sigGotDropEvent(TQDropEvent*)), TQ_SIGNAL(sigGotDropEvent(TQDropEvent*)));
1129 connect(m_canvasWidget, TQ_SIGNAL(sigGotMoveEvent(KisMoveEvent *)), TQ_SIGNAL(sigGotMoveEvent(KisMoveEvent *)));
1130 connect(m_canvasWidget, TQ_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *)), TQ_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *)));
1131 connect(m_canvasWidget, TQ_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *)), TQ_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *)));
1132 connect(m_canvasWidget, TQ_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *)), TQ_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *)));
1135void KisCanvas::createTQPaintDeviceCanvas()
1137 createCanvasWidget(TQPAINTDEVICE_CANVAS_WIDGET);
1141void KisCanvas::createOpenGLCanvas(TQGLWidget *sharedContextWidget)
1143 createCanvasWidget(OPENGL_CANVAS_WIDGET, sharedContextWidget);
1147bool KisCanvas::isOpenGLCanvas()
const
1152void KisCanvas::enableMoveEventCompressionHint(
bool enableMoveCompression)
1154 m_enableMoveEventCompressionHint = enableMoveCompression;
1155 if (m_canvasWidget != 0) {
1156 m_canvasWidget->enableMoveEventCompressionHint(enableMoveCompression);
1160TQWidget *KisCanvas::TQPaintDeviceWidget()
const
1165 return dynamic_cast<TQWidget *
>(m_canvasWidget);
1170TQGLWidget *KisCanvas::OpenGLWidget()
const
1173 return dynamic_cast<TQGLWidget *
>(m_canvasWidget);
1180KisCanvasWidgetPainter *KisCanvas::createPainter()
1182 Q_ASSERT(m_canvasWidget != 0);
1183 return m_canvasWidget->createPainter();
1186KisCanvasWidget *KisCanvas::canvasWidget()
const
1188 return m_canvasWidget;
1191void KisCanvas::setGeometry(
int x,
int y,
int width,
int height)
1193 Q_ASSERT(m_canvasWidget);
1194 dynamic_cast<TQWidget *
>(m_canvasWidget)->setGeometry(x, y, width, height);
1197void KisCanvas::show()
1199 Q_ASSERT(m_canvasWidget);
1200 dynamic_cast<TQWidget *
>(m_canvasWidget)->show();
1203void KisCanvas::hide()
1205 Q_ASSERT(m_canvasWidget);
1206 dynamic_cast<TQWidget *
>(m_canvasWidget)->hide();
1209int KisCanvas::width()
const
1211 Q_ASSERT(m_canvasWidget);
1212 return dynamic_cast<TQWidget *
>(m_canvasWidget)->width();
1215int KisCanvas::height()
const
1217 Q_ASSERT(m_canvasWidget);
1218 return dynamic_cast<TQWidget *
>(m_canvasWidget)->height();
1221void KisCanvas::update()
1223 Q_ASSERT(m_canvasWidget);
1224 dynamic_cast<TQWidget *
>(m_canvasWidget)->update();
1227void KisCanvas::update(
const TQRect& r)
1229 Q_ASSERT(m_canvasWidget);
1230 dynamic_cast<TQWidget *
>(m_canvasWidget)->update(r);
1233void KisCanvas::update(
int x,
int y,
int width,
int height)
1235 Q_ASSERT(m_canvasWidget);
1236 dynamic_cast<TQWidget *
>(m_canvasWidget)->update(x, y, width, height);
1239void KisCanvas::repaint()
1241 Q_ASSERT(m_canvasWidget);
1242 dynamic_cast<TQWidget *
>(m_canvasWidget)->repaint();
1245void KisCanvas::repaint(
bool erase)
1247 Q_ASSERT(m_canvasWidget);
1248 dynamic_cast<TQWidget *
>(m_canvasWidget)->repaint(erase);
1251void KisCanvas::repaint(
int x,
int y,
int width,
int height,
bool erase)
1253 Q_ASSERT(m_canvasWidget);
1254 dynamic_cast<TQWidget *
>(m_canvasWidget)->repaint(x, y, width, height, erase);
1257void KisCanvas::repaint(
const TQRect& r,
bool erase)
1259 Q_ASSERT(m_canvasWidget);
1260 dynamic_cast<TQWidget *
>(m_canvasWidget)->repaint(r, erase);
1263void KisCanvas::repaint(
const TQRegion& r,
bool erase)
1265 Q_ASSERT(m_canvasWidget);
1266 dynamic_cast<TQWidget *
>(m_canvasWidget)->repaint(r, erase);
1269bool KisCanvas::isUpdatesEnabled()
const
1271 Q_ASSERT(m_canvasWidget);
1272 return dynamic_cast<TQWidget *
>(m_canvasWidget)->isUpdatesEnabled();
1275void KisCanvas::setUpdatesEnabled(
bool updatesEnabled)
1277 Q_ASSERT(m_canvasWidget);
1278 dynamic_cast<TQWidget *
>(m_canvasWidget)->setUpdatesEnabled(updatesEnabled);
1281void KisCanvas::updateGeometry()
1283 Q_ASSERT(m_canvasWidget);
1284 dynamic_cast<TQWidget *
>(m_canvasWidget)->updateGeometry();
1287void KisCanvas::setFocusPolicy(TQWidget::FocusPolicy focusPolicy)
1289 Q_ASSERT(m_canvasWidget);
1290 dynamic_cast<TQWidget *
>(m_canvasWidget)->setFocusPolicy(focusPolicy);
1293const TQCursor& KisCanvas::cursor()
const
1295 Q_ASSERT(m_canvasWidget);
1296 return dynamic_cast<TQWidget *
>(m_canvasWidget)->cursor();
1299void KisCanvas::setCursor(
const TQCursor& cursor)
1301 Q_ASSERT(m_canvasWidget);
1302 dynamic_cast<TQWidget *
>(m_canvasWidget)->setCursor(cursor);
1305#if defined(EXTENDED_X11_TABLET_SUPPORT)
1306void KisCanvas::selectTabletDeviceEvents()
1308 Q_ASSERT(m_canvasWidget);
1309 m_canvasWidget->selectTabletDeviceEvents();
1313bool KisCanvas::cursorIsOverCanvas()
const
1315 if (TQApplication::activePopupWidget() != 0) {
1318 if (TQApplication::activeModalWidget() != 0) {
1322 TQWidget *canvasWidget =
dynamic_cast<TQWidget *
>(m_canvasWidget);
1323 Q_ASSERT(canvasWidget != 0);
1326 if (TQApplication::widgetAt(TQCursor::pos(),
true) == canvasWidget) {
1333void KisCanvas::handleKeyEvent(TQEvent *e)
1335 TQKeyEvent *ke =
dynamic_cast<TQKeyEvent *
>(e);
1340 TQWidget *canvasWidget =
dynamic_cast<TQWidget *
>(m_canvasWidget);
1341 Q_ASSERT(canvasWidget != 0);
1344 canvasWidget->setFocus();
1346 if (e->type() == TQEvent::KeyPress) {
1347 emit sigGotKeyPressEvent(ke);
1349 emit sigGotKeyReleaseEvent(ke);
1355#include "kis_canvas.moc"
A double-based point class that can return it's coordinates approximated to integers.