00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include <qcursor.h>
00062
00063 #include "kis_canvas.h"
00064 #include "kis_cursor.h"
00065 #include "kis_move_event.h"
00066 #include "kis_button_press_event.h"
00067 #include "kis_button_release_event.h"
00068 #include "kis_double_click_event.h"
00069 #include "kis_config.h"
00070 #include "kis_qpaintdevice_canvas.h"
00071 #include "kis_opengl_canvas.h"
00072 #include "kis_config.h"
00073 #include "kis_input_device.h"
00074 #include "fixx11h.h"
00075
00076 #ifdef Q_WS_X11
00077
00078 #include <qdesktopwidget.h>
00079 #include <qapplication.h>
00080
00081 #include <X11/keysym.h>
00082
00083 bool KisCanvasWidget::X11SupportInitialised = false;
00084 long KisCanvasWidget::X11AltMask = 0;
00085 long KisCanvasWidget::X11MetaMask = 0;
00086
00087 #if defined(EXTENDED_X11_TABLET_SUPPORT)
00088
00089 int KisCanvasWidget::X11DeviceMotionNotifyEvent = -1;
00090 int KisCanvasWidget::X11DeviceButtonPressEvent = -1;
00091 int KisCanvasWidget::X11DeviceButtonReleaseEvent = -1;
00092 int KisCanvasWidget::X11ProximityInEvent = -1;
00093 int KisCanvasWidget::X11ProximityOutEvent = -1;
00094
00095
00096 std::map<XID, KisCanvasWidget::X11TabletDevice> KisCanvasWidget::X11TabletDeviceMap;
00097
00098 #endif // EXTENDED_X11_TABLET_SUPPORT
00099
00100 #endif // Q_WS_X11
00101
00102 KisCanvasWidget::KisCanvasWidget()
00103 {
00104 m_enableMoveEventCompressionHint = false;
00105 m_lastPressure = 0;
00106
00107 #ifdef Q_WS_X11
00108 if (!X11SupportInitialised) {
00109 initX11Support();
00110 }
00111
00112 m_lastRootX = -1;
00113 m_lastRootY = -1;
00114 #endif
00115 }
00116
00117 KisCanvasWidget::~KisCanvasWidget()
00118 {
00119 }
00120
00121 void KisCanvasWidget::widgetGotPaintEvent(QPaintEvent *e)
00122 {
00123 emit sigGotPaintEvent(e);
00124 }
00125
00126 void KisCanvasWidget::widgetGotMousePressEvent(QMouseEvent *e)
00127 {
00128 KisButtonPressEvent ke(KisInputDevice::mouse(), e->pos(), e->globalPos(), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
00129 buttonPressEvent(&ke);
00130 }
00131
00132 void KisCanvasWidget::widgetGotMouseReleaseEvent(QMouseEvent *e)
00133 {
00134 KisButtonReleaseEvent ke(KisInputDevice::mouse(), e->pos(), e->globalPos(), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
00135 buttonReleaseEvent(&ke);
00136 }
00137
00138 void KisCanvasWidget::widgetGotMouseDoubleClickEvent(QMouseEvent *e)
00139 {
00140 KisDoubleClickEvent ke(KisInputDevice::mouse(), e->pos(), e->globalPos(), PRESSURE_DEFAULT, 0, 0, e->button(), e->state());
00141 doubleClickEvent(&ke);
00142 }
00143
00144 void KisCanvasWidget::widgetGotMouseMoveEvent(QMouseEvent *e)
00145 {
00146 KisMoveEvent ke(KisInputDevice::mouse(), e->pos(), e->globalPos(), PRESSURE_DEFAULT, 0, 0, e->state());
00147 moveEvent(&ke);
00148 }
00149
00150 void KisCanvasWidget::widgetGotTabletEvent(QTabletEvent *e)
00151 {
00152 KisInputDevice device;
00153
00154 switch (e->device()) {
00155 default:
00156 case QTabletEvent::NoDevice:
00157 case QTabletEvent::Stylus:
00158 device = KisInputDevice::stylus();
00159 break;
00160 case QTabletEvent::Puck:
00161 device = KisInputDevice::puck();
00162 break;
00163 case QTabletEvent::Eraser:
00164 device = KisInputDevice::eraser();
00165 break;
00166 }
00167
00168 double pressure = e->pressure() / 255.0;
00169
00170 if (e->type() == QEvent::TabletPress) {
00171 KisButtonPressEvent ke(device, e->pos(), e->globalPos(), pressure, e->xTilt(), e->yTilt(), Qt::LeftButton, Qt::NoButton);
00172 translateTabletEvent(&ke);
00173 }
00174 else
00175 if (e->type() == QEvent::TabletRelease) {
00176 KisButtonReleaseEvent ke(device, e->pos(), e->globalPos(), pressure, e->xTilt(), e->yTilt(), Qt::LeftButton, Qt::NoButton);
00177 translateTabletEvent(&ke);
00178 }
00179 else {
00180 KisMoveEvent ke(device, e->pos(), e->globalPos(), pressure, e->xTilt(), e->yTilt(), Qt::NoButton);
00181 translateTabletEvent(&ke);
00182 #ifdef Q_WS_X11
00183
00184
00185
00186
00187
00188
00189
00190
00191 e->ignore();
00192 #endif
00193 }
00194 }
00195
00196 void KisCanvasWidget::widgetGotEnterEvent(QEvent *e)
00197 {
00198 emit sigGotEnterEvent(e);
00199 }
00200
00201 void KisCanvasWidget::widgetGotLeaveEvent(QEvent *e)
00202 {
00203 emit sigGotLeaveEvent(e);
00204 }
00205
00206 void KisCanvasWidget::widgetGotWheelEvent(QWheelEvent *e)
00207 {
00208 emit sigGotMouseWheelEvent(e);
00209 }
00210
00211 void KisCanvasWidget::widgetGotKeyPressEvent(QKeyEvent *e)
00212 {
00213 emit sigGotKeyPressEvent(e);
00214 }
00215
00216 void KisCanvasWidget::widgetGotKeyReleaseEvent(QKeyEvent *e)
00217 {
00218 emit sigGotKeyReleaseEvent(e);
00219 }
00220
00221 void KisCanvasWidget::widgetGotDragEnterEvent(QDragEnterEvent *e)
00222 {
00223 emit sigGotDragEnterEvent(e);
00224 }
00225
00226 void KisCanvasWidget::widgetGotDropEvent(QDropEvent *e)
00227 {
00228 emit sigGotDropEvent(e);
00229 }
00230
00231 void KisCanvasWidget::moveEvent(KisMoveEvent *e)
00232 {
00233 emit sigGotMoveEvent(e);
00234 }
00235
00236 void KisCanvasWidget::buttonPressEvent(KisButtonPressEvent *e)
00237 {
00238 QWidget *widget = dynamic_cast<QWidget *>(this);
00239 Q_ASSERT(widget != 0);
00240
00241 if (widget) {
00242 widget->setFocus();
00243 }
00244
00245 emit sigGotButtonPressEvent(e);
00246 }
00247
00248 void KisCanvasWidget::buttonReleaseEvent(KisButtonReleaseEvent *e)
00249 {
00250 emit sigGotButtonReleaseEvent(e);
00251 }
00252
00253 void KisCanvasWidget::doubleClickEvent(KisDoubleClickEvent *e)
00254 {
00255 emit sigGotDoubleClickEvent(e);
00256 }
00257
00258 void KisCanvasWidget::translateTabletEvent(KisEvent *e)
00259 {
00260 bool checkThresholdOnly = false;
00261
00262 if (e->type() == KisEvent::ButtonPressEvent || e->type() == KisEvent::ButtonReleaseEvent) {
00263 KisButtonEvent *b = static_cast<KisButtonEvent *>(e);
00264
00265 if (b->button() == Qt::MidButton || b->button() == Qt::RightButton) {
00266
00267 if (e->type() == KisEvent::ButtonPressEvent) {
00268 buttonPressEvent(static_cast<KisButtonPressEvent *>(e));
00269 } else {
00270 buttonReleaseEvent(static_cast<KisButtonReleaseEvent *>(e));
00271 }
00272
00273 checkThresholdOnly = true;
00274 }
00275 }
00276
00277
00278 if (e->pressure() >= PRESSURE_THRESHOLD && m_lastPressure < PRESSURE_THRESHOLD) {
00279 KisButtonPressEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), Qt::LeftButton, e->state());
00280 buttonPressEvent(&ke);
00281 } else if (e->pressure() < PRESSURE_THRESHOLD && m_lastPressure >= PRESSURE_THRESHOLD) {
00282 KisButtonReleaseEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), Qt::LeftButton, e->state());
00283 buttonReleaseEvent(&ke);
00284 } else {
00285 if (!checkThresholdOnly) {
00286 KisMoveEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->state());
00287 moveEvent(&ke);
00288 }
00289 }
00290
00291 m_lastPressure = e->pressure();
00292 }
00293
00294 #ifdef Q_WS_X11
00295
00296 void KisCanvasWidget::initX11Support()
00297 {
00298 if (X11SupportInitialised)
00299 {
00300 return;
00301 }
00302
00303 X11SupportInitialised = true;
00304
00305 Display *x11Display = QApplication::desktop()->x11Display();
00306
00307
00308 XModifierKeymap *map = XGetModifierMapping(x11Display);
00309
00310 if (map) {
00311 int mapIndex = 0;
00312
00313 for (int maskIndex = 0; maskIndex < 8; maskIndex++) {
00314 for (int i = 0; i < map->max_keypermod; i++) {
00315 if (map->modifiermap[mapIndex]) {
00316
00317 KeySym sym = XKeycodeToKeysym(x11Display, map->modifiermap[mapIndex], 0);
00318
00319 if (X11AltMask == 0 && (sym == XK_Alt_L || sym == XK_Alt_R)) {
00320 X11AltMask = 1 << maskIndex;
00321 }
00322 if (X11MetaMask == 0 && (sym == XK_Meta_L || sym == XK_Meta_R)) {
00323 X11MetaMask = 1 << maskIndex;
00324 }
00325 }
00326
00327 mapIndex++;
00328 }
00329 }
00330
00331 XFreeModifiermap(map);
00332 }
00333 else {
00334
00335 X11AltMask = Mod1Mask;
00336 X11MetaMask = Mod4Mask;
00337 }
00338
00339 #if defined(EXTENDED_X11_TABLET_SUPPORT)
00340
00341 int numDevices = 0;
00342 const XDeviceInfo *devices = XListInputDevices(x11Display, &numDevices);
00343
00344 if (devices != NULL) {
00345 XID lastStylusSeen = 0;
00346 XID lastEraserSeen = 0;
00347 bool foundStylus = false;
00348 bool foundEraser = false;
00349
00350 for (int i = 0; i < numDevices; i++) {
00351
00352 const XDeviceInfo *device = devices + i;
00353 X11TabletDevice tabletDevice(device);
00354
00355 if (tabletDevice.mightBeTabletDevice()) {
00356
00357 tabletDevice.readSettingsFromConfig();
00358
00359 QString lowerCaseName = tabletDevice.name().lower();
00360
00361
00362 if (!foundStylus || !foundEraser) {
00363 if (lowerCaseName.startsWith("stylus") || lowerCaseName.startsWith("pen")) {
00364 lastStylusSeen = device->id;
00365 foundStylus = true;
00366 }
00367 else if (lowerCaseName.startsWith("eraser")) {
00368 lastEraserSeen = device->id;
00369 foundEraser = true;
00370 }
00371 }
00372
00373 X11TabletDeviceMap[device->id] = tabletDevice;
00374
00375
00376
00377 if (tabletDevice.buttonPressEvent() >= 0) {
00378 X11DeviceButtonPressEvent = tabletDevice.buttonPressEvent();
00379 }
00380 if (tabletDevice.buttonReleaseEvent() >= 0) {
00381 X11DeviceButtonReleaseEvent = tabletDevice.buttonReleaseEvent();
00382 }
00383 if (tabletDevice.motionNotifyEvent() >= 0) {
00384 X11DeviceMotionNotifyEvent = tabletDevice.motionNotifyEvent();
00385 }
00386 if (tabletDevice.proximityInEvent() >= 0) {
00387 X11ProximityInEvent = tabletDevice.proximityInEvent();
00388 }
00389 if (tabletDevice.proximityOutEvent() >= 0) {
00390 X11ProximityOutEvent = tabletDevice.proximityOutEvent();
00391 }
00392 }
00393 }
00394
00395
00396 for (X11XIDTabletDeviceMap::iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
00397
00398 X11TabletDevice& tabletDevice = (*it).second;
00399
00400 if (foundStylus && tabletDevice.id() == lastStylusSeen) {
00401 tabletDevice.setInputDevice(KisInputDevice::stylus());
00402 } else if (foundEraser && tabletDevice.id() == lastEraserSeen) {
00403 tabletDevice.setInputDevice(KisInputDevice::eraser());
00404 } else {
00405 tabletDevice.setInputDevice(KisInputDevice::allocateInputDevice());
00406 }
00407 }
00408
00409 XFreeDeviceList(const_cast<XDeviceInfo *>(devices));
00410 }
00411 #endif // EXTENDED_X11_TABLET_SUPPORT
00412 }
00413
00414 Qt::ButtonState KisCanvasWidget::translateX11ButtonState(int state)
00415 {
00416 int buttonState = 0;
00417
00418 if (state & Button1Mask)
00419 buttonState |= Qt::LeftButton;
00420 if (state & Button2Mask)
00421 buttonState |= Qt::MidButton;
00422 if (state & Button3Mask)
00423 buttonState |= Qt::RightButton;
00424 if (state & ShiftMask)
00425 buttonState |= Qt::ShiftButton;
00426 if (state & ControlMask)
00427 buttonState |= Qt::ControlButton;
00428 if (state & X11AltMask)
00429 buttonState |= Qt::AltButton;
00430 if (state & X11MetaMask)
00431 buttonState |= Qt::MetaButton;
00432
00433 return static_cast<Qt::ButtonState>(buttonState);
00434 }
00435
00436 Qt::ButtonState KisCanvasWidget::translateX11Button(unsigned int X11Button)
00437 {
00438 Qt::ButtonState qtButton;
00439
00440 switch (X11Button) {
00441 case Button1:
00442 qtButton = Qt::LeftButton;
00443 break;
00444 case Button2:
00445 qtButton = Qt::MidButton;
00446 break;
00447 case Button3:
00448 qtButton = Qt::RightButton;
00449 break;
00450 default:
00451 qtButton = Qt::NoButton;
00452 }
00453
00454 return qtButton;
00455 }
00456
00457 #if defined(EXTENDED_X11_TABLET_SUPPORT)
00458
00459 KisCanvasWidget::X11TabletDevice::X11TabletDevice()
00460 {
00461 m_mightBeTabletDevice = false;
00462 m_inputDevice = KisInputDevice::unknown();
00463 m_enabled = false;
00464 m_xAxis = NoAxis;
00465 m_yAxis = NoAxis;
00466 m_pressureAxis = NoAxis;
00467 m_xTiltAxis = NoAxis;
00468 m_yTiltAxis = NoAxis;
00469 m_wheelAxis = NoAxis;
00470 m_toolIDAxis = NoAxis;
00471 m_serialNumberAxis = NoAxis;
00472 m_buttonPressEvent = -1;
00473 m_buttonReleaseEvent = -1;
00474 m_motionNotifyEvent = -1;
00475 m_proximityInEvent = -1;
00476 m_proximityOutEvent = -1;
00477 }
00478
00479 KisCanvasWidget::X11TabletDevice::X11TabletDevice(const XDeviceInfo *deviceInfo)
00480 {
00481 m_mightBeTabletDevice = false;
00482 m_inputDevice = KisInputDevice::unknown();
00483 m_enabled = false;
00484 m_xAxis = NoAxis;
00485 m_yAxis = NoAxis;
00486 m_pressureAxis = NoAxis;
00487 m_xTiltAxis = NoAxis;
00488 m_yTiltAxis = NoAxis;
00489 m_wheelAxis = NoAxis;
00490 m_toolIDAxis = NoAxis;
00491 m_serialNumberAxis = NoAxis;
00492
00493 m_deviceId = deviceInfo->id;
00494 m_name = deviceInfo->name;
00495
00496
00497 XAnyClassPtr classInfo = const_cast<XAnyClassPtr>(deviceInfo->inputclassinfo);
00498
00499 for (int i = 0; i < deviceInfo->num_classes; i++) {
00500
00501 if (classInfo->c_class == ValuatorClass) {
00502
00503 const XValuatorInfo *valuatorInfo = reinterpret_cast<const XValuatorInfo *>(classInfo);
00504
00505
00506
00507 if (valuatorInfo->num_axes >= 3) {
00508
00509 for (unsigned int axis = 0; axis < valuatorInfo->num_axes; axis++) {
00510 m_axisInfo.append(valuatorInfo->axes[axis]);
00511 }
00512
00513 m_mightBeTabletDevice = true;
00514 }
00515 }
00516
00517 classInfo = reinterpret_cast<XAnyClassPtr>(reinterpret_cast<char *>(classInfo) + classInfo->length);
00518 }
00519
00520
00521
00522 m_buttonPressEvent = -1;
00523 m_buttonReleaseEvent = -1;
00524 m_motionNotifyEvent = -1;
00525 m_proximityInEvent = -1;
00526 m_proximityOutEvent = -1;
00527
00528 m_XDevice = XOpenDevice(QApplication::desktop()->x11Display(), m_deviceId);
00529
00530 if (m_XDevice != NULL) {
00531 for (int i = 0; i < m_XDevice->num_classes; i++) {
00532
00533 XEventClass eventClass;
00534
00535 if (m_XDevice->classes[i].input_class == ButtonClass) {
00536 DeviceButtonPress(m_XDevice, m_buttonPressEvent, eventClass);
00537 m_eventClassList.append(eventClass);
00538
00539 DeviceButtonRelease(m_XDevice, m_buttonReleaseEvent, eventClass);
00540 m_eventClassList.append(eventClass);
00541 }
00542 else
00543 if (m_XDevice->classes[i].input_class == ValuatorClass) {
00544 DeviceMotionNotify(m_XDevice, m_motionNotifyEvent, eventClass);
00545 m_eventClassList.append(eventClass);
00546 }
00547 else
00548 if (m_XDevice->classes[i].input_class == ProximityClass) {
00549 ProximityIn(m_XDevice, m_proximityInEvent, eventClass);
00550 m_eventClassList.append(eventClass);
00551
00552 ProximityOut(m_XDevice, m_proximityOutEvent, eventClass);
00553 m_eventClassList.append(eventClass);
00554 }
00555 }
00556
00557
00558
00559 }
00560
00561 if (m_buttonPressEvent == -1 || m_buttonReleaseEvent == -1 || m_motionNotifyEvent == -1) {
00562 m_mightBeTabletDevice = false;
00563 }
00564 }
00565
00566 void KisCanvasWidget::X11TabletDevice::setEnabled(bool enabled)
00567 {
00568 m_enabled = enabled;
00569 }
00570
00571 bool KisCanvasWidget::X11TabletDevice::enabled() const
00572 {
00573 return m_enabled;
00574 }
00575
00576 Q_INT32 KisCanvasWidget::X11TabletDevice::numAxes() const
00577 {
00578 return m_axisInfo.count();
00579 }
00580
00581 void KisCanvasWidget::X11TabletDevice::setXAxis(Q_INT32 axis)
00582 {
00583 m_xAxis = axis;
00584 }
00585
00586 void KisCanvasWidget::X11TabletDevice::setYAxis(Q_INT32 axis)
00587 {
00588 m_yAxis = axis;
00589 }
00590
00591 void KisCanvasWidget::X11TabletDevice::setPressureAxis(Q_INT32 axis)
00592 {
00593 m_pressureAxis = axis;
00594 }
00595
00596 void KisCanvasWidget::X11TabletDevice::setXTiltAxis(Q_INT32 axis)
00597 {
00598 m_xTiltAxis = axis;
00599 }
00600
00601 void KisCanvasWidget::X11TabletDevice::setYTiltAxis(Q_INT32 axis)
00602 {
00603 m_yTiltAxis = axis;
00604 }
00605
00606 void KisCanvasWidget::X11TabletDevice::setWheelAxis(Q_INT32 axis)
00607 {
00608 m_wheelAxis = axis;
00609 }
00610
00611 void KisCanvasWidget::X11TabletDevice::setToolIDAxis(Q_INT32 axis)
00612 {
00613 m_toolIDAxis = axis;
00614 }
00615
00616 void KisCanvasWidget::X11TabletDevice::setSerialNumberAxis(Q_INT32 axis)
00617 {
00618 m_serialNumberAxis = axis;
00619 }
00620
00621 Q_INT32 KisCanvasWidget::X11TabletDevice::xAxis() const
00622 {
00623 return m_xAxis;
00624 }
00625
00626 Q_INT32 KisCanvasWidget::X11TabletDevice::yAxis() const
00627 {
00628 return m_yAxis;
00629 }
00630
00631 Q_INT32 KisCanvasWidget::X11TabletDevice::pressureAxis() const
00632 {
00633 return m_pressureAxis;
00634 }
00635
00636 Q_INT32 KisCanvasWidget::X11TabletDevice::xTiltAxis() const
00637 {
00638 return m_xTiltAxis;
00639 }
00640
00641 Q_INT32 KisCanvasWidget::X11TabletDevice::yTiltAxis() const
00642 {
00643 return m_yTiltAxis;
00644 }
00645
00646 Q_INT32 KisCanvasWidget::X11TabletDevice::wheelAxis() const
00647 {
00648 return m_wheelAxis;
00649 }
00650
00651 Q_INT32 KisCanvasWidget::X11TabletDevice::toolIDAxis() const
00652 {
00653 return m_toolIDAxis;
00654 }
00655
00656 Q_INT32 KisCanvasWidget::X11TabletDevice::serialNumberAxis() const
00657 {
00658 return m_serialNumberAxis;
00659 }
00660
00661 void KisCanvasWidget::X11TabletDevice::readSettingsFromConfig()
00662 {
00663 KisConfig cfg;
00664
00665 m_enabled = cfg.tabletDeviceEnabled(m_name);
00666
00667 m_xAxis = cfg.tabletDeviceAxis(m_name, "XAxis", DefaultAxis);
00668 m_yAxis = cfg.tabletDeviceAxis(m_name, "YAxis", DefaultAxis);
00669 m_pressureAxis = cfg.tabletDeviceAxis(m_name, "PressureAxis", DefaultAxis);
00670 m_xTiltAxis = cfg.tabletDeviceAxis(m_name, "XTiltAxis", DefaultAxis);
00671 m_yTiltAxis = cfg.tabletDeviceAxis(m_name, "YTiltAxis", DefaultAxis);
00672 m_wheelAxis = cfg.tabletDeviceAxis(m_name, "WheelAxis", DefaultAxis);
00673 m_toolIDAxis = cfg.tabletDeviceAxis(m_name, "ToolIDAxis", DefaultAxis);
00674 m_serialNumberAxis = cfg.tabletDeviceAxis(m_name, "SerialNumberAxis", DefaultAxis);
00675
00676 if (!m_enabled && m_xAxis == DefaultAxis && m_yAxis == DefaultAxis && m_pressureAxis == DefaultAxis &&
00677 m_xTiltAxis == DefaultAxis && m_yTiltAxis == DefaultAxis && m_wheelAxis == DefaultAxis &&
00678 m_toolIDAxis == DefaultAxis && m_serialNumberAxis == DefaultAxis) {
00679
00680
00681 m_xAxis = 0;
00682 m_yAxis = 1;
00683 m_pressureAxis = 2;
00684
00685 if (m_axisInfo.count() >= 4) {
00686 m_xTiltAxis = 3;
00687 } else {
00688 m_xTiltAxis = NoAxis;
00689 }
00690
00691 if (m_axisInfo.count() >= 5) {
00692 m_yTiltAxis = 4;
00693 } else {
00694 m_yTiltAxis = NoAxis;
00695 }
00696
00697 if (m_axisInfo.count() >= 6) {
00698 m_wheelAxis = 5;
00699 } else {
00700 m_wheelAxis = NoAxis;
00701 }
00702
00703
00704 if (m_axisInfo.count() >= 7) {
00705 m_toolIDAxis = 6;
00706 } else {
00707 m_toolIDAxis = NoAxis;
00708 }
00709
00710 if (m_axisInfo.count() >= 8) {
00711 m_serialNumberAxis = 7;
00712 } else {
00713 m_serialNumberAxis = NoAxis;
00714 }
00715 }
00716 }
00717
00718 void KisCanvasWidget::X11TabletDevice::writeSettingsToConfig()
00719 {
00720 KisConfig cfg;
00721
00722 cfg.setTabletDeviceEnabled(m_name, m_enabled);
00723
00724 cfg.setTabletDeviceAxis(m_name, "XAxis", m_xAxis);
00725 cfg.setTabletDeviceAxis(m_name, "YAxis", m_yAxis);
00726 cfg.setTabletDeviceAxis(m_name, "PressureAxis", m_pressureAxis);
00727 cfg.setTabletDeviceAxis(m_name, "XTiltAxis", m_xTiltAxis);
00728 cfg.setTabletDeviceAxis(m_name, "YTiltAxis", m_yTiltAxis);
00729 cfg.setTabletDeviceAxis(m_name, "WheelAxis", m_wheelAxis);
00730 cfg.setTabletDeviceAxis(m_name, "ToolIDAxis", m_toolIDAxis);
00731 cfg.setTabletDeviceAxis(m_name, "SerialNumberAxis", m_serialNumberAxis);
00732 }
00733
00734 void KisCanvasWidget::X11TabletDevice::enableEvents(QWidget *widget) const
00735 {
00736 if (!m_eventClassList.isEmpty()) {
00737 int result = XSelectExtensionEvent(widget->x11AppDisplay(), widget->handle(),
00738 const_cast<XEventClass*>(&m_eventClassList[0]),
00739 m_eventClassList.count());
00740
00741 if (result != Success) {
00742 kdDebug(41001) << "Failed to select extension events for " << m_name << endl;
00743 }
00744 }
00745 }
00746
00747 double KisCanvasWidget::X11TabletDevice::translateAxisValue(int value, const XAxisInfo& axisInfo) const
00748 {
00749 int axisRange = axisInfo.max_value - axisInfo.min_value;
00750 double translatedValue = 0;
00751
00752 if (axisRange != 0) {
00753 translatedValue = (static_cast<double>(value) - axisInfo.min_value) / axisRange;
00754 if (axisInfo.min_value < 0) {
00755 translatedValue -= 0.5;
00756 }
00757 }
00758
00759 return translatedValue;
00760 }
00761
00762 KisCanvasWidget::X11TabletDevice::State::State(const KisPoint& pos, double pressure, const KisVector2D& tilt, double wheel,
00763 Q_UINT32 toolID, Q_UINT32 serialNumber)
00764 : m_pos(pos),
00765 m_pressure(pressure),
00766 m_tilt(tilt),
00767 m_wheel(wheel),
00768 m_toolID(toolID),
00769 m_serialNumber(serialNumber)
00770 {
00771 }
00772
00773 KisCanvasWidget::X11TabletDevice::State KisCanvasWidget::X11TabletDevice::translateAxisData(const int *axisData) const
00774 {
00775 KisPoint pos(0, 0);
00776
00777 if (m_xAxis != NoAxis && m_yAxis != NoAxis) {
00778 pos = KisPoint(translateAxisValue(axisData[m_xAxis], m_axisInfo[m_xAxis]),
00779 translateAxisValue(axisData[m_yAxis], m_axisInfo[m_yAxis]));
00780 }
00781
00782 double pressure = PRESSURE_DEFAULT;
00783
00784 if (m_pressureAxis != NoAxis) {
00785 pressure = translateAxisValue(axisData[m_pressureAxis], m_axisInfo[m_pressureAxis]);
00786 }
00787
00788 KisVector2D tilt = KisVector2D(0, 0);
00789 Q_UINT32 toolID = 0;
00790 Q_UINT32 serialNumber = 0;
00791
00792 if (m_xTiltAxis != NoAxis) {
00793
00794
00795 int xTiltAxisValue = (Q_INT16)(axisData[m_xTiltAxis] & 0xffff);
00796 toolID = ((Q_UINT32)axisData[m_xTiltAxis] >> 16) & 0xffff;
00797
00798 tilt.setX(translateAxisValue(xTiltAxisValue, m_axisInfo[m_xTiltAxis]));
00799 }
00800
00801 if (m_yTiltAxis != NoAxis) {
00802 int yTiltAxisValue = (Q_INT16)(axisData[m_yTiltAxis] & 0xffff);
00803 serialNumber = (Q_UINT32)axisData[m_yTiltAxis] & 0xffff0000;
00804
00805 tilt.setY(translateAxisValue(yTiltAxisValue, m_axisInfo[m_yTiltAxis]));
00806 }
00807
00808 double wheel = 0;
00809
00810 if (m_wheelAxis != NoAxis) {
00811 int wheelAxisValue = (Q_INT16)(axisData[m_wheelAxis] & 0xffff);
00812 serialNumber |= ((Q_UINT32)axisData[m_wheelAxis] >> 16) & 0xffff;
00813
00814 wheel = translateAxisValue(wheelAxisValue, m_axisInfo[m_wheelAxis]);
00815 }
00816
00817
00818
00819
00820 return State(pos, pressure, tilt, wheel, toolID, serialNumber);
00821 }
00822
00823 KisCanvasWidget::X11XIDTabletDeviceMap& KisCanvasWidget::tabletDeviceMap()
00824 {
00825 return X11TabletDeviceMap;
00826 }
00827
00828 void KisCanvasWidget::selectTabletDeviceEvents(QWidget *widget)
00829 {
00830 for (X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
00831
00832 const X11TabletDevice& device = (*it).second;
00833
00834 if (device.enabled()) {
00835 device.enableEvents(widget);
00836 }
00837 }
00838 }
00839
00840 #endif // EXTENDED_X11_TABLET_SUPPORT
00841
00842 bool KisCanvasWidget::x11Event(XEvent *event, Display *x11Display, WId winId, QPoint widgetOriginPos)
00843 {
00844 if (event->type == MotionNotify) {
00845
00846 if (!m_enableMoveEventCompressionHint) {
00847
00848 XMotionEvent motion = event->xmotion;
00849 QPoint globalPos(motion.x_root, motion.y_root);
00850
00851 if (globalPos.x() != m_lastRootX || globalPos.y() != m_lastRootY) {
00852
00853 int state = translateX11ButtonState(motion.state);
00854 QPoint pos(motion.x, motion.y);
00855 QMouseEvent e(QEvent::MouseMove, pos, globalPos, Qt::NoButton, state);
00856
00857 widgetGotMouseMoveEvent(&e);
00858 }
00859
00860 m_lastRootX = globalPos.x();
00861 m_lastRootY = globalPos.y();
00862
00863 return true;
00864 }
00865 else {
00866 return false;
00867 }
00868 }
00869 else
00870 #if defined(EXTENDED_X11_TABLET_SUPPORT)
00871 if (event->type == X11DeviceMotionNotifyEvent || event->type == X11DeviceButtonPressEvent || event->type == X11DeviceButtonReleaseEvent) {
00872
00873 int deviceId;
00874 const int *axisData;
00875 Qt::ButtonState button;
00876 Qt::ButtonState buttonState;
00877
00878 if (event->type == X11DeviceMotionNotifyEvent) {
00879
00880 const XDeviceMotionEvent *motion = reinterpret_cast<const XDeviceMotionEvent *>(event);
00881 XEvent mouseEvent;
00882
00883
00884 if (XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &mouseEvent)) {
00885 if (motion->time == mouseEvent.xmotion.time) {
00886
00887 } else {
00888 XPutBackEvent(x11Display, &mouseEvent);
00889 }
00890 }
00891
00892 if (m_enableMoveEventCompressionHint) {
00893 while (true) {
00894
00895
00896 if (!XCheckTypedWindowEvent(x11Display, winId, X11DeviceMotionNotifyEvent, &mouseEvent)) {
00897 break;
00898 }
00899
00900 motion = reinterpret_cast<const XDeviceMotionEvent *>(&mouseEvent);
00901
00902 XEvent coreMotionEvent;
00903
00904
00905 if (!XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &coreMotionEvent)) {
00906
00907 }
00908 }
00909 }
00910
00911 deviceId = motion->deviceid;
00912 axisData = motion->axis_data;
00913 button = Qt::NoButton;
00914 buttonState = translateX11ButtonState(motion->state);
00915 }
00916 else
00917 if (event->type == X11DeviceButtonPressEvent) {
00918
00919 const XDeviceButtonPressedEvent *buttonPressed = reinterpret_cast<const XDeviceButtonPressedEvent *>(event);
00920 deviceId = buttonPressed->deviceid;
00921 axisData = buttonPressed->axis_data;
00922 button = translateX11Button(buttonPressed->button);
00923 buttonState = translateX11ButtonState(buttonPressed->state);
00924
00925 if (QApplication::activePopupWidget() == 0) {
00926 XEvent mouseEvent;
00927
00928
00929
00930 if (XCheckTypedWindowEvent(x11Display, winId, ButtonPress, &mouseEvent)) {
00931 if (buttonPressed->time == mouseEvent.xbutton.time) {
00932
00933 }
00934 else {
00935 XPutBackEvent(x11Display, &mouseEvent);
00936 }
00937 }
00938 }
00939 }
00940 else {
00941
00942 const XDeviceButtonReleasedEvent *buttonReleased = reinterpret_cast<const XDeviceButtonReleasedEvent *>(event);
00943 deviceId = buttonReleased->deviceid;
00944 axisData = buttonReleased->axis_data;
00945 button = translateX11Button(buttonReleased->button);
00946 buttonState = translateX11ButtonState(buttonReleased->state);
00947
00948 if (QApplication::activePopupWidget() == 0) {
00949 XEvent mouseEvent;
00950
00951
00952
00953 if (XCheckTypedWindowEvent(x11Display, winId, ButtonRelease, &mouseEvent)) {
00954 if (buttonReleased->time == mouseEvent.xbutton.time) {
00955
00956 }
00957 else {
00958 XPutBackEvent(x11Display, &mouseEvent);
00959 }
00960 }
00961 }
00962 }
00963
00964 X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.find(deviceId);
00965
00966 if (it != X11TabletDeviceMap.end()) {
00967
00968 const X11TabletDevice& tabletDevice = (*it).second;
00969
00970 if (tabletDevice.enabled()) {
00971 X11TabletDevice::State deviceState = tabletDevice.translateAxisData(axisData);
00972
00973
00974 QDesktopWidget *desktop = QApplication::desktop();
00975 KisPoint globalPos(deviceState.pos().x() * desktop->width(), deviceState.pos().y() * desktop->height());
00976
00977 KisPoint pos = globalPos - KoPoint( widgetOriginPos );
00978
00979
00980 KisVector2D tilt(deviceState.tilt().x() * 60, deviceState.tilt().y() * 60);
00981
00982 if (event->type == X11DeviceMotionNotifyEvent) {
00983 KisMoveEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), buttonState);
00984 translateTabletEvent(&e);
00985 }
00986 else
00987 if (event->type == X11DeviceButtonPressEvent) {
00988 KisButtonPressEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState);
00989 translateTabletEvent(&e);
00990 }
00991 else {
00992 KisButtonReleaseEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState);
00993 translateTabletEvent(&e);
00994 }
00995 }
00996
00997
00998
00999 return true;
01000 }
01001 else {
01002 return false;
01003 }
01004 }
01005 else
01006 #endif // EXTENDED_X11_TABLET_SUPPORT
01007 {
01008 return false;
01009 }
01010 }
01011
01012 #if defined(EXTENDED_X11_TABLET_SUPPORT)
01013
01014 KisInputDevice KisCanvasWidget::findActiveInputDevice()
01015 {
01016 X11XIDTabletDeviceMap::const_iterator it;
01017
01018 for (it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) {
01019 const X11TabletDevice& tabletDevice = (*it).second;
01020
01021 XDeviceState *deviceState = XQueryDeviceState(QApplication::desktop()->x11Display(),
01022 tabletDevice.xDevice());
01023
01024
01025
01026
01027 if (!deviceState) continue;
01028
01029 const XInputClass *inputClass = deviceState->data;
01030 bool deviceIsInProximity = false;
01031
01032 for (int i = 0; i < deviceState->num_classes; i++) {
01033
01034 if (inputClass->c_class == ValuatorClass) {
01035
01036 const XValuatorState *valuatorState = reinterpret_cast<const XValuatorState *>(inputClass);
01037
01038 if ((valuatorState->mode & ProximityState) == InProximity) {
01039 deviceIsInProximity = true;
01040 break;
01041 }
01042 }
01043
01044 inputClass = reinterpret_cast<const XInputClass *>(reinterpret_cast<const char *>(inputClass) + inputClass->length);
01045 }
01046
01047 XFreeDeviceState(deviceState);
01048
01049 if (deviceIsInProximity && tabletDevice.enabled()) {
01050 return tabletDevice.inputDevice();
01051 }
01052 }
01053
01054 return KisInputDevice::mouse();
01055 }
01056
01057 #endif // EXTENDED_X11_TABLET_SUPPORT
01058
01059
01060 #endif // Q_WS_X11
01061
01062
01063
01064 #define QPAINTDEVICE_CANVAS_WIDGET false
01065 #define OPENGL_CANVAS_WIDGET true
01066
01067 KisCanvas::KisCanvas(QWidget *parent, const char *name)
01068 {
01069 m_parent = parent;
01070 m_name = name;
01071 m_enableMoveEventCompressionHint = false;
01072 m_canvasWidget = 0;
01073 m_useOpenGL = false;
01074 createCanvasWidget(QPAINTDEVICE_CANVAS_WIDGET);
01075 }
01076
01077 KisCanvas::~KisCanvas()
01078 {
01079 delete m_canvasWidget;
01080 }
01081
01082 #ifdef HAVE_GL
01083 void KisCanvas::createCanvasWidget(bool useOpenGL, QGLWidget *sharedContextWidget)
01084 #else
01085 void KisCanvas::createCanvasWidget(bool useOpenGL)
01086 #endif
01087 {
01088 delete m_canvasWidget;
01089
01090 #ifndef HAVE_GL
01091 useOpenGL = false;
01092 #else
01093 if (useOpenGL && !QGLFormat::hasOpenGL()) {
01094 kdDebug(41001) << "Tried to create OpenGL widget when system doesn't have OpenGL\n";
01095 useOpenGL = false;
01096 }
01097
01098 if (useOpenGL) {
01099 m_canvasWidget = new KisOpenGLCanvasWidget(m_parent, m_name.latin1(), sharedContextWidget);
01100 } else
01101 #endif
01102 {
01103 m_canvasWidget = new KisQPaintDeviceCanvasWidget(m_parent, m_name.latin1());
01104 }
01105
01106 m_useOpenGL = useOpenGL;
01107
01108 Q_CHECK_PTR(m_canvasWidget);
01109 QWidget *widget = dynamic_cast<QWidget *>(m_canvasWidget);
01110
01111 widget->setBackgroundMode(QWidget::NoBackground);
01112 widget->setMouseTracking(true);
01113 widget->setAcceptDrops(true);
01114 m_canvasWidget->enableMoveEventCompressionHint(m_enableMoveEventCompressionHint);
01115
01116 #if defined(EXTENDED_X11_TABLET_SUPPORT)
01117 selectTabletDeviceEvents();
01118 #endif
01119
01120 connect(m_canvasWidget, SIGNAL(sigGotPaintEvent(QPaintEvent *)), SIGNAL(sigGotPaintEvent(QPaintEvent *)));
01121 connect(m_canvasWidget, SIGNAL(sigGotEnterEvent(QEvent*)), SIGNAL(sigGotEnterEvent(QEvent*)));
01122 connect(m_canvasWidget, SIGNAL(sigGotLeaveEvent(QEvent*)), SIGNAL(sigGotLeaveEvent(QEvent*)));
01123 connect(m_canvasWidget, SIGNAL(sigGotMouseWheelEvent(QWheelEvent*)), SIGNAL(sigGotMouseWheelEvent(QWheelEvent*)));
01124 connect(m_canvasWidget, SIGNAL(sigGotKeyPressEvent(QKeyEvent*)), SIGNAL(sigGotKeyPressEvent(QKeyEvent*)));
01125 connect(m_canvasWidget, SIGNAL(sigGotKeyReleaseEvent(QKeyEvent*)), SIGNAL(sigGotKeyReleaseEvent(QKeyEvent*)));
01126 connect(m_canvasWidget, SIGNAL(sigGotDragEnterEvent(QDragEnterEvent*)), SIGNAL(sigGotDragEnterEvent(QDragEnterEvent*)));
01127 connect(m_canvasWidget, SIGNAL(sigGotDropEvent(QDropEvent*)), SIGNAL(sigGotDropEvent(QDropEvent*)));
01128 connect(m_canvasWidget, SIGNAL(sigGotMoveEvent(KisMoveEvent *)), SIGNAL(sigGotMoveEvent(KisMoveEvent *)));
01129 connect(m_canvasWidget, SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *)), SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *)));
01130 connect(m_canvasWidget, SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *)), SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *)));
01131 connect(m_canvasWidget, SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *)), SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *)));
01132 }
01133
01134 void KisCanvas::createQPaintDeviceCanvas()
01135 {
01136 createCanvasWidget(QPAINTDEVICE_CANVAS_WIDGET);
01137 }
01138
01139 #ifdef HAVE_GL
01140 void KisCanvas::createOpenGLCanvas(QGLWidget *sharedContextWidget)
01141 {
01142 createCanvasWidget(OPENGL_CANVAS_WIDGET, sharedContextWidget);
01143 }
01144 #endif
01145
01146 bool KisCanvas::isOpenGLCanvas() const
01147 {
01148 return m_useOpenGL;
01149 }
01150
01151 void KisCanvas::enableMoveEventCompressionHint(bool enableMoveCompression)
01152 {
01153 m_enableMoveEventCompressionHint = enableMoveCompression;
01154 if (m_canvasWidget != 0) {
01155 m_canvasWidget->enableMoveEventCompressionHint(enableMoveCompression);
01156 }
01157 }
01158
01159 QWidget *KisCanvas::QPaintDeviceWidget() const
01160 {
01161 if (m_useOpenGL) {
01162 return 0;
01163 } else {
01164 return dynamic_cast<QWidget *>(m_canvasWidget);
01165 }
01166 }
01167
01168 #ifdef HAVE_GL
01169 QGLWidget *KisCanvas::OpenGLWidget() const
01170 {
01171 if (m_useOpenGL) {
01172 return dynamic_cast<QGLWidget *>(m_canvasWidget);
01173 } else {
01174 return 0;
01175 }
01176 }
01177 #endif
01178
01179 KisCanvasWidgetPainter *KisCanvas::createPainter()
01180 {
01181 Q_ASSERT(m_canvasWidget != 0);
01182 return m_canvasWidget->createPainter();
01183 }
01184
01185 KisCanvasWidget *KisCanvas::canvasWidget() const
01186 {
01187 return m_canvasWidget;
01188 }
01189
01190 void KisCanvas::setGeometry(int x, int y, int width, int height)
01191 {
01192 Q_ASSERT(m_canvasWidget);
01193 dynamic_cast<QWidget *>(m_canvasWidget)->setGeometry(x, y, width, height);
01194 }
01195
01196 void KisCanvas::show()
01197 {
01198 Q_ASSERT(m_canvasWidget);
01199 dynamic_cast<QWidget *>(m_canvasWidget)->show();
01200 }
01201
01202 void KisCanvas::hide()
01203 {
01204 Q_ASSERT(m_canvasWidget);
01205 dynamic_cast<QWidget *>(m_canvasWidget)->hide();
01206 }
01207
01208 int KisCanvas::width() const
01209 {
01210 Q_ASSERT(m_canvasWidget);
01211 return dynamic_cast<QWidget *>(m_canvasWidget)->width();
01212 }
01213
01214 int KisCanvas::height() const
01215 {
01216 Q_ASSERT(m_canvasWidget);
01217 return dynamic_cast<QWidget *>(m_canvasWidget)->height();
01218 }
01219
01220 void KisCanvas::update()
01221 {
01222 Q_ASSERT(m_canvasWidget);
01223 dynamic_cast<QWidget *>(m_canvasWidget)->update();
01224 }
01225
01226 void KisCanvas::update(const QRect& r)
01227 {
01228 Q_ASSERT(m_canvasWidget);
01229 dynamic_cast<QWidget *>(m_canvasWidget)->update(r);
01230 }
01231
01232 void KisCanvas::update(int x, int y, int width, int height)
01233 {
01234 Q_ASSERT(m_canvasWidget);
01235 dynamic_cast<QWidget *>(m_canvasWidget)->update(x, y, width, height);
01236 }
01237
01238 void KisCanvas::repaint()
01239 {
01240 Q_ASSERT(m_canvasWidget);
01241 dynamic_cast<QWidget *>(m_canvasWidget)->repaint();
01242 }
01243
01244 void KisCanvas::repaint(bool erase)
01245 {
01246 Q_ASSERT(m_canvasWidget);
01247 dynamic_cast<QWidget *>(m_canvasWidget)->repaint(erase);
01248 }
01249
01250 void KisCanvas::repaint(int x, int y, int width, int height, bool erase)
01251 {
01252 Q_ASSERT(m_canvasWidget);
01253 dynamic_cast<QWidget *>(m_canvasWidget)->repaint(x, y, width, height, erase);
01254 }
01255
01256 void KisCanvas::repaint(const QRect& r, bool erase)
01257 {
01258 Q_ASSERT(m_canvasWidget);
01259 dynamic_cast<QWidget *>(m_canvasWidget)->repaint(r, erase);
01260 }
01261
01262 void KisCanvas::repaint(const QRegion& r, bool erase)
01263 {
01264 Q_ASSERT(m_canvasWidget);
01265 dynamic_cast<QWidget *>(m_canvasWidget)->repaint(r, erase);
01266 }
01267
01268 bool KisCanvas::isUpdatesEnabled() const
01269 {
01270 Q_ASSERT(m_canvasWidget);
01271 return dynamic_cast<QWidget *>(m_canvasWidget)->isUpdatesEnabled();
01272 }
01273
01274 void KisCanvas::setUpdatesEnabled(bool updatesEnabled)
01275 {
01276 Q_ASSERT(m_canvasWidget);
01277 dynamic_cast<QWidget *>(m_canvasWidget)->setUpdatesEnabled(updatesEnabled);
01278 }
01279
01280 void KisCanvas::updateGeometry()
01281 {
01282 Q_ASSERT(m_canvasWidget);
01283 dynamic_cast<QWidget *>(m_canvasWidget)->updateGeometry();
01284 }
01285
01286 void KisCanvas::setFocusPolicy(QWidget::FocusPolicy focusPolicy)
01287 {
01288 Q_ASSERT(m_canvasWidget);
01289 dynamic_cast<QWidget *>(m_canvasWidget)->setFocusPolicy(focusPolicy);
01290 }
01291
01292 const QCursor& KisCanvas::cursor() const
01293 {
01294 Q_ASSERT(m_canvasWidget);
01295 return dynamic_cast<QWidget *>(m_canvasWidget)->cursor();
01296 }
01297
01298 void KisCanvas::setCursor(const QCursor& cursor)
01299 {
01300 Q_ASSERT(m_canvasWidget);
01301 dynamic_cast<QWidget *>(m_canvasWidget)->setCursor(cursor);
01302 }
01303
01304 #if defined(EXTENDED_X11_TABLET_SUPPORT)
01305 void KisCanvas::selectTabletDeviceEvents()
01306 {
01307 Q_ASSERT(m_canvasWidget);
01308 m_canvasWidget->selectTabletDeviceEvents();
01309 }
01310 #endif
01311
01312 bool KisCanvas::cursorIsOverCanvas() const
01313 {
01314 if (QApplication::activePopupWidget() != 0) {
01315 return false;
01316 }
01317 if (QApplication::activeModalWidget() != 0) {
01318 return false;
01319 }
01320
01321 QWidget *canvasWidget = dynamic_cast<QWidget *>(m_canvasWidget);
01322 Q_ASSERT(canvasWidget != 0);
01323
01324 if (canvasWidget) {
01325 if (QApplication::widgetAt(QCursor::pos(), true) == canvasWidget) {
01326 return true;
01327 }
01328 }
01329 return false;
01330 }
01331
01332 void KisCanvas::handleKeyEvent(QEvent *e)
01333 {
01334 QKeyEvent *ke = dynamic_cast<QKeyEvent *>(e);
01335
01336 Q_ASSERT(ke != 0);
01337
01338 if (ke) {
01339 QWidget *canvasWidget = dynamic_cast<QWidget *>(m_canvasWidget);
01340 Q_ASSERT(canvasWidget != 0);
01341
01342 if (canvasWidget) {
01343 canvasWidget->setFocus();
01344
01345 if (e->type() == QEvent::KeyPress) {
01346 emit sigGotKeyPressEvent(ke);
01347 } else {
01348 emit sigGotKeyReleaseEvent(ke);
01349 }
01350 }
01351 }
01352 }
01353
01354 #include "kis_canvas.moc"
01355