diff options
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 3 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_win.cpp | 199 | ||||
-rw-r--r-- | src/gui/kernel/qcocoamenuloader_mac.mm | 7 | ||||
-rw-r--r-- | src/gui/kernel/qcocoawindowdelegate_mac.mm | 9 |
4 files changed, 130 insertions, 88 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 4764a2d..9f4cd0c 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -933,7 +933,8 @@ void QApplicationPrivate::initialize() QApplicationPrivate::wheel_scroll_lines = 3; #endif - initializeMultitouch(); + if (qt_is_gui_used) + initializeMultitouch(); } /*! diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 05e75a2..b677228 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -243,8 +243,12 @@ static PtrWTGet ptrWTGet = 0; static PACKET localPacketBuf[QT_TABLET_NPACKETQSIZE]; // our own tablet packet queue. HCTX qt_tablet_context; // the hardware context for the tablet (like a window handle) bool qt_tablet_tilt_support; -static void tabletInit(UINT wActiveCsr, HCTX hTab); + +#ifndef QT_NO_TABLETEVENT +static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab); +static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor); static void initWinTabFunctions(); // resolve the WINTAB api functions +#endif // QT_NO_TABLETEVENT #ifndef QT_NO_ACCESSIBILITY @@ -256,7 +260,7 @@ extern QWidget* qt_get_tablet_widget(); extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); extern QRegion qt_dirtyRegion(QWidget *); -typedef QHash<UINT, QTabletDeviceData> QTabletCursorInfo; +typedef QHash<quint64, QTabletDeviceData> QTabletCursorInfo; Q_GLOBAL_STATIC(QTabletCursorInfo, tCursorInfo) QTabletDeviceData currentTabletPointer; @@ -791,7 +795,9 @@ void qt_init(QApplicationPrivate *priv, int) if (QApplication::desktopSettingsAware()) qt_set_windows_resources(); +#ifndef QT_NO_TABLETEVENT initWinTabFunctions(); +#endif // QT_NO_TABLETEVENT QApplicationPrivate::inputContext = new QWinInputContext(0); // Read the initial cleartype settings... @@ -2325,25 +2331,43 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } break; case WT_PROXIMITY: - if (ptrWTPacketsGet) { - bool enteredProximity = LOWORD(lParam) != 0; - PACKET proximityBuffer[QT_TABLET_NPACKETQSIZE]; - int totalPacks = ptrWTPacketsGet(qt_tablet_context, QT_TABLET_NPACKETQSIZE, proximityBuffer); - if (totalPacks > 0 && enteredProximity) { - uint currentCursor = proximityBuffer[0].pkCursor; - if (!tCursorInfo()->contains(currentCursor)) - tabletInit(currentCursor, qt_tablet_context); - currentTabletPointer = tCursorInfo()->value(currentCursor); + + #ifndef QT_NO_TABLETEVENT + if (ptrWTPacketsGet && ptrWTInfo) { + const bool enteredProximity = LOWORD(lParam) != 0; + PACKET proximityBuffer[1]; // we are only interested in the first packet in this case + const int totalPacks = ptrWTPacketsGet(qt_tablet_context, 1, proximityBuffer); + if (totalPacks > 0) { + const UINT currentCursor = proximityBuffer[0].pkCursor; + + UINT csr_physid; + ptrWTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &csr_physid); + UINT csr_type; + ptrWTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &csr_type); + const UINT deviceIdMask = 0xFF6; // device type mask && device color mask + quint64 uniqueId = (csr_type & deviceIdMask); + uniqueId = (uniqueId << 32) | csr_physid; + + // initialising and updating the cursor should be done in response to + // WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send + // the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES + const QTabletCursorInfo *const globalCursorInfo = tCursorInfo(); + if (!globalCursorInfo->contains(uniqueId)) + tabletInit(uniqueId, csr_type, qt_tablet_context); + + currentTabletPointer = globalCursorInfo->value(uniqueId); + tabletUpdateCursor(currentTabletPointer, currentCursor); } qt_tabletChokeMouse = false; -#ifndef QT_NO_TABLETEVENT + QTabletEvent tabletProximity(enteredProximity ? QEvent::TabletEnterProximity : QEvent::TabletLeaveProximity, QPoint(), QPoint(), QPointF(), currentTabletPointer.currentDevice, currentTabletPointer.currentPointerType, 0, 0, 0, 0, 0, 0, 0, currentTabletPointer.llId); QApplication::sendEvent(qApp, &tabletProximity); -#endif // QT_NO_TABLETEVENT } + #endif // QT_NO_TABLETEVENT + break; #ifdef Q_WS_WINCE_WM case WM_SETFOCUS: { @@ -3317,63 +3341,57 @@ bool QETWidget::translateWheelEvent(const MSG &msg) // the following is adapted from the wintab syspress example (public domain) /* -------------------------------------------------------------------------- */ -static void tabletInit(UINT wActiveCsr, HCTX hTab) +// Initialize the "static" information of a cursor device (pen, airbrush, etc). +// The QTabletDeviceData is initialized with the data that do not change in time +// (number of button, type of device, etc) but do not initialize the variable data +// (e.g.: pen or eraser) +#ifndef QT_NO_TABLETEVENT + +static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab) { + Q_ASSERT(ptrWTInfo); + Q_ASSERT(ptrWTGet); + + Q_ASSERT(!tCursorInfo()->contains(uniqueId)); + /* browse WinTab's many info items to discover pressure handling. */ - if (ptrWTInfo && ptrWTGet) { - AXIS np; - LOGCONTEXT lc; - BYTE wPrsBtn; - BYTE logBtns[32]; - UINT size; - - /* discover the LOGICAL button generated by the pressure channel. */ - /* get the PHYSICAL button from the cursor category and run it */ - /* through that cursor's button map (usually the identity map). */ - wPrsBtn = (BYTE)-1; - ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_NPBUTTON, &wPrsBtn); - size = ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_BUTTONMAP, &logBtns); - if ((UINT)wPrsBtn < size) - wPrsBtn = logBtns[wPrsBtn]; - - /* get the current context for its device variable. */ - ptrWTGet(hTab, &lc); - - /* get the size of the pressure axis. */ - QTabletDeviceData tdd; - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np); - tdd.minPressure = int(np.axMin); - tdd.maxPressure = int(np.axMax); - - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &np); - tdd.minTanPressure = int(np.axMin); - tdd.maxTanPressure = int(np.axMax); - - LOGCONTEXT lcMine; - - /* get default region */ - ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine); - - tdd.minX = 0; - tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX); - - tdd.minY = 0; - tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY); - - tdd.minZ = 0; - tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ); - - int csr_type, - csr_physid; - ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_TYPE, &csr_type); - ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_PHYSID, &csr_physid); - tdd.llId = csr_type & 0x0F06; - tdd.llId = (tdd.llId << 24) | csr_physid; -#ifndef QT_NO_TABLETEVENT - if (((csr_type & 0x0006) == 0x0002) && ((csr_type & 0x0F06) != 0x0902)) { - tdd.currentDevice = QTabletEvent::Stylus; - } else { - switch (csr_type & 0x0F06) { + AXIS np; + LOGCONTEXT lc; + + /* get the current context for its device variable. */ + ptrWTGet(hTab, &lc); + + /* get the size of the pressure axis. */ + QTabletDeviceData tdd; + tdd.llId = uniqueId; + + ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np); + tdd.minPressure = int(np.axMin); + tdd.maxPressure = int(np.axMax); + + ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &np); + tdd.minTanPressure = int(np.axMin); + tdd.maxTanPressure = int(np.axMax); + + LOGCONTEXT lcMine; + + /* get default region */ + ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine); + + tdd.minX = 0; + tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX); + + tdd.minY = 0; + tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY); + + tdd.minZ = 0; + tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ); + + const uint cursorTypeBitMask = 0x0F06; // bitmask to find the specific cursor type (see Wacom FAQ) + if (((csr_type & 0x0006) == 0x0002) && ((csr_type & cursorTypeBitMask) != 0x0902)) { + tdd.currentDevice = QTabletEvent::Stylus; + } else { + switch (csr_type & cursorTypeBitMask) { case 0x0802: tdd.currentDevice = QTabletEvent::Stylus; break; @@ -3391,26 +3409,34 @@ static void tabletInit(UINT wActiveCsr, HCTX hTab) break; default: tdd.currentDevice = QTabletEvent::NoDevice; - } - } - - switch (wActiveCsr % 3) { - case 2: - tdd.currentPointerType = QTabletEvent::Eraser; - break; - case 1: - tdd.currentPointerType = QTabletEvent::Pen; - break; - case 0: - tdd.currentPointerType = QTabletEvent::Cursor; - break; - default: - tdd.currentPointerType = QTabletEvent::UnknownPointer; } + } + tCursorInfo()->insert(uniqueId, tdd); +} #endif // QT_NO_TABLETEVENT - tCursorInfo()->insert(wActiveCsr, tdd); + +// Update the "dynamic" informations of a cursor device (pen, airbrush, etc). +// The dynamic information is the information of QTabletDeviceData that can change +// in time (eraser or pen if a device is turned around). +#ifndef QT_NO_TABLETEVENT + +static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor) +{ + switch (currentCursor % 3) { // %3 for dual track + case 0: + tdd.currentPointerType = QTabletEvent::Cursor; + break; + case 1: + tdd.currentPointerType = QTabletEvent::Pen; + break; + case 2: + tdd.currentPointerType = QTabletEvent::Eraser; + break; + default: + tdd.currentPointerType = QTabletEvent::UnknownPointer; } } +#endif // QT_NO_TABLETEVENT bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets) @@ -3546,6 +3572,10 @@ bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, } extern bool qt_is_gui_used; + + +#ifndef QT_NO_TABLETEVENT + static void initWinTabFunctions() { #if defined(Q_OS_WINCE) @@ -3564,6 +3594,7 @@ static void initWinTabFunctions() } #endif // Q_OS_WINCE } +#endif // QT_NO_TABLETEVENT // diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 9ab077f..990571d 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -76,9 +76,14 @@ QT_USE_NAMESPACE - (void)ensureAppMenuInMenu:(NSMenu *)menu { + // The application menu is the menu in the menu bar that contains the + // 'Quit' item. When changing menu bar (e.g when swithing between + // windows with different menu bars), we never recreate this menu, but + // instead pull it out the current menu bar and place into the new one: NSMenu *mainMenu = [NSApp mainMenu]; if ([NSApp mainMenu] == menu) - return; // nothing to do! + return; // nothing to do (menu is the current menu bar)! + #ifndef QT_NAMESPACE Q_ASSERT(mainMenu); #endif diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 9fb674e..8a22a65 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -324,8 +324,13 @@ static void cleanupCocoaWindowDelegate() NSRect frameToReturn = defaultFrame; QWidget *qwidget = m_windowHash->value(window); QSizeF size = qwidget->maximumSize(); - frameToReturn.size.width = qMin<CGFloat>(frameToReturn.size.width, size.width()); - frameToReturn.size.height = qMin<CGFloat>(frameToReturn.size.height, size.height()); + NSRect windowFrameRect = [window frame]; + NSRect viewFrameRect = [[window contentView] frame]; + // consider additional size required for titlebar & frame + frameToReturn.size.width = qMin<CGFloat>(frameToReturn.size.width, + size.width()+(windowFrameRect.size.width - viewFrameRect.size.width)); + frameToReturn.size.height = qMin<CGFloat>(frameToReturn.size.height, + size.height()+(windowFrameRect.size.height - viewFrameRect.size.height)); return frameToReturn; } |