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