diff options
Diffstat (limited to 'src/gui/platforms/win')
28 files changed, 0 insertions, 20260 deletions
diff --git a/src/gui/platforms/win/qapplication_win.cpp b/src/gui/platforms/win/qapplication_win.cpp deleted file mode 100644 index 72a05afbd0..0000000000 --- a/src/gui/platforms/win/qapplication_win.cpp +++ /dev/null @@ -1,4243 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifdef Q_WS_WINCE -#include "qguifunctions_wince.h" -#include "qmenubar.h" -extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp -extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp -extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp -extern bool qt_wince_is_pocket_pc(); //defined in qguifunctions_wince.cpp -extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.cpp -#endif -#ifdef Q_WS_WINCE_WM -#include <windowsm.h> -#include <tpcshell.h> -#ifdef QT_WINCE_GESTURES -#ifndef QT_NO_GESTURES -#include <gesture.h> -#endif -#endif -#endif - -#include "qapplication.h" -#include "qdesktopwidget.h" -#include "qevent.h" -#include "private/qeventdispatcher_win_p.h" -#include "qeventloop.h" -#include "qclipboard.h" -#include "qcursor.h" -#include "qdatetime.h" -#include "qpointer.h" -#include "qhash.h" -#include "qmetaobject.h" -#include "qmime.h" -#include "qpainter.h" -#include "qpixmapcache.h" -#include "qsessionmanager.h" -#include "qstyle.h" -#include "qwhatsthis.h" // ######## dependency -#include "qwidget.h" -#include "qcolormap.h" -#include "qlayout.h" -#include "qtooltip.h" -#include "qt_windows.h" -#include "qscrollbar.h" -#if defined(QT_NON_COMMERCIAL) -#include "qnc_win.h" -#endif -#include "private/qwininputcontext_p.h" -#include "private/qcursor_p.h" -#include "private/qmath_p.h" -#include "private/qapplication_p.h" -#include "private/qbackingstore_p.h" -#include "private/qwindowsurface_raster_p.h" -#include "qdebug.h" -#include <private/qkeymapper_p.h> -#include <private/qlocale_p.h> -#include <private/qsystemlibrary_p.h> -#include "qevent_p.h" - -//#define ALIEN_DEBUG - -#ifndef QT_NO_THREAD -#include "qmutex.h" -#endif - -#ifndef QT_NO_ACCESSIBILITY -#include "qaccessible.h" - -#include <oleacc.h> -#ifndef WM_GETOBJECT -#define WM_GETOBJECT 0x003D -#endif -#endif // QT_NO_ACCESSIBILITY - -#if !defined(WINABLEAPI) -# if defined(Q_WS_WINCE) -# include <bldver.h> -# endif -# if !defined(Q_WS_WINCE) -# include <winable.h> -# endif -#endif - -#ifndef QT_NO_GESTURES -# ifndef GID_ZOOM -# define GID_ZOOM 3 -# define GID_TWOFINGERTAP 6 -# define GID_PRESSANDTAP 7 -# define GID_ROLLOVER GID_PRESSANDTAP -# endif -#endif - -#ifndef WM_TOUCH -# define WM_TOUCH 0x0240 -#endif - -#ifndef TOUCHEVENTF_MOVE -# define TOUCHEVENTF_MOVE 0x0001 -# define TOUCHEVENTF_DOWN 0x0002 -# define TOUCHEVENTF_UP 0x0004 -# define TOUCHEVENTF_INRANGE 0x0008 -# define TOUCHEVENTF_PRIMARY 0x0010 -# define TOUCHEVENTF_NOCOALESCE 0x0020 -# define TOUCHEVENTF_PEN 0x0040 -# define TOUCHEVENTF_PALM 0x0080 - -# define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001 -# define TOUCHINPUTMASKF_EXTRAINFO 0x0002 -# define TOUCHINPUTMASKF_CONTACTAREA 0x0004 - -typedef struct tagTOUCHINPUT -{ - LONG x; - LONG y; - HANDLE hSource; - DWORD dwID; - DWORD dwFlags; - DWORD dwMask; - DWORD dwTime; - ULONG_PTR dwExtraInfo; - DWORD cxContact; - DWORD cyContact; -} TOUCHINPUT, *PTOUCHINPUT; - -#endif - -#include <windowsx.h> -#include <limits.h> -#include <string.h> -#include <ctype.h> -#include <stdio.h> -#include <math.h> - -#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \ - | PK_ORIENTATION | PK_CURSOR | PK_Z) -#define PACKETMODE 0 - -#include <wintab.h> -#ifndef CSR_TYPE -#define CSR_TYPE 20 // Some old Wacom wintab.h may not provide this constant. -#endif -#include <pktdef.h> - -#if defined(__CYGWIN32__) -#define __INSIDE_CYGWIN32__ -#include <mywinsock.h> -#endif - -#ifndef IMR_RECONVERTSTRING -#define IMR_RECONVERTSTRING 4 -#endif - -#ifndef IMR_CONFIRMRECONVERTSTRING -#define IMR_CONFIRMRECONVERTSTRING 0x0005 -#endif -QT_BEGIN_NAMESPACE - -#ifdef Q_WS_WINCE -#ifndef SHRG_RETURNCMD -struct SHRGINFO { - DWORD cbSize; - HWND hwndClient; - POINT ptDown; - DWORD dwFlags; -}; -#define GN_CONTEXTMENU 1000 -#define SHRG_RETURNCMD 0x00000001 -#define SHRG_NOANIMATION 0x00000010 -#endif - -#ifndef SPI_SETSIPINFO -#define SPI_SETSIPINFO 224 -#endif - -#ifndef QT_NO_GESTURES -typedef DWORD (API *AygRecognizeGesture)(SHRGINFO*); -static AygRecognizeGesture ptrRecognizeGesture = 0; -static bool aygResolved = false; -static void resolveAygLibs() -{ - if (!aygResolved) { - aygResolved = true; - QSystemLibrary ayglib(QLatin1String("aygshell")); - ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture"); - } -} -#endif // QT_NO_GESTURES - -#endif - -#ifndef SPI_SETFONTSMOOTHINGTYPE -# define SPI_SETFONTSMOOTHINGTYPE 0x200B -#endif -#ifndef SPI_GETFONTSMOOTHINGTYPE -# define SPI_GETFONTSMOOTHINGTYPE 0x200A -#endif -#ifndef FE_FONTSMOOTHINGCLEARTYPE -# define FE_FONTSMOOTHINGCLEARTYPE 0x0002 -#endif - -Q_GUI_EXPORT qreal qt_fontsmoothing_gamma; -Q_GUI_EXPORT bool qt_cleartype_enabled; -Q_GUI_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default - -typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL); -typedef BOOL (API *PtrWTClose)(HCTX); -typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID); -typedef BOOL (API *PtrWTEnable)(HCTX, BOOL); -typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL); -typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID); -typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT); -typedef int (API *PtrWTQueueSizeGet)(HCTX); -typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int); - -static PtrWTInfo ptrWTInfo = 0; -static PtrWTEnable ptrWTEnable = 0; -static PtrWTOverlap ptrWTOverlap = 0; -static PtrWTPacketsGet ptrWTPacketsGet = 0; -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; - -#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 -extern IAccessible *qt_createWindowsAccessible(QAccessibleInterface *object); -#endif // QT_NO_ACCESSIBILITY - -extern bool qt_tabletChokeMouse; -extern QWidget* qt_get_tablet_widget(); -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); -extern QRegion qt_dirtyRegion(QWidget *); - -typedef QHash<quint64, QTabletDeviceData> QTabletCursorInfo; -Q_GLOBAL_STATIC(QTabletCursorInfo, tCursorInfo) -QTabletDeviceData currentTabletPointer; - -// from qregion_win.cpp -extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom); - -// support for on-the-fly changes of the XP theme engine -#ifndef WM_THEMECHANGED -#define WM_THEMECHANGED 0x031A -#endif -#ifndef COLOR_MENUHILIGHT -#define COLOR_MENUHILIGHT 29 -#define COLOR_MENUBAR 30 -#endif - -// support for xbuttons -#ifndef WM_XBUTTONDOWN -#define WM_XBUTTONDOWN 0x020B -#define WM_XBUTTONUP 0x020C -#define WM_XBUTTONDBLCLK 0x020D -#endif -#ifndef GET_KEYSTATE_WPARAM -#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam)) -#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) -#define XBUTTON1 0x0001 -#define XBUTTON2 0x0002 -#endif -#ifndef MK_XBUTTON1 -#define MK_XBUTTON1 0x0020 -#define MK_XBUTTON2 0x0040 -#endif - -// support for multi-media-keys -#ifndef WM_APPCOMMAND -#define WM_APPCOMMAND 0x0319 -#endif - -#ifndef FAPPCOMMAND_MOUSE -#define FAPPCOMMAND_MOUSE 0x8000 -#define FAPPCOMMAND_KEY 0 -#define FAPPCOMMAND_OEM 0x1000 -#define FAPPCOMMAND_MASK 0xF000 -#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK)) -#define GET_DEVICE_LPARAM(lParam) ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK)) -#define GET_MOUSEORKEY_LPARAM GET_DEVICE_LPARAM -#define GET_FLAGS_LPARAM(lParam) (LOWORD(lParam)) -#define GET_KEYSTATE_LPARAM(lParam) GET_FLAGS_LPARAM(lParam) - -#define APPCOMMAND_BROWSER_BACKWARD 1 -#define APPCOMMAND_BROWSER_FORWARD 2 -#define APPCOMMAND_BROWSER_REFRESH 3 -#define APPCOMMAND_BROWSER_STOP 4 -#define APPCOMMAND_BROWSER_SEARCH 5 -#define APPCOMMAND_BROWSER_FAVORITES 6 -#define APPCOMMAND_BROWSER_HOME 7 -#define APPCOMMAND_VOLUME_MUTE 8 -#define APPCOMMAND_VOLUME_DOWN 9 -#define APPCOMMAND_VOLUME_UP 10 -#define APPCOMMAND_MEDIA_NEXTTRACK 11 -#define APPCOMMAND_MEDIA_PREVIOUSTRACK 12 -#define APPCOMMAND_MEDIA_STOP 13 -#define APPCOMMAND_MEDIA_PLAY_PAUSE 14 -#define APPCOMMAND_LAUNCH_MAIL 15 -#define APPCOMMAND_LAUNCH_MEDIA_SELECT 16 -#define APPCOMMAND_LAUNCH_APP1 17 -#define APPCOMMAND_LAUNCH_APP2 18 -#define APPCOMMAND_BASS_DOWN 19 -#define APPCOMMAND_BASS_BOOST 20 -#define APPCOMMAND_BASS_UP 21 -#define APPCOMMAND_TREBLE_DOWN 22 -#define APPCOMMAND_TREBLE_UP 23 -#endif // FAPPCOMMAND_MOUSE - -// New commands from Windows XP (some even Sp1) -#ifndef APPCOMMAND_MICROPHONE_VOLUME_MUTE -#define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24 -#define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25 -#define APPCOMMAND_MICROPHONE_VOLUME_UP 26 -#define APPCOMMAND_HELP 27 -#define APPCOMMAND_FIND 28 -#define APPCOMMAND_NEW 29 -#define APPCOMMAND_OPEN 30 -#define APPCOMMAND_CLOSE 31 -#define APPCOMMAND_SAVE 32 -#define APPCOMMAND_PRINT 33 -#define APPCOMMAND_UNDO 34 -#define APPCOMMAND_REDO 35 -#define APPCOMMAND_COPY 36 -#define APPCOMMAND_CUT 37 -#define APPCOMMAND_PASTE 38 -#define APPCOMMAND_REPLY_TO_MAIL 39 -#define APPCOMMAND_FORWARD_MAIL 40 -#define APPCOMMAND_SEND_MAIL 41 -#define APPCOMMAND_SPELL_CHECK 42 -#define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE 43 -#define APPCOMMAND_MIC_ON_OFF_TOGGLE 44 -#define APPCOMMAND_CORRECTION_LIST 45 -#define APPCOMMAND_MEDIA_PLAY 46 -#define APPCOMMAND_MEDIA_PAUSE 47 -#define APPCOMMAND_MEDIA_RECORD 48 -#define APPCOMMAND_MEDIA_FAST_FORWARD 49 -#define APPCOMMAND_MEDIA_REWIND 50 -#define APPCOMMAND_MEDIA_CHANNEL_UP 51 -#define APPCOMMAND_MEDIA_CHANNEL_DOWN 52 -#endif // APPCOMMAND_MICROPHONE_VOLUME_MUTE - -#if (_WIN32_WINNT < 0x0400) -// This struct is defined in winuser.h if the _WIN32_WINNT >= 0x0400 -- in the -// other cases we have to define it on our own. -typedef struct tagTRACKMOUSEEVENT { - DWORD cbSize; - DWORD dwFlags; - HWND hwndTrack; - DWORD dwHoverTime; -} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT; -#endif -#ifndef WM_MOUSELEAVE -#define WM_MOUSELEAVE 0x02A3 -#endif - -QT_BEGIN_INCLUDE_NAMESPACE -#include "private/qwidget_p.h" -QT_END_INCLUDE_NAMESPACE - -static int translateButtonState(int s, int type, int button); - -// ##### get rid of this! -QRgb qt_colorref2qrgb(COLORREF col) -{ - return qRgb(GetRValue(col),GetGValue(col),GetBValue(col)); -} - - -/***************************************************************************** - Internal variables and functions - *****************************************************************************/ - -static HWND curWin = 0; // current window -static HDC displayDC = 0; // display device context - -// Session management -static bool sm_blockUserInput = false; -static bool sm_smActive = false; -extern QSessionManager* qt_session_manager_self; -static bool sm_cancel; - -static bool replayPopupMouseEvent = false; // replay handling when popups close - -// ignore the next release event if return from a modal widget -Q_GUI_EXPORT bool qt_win_ignoreNextMouseReleaseEvent = false; - - -#if defined(QT_DEBUG) -static bool appNoGrab = false; // mouse/keyboard grabbing -#endif - -static bool app_do_modal = false; // modal mode -extern QWidgetList *qt_modal_stack; -extern QDesktopWidget *qt_desktopWidget; -static QPointer<QWidget> popupButtonFocus; -static bool qt_try_modal(QWidget *, MSG *, int& ret); - -QWidget *qt_button_down = 0; // widget got last button-down -QPointer<QWidget> qt_last_mouse_receiver = 0; - -static HWND autoCaptureWnd = 0; -static HWND imeParentWnd = 0; -static void setAutoCapture(HWND); // automatic capture -static void releaseAutoCapture(); - -static void unregWinClasses(); - -extern QCursor *qt_grab_cursor(); - -#if defined(Q_WS_WIN) -#define __export -#endif - -extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); - -class QETWidget : public QWidget // event translator widget -{ -public: - QWExtra *xtra() { return d_func()->extraData(); } - QTLWExtra *topData() { return d_func()->topData(); } - QTLWExtra *maybeTopData() { return d_func()->maybeTopData(); } - void syncBackingStore(const QRegion &rgn) { d_func()->syncBackingStore(rgn); } - void syncBackingStore() { d_func()->syncBackingStore(); } - QWidgetData *dataPtr() { return data; } - QWidgetPrivate *dptr() { return d_func(); } - QRect frameStrut() const { return d_func()->frameStrut(); } - bool winEvent(MSG *m, long *r) { return QWidget::winEvent(m, r); } - void markFrameStrutDirty() { data->fstrut_dirty = 1; } - bool translateMouseEvent(const MSG &msg); - bool translateWheelEvent(const MSG &msg); - bool translatePaintEvent(const MSG &msg); - bool translateConfigEvent(const MSG &msg); - bool translateCloseEvent(const MSG &msg); - bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets); -#ifndef QT_NO_GESTURES - bool translateGestureEvent(const MSG &msg, const GESTUREINFO &gi); -#endif - void repolishStyle(QStyle &style); - inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); } - inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); } - inline uint testWindowState(uint teststate){ return dataPtr()->window_state & teststate; } - inline void setWindowTitle_helper(const QString &title) { d_func()->setWindowTitle_helper(title); } - inline void forceUpdate() { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && tlwExtra->backingStore) - tlwExtra->backingStore->markDirty(rect(), this, true, true); - } -}; - -// need to get default font? -extern bool qt_app_has_font; - -extern QFont qt_LOGFONTtoQFont(LOGFONT& lf,bool scale); - -static void qt_set_windows_color_resources() -{ - // Do the color settings - QPalette pal; - pal.setColor(QPalette::WindowText, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT)))); - pal.setColor(QPalette::Button, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE)))); - pal.setColor(QPalette::Light, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT)))); - pal.setColor(QPalette::Dark, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNSHADOW)))); - pal.setColor(QPalette::Mid, pal.button().color().darker(150)); - pal.setColor(QPalette::Text, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT)))); - pal.setColor(QPalette::BrightText, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT)))); - pal.setColor(QPalette::Base, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOW)))); - pal.setColor(QPalette::Window, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE)))); - pal.setColor(QPalette::ButtonText, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNTEXT)))); - pal.setColor(QPalette::Midlight, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DLIGHT)))); - pal.setColor(QPalette::Shadow, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DDKSHADOW)))); - pal.setColor(QPalette::Highlight, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT)))); - pal.setColor(QPalette::HighlightedText, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT)))); - -#if defined(Q_WS_WINCE) - // ### hardcoded until I find out how to get it from the system settings. - pal.setColor(QPalette::LinkVisited, pal.highlight().color().dark(150)); - pal.setColor(QPalette::Link, pal.highlight().color().light(130)); - // Background == Base on Windows CE - if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc()) - pal.setColor(QPalette::Background, pal.base().color()); -#else - pal.setColor(QPalette::Link, Qt::blue); - pal.setColor(QPalette::LinkVisited, Qt::magenta); -#endif - - - - pal.setColor(QPalette::Inactive, QPalette::Button, pal.button().color()); - pal.setColor(QPalette::Inactive, QPalette::Window, pal.background().color()); - pal.setColor(QPalette::Inactive, QPalette::Light, pal.light().color()); - pal.setColor(QPalette::Inactive, QPalette::Dark, pal.dark().color()); - - if (pal.midlight() == pal.button()) - pal.setColor(QPalette::Midlight, pal.button().color().lighter(110)); - if (pal.background() != pal.base()) { - pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window)); - pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text)); - } - - const QColor bg = pal.background().color(); - const QColor fg = pal.foreground().color(), btn = pal.button().color(); - QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2, - (fg.blue()+btn.blue())/2); - pal.setColorGroup(QPalette::Disabled, pal.foreground(), pal.button(), pal.light(), - pal.dark(), pal.mid(), pal.text(), pal.brightText(), pal.base(), pal.background() ); - pal.setColor(QPalette::Disabled, QPalette::WindowText, disabled); - pal.setColor(QPalette::Disabled, QPalette::Text, disabled); - pal.setColor(QPalette::Disabled, QPalette::ButtonText, disabled); - pal.setColor(QPalette::Disabled, QPalette::Highlight, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT)))); - pal.setColor(QPalette::Disabled, QPalette::HighlightedText, - QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT)))); - pal.setColor(QPalette::Disabled, QPalette::Base, bg); - - QApplicationPrivate::setSystemPalette(pal); - - QApplicationPrivate::initializeWidgetPaletteHash(); - - QColor ttip(qt_colorref2qrgb(GetSysColor(COLOR_INFOBK))); - - QColor ttipText(qt_colorref2qrgb(GetSysColor(COLOR_INFOTEXT))); - { -#ifndef QT_NO_TOOLTIP - QPalette tiplabel(pal); - tiplabel.setColor(QPalette::All, QPalette::Button, ttip); - tiplabel.setColor(QPalette::All, QPalette::Window, ttip); - tiplabel.setColor(QPalette::All, QPalette::Text, ttipText); - tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText); - tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText); - tiplabel.setColor(QPalette::All, QPalette::Button, ttip); - tiplabel.setColor(QPalette::All, QPalette::Window, ttip); - tiplabel.setColor(QPalette::All, QPalette::Text, ttipText); - tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText); - tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText); - const QColor fg = tiplabel.foreground().color(), btn = tiplabel.button().color(); - QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2, - (fg.blue()+btn.blue())/2); - tiplabel.setColor(QPalette::Disabled, QPalette::WindowText, disabled); - tiplabel.setColor(QPalette::Disabled, QPalette::Text, disabled); - tiplabel.setColor(QPalette::Disabled, QPalette::Base, Qt::white); - tiplabel.setColor(QPalette::Disabled, QPalette::BrightText, Qt::white); - QToolTip::setPalette(tiplabel); -#endif //QT_NO_TOOLTIP - } -} - -static void qt_set_windows_font_resources() -{ -#ifndef Q_WS_WINCE - NONCLIENTMETRICS ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); - - QFont menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont, true); - QFont messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont, true); - QFont statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont, true); - QFont titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont, true); - - LOGFONT lfIconTitleFont; - SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); - QFont iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont, true); - - QApplication::setFont(menuFont, "QMenu"); - QApplication::setFont(menuFont, "QMenuBar"); - QApplication::setFont(messageFont, "QMessageBox"); - QApplication::setFont(statusFont, "QTipLabel"); - QApplication::setFont(statusFont, "QStatusBar"); - QApplication::setFont(titleFont, "Q3TitleBar"); - QApplication::setFont(titleFont, "QWorkspaceTitleBar"); - QApplication::setFont(iconTitleFont, "QAbstractItemView"); - QApplication::setFont(iconTitleFont, "QDockWidgetTitle"); - -#else - LOGFONT lf; - HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT); - GetObject(stockFont, sizeof(lf), &lf); - QFont systemFont = qt_LOGFONTtoQFont(lf, true); - QApplicationPrivate::setSystemFont(systemFont); - QFont smallerFont = systemFont; - if (qt_wince_is_mobile()) { - smallerFont.setPointSize(systemFont.pointSize()-1); - QApplication::setFont(smallerFont, "QTabBar"); - smallerFont.setBold(true); - QApplication::setFont(smallerFont, "QAbstractButton"); - } -#endif// Q_WS_WINCE -} - -static void qt_win_read_cleartype_settings() -{ - UINT result = 0; -#ifdef Q_OS_WINCE - if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &result, 0)) - qt_cleartype_enabled = result; -#else - if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0)) - qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); -#endif - - int winSmooth; - if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) { - qt_fontsmoothing_gamma = winSmooth / qreal(1000.0); - } else { - qt_fontsmoothing_gamma = 1.0; - } - - // Safeguard ourselves against corrupt registry values... - if (qt_fontsmoothing_gamma > 5 || qt_fontsmoothing_gamma < 1) - qt_fontsmoothing_gamma = qreal(1.4); -} - -static void qt_set_windows_resources() -{ - if (QApplication::type() != QApplication::Tty) - (void) QApplication::style(); // trigger creation of application style - qt_set_windows_font_resources(); - qt_set_windows_color_resources(); -} - -void QApplicationPrivate::initializeWidgetPaletteHash() -{ - QPalette pal = *QApplicationPrivate::sys_pal; - QColor menuCol(qt_colorref2qrgb(GetSysColor(COLOR_MENU))); - QColor menuText(qt_colorref2qrgb(GetSysColor(COLOR_MENUTEXT))); - BOOL isFlat = false; - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlat, 0); - QPalette menu(pal); - // we might need a special color group for the menu. - menu.setColor(QPalette::Active, QPalette::Button, menuCol); - menu.setColor(QPalette::Active, QPalette::Text, menuText); - menu.setColor(QPalette::Active, QPalette::WindowText, menuText); - menu.setColor(QPalette::Active, QPalette::ButtonText, menuText); - const QColor fg = menu.foreground().color(), btn = menu.button().color(); - QColor disabled(qt_colorref2qrgb(GetSysColor(COLOR_GRAYTEXT))); - menu.setColor(QPalette::Disabled, QPalette::WindowText, disabled); - menu.setColor(QPalette::Disabled, QPalette::Text, disabled); - menu.setColor(QPalette::Disabled, QPalette::Highlight, - QColor(qt_colorref2qrgb(GetSysColor( - (QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) - && isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT)))); - menu.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled); - menu.setColor(QPalette::Disabled, QPalette::Button, - menu.color(QPalette::Active, QPalette::Button)); - menu.setColor(QPalette::Inactive, QPalette::Button, - menu.color(QPalette::Active, QPalette::Button)); - menu.setColor(QPalette::Inactive, QPalette::Text, - menu.color(QPalette::Active, QPalette::Text)); - menu.setColor(QPalette::Inactive, QPalette::WindowText, - menu.color(QPalette::Active, QPalette::WindowText)); - menu.setColor(QPalette::Inactive, QPalette::ButtonText, - menu.color(QPalette::Active, QPalette::ButtonText)); - menu.setColor(QPalette::Inactive, QPalette::Highlight, - menu.color(QPalette::Active, QPalette::Highlight)); - menu.setColor(QPalette::Inactive, QPalette::HighlightedText, - menu.color(QPalette::Active, QPalette::HighlightedText)); - menu.setColor(QPalette::Inactive, QPalette::ButtonText, - pal.color(QPalette::Inactive, QPalette::Dark)); - QApplication::setPalette(menu, "QMenu"); - - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) && isFlat) { - QColor menubar(qt_colorref2qrgb(GetSysColor(COLOR_MENUBAR))); - menu.setColor(QPalette::Active, QPalette::Button, menubar); - menu.setColor(QPalette::Disabled, QPalette::Button, menubar); - menu.setColor(QPalette::Inactive, QPalette::Button, menubar); - } - QApplication::setPalette(menu, "QMenuBar"); -} - -static void qt_set_windows_updateScrollBar(QWidget *widget) -{ - QList<QObject*> children = widget->children(); - for (int i = 0; i < children.size(); ++i) { - QObject *o = children.at(i); - if(!o->isWidgetType()) - continue; - if (QWidget *w = static_cast<QWidget *>(o)) - qt_set_windows_updateScrollBar(w); - } -#ifndef QT_NO_SCROLLBAR - if (qobject_cast<QScrollBar*>(widget)) - widget->updateGeometry(); -#endif -} - - -/***************************************************************************** - qt_init() - initializes Qt for Windows - *****************************************************************************/ - -typedef BOOL (WINAPI *PtrSetProcessDPIAware) (VOID); -static PtrSetProcessDPIAware ptrSetProcessDPIAware = 0; -PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0; -PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect = 0; -static BOOL WINAPI qt_updateLayeredWindowIndirect(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *info) -{ - return (*ptrUpdateLayeredWindow)(hwnd, info->hdcDst, info->pptDst, info->psize, info->hdcSrc, - info->pptSrc, info->crKey, info->pblend, info->dwFlags); -} - -void qt_init(QApplicationPrivate *priv, int) -{ - - int argc = priv->argc; - char **argv = priv->argv; - int i, j; - - // Get command line params - - j = argc ? 1 : 0; - for (i=1; i<argc; i++) { - if (argv[i] && *argv[i] != '-') { - argv[j++] = argv[i]; - continue; - } -#if defined(QT_DEBUG) - if (qstrcmp(argv[i], "-nograb") == 0) - appNoGrab = !appNoGrab; - else -#endif // QT_DEBUG - argv[j++] = argv[i]; - } - if(j < priv->argc) { - priv->argv[j] = 0; - priv->argc = j; - } - -#ifndef Q_WS_WINCE - // No message boxes but important ones - SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); -#endif - -#ifndef Q_WS_WINCE - // Initialize OLE/COM - // S_OK means success and S_FALSE means that it has already - // been initialized - HRESULT r; - r = OleInitialize(0); - if (r != S_OK && r != S_FALSE) { - qWarning("Qt: Could not initialize OLE (error %x)", (unsigned int)r); - } -#endif - - // Misc. initialization -#if defined(QT_DEBUG) && !defined(Q_WS_WINCE) - GdiSetBatchLimit(1); -#endif - - // initialize key mapper - QKeyMapper::changeKeyboard(); - - QColormap::initialize(); - QFont::initialize(); -#ifndef QT_NO_CURSOR - QCursorData::initialize(); -#endif - qApp->setObjectName(priv->appName()); - - // default font -#ifndef Q_WS_WINCE - HGDIOBJ stockFont = GetStockObject(DEFAULT_GUI_FONT); -#else - HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT); -#endif - - LOGFONT lf; - GetObject(stockFont, sizeof(lf), &lf); - QFont systemFont = qt_LOGFONTtoQFont(lf, true); - -#ifndef Q_WS_WINCE - if (systemFont.family() == QLatin1String("MS Shell Dlg")) { - systemFont.setFamily(QLatin1String("MS Shell Dlg 2")); - } -#endif - - QApplicationPrivate::setSystemFont(systemFont); - - // QFont::locale_init(); ### Uncomment when it does something on Windows - - 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... - qt_win_read_cleartype_settings(); - qt_win_owndc_required = false; - - extern void qt_win_initialize_directdraw(); - qt_win_initialize_directdraw(); - -#ifndef Q_OS_WINCE - ptrUpdateLayeredWindowIndirect = - (PtrUpdateLayeredWindowIndirect) QSystemLibrary::resolve(QLatin1String("user32"), - "UpdateLayeredWindowIndirect"); - ptrUpdateLayeredWindow = - (PtrUpdateLayeredWindow) QSystemLibrary::resolve(QLatin1String("user32"), - "UpdateLayeredWindow"); - - if (ptrUpdateLayeredWindow && !ptrUpdateLayeredWindowIndirect) - ptrUpdateLayeredWindowIndirect = qt_updateLayeredWindowIndirect; - - // Notify Vista and Windows 7 that we support highter DPI settings - ptrSetProcessDPIAware = (PtrSetProcessDPIAware) - QSystemLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware"); - if (ptrSetProcessDPIAware) - ptrSetProcessDPIAware(); -#endif - -#ifndef QT_NO_GESTURES - priv->GetGestureInfo = 0; - priv->GetGestureExtraArgs = 0; - priv->CloseGestureInfoHandle = 0; - priv->SetGestureConfig = 0; - priv->GetGestureConfig = 0; - priv->BeginPanningFeedback = 0; - priv->UpdatePanningFeedback = 0; - priv->EndPanningFeedback = 0; - -#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES) - priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo; - priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments; -#elif !defined(Q_WS_WINCE) - #if !defined(QT_NO_NATIVE_GESTURES) - priv->GetGestureInfo = - (PtrGetGestureInfo)QSystemLibrary::resolve(QLatin1String("user32"), - "GetGestureInfo"); - priv->GetGestureExtraArgs = - (PtrGetGestureExtraArgs)QSystemLibrary::resolve(QLatin1String("user32"), - "GetGestureExtraArgs"); - priv->CloseGestureInfoHandle = - (PtrCloseGestureInfoHandle)QSystemLibrary::resolve(QLatin1String("user32"), - "CloseGestureInfoHandle"); - priv->SetGestureConfig = - (PtrSetGestureConfig)QSystemLibrary::resolve(QLatin1String("user32"), - "SetGestureConfig"); - priv->GetGestureConfig = - (PtrGetGestureConfig)QSystemLibrary::resolve(QLatin1String("user32"), - "GetGestureConfig"); - #endif // QT_NO_NATIVE_GESTURES - QSystemLibrary libTheme(QLatin1String("uxtheme")); - priv->BeginPanningFeedback = - (PtrBeginPanningFeedback)libTheme.resolve("BeginPanningFeedback"); - priv->UpdatePanningFeedback = - (PtrUpdatePanningFeedback)libTheme.resolve("UpdatePanningFeedback"); - priv->EndPanningFeedback = - (PtrEndPanningFeedback)libTheme.resolve("EndPanningFeedback"); -#endif -#endif // QT_NO_GESTURES -} - -/***************************************************************************** - qt_cleanup() - cleans up when the application is finished - *****************************************************************************/ - -void qt_cleanup() -{ - unregWinClasses(); - QPixmapCache::clear(); - -#ifndef QT_NO_CURSOR - QCursorData::cleanup(); -#endif - QFont::cleanup(); - QColormap::cleanup(); - if (displayDC) { - ReleaseDC(0, displayDC); - displayDC = 0; - } - - delete QApplicationPrivate::inputContext; - QApplicationPrivate::inputContext = 0; - -#ifndef Q_WS_WINCE - // Deinitialize OLE/COM - OleUninitialize(); -#endif -} - - -/***************************************************************************** - Platform specific global and internal functions - *****************************************************************************/ - -Q_GUI_EXPORT HDC qt_win_display_dc() // get display DC -{ - Q_ASSERT(qApp && qApp->thread() == QThread::currentThread()); - if (!displayDC) - displayDC = GetDC(0); - return displayDC; -} - -bool qt_nograb() // application no-grab option -{ -#if defined(QT_DEBUG) - return appNoGrab; -#else - return false; -#endif -} - -typedef QHash<QString, int> WinClassNameHash; -Q_GLOBAL_STATIC(WinClassNameHash, winclassNames) - -// -// If 0 is passed as the widget pointer, register a window class -// for QWidget as default. This is used in QGLTemporaryContext -// during GL initialization, where we don't want to use temporary -// QWidgets or QGLWidgets, neither do we want to have separate code -// to register window classes. -// -const QString qt_reg_winclass(QWidget *w) // register window class -{ - Qt::WindowFlags flags = w ? w->windowFlags() : (Qt::WindowFlags)0; - Qt::WindowFlags type = flags & Qt::WindowType_Mask; - - uint style; - bool icon; - QString cname; - if (w && qt_widget_private(w)->isGLWidget) { - cname = QLatin1String("QGLWidget"); - style = CS_DBLCLKS; -#ifndef Q_WS_WINCE - style |= CS_OWNDC; -#endif - icon = true; - } else if (w && (flags & Qt::MSWindowsOwnDC)) { - cname = QLatin1String("QWidgetOwnDC"); - style = CS_DBLCLKS; -#ifndef Q_WS_WINCE - style |= CS_OWNDC; -#endif - icon = true; - } else if (w && (type == Qt::Tool || type == Qt::ToolTip)) { - style = CS_DBLCLKS; - if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) { - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) { - style |= CS_DROPSHADOW; - } - cname = QLatin1String("QToolTip"); - } else { - cname = QLatin1String("QTool"); - } -#ifndef Q_WS_WINCE - style |= CS_SAVEBITS; -#endif - icon = false; - } else if (w && (type == Qt::Popup)) { - cname = QLatin1String("QPopup"); - style = CS_DBLCLKS; -#ifndef Q_WS_WINCE - style |= CS_SAVEBITS; -#endif - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - style |= CS_DROPSHADOW; - icon = false; - } else { - cname = QLatin1String("QWidget"); - style = CS_DBLCLKS; - icon = true; - } - -#ifndef Q_WS_WINCE - // force CS_OWNDC when the GL graphics system is - // used as the default renderer - if (qt_win_owndc_required) - style |= CS_OWNDC; -#endif - -#ifdef Q_OS_WINCE - // We need to register the classes with the - // unique ID on WinCE to make sure we can - // move the windows to the front when starting - // a second instance. - wchar_t uniqueAppID[MAX_PATH]; - GetModuleFileName(0, uniqueAppID, MAX_PATH); - cname = QString::number(RegisterWindowMessage( - (const wchar_t *) QString::fromWCharArray(uniqueAppID).toLower().replace(QLatin1Char('\\'), - QLatin1Char('_')).utf16())); -#endif - - // since multiple Qt versions can be used in one process - // each one has to have window class names with a unique name - // The first instance gets the unmodified name; if the class - // has already been registered by another instance of Qt then - // add an instance-specific ID, the address of the window proc. - static int classExists = -1; - - if (classExists == -1) { - WNDCLASS wcinfo; - classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (wchar_t*)cname.utf16(), &wcinfo); - classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; - } - - if (classExists) - cname += QString::number((quintptr)QtWndProc); - - if (winclassNames()->contains(cname)) // already registered in our list - return cname; - -#ifndef Q_WS_WINCE - WNDCLASSEX wc; - wc.cbSize = sizeof(WNDCLASSEX); -#else - WNDCLASS wc; -#endif - wc.style = style; - wc.lpfnWndProc = (WNDPROC)QtWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = qWinAppInst(); - if (icon) { - wc.hIcon = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); -#ifndef Q_WS_WINCE - if (wc.hIcon) { - int sw = GetSystemMetrics(SM_CXSMICON); - int sh = GetSystemMetrics(SM_CYSMICON); - wc.hIconSm = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, sw, sh, 0); - } else { - wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); - wc.hIconSm = 0; - } -#endif - } else { - wc.hIcon = 0; -#ifndef Q_WS_WINCE - wc.hIconSm = 0; -#endif - } - wc.hCursor = 0; -#ifndef Q_WS_WINCE - HBRUSH brush = 0; - if (w && !qt_widget_private(w)->isGLWidget) - brush = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); - wc.hbrBackground = brush; -#else - wc.hbrBackground = 0; -#endif - wc.lpszMenuName = 0; - wc.lpszClassName = (wchar_t*)cname.utf16(); - -#ifndef Q_WS_WINCE - ATOM atom = RegisterClassEx(&wc); -#else - ATOM atom = RegisterClass(&wc); -#endif - -#ifndef QT_NO_DEBUG - if (!atom) - qErrnoWarning("QApplication::regClass: Registering window class failed."); -#else - Q_UNUSED(atom); -#endif - - winclassNames()->insert(cname, 1); - return cname; -} - -Q_GUI_EXPORT const QString qt_getRegisteredWndClass() -{ - return qt_reg_winclass(0); -} - -static void unregWinClasses() -{ - WinClassNameHash *hash = winclassNames(); - QHash<QString, int>::ConstIterator it = hash->constBegin(); - while (it != hash->constEnd()) { - UnregisterClass((wchar_t*)it.key().utf16(), qWinAppInst()); - ++it; - } - hash->clear(); -} - - -/***************************************************************************** - Safe configuration (move,resize,setGeometry) mechanism to avoid - recursion when processing messages. - *****************************************************************************/ - -struct QWinConfigRequest { - WId id; // widget to be configured - int req; // 0=move, 1=resize, 2=setGeo - int x, y, w, h; // request parameters -}; - -static QList<QWinConfigRequest*> *configRequests = 0; - -void qWinRequestConfig(WId id, int req, int x, int y, int w, int h) -{ - if (!configRequests) // create queue - configRequests = new QList<QWinConfigRequest*>; - QWinConfigRequest *r = new QWinConfigRequest; - r->id = id; // create new request - r->req = req; - r->x = x; - r->y = y; - r->w = w; - r->h = h; - configRequests->append(r); // store request in queue -} - -static void qWinProcessConfigRequests() // perform requests in queue -{ - if (!configRequests) - return; - QWinConfigRequest *r; - for (;;) { - if (configRequests->isEmpty()) - break; - r = configRequests->takeLast(); - QWidget *w = QWidget::find(r->id); - QRect rect(r->x, r->y, r->w, r->h); - int req = r->req; - delete r; - - if ( w ) { // widget exists - if (w->testAttribute(Qt::WA_WState_ConfigPending)) - return; // biting our tail - if (req == 0) - w->move(rect.topLeft()); - else if (req == 1) - w->resize(rect.size()); - else - w->setGeometry(rect); - } - } - delete configRequests; - configRequests = 0; -} - - -/***************************************************************************** - GUI event dispatcher - *****************************************************************************/ - -class QGuiEventDispatcherWin32 : public QEventDispatcherWin32 -{ - Q_DECLARE_PRIVATE(QEventDispatcherWin32) -public: - QGuiEventDispatcherWin32(QObject *parent = 0); - bool processEvents(QEventLoop::ProcessEventsFlags flags); -}; - -QGuiEventDispatcherWin32::QGuiEventDispatcherWin32(QObject *parent) - : QEventDispatcherWin32(parent) -{ - createInternalHwnd(); -} - -bool QGuiEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) -{ - if (!QEventDispatcherWin32::processEvents(flags)) - return false; - - if (configRequests) // any pending configs? - qWinProcessConfigRequests(); - - return true; -} - -void QApplicationPrivate::createEventDispatcher() -{ - Q_Q(QApplication); - if (q->type() != QApplication::Tty) - eventDispatcher = new QGuiEventDispatcherWin32(q); - else - eventDispatcher = new QEventDispatcherWin32(q); -} - -/***************************************************************************** - Platform specific QApplication members - *****************************************************************************/ - -#ifdef QT3_SUPPORT -void QApplication::setMainWidget(QWidget *mainWidget) -{ - QApplicationPrivate::main_widget = mainWidget; - if (QApplicationPrivate::main_widget && windowIcon().isNull() - && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon)) - setWindowIcon(QApplicationPrivate::main_widget->windowIcon()); -} -#endif - -#ifndef QT_NO_CURSOR - -/***************************************************************************** - QApplication cursor stack - *****************************************************************************/ - -void QApplication::setOverrideCursor(const QCursor &cursor) -{ - qApp->d_func()->cursor_list.prepend(cursor); - SetCursor(qApp->d_func()->cursor_list.first().handle()); -} - -void QApplication::restoreOverrideCursor() -{ - if (qApp->d_func()->cursor_list.isEmpty()) - return; - qApp->d_func()->cursor_list.removeFirst(); - - if (!qApp->d_func()->cursor_list.isEmpty()) { - SetCursor(qApp->d_func()->cursor_list.first().handle()); - } else { - QWidget *w = QWidget::find(curWin); - if (w) - SetCursor(w->cursor().handle()); - else - SetCursor(QCursor(Qt::ArrowCursor).handle()); - } -} - -#endif - -/* - Internal function called from QWidget::setCursor() - force is true if this function is called from dispatchEnterLeave, it means that the - mouse is actually directly under this widget. -*/ - -#ifndef QT_NO_CURSOR -void qt_win_set_cursor(QWidget *w, bool force) -{ - static QPointer<QWidget> lastUnderMouse = 0; - if (force) { - lastUnderMouse = w; - } else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse - && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) { - w = lastUnderMouse; - } - - if (!curWin && w && w->internalWinId()) - return; - QWidget* cW = w && !w->internalWinId() ? w : QWidget::find(curWin); - if (!cW || cW->window() != w->window() || - !cW->isVisible() || !cW->underMouse() || QApplication::overrideCursor()) - return; - - SetCursor(cW->cursor().handle()); -} -#endif // QT_NO_CURSOR - -Qt::KeyboardModifiers qt_win_getKeyboardModifiers() -{ - Qt::KeyboardModifiers modifiers = Qt::NoModifier; - if (GetKeyState(VK_SHIFT) < 0) - modifiers |= Qt::ShiftModifier; - if (GetKeyState(VK_CONTROL) < 0) - modifiers |= Qt::ControlModifier; - if (GetKeyState(VK_MENU) < 0) - modifiers |= Qt::AltModifier; - return modifiers; -} - -/***************************************************************************** - Routines to find a Qt widget from a screen position - *****************************************************************************/ - -QWidget *QApplication::topLevelAt(const QPoint &pos) -{ - POINT p; - HWND win; - QWidget *w; - p.x = pos.x(); - p.y = pos.y(); - win = WindowFromPoint(p); - if (!win) - return 0; - - w = QWidget::find(win); - while (!w && win) { - win = GetParent(win); - w = QWidget::find(win); - } - return w ? w->window() : 0; -} - -void QApplication::beep() -{ - MessageBeep(MB_OK); -} - -static void alert_widget(QWidget *widget, int duration) -{ -#ifdef Q_OS_WINCE - Q_UNUSED(widget); - Q_UNUSED(duration); -#else - bool stopFlash = duration < 0; - - if (widget && (!widget->isActiveWindow() || stopFlash)) { - DWORD timeOut = GetCaretBlinkTime(); - if (timeOut <= 0) - timeOut = 250; - - UINT flashCount; - if (duration == 0) - flashCount = 10; - else - flashCount = duration/timeOut; - - FLASHWINFO info; - info.cbSize = sizeof(info); - info.hwnd = widget->window()->winId(); - info.dwFlags = stopFlash ? FLASHW_STOP : FLASHW_TRAY; - info.dwTimeout = stopFlash ? 0 : timeOut; - info.uCount = stopFlash ? 0 : flashCount; - - FlashWindowEx(&info); - } -#endif -} - -void QApplication::alert(QWidget *widget, int duration) -{ - if (!QApplicationPrivate::checkInstance("alert")) - return; - - if (widget) { - alert_widget(widget, duration); - } else { - const QWidgetList toplevels(topLevelWidgets()); - for (int i = 0; i < toplevels.count(); ++i) { - QWidget *topLevel = toplevels.at(i); - alert_widget(topLevel, duration); - } - } -} - -QString QApplicationPrivate::appName() const -{ - return QCoreApplicationPrivate::appName(); -} - - -/***************************************************************************** - Main event loop - *****************************************************************************/ - -extern uint qGlobalPostedEventsCount(); - -void QApplication::winFocus(QWidget *widget, bool gotFocus) -{ - if (d_func()->inPopupMode()) // some delayed focus event to ignore - return; - if (gotFocus) { - setActiveWindow(widget); - if (QApplicationPrivate::active_window - && (QApplicationPrivate::active_window->windowType() == Qt::Dialog)) { - // raise the entire application, not just the dialog - QWidget* mw = QApplicationPrivate::active_window; -#ifndef Q_WS_WINCE - while(mw->parentWidget() && (mw->windowType() == Qt::Dialog)) - mw = mw->parentWidget()->window(); - if (mw->testAttribute(Qt::WA_WState_Created) && mw != QApplicationPrivate::active_window) - SetWindowPos(mw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); -#else - // On Desktop Windows, we set the first parent of the dialog on top - // Child windows will be automatically set above again. - // On Windows CE we pass no parent in CreateWindowEx as otherwise - // dialogs get embedded into the parent window. Thus we need to - // manually iterate and reactivate all windows from bottom up. - QList<QWidget*> raiseList; - raiseList.push_back(mw); - while(mw->parentWidget() && (mw->windowType() == Qt::Dialog)) { - mw = mw->parentWidget()->window(); - raiseList.push_back(mw); - } - while(!raiseList.isEmpty()) { - mw = raiseList.takeLast(); - if (mw->testAttribute(Qt::WA_WState_Created)) { - HWND state = HWND_TOP; - if (mw->windowFlags() & Qt::WindowStaysOnBottomHint) - state = HWND_BOTTOM; - else if (mw->windowFlags() & Qt::WindowStaysOnTopHint) - state = HWND_TOPMOST; - SetWindowPos(mw->internalWinId(), state, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - } - } -#endif - } - } else { - setActiveWindow(0); - } -} - - -// -// QtWndProc() receives all messages from the main event loop -// - -static bool inLoop = false; -static int inputcharset = CP_ACP; - -#define RETURN(x) { inLoop=false;return x; } - -static bool qt_is_translatable_mouse_event(UINT message) -{ - return (((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) || - (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK)) - && message != WM_MOUSEWHEEL - && message != WM_MOUSEHWHEEL) - -#ifndef Q_WS_WINCE - || (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK) -#endif - ; -} - -extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - bool result = true; - QEvent::Type evt_type = QEvent::None; - QETWidget *widget = 0; - - // there is no need to process pakcets from tablet unless - // it is actually on the tablet, a flag to let us know... - int nPackets; // the number of packets we get from the queue - - long res = 0; - if (!qApp) // unstable app state - RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam)) - - QScopedLoopLevelCounter loopLevelCounter(QThreadData::get2(qApp->thread())); - -#if 0 - // make sure we update widgets also when the user resizes - if (inLoop && qApp->loopLevel()) - qApp->sendPostedEvents(0, QEvent::Paint); -#endif - - inLoop = true; - - MSG msg; - msg.hwnd = hwnd; // create MSG structure - msg.message = message; // time and pt fields ignored - msg.wParam = wParam; - msg.lParam = lParam; - msg.pt.x = GET_X_LPARAM(lParam); - msg.pt.y = GET_Y_LPARAM(lParam); - // If it's a non-client-area message the coords are screen coords, otherwise they are - // client coords. -#ifndef Q_WS_WINCE - if (message < WM_NCMOUSEMOVE || message > WM_NCMBUTTONDBLCLK) -#endif - ClientToScreen(msg.hwnd, &msg.pt); - - /* - // sometimes the autograb is not released, so the clickevent is sent - // to the wrong window. We ignore this for now, because it doesn't - // cause any problems. - if (msg.message == WM_LBUTTONDOWN || msg.message == WM_RBUTTONDOWN || msg.message == WM_MBUTTONDOWN) { - HWND handle = WindowFromPoint(msg.pt); - if (msg.hwnd != handle) { - msg.hwnd = handle; - hwnd = handle; - } - } - */ - -#if defined(QT_NON_COMMERCIAL) - QT_NC_WNDPROC -#endif - - // send through app filter - if (qApp->filterEvent(&msg, &res)) - return res; - - // close any opened ime candidate window (enabled only on a popup widget) - if (imeParentWnd && QApplication::activePopupWidget() - && (message == WM_MBUTTONDOWN || message == WM_XBUTTONDOWN - || message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN -#ifndef Q_WS_WINCE - || message == WM_NCMBUTTONDOWN || message == WM_NCLBUTTONDOWN - || message == WM_NCRBUTTONDOWN)) { -#else - )) { -#endif - ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0); - } - - switch (message) { -#ifndef Q_WS_WINCE -#ifndef QT_NO_SESSIONMANAGER - case WM_QUERYENDSESSION: { - if (sm_smActive) // bogus message from windows - RETURN(true); - - sm_smActive = true; - sm_blockUserInput = true; // prevent user-interaction outside interaction windows - sm_cancel = false; - if (qt_session_manager_self) - qApp->commitData(*qt_session_manager_self); - if (lParam & ENDSESSION_LOGOFF) { - _flushall(); - } - RETURN(!sm_cancel); - } - case WM_ENDSESSION: { - sm_smActive = false; - sm_blockUserInput = false; - bool endsession = (bool) wParam; - - // we receive the message for each toplevel window included internal hidden ones, - // but the aboutToQuit signal should be emitted only once. - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - if (endsession && !qAppPriv->aboutToQuitEmitted) { - qAppPriv->aboutToQuitEmitted = true; - int index = QApplication::staticMetaObject.indexOfSignal("aboutToQuit()"); - qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,0); - // since the process will be killed immediately quit() has no real effect - QApplication::quit(); - } - - RETURN(0); - } -#endif - case WM_DISPLAYCHANGE: - if (QApplication::type() == QApplication::Tty) - break; - if (qt_desktopWidget) { - qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77)); - QSize sz(GetSystemMetrics(78), GetSystemMetrics(79)); - if (sz == qt_desktopWidget->size()) { - // a screen resized without changing size of the virtual desktop - QResizeEvent rs(sz, qt_desktopWidget->size()); - QApplication::sendEvent(qt_desktopWidget, &rs); - } else { - qt_desktopWidget->resize(sz); - } - } - break; -#endif - - case WM_SETTINGCHANGE: -#ifdef Q_WS_WINCE - // CE SIP hide/show - if (qt_desktopWidget && wParam == SPI_SETSIPINFO) { - QResizeEvent re(QSize(0, 0), QSize(0, 0)); // Calculated by QDesktopWidget - QApplication::sendEvent(qt_desktopWidget, &re); - break; - } -#endif - // ignore spurious XP message when user logs in again after locking - if (QApplication::type() == QApplication::Tty) - break; - if (QApplication::desktopSettingsAware() && wParam != SPI_SETWORKAREA) { - widget = (QETWidget*)QWidget::find(hwnd); - if (widget) { - if (wParam == SPI_SETNONCLIENTMETRICS) - widget->markFrameStrutDirty(); - } - } - else if (qt_desktopWidget && wParam == SPI_SETWORKAREA) { - qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77)); - QSize sz(GetSystemMetrics(78), GetSystemMetrics(79)); - if (sz == qt_desktopWidget->size()) { - // a screen resized without changing size of the virtual desktop - QResizeEvent rs(sz, qt_desktopWidget->size()); - QApplication::sendEvent(qt_desktopWidget, &rs); - } else { - qt_desktopWidget->resize(sz); - } - } - - if (wParam == SPI_SETFONTSMOOTHINGTYPE) { - qt_win_read_cleartype_settings(); - foreach (QWidget *w, QApplication::topLevelWidgets()) { - if (!w->isVisible()) - continue; - ((QETWidget *) w)->forceUpdate(); - } - } - - break; - case WM_SYSCOLORCHANGE: - if (QApplication::type() == QApplication::Tty) - break; - if (QApplication::desktopSettingsAware()) { - widget = (QETWidget*)QWidget::find(hwnd); - if (widget && !widget->parentWidget()) - qt_set_windows_color_resources(); - } - break; - - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_XBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONDBLCLK: - case WM_MBUTTONDBLCLK: - case WM_XBUTTONDBLCLK: - if (qt_win_ignoreNextMouseReleaseEvent) - qt_win_ignoreNextMouseReleaseEvent = false; - break; - - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_XBUTTONUP: - if (qt_win_ignoreNextMouseReleaseEvent) { - qt_win_ignoreNextMouseReleaseEvent = false; - if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) { - releaseAutoCapture(); - qt_button_down = 0; - } - - RETURN(0); - } - break; - - default: - break; - } - - if (!widget) - widget = (QETWidget*)QWidget::find(hwnd); - if (!widget) // don't know this widget - goto do_default; - - if (app_do_modal) { // modal event handling - int ret = 0; - if (!qt_try_modal(widget, &msg, ret)) - RETURN(ret); - } - - res = 0; - if (widget->winEvent(&msg, &res)) // send through widget filter - RETURN(res); - - if (qt_is_translatable_mouse_event(message)) { - if (QApplication::activePopupWidget() != 0) { // in popup mode - POINT curPos = msg.pt; - QWidget* w = QApplication::widgetAt(curPos.x, curPos.y); - if (w) - widget = (QETWidget*)w; - } - - if (!qt_tabletChokeMouse) { - result = widget->translateMouseEvent(msg); // mouse event -#if defined(Q_WS_WINCE) && !defined(QT_NO_CONTEXTMENU) - if (message == WM_LBUTTONDOWN && widget != QApplication::activePopupWidget()) { - QWidget* alienWidget = widget; - if ((alienWidget != QApplication::activePopupWidget()) && (alienWidget->contextMenuPolicy() != Qt::PreventContextMenu)) { - QPoint pos(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - QPoint globalPos(msg.pt.x, msg.pt.y); - // In case we are using Alien, then the widget to - // send the context menu event is a different one - if (!alienWidget->testAttribute(Qt::WA_NativeWindow) && !alienWidget->testAttribute(Qt::WA_PaintOnScreen)) { - alienWidget = QApplication::widgetAt(globalPos); - if (alienWidget) - pos = alienWidget->mapFromGlobal(globalPos); - } - if (alienWidget) { - SHRGINFO shrg; - shrg.cbSize = sizeof(shrg); - shrg.hwndClient = hwnd; - shrg.ptDown.x = GET_X_LPARAM(lParam); - shrg.ptDown.y = GET_Y_LPARAM(lParam); - shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION; - resolveAygLibs(); -#ifndef QT_NO_GESTURES - if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) { - if (QApplication::activePopupWidget()) - QApplication::activePopupWidget()->close(); - QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos); - result = qt_sendSpontaneousEvent(alienWidget, &e); - } -#endif // QT_NO_GESTURES - } - } - } -#endif - } else { - // Sometimes we only get a WM_MOUSEMOVE message - // and sometimes we get both a WM_MOUSEMOVE and - // a WM_LBUTTONDOWN/UP, this creates a spurious mouse - // press/release event, using the PeekMessage - // will help us fix this. This leaves us with a - // question: - // This effectively kills using the mouse AND the - // tablet simultaneously, well creates wacky input. - // Is this going to be a problem? (probably not) - bool next_is_button = false; - bool is_mouse_move = (message == WM_MOUSEMOVE); - if (is_mouse_move) { - MSG msg1; - if (PeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST, - WM_MOUSELAST, PM_NOREMOVE)) - next_is_button = (msg1.message == WM_LBUTTONUP - || msg1.message == WM_LBUTTONDOWN); - } - if (!is_mouse_move || (is_mouse_move && !next_is_button)) - qt_tabletChokeMouse = false; - } - } else { - switch (message) { - case WM_TOUCH: - result = QApplicationPrivate::instance()->translateTouchEvent(msg); - break; - case WM_KEYDOWN: // keyboard event - case WM_SYSKEYDOWN: - qt_keymapper_private()->updateKeyMap(msg); - // fall-through intended - case WM_KEYUP: - case WM_SYSKEYUP: -#if Q_OS_WINCE_WM - case WM_HOTKEY: - if(HIWORD(msg.lParam) == VK_TBACK) { - const bool hotKeyDown = !(LOWORD(msg.lParam) & MOD_KEYUP); - msg.lParam = 0x69 << 16; - msg.wParam = VK_BACK; - if (hotKeyDown) { - msg.message = WM_KEYDOWN; - qt_keymapper_private()->updateKeyMap(msg); - } else { - msg.message = WM_KEYUP; - } - } - // fall-through intended -#endif - case WM_IME_CHAR: - case WM_IME_KEYDOWN: - case WM_CHAR: { - MSG msg1; - bool anyMsg = PeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE); - if (anyMsg && msg1.message == WM_DEADCHAR) { - result = true; // consume event since there is a dead char next - break; - } - QWidget *g = QWidget::keyboardGrabber(); - if (g && qt_get_tablet_widget() && hwnd == qt_get_tablet_widget()->winId()) { - // if we get an event for the internal tablet widget, - // then don't send it to the keyboard grabber, but - // send it to the widget itself (we don't use it right - // now, just in case). - g = 0; - } - if (g) - widget = (QETWidget*)g; - else if (QApplication::activePopupWidget()) - widget = (QETWidget*)QApplication::activePopupWidget()->focusWidget() - ? (QETWidget*)QApplication::activePopupWidget()->focusWidget() - : (QETWidget*)QApplication::activePopupWidget(); - else if (QApplication::focusWidget()) - widget = (QETWidget*)QApplication::focusWidget(); - else if (!widget || widget->internalWinId() == GetFocus()) // We faked the message to go to exactly that widget. - widget = (QETWidget*)widget->window(); - if (widget->isEnabled()) - result = sm_blockUserInput - ? true - : qt_keymapper_private()->translateKeyEvent(widget, msg, g != 0); - break; - } - case WM_SYSCHAR: - result = true; // consume event - break; - - case WM_MOUSEWHEEL: - case WM_MOUSEHWHEEL: - result = widget->translateWheelEvent(msg); - break; - - case WM_APPCOMMAND: - { - uint cmd = GET_APPCOMMAND_LPARAM(lParam); - uint uDevice = GET_DEVICE_LPARAM(lParam); - uint dwKeys = GET_KEYSTATE_LPARAM(lParam); - - int state = translateButtonState(dwKeys, QEvent::KeyPress, 0); - - switch (uDevice) { - case FAPPCOMMAND_KEY: - { - int key = 0; - - switch(cmd) { - case APPCOMMAND_BASS_BOOST: - key = Qt::Key_BassBoost; - break; - case APPCOMMAND_BASS_DOWN: - key = Qt::Key_BassDown; - break; - case APPCOMMAND_BASS_UP: - key = Qt::Key_BassUp; - break; - case APPCOMMAND_TREBLE_DOWN: - key = Qt::Key_TrebleDown; - break; - case APPCOMMAND_TREBLE_UP: - key = Qt::Key_TrebleUp; - break; - case APPCOMMAND_HELP: - key = Qt::Key_Help; - break; - case APPCOMMAND_FIND: - key = Qt::Key_Search; - break; - default: - break; - } - if (key) { - bool res = false; - QWidget *g = QWidget::keyboardGrabber(); - if (g) - widget = (QETWidget*)g; - else if (QApplication::focusWidget()) - widget = (QETWidget*)QApplication::focusWidget(); - else - widget = (QETWidget*)widget->window(); - if (widget->isEnabled()) { - res = QKeyMapper::sendKeyEvent(widget, g != 0, QEvent::KeyPress, key, - Qt::KeyboardModifier(state), - QString(), false, 0, 0, 0, 0); - } - if (res) - return true; - } - } - break; - - default: - break; - } - - result = false; - } - break; - -#ifndef Q_WS_WINCE - case WM_NCHITTEST: - if (widget->isWindow()) { - QPoint pos = widget->mapFromGlobal(QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); - // don't show resize-cursors for fixed-size widgets - QRect fs = widget->frameStrut(); - if (!widget->isMinimized()) { - if (widget->minimumHeight() == widget->maximumHeight()) { - if (pos.y() < -(fs.top() - fs.left())) - return HTCAPTION; - if (pos.y() >= widget->height()) - return HTBORDER; - } - if (widget->minimumWidth() == widget->maximumWidth() && (pos.x() < 0 || pos.x() >= widget->width())) - return HTBORDER; - } - } - - result = false; - break; -#endif - - case WM_SYSCOMMAND: { -#ifndef Q_WS_WINCE - bool window_state_change = false; - Qt::WindowStates oldstate = Qt::WindowStates(widget->dataPtr()->window_state); - // MSDN:In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are - // used internally by the system. To obtain the correct result when testing the value of - // wParam, an application must combine the value 0xFFF0 with the wParam value by using - // the bitwise AND operator. - switch(0xfff0 & wParam) { - case SC_CONTEXTHELP: -#ifndef QT_NO_WHATSTHIS - QWhatsThis::enterWhatsThisMode(); -#endif - DefWindowProc(hwnd, WM_NCPAINT, 1, 0); - break; -#if defined(QT_NON_COMMERCIAL) - QT_NC_SYSCOMMAND -#endif - case SC_MINIMIZE: - window_state_change = true; - widget->dataPtr()->window_state |= Qt::WindowMinimized; - if (widget->isVisible()) { - QHideEvent e; - qt_sendSpontaneousEvent(widget, &e); - widget->hideChildren(true); - const QString title = widget->windowIconText(); - if (!title.isEmpty()) - widget->setWindowTitle_helper(title); - } - result = false; - break; - case SC_MAXIMIZE: - if(widget->isWindow()) - widget->topData()->normalGeometry = widget->geometry(); - case SC_RESTORE: - window_state_change = true; - if ((0xfff0 & wParam) == SC_MAXIMIZE) - widget->dataPtr()->window_state |= Qt::WindowMaximized; - else if (!widget->isMinimized()) - widget->dataPtr()->window_state &= ~Qt::WindowMaximized; - - if (widget->isMinimized()) { - widget->dataPtr()->window_state &= ~Qt::WindowMinimized; - widget->showChildren(true); - QShowEvent e; - qt_sendSpontaneousEvent(widget, &e); - const QString title = widget->windowTitle(); - if (!title.isEmpty()) - widget->setWindowTitle_helper(title); - } - result = false; - break; - default: - result = false; - break; - } - - if (window_state_change) { - QWindowStateChangeEvent e(oldstate); - qt_sendSpontaneousEvent(widget, &e); - } -#endif // #ifndef Q_OS_WINCE - - break; - } - - case WM_SETTINGCHANGE: - if ( QApplication::type() == QApplication::Tty ) - break; - - if (!msg.wParam) { -#ifdef Q_WS_WINCE - // On Windows CE, lParam parameter is a constant, not a char pointer. - if (msg.lParam == INI_INTL) { -#else - QString area = QString::fromWCharArray((wchar_t*)msg.lParam); - if (area == QLatin1String("intl")) { -#endif - QLocalePrivate::updateSystemPrivate(); - if (!widget->testAttribute(Qt::WA_SetLocale)) - widget->dptr()->setLocale_helper(QLocale(), true); - QEvent e(QEvent::LocaleChange); - QApplication::sendEvent(qApp, &e); - } - } - else if (msg.wParam == SPI_SETICONTITLELOGFONT) { - if (QApplication::desktopSettingsAware()) { - widget = (QETWidget*)QWidget::find(hwnd); - if (widget && !widget->parentWidget()) { - qt_set_windows_font_resources(); - } - } - } - else if (msg.wParam == SPI_SETNONCLIENTMETRICS) { - widget = (QETWidget*)QWidget::find(hwnd); - if (widget && !widget->parentWidget()) { - qt_set_windows_updateScrollBar(widget); - QEvent e(QEvent::LayoutRequest); - QApplication::sendEvent(widget, &e); - } - } - - break; - - case WM_PAINT: // paint event - case WM_ERASEBKGND: // erase window background - result = widget->translatePaintEvent(msg); - break; - -#ifndef Q_WS_WINCE - case WM_ENTERSIZEMOVE: - autoCaptureWnd = hwnd; - break; - case WM_EXITSIZEMOVE: - autoCaptureWnd = 0; - break; -#endif - case WM_MOVE: // move window - case WM_SIZE: // resize window - result = widget->translateConfigEvent(msg); - break; - - case WM_ACTIVATEAPP: - if (wParam == FALSE) { - QApplication::setActiveWindow(0); - // Another application was activated while our popups are open, - // then close all popups. In case some popup refuses to close, - // we give up after 1024 attempts (to avoid an infinite loop). - int maxiter = 1024; - QWidget *popup; - while ((popup=QApplication::activePopupWidget()) && maxiter--) - popup->close(); - } - break; - - case WM_ACTIVATE: - if ( QApplication::type() == QApplication::Tty ) - break; - - if (ptrWTOverlap && ptrWTEnable) { - // cooperate with other tablet applications, but when - // we get focus, I want to use the tablet... - if (qt_tablet_context && GET_WM_ACTIVATE_STATE(wParam, lParam)) { - if (ptrWTEnable(qt_tablet_context, true)) - ptrWTOverlap(qt_tablet_context, true); - } - } - if (QApplication::activePopupWidget() && LOWORD(wParam) == WA_INACTIVE && - QWidget::find((HWND)lParam) == 0) { - // Another application was activated while our popups are open, - // then close all popups. In case some popup refuses to close, - // we give up after 1024 attempts (to avoid an infinite loop). - int maxiter = 1024; - QWidget *popup; - while ((popup=QApplication::activePopupWidget()) && maxiter--) - popup->close(); - } - - if (LOWORD(wParam) != WA_INACTIVE) { - // WM_ACTIVATEAPP handles the "true" false case, as this is only when the application - // loses focus. Doing it here would result in the widget getting focus to not know - // where it got it from; it would simply get a 0 value as the old focus widget. -#ifdef Q_WS_WINCE - { -#ifdef Q_WS_WINCE_WM - // On Windows mobile we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages. - // Thus we have to unset the minimized state explicitly. We must do this for all - // top-level widgets, because we get the HWND of a random widget here. - foreach (QWidget* tlw, QApplication::topLevelWidgets()) { - if (tlw->isMinimized()) - tlw->setWindowState(tlw->windowState() & ~Qt::WindowMinimized); - } -#else - // On Windows CE we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages. - // Thus we have to unset the minimized state explicitly. - if (widget->windowState() & Qt::WindowMinimized) - widget->setWindowState(widget->windowState() & ~Qt::WindowMinimized); -#endif // Q_WS_WINCE_WM - -#else - if (!(widget->windowState() & Qt::WindowMinimized)) { -#endif - // Ignore the activate message send by WindowsXP to a minimized window -#ifdef Q_WS_WINCE_WM - if (widget->windowState() & Qt::WindowFullScreen) - qt_wince_hide_taskbar(widget->winId()); -#endif - qApp->winFocus(widget, true); - // reset any window alert flashes - alert_widget(widget, -1); - } - } - - // Windows tries to activate a modally blocked window. - // This happens when restoring an application after "Show Desktop" - if (app_do_modal && LOWORD(wParam) == WA_ACTIVE) { - QWidget *top = 0; - if (!QApplicationPrivate::tryModalHelper(widget, &top) && top && widget != top) { - if (top->isVisible()) { - top->activateWindow(); - } else { - // This is the case when native file dialogs are shown - QWidget *p = (top->parentWidget() ? top->parentWidget()->window() : 0); - if (p && p->isVisible()) - p->activateWindow(); - } - } - } - break; - -#ifndef Q_WS_WINCE - case WM_MOUSEACTIVATE: - if (widget->window()->windowType() == Qt::Tool) { - QWidget *w = widget; - if (!w->window()->focusWidget()) { - while (w && (w->focusPolicy() & Qt::ClickFocus) == 0) { - if (w->isWindow()) { - QWidget *fw = w; - while ((fw = fw->nextInFocusChain()) != w && fw->focusPolicy() == Qt::NoFocus) - ; - if (fw != w) - break; - QWidget *pw = w->parentWidget(); - while (pw) { - pw = pw->window(); - if (pw && pw->isVisible() && pw->focusWidget()) { - Q_ASSERT(pw->testAttribute(Qt::WA_WState_Created)); - SetWindowPos(pw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - break; - } - pw = pw->parentWidget(); - } - RETURN(MA_NOACTIVATE); - } - w = w->parentWidget(); - } - } - } - RETURN(MA_ACTIVATE); - break; -#endif - case WM_SHOWWINDOW: - if (lParam == SW_PARENTOPENING) { - if (widget->testAttribute(Qt::WA_WState_Hidden)) - RETURN(0); - } - if (widget->isWindow() && widget->testAttribute(Qt::WA_WState_Visible) - && !widget->testWindowState(Qt::WindowMinimized)) { - if (lParam == SW_PARENTOPENING) { - QShowEvent e; - qt_sendSpontaneousEvent(widget, &e); - widget->showChildren(true); - } else if (lParam == SW_PARENTCLOSING) { - QHideEvent e; - qt_sendSpontaneousEvent(widget, &e); - widget->hideChildren(true); - } - } - if (!wParam && autoCaptureWnd == widget->internalWinId()) - releaseAutoCapture(); - result = false; - break; - - case WM_PALETTECHANGED: // our window changed palette - if (QColormap::hPal() && (WId)wParam == widget->internalWinId()) - RETURN(0); // otherwise: FALL THROUGH! - // FALL THROUGH - case WM_QUERYNEWPALETTE: // realize own palette - if (QColormap::hPal()) { - Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created)); - HDC hdc = GetDC(widget->internalWinId()); - HPALETTE hpalOld = SelectPalette(hdc, QColormap::hPal(), FALSE); - uint n = RealizePalette(hdc); - if (n) - InvalidateRect(widget->internalWinId(), 0, TRUE); - SelectPalette(hdc, hpalOld, TRUE); - RealizePalette(hdc); - ReleaseDC(widget->internalWinId(), hdc); - RETURN(n); - } - break; - case WM_CLOSE: // close window - widget->translateCloseEvent(msg); - RETURN(0); // always handled - - case WM_DESTROY: // destroy window - if (hwnd == curWin) { - QWidget *enter = QWidget::mouseGrabber(); - if (enter == widget) - enter = 0; - QApplicationPrivate::dispatchEnterLeave(enter, widget); - curWin = enter ? enter->effectiveWinId() : 0; - qt_last_mouse_receiver = enter; - } - if (widget == popupButtonFocus) - popupButtonFocus = 0; - result = false; - break; - -#ifndef Q_WS_WINCE - case WM_WINDOWPOSCHANGING: - { - result = false; - if (widget->isWindow()) { - WINDOWPOS *winPos = (WINDOWPOS *)lParam; - if (widget->layout() && widget->layout()->hasHeightForWidth() - && !(winPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE))) { - QRect fs = widget->frameStrut(); - QRect rect = widget->geometry(); - QRect newRect = QRect(winPos->x + fs.left(), - winPos->y + fs.top(), - winPos->cx - fs.left() - fs.right(), - winPos->cy - fs.top() - fs.bottom()); - - QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size()); - - int dh = newSize.height() - newRect.height(); - int dw = newSize.width() - newRect.width(); - if (!dw && ! dh) - break; // Size OK - - if (rect.y() != newRect.y()) { - newRect.setTop(newRect.top() - dh); - } else { - newRect.setBottom(newRect.bottom() + dh); - } - - if (rect.x() != newRect.x()) { - newRect.setLeft(newRect.left() - dw); - } else { - newRect.setRight(newRect.right() + dw); - } - - winPos->x = newRect.x() - fs.left(); - winPos->y = newRect.y() - fs.top(); - winPos->cx = newRect.width() + fs.left() + fs.right(); - winPos->cy = newRect.height() + fs.top() + fs.bottom(); - - RETURN(0); - } - if (widget->windowFlags() & Qt::WindowStaysOnBottomHint) { - winPos->hwndInsertAfter = HWND_BOTTOM; - } - } - } - break; - - case WM_GETMINMAXINFO: - if (widget->xtra()) { - MINMAXINFO *mmi = (MINMAXINFO *)lParam; - QWExtra *x = widget->xtra(); - QRect fs = widget->frameStrut(); - if ( x->minw > 0 ) - mmi->ptMinTrackSize.x = x->minw + fs.right() + fs.left(); - if ( x->minh > 0 ) - mmi->ptMinTrackSize.y = x->minh + fs.top() + fs.bottom(); - qint32 maxw = (x->maxw >= x->minw) ? x->maxw : x->minw; - qint32 maxh = (x->maxh >= x->minh) ? x->maxh : x->minh; - if ( maxw < QWIDGETSIZE_MAX ) { - mmi->ptMaxTrackSize.x = maxw + fs.right() + fs.left(); - // windows with title bar have an implicit size limit of 112 pixels - if (widget->windowFlags() & Qt::WindowTitleHint) - mmi->ptMaxTrackSize.x = qMax<long>(mmi->ptMaxTrackSize.x, 112); - } - if ( maxh < QWIDGETSIZE_MAX ) - mmi->ptMaxTrackSize.y = maxh + fs.top() + fs.bottom(); - RETURN(0); - } - break; - -#ifndef QT_NO_CONTEXTMENU - case WM_CONTEXTMENU: - { - // it's not VK_APPS or Shift+F10, but a click in the NC area - if (lParam != (int)0xffffffff) { - result = false; - break; - } - - QWidget *fw = QWidget::keyboardGrabber(); - if (!fw) { - if (QApplication::activePopupWidget()) - fw = (QApplication::activePopupWidget()->focusWidget() - ? QApplication::activePopupWidget()->focusWidget() - : QApplication::activePopupWidget()); - else if (QApplication::focusWidget()) - fw = QApplication::focusWidget(); - else if (widget) - fw = widget->window(); - } - if (fw && fw->isEnabled()) { - QPoint pos = fw->inputMethodQuery(Qt::ImMicroFocus).toRect().center(); - QContextMenuEvent e(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos), - qt_win_getKeyboardModifiers()); - result = qt_sendSpontaneousEvent(fw, &e); - } - } - break; -#endif -#endif - - case WM_IME_STARTCOMPOSITION: - case WM_IME_ENDCOMPOSITION: - case WM_IME_COMPOSITION: { - QWidget *fw = QApplication::focusWidget(); - QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0; - if (fw && im) { - if(message == WM_IME_STARTCOMPOSITION) - result = im->startComposition(); - else if (message == WM_IME_ENDCOMPOSITION) - result = im->endComposition(); - else if (message == WM_IME_COMPOSITION) - result = im->composition(lParam); - } - break; - } - case WM_IME_REQUEST: { - QWidget *fw = QApplication::focusWidget(); - QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0; - if (fw && im) { - if(wParam == IMR_RECONVERTSTRING) { - int ret = im->reconvertString((RECONVERTSTRING *)lParam); - if (ret == -1) { - result = false; - } else { - return ret; - } - } else if (wParam == IMR_CONFIRMRECONVERTSTRING) { - RETURN(TRUE); - } else { - // in all other cases, call DefWindowProc() - result = false; - } - } - break; - } -#ifndef Q_WS_WINCE - case WM_CHANGECBCHAIN: - case WM_DRAWCLIPBOARD: -#endif - case WM_RENDERFORMAT: - case WM_RENDERALLFORMATS: -#ifndef QT_NO_CLIPBOARD - case WM_DESTROYCLIPBOARD: - if (qt_clipboard) { - QClipboardEvent e(reinterpret_cast<QEventPrivate *>(&msg)); - qt_sendSpontaneousEvent(qt_clipboard, &e); - RETURN(0); - } - result = false; - break; -#endif //QT_NO_CLIPBOARD -#ifndef QT_NO_ACCESSIBILITY - case WM_GETOBJECT: - { - // Ignoring all requests while starting up - if (QApplication::startingUp() || QApplication::closingDown() || lParam != (LPARAM)OBJID_CLIENT) { - result = false; - break; - } - - typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN); - static PtrLresultFromObject ptrLresultFromObject = 0; - static bool oleaccChecked = false; - - if (!oleaccChecked) { - oleaccChecked = true; -#if !defined(Q_OS_WINCE) - ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject"); -#endif - } - if (ptrLresultFromObject) { - QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget); - if (!acc) { - result = false; - break; - } - - // and get an instance of the IAccessibile implementation - IAccessible *iface = qt_createWindowsAccessible(acc); - res = ptrLresultFromObject(IID_IAccessible, wParam, iface); // ref == 2 - iface->Release(); // the client will release the object again, and then it will destroy itself - - if (res > 0) - RETURN(res); - } - } - result = false; - break; - case WM_GETTEXT: - if (!widget->isWindow()) { - int ret = 0; - QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget); - if (acc) { - QString text = acc->text(QAccessible::Name, 0); - if (text.isEmpty()) - text = widget->objectName(); - ret = qMin<int>(wParam - 1, text.size()); - text.resize(ret); - memcpy((void *)lParam, text.utf16(), (text.size() + 1) * sizeof(ushort)); - delete acc; - } - if (!ret) { - result = false; - break; - } - RETURN(ret); - } - result = false; - break; -#endif - case WT_PACKET: - if (ptrWTPacketsGet) { - if ((nPackets = ptrWTPacketsGet(qt_tablet_context, QT_TABLET_NPACKETQSIZE, &localPacketBuf))) { - result = widget->translateTabletEvent(msg, localPacketBuf, nPackets); - } - } - break; - case WT_PROXIMITY: - - #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; - - 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 - - break; -#ifdef Q_WS_WINCE_WM - case WM_SETFOCUS: { - HIMC hC; - hC = ImmGetContext(hwnd); - ImmSetOpenStatus(hC, TRUE); - ImmEscape(NULL, hC, IME_ESC_SET_MODE, (LPVOID)IM_SPELL); - result = false; - } - break; -#endif - case WM_KILLFOCUS: - if (!QWidget::find((HWND)wParam)) { // we don't get focus, so unset it now - if (!widget->hasFocus()) // work around Windows bug after minimizing/restoring - widget = (QETWidget*)QApplication::focusWidget(); - HWND focus = ::GetFocus(); - //if there is a current widget and the new widget belongs to the same toplevel window - //or if the current widget was embedded into non-qt window (i.e. we won't get WM_ACTIVATEAPP) - //then we clear the focus on the widget - //in case the new widget belongs to a different widget hierarchy, clearing the focus - //will be handled because the active window will change - const bool embedded = widget && ((QETWidget*)widget->window())->topData()->embedded; - if (widget && (embedded || ::IsChild(widget->window()->internalWinId(), focus))) { - widget->clearFocus(); - result = true; - } else { - result = false; - } - } else { - result = false; - } - break; - case WM_THEMECHANGED: - if ((widget->windowType() == Qt::Desktop) || !qApp || QApplication::closingDown() - || QApplication::type() == QApplication::Tty) - break; - - if (widget->testAttribute(Qt::WA_WState_Polished)) - QApplication::style()->unpolish(widget); - - if (widget->testAttribute(Qt::WA_WState_Polished)) - QApplication::style()->polish(widget); - widget->repolishStyle(*QApplication::style()); - if (widget->isVisible()) - widget->update(); - break; - -#ifndef Q_WS_WINCE - case WM_INPUTLANGCHANGE: { - wchar_t info[7]; - if (!GetLocaleInfo(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) { - inputcharset = CP_ACP; - } else { - inputcharset = QString::fromWCharArray(info).toInt(); - } - QKeyMapper::changeKeyboard(); - break; - } -#else - case WM_COMMAND: { - bool OkCommand = (LOWORD(wParam) == 0x1); - bool CancelCommand = (LOWORD(wParam) == 0x2); - if (OkCommand) - QApplication::postEvent(widget, new QEvent(QEvent::OkRequest)); - if (CancelCommand) - widget->showMinimized(); - else -#ifndef QT_NO_MENUBAR - QMenuBar::wceCommands(LOWORD(wParam)); -#endif - result = true; - } - break; - case WM_HELP: - QApplication::postEvent(widget, new QEvent(QEvent::HelpRequest)); - result = true; - break; -#endif - - case WM_MOUSELEAVE: - // We receive a mouse leave for curWin, meaning - // the mouse was moved outside our widgets - if (widget->internalWinId() == curWin) { - bool dispatch = !widget->underMouse(); - // hasMouse is updated when dispatching enter/leave, - // so test if it is actually up-to-date - if (!dispatch) { - QRect geom = widget->geometry(); - if (widget->parentWidget() && !widget->isWindow()) { - QPoint gp = widget->parentWidget()->mapToGlobal(widget->pos()); - geom.setX(gp.x()); - geom.setY(gp.y()); - } - QPoint cpos = QCursor::pos(); - dispatch = !geom.contains(cpos); - if ( !dispatch && !QWidget::mouseGrabber()) { - QWidget *hittest = QApplication::widgetAt(cpos); - dispatch = !hittest || hittest->internalWinId() != curWin; - } - if (!dispatch) { - HRGN hrgn = qt_tryCreateRegion(QRegion::Rectangle, 0,0,0,0); - if (GetWindowRgn(curWin, hrgn) != ERROR) { - QPoint lcpos = widget->mapFromGlobal(cpos); - dispatch = !PtInRegion(hrgn, lcpos.x(), lcpos.y()); - } - DeleteObject(hrgn); - } - } - if (dispatch) { - if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId()) - QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver); - else - QApplicationPrivate::dispatchEnterLeave(0, QWidget::find((WId)curWin)); - curWin = 0; - qt_last_mouse_receiver = 0; - } - } - break; - - case WM_CANCELMODE: - { - // this goes through QMenuBar's event filter - QEvent e(QEvent::ActivationChange); - QApplication::sendEvent(qApp, &e); - } - break; - - case WM_IME_NOTIFY: - // special handling for ime, only for widgets in a popup - if (wParam == IMN_OPENCANDIDATE) { - imeParentWnd = hwnd; - if (QApplication::activePopupWidget()) { - // temporarily disable the mouse grab to allow mouse input in - // the ime candidate window. The actual handle is untouched - if (autoCaptureWnd) - ReleaseCapture(); - } - } else if (wParam == IMN_CLOSECANDIDATE) { - imeParentWnd = 0; - if (QApplication::activePopupWidget()) { - // undo the action above, when candidate window is closed - if (autoCaptureWnd) - SetCapture(autoCaptureWnd); - } - } - result = false; - break; -#ifndef QT_NO_GESTURES -#if !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES) - case WM_GESTURE: { - GESTUREINFO gi; - memset(&gi, 0, sizeof(GESTUREINFO)); - gi.cbSize = sizeof(GESTUREINFO); - - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - BOOL bResult = false; - if (qAppPriv->GetGestureInfo) - bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); - if (bResult) { - if (gi.dwID == GID_BEGIN) { - // find the alien widget for the gesture position. - // This might not be accurate as the position is the center - // point of two fingers for multi-finger gestures. - QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y); - QWidget *w = widget->childAt(widget->mapFromGlobal(pt)); - qAppPriv->gestureWidget = w ? w : widget; - } - if (qAppPriv->gestureWidget) - static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi); - if (qAppPriv->CloseGestureInfoHandle) - qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam); - if (gi.dwID == GID_END) - qAppPriv->gestureWidget = 0; - } else { - DWORD dwErr = GetLastError(); - if (dwErr > 0) - qWarning() << "translateGestureEvent: error = " << dwErr; - } - result = true; - break; - } -#endif // !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES) -#endif // QT_NO_GESTURES -#ifndef QT_NO_CURSOR - case WM_SETCURSOR: { - QCursor *ovr = QApplication::overrideCursor(); - if (ovr) { - SetCursor(ovr->handle()); - RETURN(TRUE); - } - result = false; - break; - } -#endif - default: - result = false; // event was not processed - break; - } - } - - if (evt_type != QEvent::None) { // simple event - QEvent e(evt_type); - result = qt_sendSpontaneousEvent(widget, &e); - } - - if (result) - RETURN(false); - -do_default: - RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam)) -} - - -/***************************************************************************** - Modal widgets; We have implemented our own modal widget mechanism - to get total control. - A modal widget without a parent becomes application-modal. - A modal widget with a parent becomes modal to its parent and grandparents.. - - QApplicationPrivate::enterModal() - Enters modal state - Arguments: - QWidget *widget A modal widget - - QApplicationPrivate::leaveModal() - Leaves modal state for a widget - Arguments: - QWidget *widget A modal widget - *****************************************************************************/ - -bool QApplicationPrivate::modalState() -{ - return app_do_modal; -} - -void QApplicationPrivate::enterModal_sys(QWidget *widget) -{ - if (!qt_modal_stack) - qt_modal_stack = new QWidgetList; - - releaseAutoCapture(); - ClipCursor(0); - QWidget *leave = qt_last_mouse_receiver; - if (!leave) - leave = QWidget::find((WId)curWin); - QApplicationPrivate::dispatchEnterLeave(0, leave); - qt_modal_stack->insert(0, widget); - app_do_modal = true; - curWin = 0; - qt_last_mouse_receiver = 0; - qt_win_ignoreNextMouseReleaseEvent = false; -} - -void QApplicationPrivate::leaveModal_sys(QWidget *widget) -{ - if (qt_modal_stack && qt_modal_stack->removeAll(widget)) { - if (qt_modal_stack->isEmpty()) { - delete qt_modal_stack; - qt_modal_stack = 0; - QPoint p(QCursor::pos()); - app_do_modal = false; // necessary, we may get recursively into qt_try_modal below - QWidget* w = QApplication::widgetAt(p.x(), p.y()); - QWidget *leave = qt_last_mouse_receiver; - if (!leave) - leave = QWidget::find((WId)curWin); - if (QWidget *grabber = QWidget::mouseGrabber()) { - w = grabber; - if (leave == w) - leave = 0; - } - QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event - curWin = w ? w->effectiveWinId() : 0; - qt_last_mouse_receiver = w; - } - qt_win_ignoreNextMouseReleaseEvent = true; - } - app_do_modal = qt_modal_stack != 0; -} - -bool qt_try_modal(QWidget *widget, MSG *msg, int& ret) -{ -#if defined(Q_OS_WINCE) - Q_UNUSED(ret); -#endif - QWidget * top = 0; - - if (QApplicationPrivate::tryModalHelper(widget, &top)) - return true; - - int type = msg->message; - - bool block_event = false; -#ifndef Q_WS_WINCE - if (type != WM_NCHITTEST) { -#endif - if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) || - type == WM_MOUSEWHEEL || type == WM_MOUSEHWHEEL || - type == WM_MOUSELEAVE || - (type >= WM_KEYFIRST && type <= WM_KEYLAST) -#ifndef Q_WS_WINCE - || type == WM_NCMOUSEMOVE -#endif - ) { - if (type == WM_MOUSEMOVE -#ifndef Q_WS_WINCE - || type == WM_NCMOUSEMOVE -#endif - ) { -#ifndef QT_NO_CURSOR - QCursor *c = qt_grab_cursor(); - if (!c) - c = QApplication::overrideCursor(); - if (c) // application cursor defined - SetCursor(c->handle()); - else - SetCursor(QCursor(Qt::ArrowCursor).handle()); -#endif // QT_NO_CURSOR - } - block_event = true; - } else if (type == WM_CLOSE) { - block_event = true; - } -#ifndef Q_WS_WINCE - else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){ - if (!top->isActiveWindow()) { - top->activateWindow(); - } else { - QApplication::beep(); - } - block_event = true; - ret = MA_NOACTIVATEANDEAT; - } else if (type == WM_SYSCOMMAND) { - if (!(msg->wParam == SC_RESTORE && widget->isMinimized())) - block_event = true; - } - } -#endif - - return !block_event; -} - - -/***************************************************************************** - Popup widget mechanism - - openPopup() - Adds a widget to the list of popup widgets - Arguments: - QWidget *widget The popup widget to be added - - closePopup() - Removes a widget from the list of popup widgets - Arguments: - QWidget *widget The popup widget to be removed - *****************************************************************************/ - -void QApplicationPrivate::openPopup(QWidget *popup) -{ - if (!QApplicationPrivate::popupWidgets) - QApplicationPrivate::popupWidgets = new QWidgetList; - QApplicationPrivate::popupWidgets->append(popup); - if (!popup->isEnabled()) - return; - - // close any opened 'ime candidate window' - if (imeParentWnd) - ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0); - - if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()) { - Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); - setAutoCapture(popup->internalWinId()); // grab mouse/keyboard - } - // Popups are not focus-handled by the window system (the first - // popup grabbed the keyboard), so we have to do that manually: A - // new popup gets the focus - if (popup->focusWidget()) { - popup->focusWidget()->setFocus(Qt::PopupFocusReason); - } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup - if (QWidget *fw = QApplication::focusWidget()) { - QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason); - QApplication::sendEvent(fw, &e); - } - } -} - -void QApplicationPrivate::closePopup(QWidget *popup) -{ - if (!QApplicationPrivate::popupWidgets) - return; - QApplicationPrivate::popupWidgets->removeAll(popup); - POINT curPos; - GetCursorPos(&curPos); - - // close any opened 'ime candidate window' - if (imeParentWnd) - ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0); - - if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup - delete QApplicationPrivate::popupWidgets; - QApplicationPrivate::popupWidgets = 0; - replayPopupMouseEvent = (!popup->geometry().contains(QPoint(curPos.x, curPos.y)) - && !popup->testAttribute(Qt::WA_NoMouseReplay)); - if (!popup->isEnabled()) - return; - if (!qt_nograb()) // grabbing not disabled - releaseAutoCapture(); - QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget() - : QApplication::focusWidget(); - if (fw) { - if (fw != QApplication::focusWidget()) { - fw->setFocus(Qt::PopupFocusReason); - } else { - QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason); - QApplication::sendEvent(fw, &e); - } - } - } else { - // Popups are not focus-handled by the window system (the - // first popup grabbed the keyboard), so we have to do that - // manually: A popup was closed, so the previous popup gets - // the focus. - QWidget* aw = QApplicationPrivate::popupWidgets->last(); - if (QApplicationPrivate::popupWidgets->count() == 1) { - Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created)); - setAutoCapture(aw->internalWinId()); - } - if (QWidget *fw = aw->focusWidget()) - fw->setFocus(Qt::PopupFocusReason); - } -} - - - - -/***************************************************************************** - Event translation; translates Windows events to Qt events - *****************************************************************************/ - -// -// Auto-capturing for mouse press and mouse release -// - -static void setAutoCapture(HWND h) -{ - if (autoCaptureWnd) - releaseAutoCapture(); - autoCaptureWnd = h; - SetCapture(h); -} - -static void releaseAutoCapture() -{ - if (autoCaptureWnd) { - ReleaseCapture(); - autoCaptureWnd = 0; - } -} - - -// -// Mouse event translation -// -// Non-client mouse messages are not translated -// - -static const ushort mouseTbl[] = { - WM_MOUSEMOVE, QEvent::MouseMove, 0, - WM_LBUTTONDOWN, QEvent::MouseButtonPress, Qt::LeftButton, - WM_LBUTTONUP, QEvent::MouseButtonRelease, Qt::LeftButton, - WM_LBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::LeftButton, - WM_RBUTTONDOWN, QEvent::MouseButtonPress, Qt::RightButton, - WM_RBUTTONUP, QEvent::MouseButtonRelease, Qt::RightButton, - WM_RBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::RightButton, - WM_MBUTTONDOWN, QEvent::MouseButtonPress, Qt::MidButton, - WM_MBUTTONUP, QEvent::MouseButtonRelease, Qt::MidButton, - WM_MBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::MidButton, - // use XButton1 for now, the real X button is decided later - WM_XBUTTONDOWN, QEvent::MouseButtonPress, Qt::XButton1, - WM_XBUTTONUP, QEvent::MouseButtonRelease, Qt::XButton1, - WM_XBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::XButton1, - -#ifndef Q_WS_WINCE - WM_NCMOUSEMOVE, QEvent::NonClientAreaMouseMove, 0, - WM_NCLBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton, - WM_NCLBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton, - WM_NCLBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton, - WM_NCRBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::RightButton, - WM_NCRBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton, - WM_NCRBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton, - WM_NCMBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::MidButton, - WM_NCMBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton, - WM_NCMBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton, -#endif - - 0, 0, 0 -}; - -static int translateButtonState(int s, int type, int button) -{ - Q_UNUSED(type); - Q_UNUSED(button); - int bst = 0; - if (s & MK_LBUTTON) - bst |= Qt::LeftButton; - if (s & MK_MBUTTON) - bst |= Qt::MidButton; - if (s & MK_RBUTTON) - bst |= Qt::RightButton; - if (s & MK_SHIFT) - bst |= Qt::ShiftModifier; - if (s & MK_CONTROL) - bst |= Qt::ControlModifier; - - if (s & MK_XBUTTON1) - bst |= Qt::XButton1; - if (s & MK_XBUTTON2) - bst |= Qt::XButton2; - - if (GetKeyState(VK_MENU) < 0) - bst |= Qt::AltModifier; - - if ((GetKeyState(VK_LWIN) < 0) || - (GetKeyState(VK_RWIN) < 0)) - bst |= Qt::MetaModifier; - - return bst; -} - -void qt_win_eatMouseMove() -{ - // after closing a windows dialog with a double click (i.e. open a file) - // the message queue still contains a dubious WM_MOUSEMOVE message where - // the left button is reported to be down (wParam != 0). - // remove all those messages (usually 1) and post the last one with a - // reset button state - - MSG msg = {0, 0, 0, 0, 0, {0, 0} }; - while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - ; - if (msg.message == WM_MOUSEMOVE) - PostMessage(msg.hwnd, msg.message, 0, msg.lParam); -} - -// In DnD, the mouse release event never appears, so the -// mouse button state machine must be manually reset -void QApplication::winMouseButtonUp() -{ - qt_button_down = 0; - releaseAutoCapture(); -} - -void QETWidget::repolishStyle(QStyle &) -{ - QEvent e(QEvent::StyleChange); - QApplication::sendEvent(this, &e); -} - -bool QETWidget::translateMouseEvent(const MSG &msg) -{ - if (!isWindow() && testAttribute(Qt::WA_NativeWindow)) - Q_ASSERT(internalWinId()); - - static QPoint pos; - static POINT gpos={-1,-1}; - QEvent::Type type; // event parameters - int button; - int state; - int i; - - if (sm_blockUserInput) //block user interaction during session management - return true; - - // Compress mouse move events - if (msg.message == WM_MOUSEMOVE) { - MSG mouseMsg; - while (PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST, - WM_MOUSELAST, PM_NOREMOVE)) { - if (mouseMsg.message == WM_MOUSEMOVE) { -#define PEEKMESSAGE_IS_BROKEN 1 -#ifdef PEEKMESSAGE_IS_BROKEN - // Since the Windows PeekMessage() function doesn't - // correctly return the wParam for WM_MOUSEMOVE events - // if there is a key release event in the queue - // _before_ the mouse event, we have to also consider - // key release events (kls 2003-05-13): - MSG keyMsg; - bool done = false; - while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST, - PM_NOREMOVE)) { - if (keyMsg.time < mouseMsg.time) { - if ((keyMsg.lParam & 0xC0000000) == 0x40000000) { - PeekMessage(&keyMsg, 0, keyMsg.message, - keyMsg.message, PM_REMOVE); - } else { - done = true; - break; - } - } else { - break; // no key event before the WM_MOUSEMOVE event - } - } - if (done) - break; -#else - // Actually the following 'if' should work instead of - // the above key event checking, but apparently - // PeekMessage() is broken :-( - if (mouseMsg.wParam != msg.wParam) - break; // leave the message in the queue because - // the key state has changed -#endif - MSG *msgPtr = (MSG *)(&msg); - // Update the passed in MSG structure with the - // most recent one. - msgPtr->lParam = mouseMsg.lParam; - msgPtr->wParam = mouseMsg.wParam; - // Extract the x,y coordinates from the lParam as we do in the WndProc - msgPtr->pt.x = GET_X_LPARAM(mouseMsg.lParam); - msgPtr->pt.y = GET_Y_LPARAM(mouseMsg.lParam); - ClientToScreen(msg.hwnd, &(msgPtr->pt)); - // Remove the mouse move message - PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE, - WM_MOUSEMOVE, PM_REMOVE); - } else { - break; // there was no more WM_MOUSEMOVE event - } - } - } - - for (i=0; (UINT)mouseTbl[i] != msg.message && mouseTbl[i]; i += 3) - ; - if (!mouseTbl[i]) - return false; - type = (QEvent::Type)mouseTbl[++i]; // event type - button = mouseTbl[++i]; // which button - if (button == Qt::XButton1) { - switch(GET_XBUTTON_WPARAM(msg.wParam)) { - case XBUTTON1: - button = Qt::XButton1; - break; - case XBUTTON2: - button = Qt::XButton2; - break; - } - } -#ifndef Q_OS_WINCE - static bool trackMouseEventLookup = false; - typedef BOOL (WINAPI *PtrTrackMouseEvent)(LPTRACKMOUSEEVENT); - static PtrTrackMouseEvent ptrTrackMouseEvent = 0; -#endif - state = translateButtonState(msg.wParam, type, button); // button state - const QPoint widgetPos = mapFromGlobal(QPoint(msg.pt.x, msg.pt.y)); - QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); - if (alienWidget && alienWidget->internalWinId()) - alienWidget = 0; - - if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove - || type == QEvent::TabletMove) { - - if (!(state & Qt::MouseButtonMask)) - qt_button_down = 0; -#ifndef QT_NO_CURSOR - QCursor *c = qt_grab_cursor(); - if (!c) - c = QApplication::overrideCursor(); - if (c) // application cursor defined - SetCursor(c->handle()); - else if (type != QEvent::NonClientAreaMouseMove && !qt_button_down) { - // use widget cursor if widget is enabled - QWidget *w = alienWidget ? alienWidget : this; - while (!w->isWindow() && !w->isEnabled()) - w = w->parentWidget(); - SetCursor(w->cursor().handle()); - } -#endif // QT_NO_CURSOR - - HWND id = effectiveWinId(); - QWidget *mouseGrabber = QWidget::mouseGrabber(); - QWidget *activePopupWidget = QApplication::activePopupWidget(); - if (mouseGrabber) { - if (!activePopupWidget || (activePopupWidget == this && !rect().contains(widgetPos))) - id = mouseGrabber->effectiveWinId(); - } else if (type == QEvent::NonClientAreaMouseMove) { - id = 0; - } - - if (curWin != id) { // new current window - if (id == 0) { - QWidget *leave = qt_last_mouse_receiver; - if (!leave) - leave = QWidget::find(curWin); - QApplicationPrivate::dispatchEnterLeave(0, leave); - qt_last_mouse_receiver = 0; - curWin = 0; - } else { - QWidget *leave = 0; - if (curWin && qt_last_mouse_receiver) - leave = qt_last_mouse_receiver; - else - leave = QWidget::find(curWin); - QWidget *enter = alienWidget ? alienWidget : this; - if (mouseGrabber && activePopupWidget) { - if (leave != mouseGrabber) - enter = mouseGrabber; - else - enter = activePopupWidget == this ? this : mouseGrabber; - } - QApplicationPrivate::dispatchEnterLeave(enter, leave); - qt_last_mouse_receiver = enter; - curWin = enter ? enter->effectiveWinId() : 0; - } -#ifndef Q_OS_WINCE - - if (curWin != 0) { - if (!trackMouseEventLookup) { - trackMouseEventLookup = true; - ptrTrackMouseEvent = (PtrTrackMouseEvent)QSystemLibrary::resolve(QLatin1String("comctl32"), "_TrackMouseEvent"); - } - if (ptrTrackMouseEvent && !qApp->d_func()->inPopupMode()) { - // We always have to set the tracking, since - // Windows detects more leaves than we do.. - TRACKMOUSEEVENT tme; - tme.cbSize = sizeof(TRACKMOUSEEVENT); - tme.dwFlags = 0x00000002; // TME_LEAVE - tme.hwndTrack = curWin; // Track on window receiving msgs - tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT - ptrTrackMouseEvent(&tme); - } - } -#endif // Q_OS_WINCE - } - - POINT curPos = msg.pt; - if (curPos.x == gpos.x && curPos.y == gpos.y) - return true; // same global position - gpos = curPos; - - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - ScreenToClient(internalWinId(), &curPos); - - pos.rx() = curPos.x; - pos.ry() = curPos.y; - pos = d_func()->mapFromWS(pos); - } else { - gpos = msg.pt; - pos = mapFromGlobal(QPoint(gpos.x, gpos.y)); - - // mouse button pressed - if (!qt_button_down && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick)) { - QWidget *tlw = window(); - if (QWidget *child = tlw->childAt(mapTo(tlw, pos))) - qt_button_down = child; - else - qt_button_down = this; - } - } - - bool res = false; - - bool nonClientAreaEvent = type >= QEvent::NonClientAreaMouseMove - && type <= QEvent::NonClientAreaMouseButtonDblClick; - - if (qApp->d_func()->inPopupMode()) { // in popup mode - - if (nonClientAreaEvent) - return false; - - replayPopupMouseEvent = false; - QWidget* activePopupWidget = QApplication::activePopupWidget(); - QWidget *target = activePopupWidget; - const QPoint globalPos(gpos.x, gpos.y); - - if (target != this) { - if ((windowType() == Qt::Popup) && rect().contains(pos) && 0) - target = this; - else // send to last popup - pos = target->mapFromGlobal(globalPos); - } - QWidget *popupChild = target->childAt(pos); - bool releaseAfter = false; - switch (type) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonDblClick: - popupButtonFocus = popupChild; - break; - case QEvent::MouseButtonRelease: - case QEvent::TabletRelease: - - releaseAfter = true; - break; - default: - break; // nothing for mouse move - } - - if (target->isEnabled()) { - if (popupButtonFocus) { - target = popupButtonFocus; - } else if (popupChild) { - target = popupChild; - } - - pos = target->mapFromGlobal(globalPos); - QMouseEvent e(type, pos, globalPos, - Qt::MouseButton(button), - Qt::MouseButtons(state & Qt::MouseButtonMask), - Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask)); - res = QApplicationPrivate::sendMouseEvent(target, &e, alienWidget, this, &qt_button_down, - qt_last_mouse_receiver); - res = res && e.isAccepted(); - } else { - // close disabled popups when a mouse button is pressed or released - switch (type) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonDblClick: - case QEvent::MouseButtonRelease: - target->close(); - break; - default: - break; - } - } - - if (releaseAfter) { - popupButtonFocus = 0; - qt_button_down = 0; - } - -#ifndef Q_OS_WINCE - if (type == QEvent::MouseButtonPress - && QApplication::activePopupWidget() != activePopupWidget - && ptrTrackMouseEvent - && curWin) { - // Since curWin is already the window we clicked on, - // we have to setup the mouse tracking here. - TRACKMOUSEEVENT tme; - tme.cbSize = sizeof(TRACKMOUSEEVENT); - tme.dwFlags = 0x00000002; // TME_LEAVE - tme.hwndTrack = curWin; // Track on window receiving msgs - tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT - ptrTrackMouseEvent(&tme); - } -#endif - if (type == QEvent::MouseButtonPress - && QApplication::activePopupWidget() != activePopupWidget - && replayPopupMouseEvent) { - // the popup disappeared. Replay the event - QWidget* w = QApplication::widgetAt(gpos.x, gpos.y); - if (w && !QApplicationPrivate::isBlockedByModal(w)) { - Q_ASSERT(w->testAttribute(Qt::WA_WState_Created)); - HWND hwndTarget = w->effectiveWinId(); - if (QWidget::mouseGrabber() == 0) - setAutoCapture(hwndTarget); - if (!w->isActiveWindow()) - w->activateWindow(); - POINT widgetpt = gpos; - ScreenToClient(hwndTarget, &widgetpt); - LPARAM lParam = MAKELPARAM(widgetpt.x, widgetpt.y); - PostMessage(hwndTarget, msg.message, msg.wParam, lParam); - } - } else if (type == QEvent::MouseButtonRelease && button == Qt::RightButton - && QApplication::activePopupWidget() == activePopupWidget) { - // popup still alive and received right-button-release -#if !defined(QT_NO_CONTEXTMENU) - QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos, - qt_win_getKeyboardModifiers()); - bool res2 = QApplication::sendSpontaneousEvent( target, &e2 ); - if (!res) // RMB not accepted - res = res2 && e2.isAccepted(); -#endif - } - } else { // not popup mode - int bs = state & Qt::MouseButtonMask; - if ((type == QEvent::MouseButtonPress || - type == QEvent::MouseButtonDblClick) && bs == button) { - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - if (QWidget::mouseGrabber() == 0) - setAutoCapture(internalWinId()); - } else if (type == QEvent::MouseButtonRelease && bs == 0) { - if (QWidget::mouseGrabber() == 0) - releaseAutoCapture(); - } - - const QPoint globalPos(gpos.x,gpos.y); - QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type, - Qt::MouseButtons(bs), - qt_button_down, alienWidget); - if (!widget) - return false; // don't send event - - QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), - Qt::MouseButtons(state & Qt::MouseButtonMask), - Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask)); - - res = QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down, - qt_last_mouse_receiver); - - // non client area events are only informational, you cannot "handle" them - res = res && e.isAccepted() && !nonClientAreaEvent; -#if !defined(QT_NO_CONTEXTMENU) - if (type == QEvent::MouseButtonRelease && button == Qt::RightButton) { - QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos, - qt_win_getKeyboardModifiers()); - bool res2 = QApplication::sendSpontaneousEvent(widget, &e2); - if (!res) - res = res2 && e2.isAccepted(); - } -#endif - - if (type != QEvent::MouseMove) - pos.rx() = pos.ry() = -9999; // init for move compression - } - return res; -} - -bool QETWidget::translateWheelEvent(const MSG &msg) -{ - int state = 0; - - if (sm_blockUserInput) // block user interaction during session management - return true; - - state = translateButtonState(GET_KEYSTATE_WPARAM(msg.wParam), 0, 0); - - int delta; - if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL) - delta = (short) HIWORD (msg.wParam); - else - delta = (int) msg.wParam; - - Qt::Orientation orient = (msg.message == WM_MOUSEHWHEEL || state&Qt::AltModifier -#if 0 - // disabled for now - Trenton's one-wheel mouse makes trouble... - // "delta" for usual wheels is +-120. +-240 seems to indicate - // the second wheel see more recent MSDN for WM_MOUSEWHEEL - - ( // <- parantheses added to make update happy, remove if the - // #if 0 is removed - || delta == 240 || delta == -240)?Qt::Horizontal:Vertical; - if (delta == 240 || delta == -240) - delta /= 2; -#endif - ) ? Qt::Horizontal : Qt::Vertical; - - // according to the MSDN documentation on WM_MOUSEHWHEEL: - // a positive value indicates that the wheel was rotated to the right; - // a negative value indicates that the wheel was rotated to the left. - // Qt defines this value as the exact opposite, so we have to flip the value! - if (msg.message == WM_MOUSEHWHEEL) - delta = -delta; - - QPoint globalPos; - - globalPos.rx() = (short)LOWORD (msg.lParam); - globalPos.ry() = (short)HIWORD (msg.lParam); - - - // if there is a widget under the mouse and it is not shadowed - // by modality, we send the event to it first - int ret = 0; - QWidget* w = QApplication::widgetAt(globalPos); - if (!w || !qt_try_modal(w, (MSG*)&msg, ret)) { - //synaptics touchpad shows its own widget at this position - //so widgetAt() will fail with that HWND, try child of this widget - w = this->childAt(this->mapFromGlobal(globalPos)); - if (!w) - w = this; - } - - // send the event to the widget or its ancestors - { - QWidget* popup = QApplication::activePopupWidget(); - if (popup && w->window() != popup) - popup->close(); -#ifndef QT_NO_WHEELEVENT - QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta, - Qt::MouseButtons(state & Qt::MouseButtonMask), - Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient); - - if (QApplication::sendSpontaneousEvent(w, &e)) -#else - Q_UNUSED(orient); -#endif //QT_NO_WHEELEVENT - return true; - } - - // send the event to the widget that has the focus or its ancestors, if different - if (w != QApplication::focusWidget() && (w = QApplication::focusWidget())) { - QWidget* popup = QApplication::activePopupWidget(); - if (popup && w->window() != popup) - popup->close(); -#ifndef QT_NO_WHEELEVENT - QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta, - Qt::MouseButtons(state & Qt::MouseButtonMask), - Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient); - if (QApplication::sendSpontaneousEvent(w, &e)) -#endif //QT_NO_WHEELEVENT - return true; - } - return false; -} - - -// -// Windows Wintab to QTabletEvent translation -// - -// the following is adapted from the wintab syspress example (public domain) -/* -------------------------------------------------------------------------- */ -// 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. */ - 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; - case 0x0902: - tdd.currentDevice = QTabletEvent::Airbrush; - break; - case 0x0004: - tdd.currentDevice = QTabletEvent::FourDMouse; - break; - case 0x0006: - tdd.currentDevice = QTabletEvent::Puck; - break; - case 0x0804: - tdd.currentDevice = QTabletEvent::RotationStylus; - break; - default: - tdd.currentDevice = QTabletEvent::NoDevice; - } - } - tCursorInfo()->insert(uniqueId, tdd); -} -#endif // QT_NO_TABLETEVENT - -// Update the "dynamic" information 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) -{ - Q_UNUSED(msg); - POINT ptNew; - static DWORD btnNew, btnOld, btnChange; - qreal prsNew; - ORIENTATION ort; - static bool button_pressed = false; - int i, - tiltX, - tiltY; - bool sendEvent = false; - QEvent::Type t; - int z = 0; - qreal rotation = 0.0; - qreal tangentialPressure; - - // the most common event that we get... - t = QEvent::TabletMove; - for (i = 0; i < numPackets; i++) { - // get the unique ID of the device... - btnOld = btnNew; - btnNew = localPacketBuf[i].pkButtons; - btnChange = btnOld ^ btnNew; - - if (btnNew & btnChange) { - button_pressed = true; - t = QEvent::TabletPress; - } - ptNew.x = UINT(localPacketBuf[i].pkX); - ptNew.y = UINT(localPacketBuf[i].pkY); -#ifndef QT_NO_TABLETEVENT - z = (currentTabletPointer.currentDevice == QTabletEvent::FourDMouse) ? UINT(localPacketBuf[i].pkZ) : 0; -#else - Q_UNUSED(z); -#endif // QT_NO_TABLETEVENT - prsNew = 0.0; - QRect desktopArea = QApplication::desktop()->geometry(); - QPointF hiResGlobal = currentTabletPointer.scaleCoord(ptNew.x, ptNew.y, desktopArea.left(), - desktopArea.width(), desktopArea.top(), - desktopArea.height()); - - if (btnNew) { -#ifndef QT_NO_TABLETEVENT - if (currentTabletPointer.currentPointerType == QTabletEvent::Pen || currentTabletPointer.currentPointerType == QTabletEvent::Eraser) - prsNew = localPacketBuf[i].pkNormalPressure - / qreal(currentTabletPointer.maxPressure - - currentTabletPointer.minPressure); - else -#endif // QT_NO_TABLETEVENT - prsNew = 0; - } else if (button_pressed) { - // One button press, should only give one button release - t = QEvent::TabletRelease; - button_pressed = false; - } - QPoint globalPos(qRound(hiResGlobal.x()), qRound(hiResGlobal.y())); - - if (t == QEvent::TabletPress) - { - qt_button_down = QApplication::widgetAt(globalPos); - } - - // make sure the tablet event get's sent to the proper widget... - QWidget *w = 0; - - if (qt_button_down) - w = qt_button_down; // Pass it to the thing that's grabbed it. - else - w = QApplication::widgetAt(globalPos); - - if (!w) - w = this; - - if (t == QEvent::TabletRelease) - { - if (qt_win_ignoreNextMouseReleaseEvent) { - qt_win_ignoreNextMouseReleaseEvent = false; - if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) { - releaseAutoCapture(); - qt_button_down = 0; - } - } - - } - - QPoint localPos = w->mapFromGlobal(globalPos); -#ifndef QT_NO_TABLETEVENT - if (currentTabletPointer.currentDevice == QTabletEvent::Airbrush) { - tangentialPressure = localPacketBuf[i].pkTangentPressure - / qreal(currentTabletPointer.maxTanPressure - - currentTabletPointer.minTanPressure); - } else { - tangentialPressure = 0.0; - } -#else - tangentialPressure = 0.0; -#endif // QT_NO_TABLETEVENT - - if (!qt_tablet_tilt_support) { - tiltX = tiltY = 0; - rotation = 0.0; - } else { - ort = localPacketBuf[i].pkOrientation; - // convert from azimuth and altitude to x tilt and y tilt - // what follows is the optimized version. Here are the equations - // I used to get to this point (in case things change :) - // X = sin(azimuth) * cos(altitude) - // Y = cos(azimuth) * cos(altitude) - // Z = sin(altitude) - // X Tilt = arctan(X / Z) - // Y Tilt = arctan(Y / Z) - double radAzim = (ort.orAzimuth / 10) * (Q_PI / 180); - //double radAlt = abs(ort.orAltitude / 10) * (Q_PI / 180); - double tanAlt = tan((abs(ort.orAltitude / 10)) * (Q_PI / 180)); - - double degX = atan(sin(radAzim) / tanAlt); - double degY = atan(cos(radAzim) / tanAlt); - tiltX = int(degX * (180 / Q_PI)); - tiltY = int(-degY * (180 / Q_PI)); - rotation = ort.orTwist; - } -#ifndef QT_NO_TABLETEVENT - QTabletEvent e(t, localPos, globalPos, hiResGlobal, currentTabletPointer.currentDevice, - currentTabletPointer.currentPointerType, prsNew, tiltX, tiltY, - tangentialPressure, rotation, z, QApplication::keyboardModifiers(), currentTabletPointer.llId); - sendEvent = QApplication::sendSpontaneousEvent(w, &e); -#endif // QT_NO_TABLETEVENT - } - return sendEvent; -} - -extern bool qt_is_gui_used; - - -#ifndef QT_NO_TABLETEVENT - -static void initWinTabFunctions() -{ -#if defined(Q_OS_WINCE) - return; -#else - if (!qt_is_gui_used) - return; - - QSystemLibrary library(QLatin1String("wintab32")); - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); - ptrWTGet = (PtrWTGet)library.resolve("WTGetW"); - ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable"); - ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap"); - ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet"); -#endif // Q_OS_WINCE -} -#endif // QT_NO_TABLETEVENT - - -// -// Paint event translation -// -bool QETWidget::translatePaintEvent(const MSG &msg) -{ - if (!isWindow() && testAttribute(Qt::WA_NativeWindow)) - Q_ASSERT(internalWinId()); - - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - if (!GetUpdateRect(internalWinId(), 0, FALSE)) { // The update bounding rect is invalid - d_func()->hd = 0; - setAttribute(Qt::WA_PendingUpdate, false); - return false; - } - - if (msg.message == WM_ERASEBKGND) - return true; - - setAttribute(Qt::WA_PendingUpdate, false); - - if (d_func()->isGLWidget) { - if (d_func()->usesDoubleBufferedGLContext) - InvalidateRect(internalWinId(), 0, false); - } else { - const QRegion dirtyInBackingStore(qt_dirtyRegion(this)); - // Make sure the invalidated region contains the region we're about to repaint. - // BeginPaint will set the clip to the invalidated region and it is impossible - // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient - // as it may return an invalid context (especially on Windows Vista). - if (!dirtyInBackingStore.isEmpty()) - InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false); - } - PAINTSTRUCT ps; - d_func()->hd = BeginPaint(internalWinId(), &ps); - - const QRect updateRect(QPoint(ps.rcPaint.left, ps.rcPaint.top), - QPoint(ps.rcPaint.right, ps.rcPaint.bottom)); - - // Mapping region from system to qt (32 bit) coordinate system. - d_func()->syncBackingStore(updateRect.translated(data->wrect.topLeft())); - - d_func()->hd = 0; - EndPaint(internalWinId(), &ps); - - return true; -} - -// -// Window move and resize (configure) events -// - -bool QETWidget::translateConfigEvent(const MSG &msg) -{ - if (!testAttribute(Qt::WA_WState_Created)) // in QWidget::create() - return true; - if (testAttribute(Qt::WA_WState_ConfigPending)) - return true; - if (testAttribute(Qt::WA_DontShowOnScreen)) - return true; - if (!isWindow()) - return true; - setAttribute(Qt::WA_WState_ConfigPending); // set config flag - QRect cr = geometry(); - if (msg.message == WM_SIZE) { // resize event - WORD a = LOWORD(msg.lParam); - WORD b = HIWORD(msg.lParam); - QSize oldSize = size(); - QSize newSize(a, b); -#ifdef Q_WS_WINCE_WM - if (isFullScreen() && (oldSize.width() == newSize.height()) && (oldSize.height() == newSize.width())) - qt_wince_hide_taskbar(internalWinId()); -#endif - cr.setSize(newSize); - if (msg.wParam != SIZE_MINIMIZED) - data->crect = cr; - if (isWindow()) { // update title/icon text - d_func()->createTLExtra(); - // Capture SIZE_MINIMIZED without preceding WM_SYSCOMMAND - // (like Windows+M) - if (msg.wParam == SIZE_MINIMIZED && !isMinimized()) { -#ifndef Q_WS_WINCE - const QString title = windowIconText(); - if (!title.isEmpty()) - d_func()->setWindowTitle_helper(title); -#endif - data->window_state |= Qt::WindowMinimized; - if (isVisible()) { - QHideEvent e; - QApplication::sendSpontaneousEvent(this, &e); - hideChildren(true); - } - } else if (msg.wParam != SIZE_MINIMIZED) { - bool window_state_changed = false; - Qt::WindowStates oldstate = Qt::WindowStates(dataPtr()->window_state); - if (isMinimized()) { -#ifndef Q_WS_WINCE - const QString title = windowTitle(); - if (!title.isEmpty()) - d_func()->setWindowTitle_helper(title); -#endif - data->window_state &= ~Qt::WindowMinimized; - showChildren(true); - QShowEvent e; - QApplication::sendSpontaneousEvent(this, &e); - // Capture SIZE_MAXIMIZED and SIZE_RESTORED without preceding WM_SYSCOMMAND - // (Aero Snap on Win7) - } else if (msg.wParam == SIZE_MAXIMIZED && !isMaximized()) { - data->window_state |= Qt::WindowMaximized; - window_state_changed = true; - } else if (msg.wParam == SIZE_RESTORED && isMaximized()) { - data->window_state &= ~(Qt::WindowMaximized); - window_state_changed = true; - } - if (window_state_changed) { - QWindowStateChangeEvent e(oldstate); - QApplication::sendSpontaneousEvent(this, &e); - } - } - } - if (msg.wParam != SIZE_MINIMIZED && oldSize != newSize) { - if (isVisible()) { - QTLWExtra *tlwExtra = maybeTopData(); - static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt(); - const bool hasStaticContents = tlwExtra && tlwExtra->backingStore - && tlwExtra->backingStore->hasStaticContents(); - // If we have a backing store with static contents, we have to disable the top-level - // resize optimization in order to get invalidated regions for resized widgets. - // The optimization discards all invalidateBuffer() calls since we're going to - // repaint everything anyways, but that's not the case with static contents. - if (!slowResize && tlwExtra && !hasStaticContents) - tlwExtra->inTopLevelResize = true; - QResizeEvent e(newSize, oldSize); - QApplication::sendSpontaneousEvent(this, &e); - if (d_func()->paintOnScreen()) { - QRegion updateRegion(rect()); - if (testAttribute(Qt::WA_StaticContents)) - updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height()); - d_func()->syncBackingStore(updateRegion); - } else { - d_func()->syncBackingStore(); - } - if (!slowResize && tlwExtra) - tlwExtra->inTopLevelResize = false; - } else { - QResizeEvent *e = new QResizeEvent(newSize, oldSize); - QApplication::postEvent(this, e); - } - } - } else if (msg.message == WM_MOVE) { // move event - int a = (int) (short) LOWORD(msg.lParam); - int b = (int) (short) HIWORD(msg.lParam); - QPoint oldPos = geometry().topLeft(); - QPoint newCPos(a, b); - // Ignore silly Windows move event to wild pos after iconify. -#if !defined(Q_WS_WINCE) - if (!IsIconic(internalWinId()) && newCPos != oldPos) { -#endif - cr.moveTopLeft(newCPos); - data->crect = cr; - if (isVisible()) { - QMoveEvent e(newCPos, oldPos); // cpos (client position) - QApplication::sendSpontaneousEvent(this, &e); - } else { - QMoveEvent * e = new QMoveEvent(newCPos, oldPos); - QApplication::postEvent(this, e); - } -#if !defined(Q_WS_WINCE) - } -#endif - } - setAttribute(Qt::WA_WState_ConfigPending, false); // clear config flag - return true; -} - - -// -// Close window event translation. -// -// This class is a friend of QApplication because it needs to emit the -// lastWindowClosed() signal when the last top level widget is closed. -// - -bool QETWidget::translateCloseEvent(const MSG &) -{ - return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); -} - -#ifndef QT_NO_GESTURES -bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi) -{ - const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); - QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); - if (alienWidget && alienWidget->internalWinId()) - alienWidget = 0; - QWidget *widget = alienWidget ? alienWidget : this; - - QNativeGestureEvent event; - event.sequenceId = gi.dwSequenceID; - event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); - event.argument = gi.ullArguments; - - switch (gi.dwID) { - case GID_BEGIN: - event.gestureType = QNativeGestureEvent::GestureBegin; - break; - case GID_END: - event.gestureType = QNativeGestureEvent::GestureEnd; - break; - case GID_ZOOM: - event.gestureType = QNativeGestureEvent::Zoom; - break; - case GID_PAN: - event.gestureType = QNativeGestureEvent::Pan; - break; - case GID_ROTATE: - event.gestureType = QNativeGestureEvent::Rotate; - break; - case GID_TWOFINGERTAP: - case GID_ROLLOVER: - default: - break; - } - if (event.gestureType != QNativeGestureEvent::None) - qt_sendSpontaneousEvent(widget, &event); - return true; -} -#endif // QT_NO_GESTURES - -void QApplication::setCursorFlashTime(int msecs) -{ - SetCaretBlinkTime(msecs / 2); - QApplicationPrivate::cursor_flash_time = msecs; -} - - -int QApplication::cursorFlashTime() -{ - int blink = (int)GetCaretBlinkTime(); - if (!blink) - return QApplicationPrivate::cursor_flash_time; - if (blink > 0) - return 2*blink; - return 0; -} - - -void QApplication::setDoubleClickInterval(int ms) -{ -#ifndef Q_WS_WINCE - SetDoubleClickTime(ms); -#endif - QApplicationPrivate::mouse_double_click_time = ms; -} - -int QApplication::doubleClickInterval() -{ - int ms = GetDoubleClickTime(); - if (ms != 0) - return ms; - return QApplicationPrivate::mouse_double_click_time; -} - - -void QApplication::setKeyboardInputInterval(int ms) -{ - QApplicationPrivate::keyboard_input_time = ms; -} - -int QApplication::keyboardInputInterval() -{ - // FIXME: get from the system - return QApplicationPrivate::keyboard_input_time; -} - -#ifndef QT_NO_WHEELEVENT -void QApplication::setWheelScrollLines(int n) -{ -#ifdef SPI_SETWHEELSCROLLLINES - if (n < 0) - n = 0; - SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0); -#else - QApplicationPrivate::wheel_scroll_lines = n; -#endif -} - -int QApplication::wheelScrollLines() -{ -#ifdef SPI_GETWHEELSCROLLLINES - uint i = 3; - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0); - if (i > INT_MAX) - i = INT_MAX; - return i; -#else - return QApplicationPrivate::wheel_scroll_lines; -#endif -} -#endif //QT_NO_WHEELEVENT - -static bool effect_override = false; - -void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) -{ - effect_override = true; - switch (effect) { - case Qt::UI_AnimateMenu: - QApplicationPrivate::animate_menu = enable; - break; - case Qt::UI_FadeMenu: - QApplicationPrivate::fade_menu = enable; - break; - case Qt::UI_AnimateCombo: - QApplicationPrivate::animate_combo = enable; - break; - case Qt::UI_AnimateTooltip: - QApplicationPrivate::animate_tooltip = enable; - break; - case Qt::UI_FadeTooltip: - QApplicationPrivate::fade_tooltip = enable; - break; - case Qt::UI_AnimateToolBox: - QApplicationPrivate::animate_toolbox = enable; - break; - default: - QApplicationPrivate::animate_ui = enable; - break; - } -} - -bool QApplication::isEffectEnabled(Qt::UIEffect effect) -{ - if (QColormap::instance().depth() < 16) - return false; - - if (!effect_override && desktopSettingsAware()) { - // we know that they can be used when we are here - BOOL enabled = false; - UINT api; - switch (effect) { - case Qt::UI_AnimateMenu: - api = SPI_GETMENUANIMATION; - break; - case Qt::UI_FadeMenu: - api = SPI_GETMENUFADE; - break; - case Qt::UI_AnimateCombo: - api = SPI_GETCOMBOBOXANIMATION; - break; - case Qt::UI_AnimateTooltip: - api = SPI_GETTOOLTIPANIMATION; - break; - case Qt::UI_FadeTooltip: - api = SPI_GETTOOLTIPFADE; - break; - default: - api = SPI_GETUIEFFECTS; - break; - } - SystemParametersInfo(api, 0, &enabled, 0); - return enabled; - } - - switch(effect) { - case Qt::UI_AnimateMenu: - return QApplicationPrivate::animate_menu; - case Qt::UI_FadeMenu: - return QApplicationPrivate::fade_menu; - case Qt::UI_AnimateCombo: - return QApplicationPrivate::animate_combo; - case Qt::UI_AnimateTooltip: - return QApplicationPrivate::animate_tooltip; - case Qt::UI_FadeTooltip: - return QApplicationPrivate::fade_tooltip; - case Qt::UI_AnimateToolBox: - return QApplicationPrivate::animate_toolbox; - default: - return QApplicationPrivate::animate_ui; - } -} - -#ifndef QT_NO_SESSIONMANAGER - -bool QSessionManager::allowsInteraction() -{ - sm_blockUserInput = false; - return true; -} - -bool QSessionManager::allowsErrorInteraction() -{ - sm_blockUserInput = false; - return true; -} - -void QSessionManager::release() -{ - if (sm_smActive) - sm_blockUserInput = true; -} - -void QSessionManager::cancel() -{ - sm_cancel = true; -} - -#endif //QT_NO_SESSIONMANAGER - - -bool QApplicationPrivate::HasTouchSupport = false; -PtrRegisterTouchWindow QApplicationPrivate::RegisterTouchWindow = 0; -PtrGetTouchInputInfo QApplicationPrivate::GetTouchInputInfo = 0; -PtrCloseTouchInputHandle QApplicationPrivate::CloseTouchInputHandle = 0; - -void QApplicationPrivate::initializeMultitouch_sys() -{ - if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) { - static const int QT_SM_DIGITIZER = 94; - int value = GetSystemMetrics(QT_SM_DIGITIZER); - static const int QT_NID_INTEGRATED_TOUCH = 0x01; - static const int QT_NID_EXTERNAL_TOUCH = 0x02; - static const int QT_NID_MULTI_INPUT = 0x40; - QApplicationPrivate::HasTouchSupport = - value & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH | QT_NID_MULTI_INPUT); - } - - QSystemLibrary library(QLatin1String("user32")); - // MinGW (g++ 3.4.5) accepts only C casts. - RegisterTouchWindow = (PtrRegisterTouchWindow)(library.resolve("RegisterTouchWindow")); - GetTouchInputInfo = (PtrGetTouchInputInfo)(library.resolve("GetTouchInputInfo")); - CloseTouchInputHandle = (PtrCloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); - - touchInputIDToTouchPointID.clear(); -} - -void QApplicationPrivate::cleanupMultitouch_sys() -{ - touchInputIDToTouchPointID.clear(); -} - -bool QApplicationPrivate::translateTouchEvent(const MSG &msg) -{ - QWidget *widgetForHwnd = QWidget::find(msg.hwnd); - if (!widgetForHwnd) - return false; - - QRect screenGeometry = QApplication::desktop()->screenGeometry(widgetForHwnd); - - QList<QTouchEvent::TouchPoint> touchPoints; - - QVector<TOUCHINPUT> winTouchInputs(msg.wParam); - memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchInputs.count()); - Qt::TouchPointStates allStates = 0; - QApplicationPrivate::GetTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); - for (int i = 0; i < winTouchInputs.count(); ++i) { - const TOUCHINPUT &touchInput = winTouchInputs.at(i); - - int touchPointID = touchInputIDToTouchPointID.value(touchInput.dwID, -1); - if (touchPointID == -1) { - touchPointID = touchInputIDToTouchPointID.count(); - touchInputIDToTouchPointID.insert(touchInput.dwID, touchPointID); - } - - QTouchEvent::TouchPoint touchPoint(touchPointID); - - // update state - QPointF screenPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.)); - QRectF screenRect; - if (touchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA) - screenRect.setSize(QSizeF(qreal(touchInput.cxContact) / qreal(100.), - qreal(touchInput.cyContact) / qreal(100.))); - screenRect.moveCenter(screenPos); - - Qt::TouchPointStates state; - if (touchInput.dwFlags & TOUCHEVENTF_DOWN) { - state = Qt::TouchPointPressed; - } else if (touchInput.dwFlags & TOUCHEVENTF_UP) { - state = Qt::TouchPointReleased; - } else { - state = (screenPos == touchPoint.screenPos() - ? Qt::TouchPointStationary - : Qt::TouchPointMoved); - } - if (touchInput.dwFlags & TOUCHEVENTF_PRIMARY) - state |= Qt::TouchPointPrimary; - touchPoint.setState(state); - touchPoint.setScreenRect(screenRect); - touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), - screenPos.y() / screenGeometry.height())); - - allStates |= state; - - touchPoints.append(touchPoint); - } - QApplicationPrivate::CloseTouchInputHandle((HANDLE) msg.lParam); - - if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) { - // all touch points released, forget the ids we've seen, they may not be reused - touchInputIDToTouchPointID.clear(); - } - - translateRawTouchEvent(widgetForHwnd, QTouchEvent::TouchScreen, touchPoints); - return true; -} - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qclipboard_win.cpp b/src/gui/platforms/win/qclipboard_win.cpp deleted file mode 100644 index ea41165b9c..0000000000 --- a/src/gui/platforms/win/qclipboard_win.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qclipboard.h" - -#ifndef QT_NO_CLIPBOARD - -#include "qapplication.h" -#include "qapplication_p.h" -#include "qeventloop.h" -#include "qwidget.h" -#include "qevent.h" -#include "qmime.h" -#include "qt_windows.h" -#include "qdnd_p.h" -#include <private/qwidget_p.h> -#include <private/qsystemlibrary_p.h> - -QT_BEGIN_NAMESPACE - -#if defined(Q_OS_WINCE) -QT_BEGIN_INCLUDE_NAMESPACE -#include "qguifunctions_wince.h" -QT_END_INCLUDE_NAMESPACE - -HRESULT QtCeGetClipboard(IDataObject** obj); -HRESULT QtCeSetClipboard(IDataObject* obj); -void QtCeFlushClipboard(); - -#define OleGetClipboard QtCeGetClipboard -#define OleSetClipboard QtCeSetClipboard -#define OleFlushClipboard QtCeFlushClipboard - -#endif - -typedef BOOL (WINAPI *PtrIsHungAppWindow)(HWND); - -static PtrIsHungAppWindow ptrIsHungAppWindow = 0; - -class QClipboardWatcher : public QInternalMimeData { -public: - QClipboardWatcher() - : QInternalMimeData() - { - } - - bool hasFormat_sys(const QString &mimetype) const; - QStringList formats_sys() const; - QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const; -}; - - -bool QClipboardWatcher::hasFormat_sys(const QString &mime) const -{ - IDataObject * pDataObj = 0; - - if (OleGetClipboard(&pDataObj) != S_OK && !pDataObj) // Sanity - return false; - - bool has = QWindowsMime::converterToMime(mime, pDataObj) != 0; - - pDataObj->Release(); - - return has; -} - -QStringList QClipboardWatcher::formats_sys() const -{ - QStringList fmts; - IDataObject * pDataObj = 0; - - if (OleGetClipboard(&pDataObj) != S_OK && !pDataObj) // Sanity - return QStringList(); - - fmts = QWindowsMime::allMimesForFormats(pDataObj); - - pDataObj->Release(); - - return fmts; -} - -QVariant QClipboardWatcher::retrieveData_sys(const QString &mimeType, QVariant::Type type) const -{ - QVariant result; - IDataObject * pDataObj = 0; - - if (OleGetClipboard(&pDataObj) != S_OK && !pDataObj) // Sanity - return result; - - QWindowsMime *converter = QWindowsMime::converterToMime(mimeType, pDataObj); - - if (converter) - result = converter->convertToMime(mimeType, pDataObj, type); - - pDataObj->Release(); - - return result; -} - -class QClipboardData -{ -public: - QClipboardData() - : iData(0) - , nextClipboardViewer(0) - { - clipBoardViewer = new QWidget(); - clipBoardViewer->createWinId(); - clipBoardViewer->setObjectName(QLatin1String("internal clipboard owner")); - // We don't need this internal widget to appear in QApplication::topLevelWidgets() - if (QWidgetPrivate::allWidgets) - QWidgetPrivate::allWidgets->remove(clipBoardViewer); - } - - ~QClipboardData() - { - Q_ASSERT(clipBoardViewer->testAttribute(Qt::WA_WState_Created)); - ChangeClipboardChain(clipBoardViewer->internalWinId(), nextClipboardViewer); - delete clipBoardViewer; - releaseIData(); - } - - void releaseIData() - { - if (iData) { - delete iData->mimeData(); - iData->releaseQt(); - iData->Release(); - iData = 0; - } - } - - QOleDataObject * iData; - QWidget *clipBoardViewer; - HWND nextClipboardViewer; - QClipboardWatcher watcher; -}; - -static QClipboardData *ptrClipboardData = 0; - -static QClipboardData *clipboardData() -{ - if (ptrClipboardData == 0) { - ptrClipboardData = new QClipboardData; - // this needs to be done here to avoid recursion - Q_ASSERT(ptrClipboardData->clipBoardViewer->testAttribute(Qt::WA_WState_Created)); - ptrClipboardData->nextClipboardViewer = SetClipboardViewer(ptrClipboardData->clipBoardViewer->internalWinId()); - } - return ptrClipboardData; -} - -static void cleanupClipboardData() -{ - delete ptrClipboardData; - ptrClipboardData = 0; -} - -#if defined(Q_OS_WINCE) -HRESULT QtCeGetClipboard(IDataObject** obj) -{ - HWND owner = ptrClipboardData->clipBoardViewer->internalWinId(); - if (!OpenClipboard(owner)) - return !S_OK; - - if (!IsClipboardFormatAvailable(CF_TEXT) && !IsClipboardFormatAvailable(CF_UNICODETEXT)) - return !S_OK; - - HANDLE clipData = GetClipboardData(CF_TEXT); - QString clipText; - if (clipData == 0) { - clipData = GetClipboardData(CF_UNICODETEXT); - if (clipData != 0) - clipText = QString::fromWCharArray((wchar_t *)clipData); - } else { - clipText = QString::fromLatin1((const char*)clipData); - } - - QMimeData *mimeData = new QMimeData(); - mimeData->setText(clipText); - QOleDataObject* data = new QOleDataObject(mimeData); - *obj = data; - CloseClipboard(); - return S_OK; -} - -HRESULT QtCeSetClipboard(IDataObject* obj) -{ - HWND owner = ptrClipboardData->clipBoardViewer->internalWinId(); - if (!OpenClipboard(owner)) - return !S_OK; - - bool result = false; - if (obj == 0) { - result = true; - EmptyClipboard(); - CloseClipboard(); - } else { - QOleDataObject* qobj = static_cast<QOleDataObject*>(obj); - - const QMimeData* data = qobj->mimeData(); - if (data->hasText()) { - EmptyClipboard(); - result = SetClipboardData(CF_UNICODETEXT, wcsdup(reinterpret_cast<const wchar_t *> (data->text().utf16()))) != NULL; - CloseClipboard(); - result = true; - } - } - return result ? S_OK : !S_OK; -} - -void QtCeFlushClipboard() { } -#endif - - - -QClipboard::~QClipboard() -{ - cleanupClipboardData(); -} - -void QClipboard::setMimeData(QMimeData *src, Mode mode) -{ - if (mode != Clipboard) - return; - QClipboardData *d = clipboardData(); - - if (!(d->iData && d->iData->mimeData() == src)) { - d->releaseIData(); - d->iData = new QOleDataObject(src); - } - - if (OleSetClipboard(d->iData) != S_OK) { - d->releaseIData(); - qErrnoWarning("QClipboard::setMimeData: Failed to set data on clipboard"); - return; - } -#if defined(Q_OS_WINCE) - // As WinCE does not support notifications we send the signal here - // We will get no event when the clipboard changes outside... - emit dataChanged(); - emit changed(Clipboard); -#endif -} - -void QClipboard::clear(Mode mode) -{ - if (mode != Clipboard) return; - - QClipboardData *d = clipboardData(); - - d->releaseIData(); - - if (OleSetClipboard(0) != S_OK) { - qErrnoWarning("QClipboard::clear: Failed to clear data on clipboard"); - return; - } -#if defined(Q_OS_WINCE) - // As WinCE does not support notifications we send the signal here - // We will get no event when the clipboard changes outside... - emit dataChanged(); - emit changed(Clipboard); -#endif -} - -bool QClipboard::event(QEvent *e) -{ - if (e->type() != QEvent::Clipboard) - return QObject::event(e); - - QClipboardData *d = clipboardData(); - - MSG *m = (MSG *)((QClipboardEvent*)e)->data(); - if (!m) { - // this is sent to render all formats at app shut down - if (ownsClipboard()) { - OleFlushClipboard(); - d->releaseIData(); - } - return true; - } - - bool propagate = false; - - if (m->message == WM_CHANGECBCHAIN) { - if ((HWND)m->wParam == d->nextClipboardViewer) - d->nextClipboardViewer = (HWND)m->lParam; - else - propagate = true; - } else if (m->message == WM_DRAWCLIPBOARD) { - emitChanged(QClipboard::Clipboard); - if (!ownsClipboard() && d->iData) - // clean up the clipboard object if we no longer own the clipboard - d->releaseIData(); - propagate = true; - } - if (propagate && d->nextClipboardViewer) { - if (ptrIsHungAppWindow == 0) { - QSystemLibrary library(QLatin1String("User32")); - ptrIsHungAppWindow = (PtrIsHungAppWindow)library.resolve("IsHungAppWindow"); - } - if (ptrIsHungAppWindow && ptrIsHungAppWindow(d->nextClipboardViewer)) { - qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO); - } else { - SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam); - } - } - - return true; -} - -void QClipboard::connectNotify(const char *signal) -{ - if (qstrcmp(signal,SIGNAL(dataChanged())) == 0) { - // ensure we are up and running but block signals so the dataChange signal - // is not emitted while being connected to. - bool blocked = blockSignals(true); - QClipboardData *d = clipboardData(); - blockSignals(blocked); - Q_UNUSED(d); - } -} - -const QMimeData *QClipboard::mimeData(Mode mode) const -{ - if (mode != Clipboard) - return 0; - - QClipboardData *data = clipboardData(); - // sort cut for local copy / paste - if (ownsClipboard() && data->iData->mimeData()) - return data->iData->mimeData(); - return &data->watcher; -} - -bool QClipboard::supportsMode(Mode mode) const -{ - return (mode == Clipboard); -} - -bool QClipboard::ownsMode(Mode mode) const -{ - if (mode == Clipboard) { - QClipboardData *d = clipboardData(); -#if !defined(Q_OS_WINCE) - return d->iData && OleIsCurrentClipboard(d->iData) == S_OK; -#else - return d->iData && GetClipboardOwner() == d->clipBoardViewer->internalWinId(); -#endif - } else { - return false; - } -} - -void QClipboard::ownerDestroyed() -{ -} - -QT_END_NAMESPACE - -#endif // QT_NO_CLIPBOARD diff --git a/src/gui/platforms/win/qcolormap_win.cpp b/src/gui/platforms/win/qcolormap_win.cpp deleted file mode 100644 index 1773f717c0..0000000000 --- a/src/gui/platforms/win/qcolormap_win.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcolor.h" -#include "qcolormap.h" -#include "qvector.h" -#include "qt_windows.h" - -#if defined(Q_WS_WINCE) -#include "qguifunctions_wince.h" -#endif - -QT_BEGIN_NAMESPACE - -class QColormapPrivate -{ -public: - inline QColormapPrivate() - : ref(1), mode(QColormap::Direct), depth(0), hpal(0) - { } - - QAtomicInt ref; - - QColormap::Mode mode; - int depth; - int numcolors; - - HPALETTE hpal; - QVector<QColor> palette; -}; - -static QColormapPrivate *screenMap = 0; - -void QColormap::initialize() -{ - HDC dc = qt_win_display_dc(); - - screenMap = new QColormapPrivate; - screenMap->depth = GetDeviceCaps(dc, BITSPIXEL); - - screenMap->numcolors = -1; - if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) - screenMap->numcolors = GetDeviceCaps(dc, SIZEPALETTE); - - if (screenMap->numcolors <= 16 || screenMap->numcolors > 256) // no need to create palette - return; - - LOGPALETTE* pal = 0; - int numPalEntries = 6*6*6; // color cube - - pal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + numPalEntries * sizeof(PALETTEENTRY)); - // Make 6x6x6 color cube - int idx = 0; - for(int ir = 0x0; ir <= 0xff; ir+=0x33) { - for(int ig = 0x0; ig <= 0xff; ig+=0x33) { - for(int ib = 0x0; ib <= 0xff; ib+=0x33) { - pal->palPalEntry[idx].peRed = ir; - pal->palPalEntry[idx].peGreen = ig; - pal->palPalEntry[idx].peBlue = ib; - pal->palPalEntry[idx].peFlags = 0; - idx++; - } - } - } - - pal->palVersion = 0x300; - pal->palNumEntries = numPalEntries; - - screenMap->hpal = CreatePalette(pal); - if (!screenMap->hpal) - qErrnoWarning("QColor::initialize: Failed to create logical palette"); - free (pal); - - SelectPalette(dc, screenMap->hpal, FALSE); - RealizePalette(dc); - - PALETTEENTRY paletteEntries[256]; - screenMap->numcolors = GetPaletteEntries(screenMap->hpal, 0, 255, paletteEntries); - - screenMap->palette.resize(screenMap->numcolors); - for (int i = 0; i < screenMap->numcolors; i++) { - screenMap->palette[i] = qRgb(paletteEntries[i].peRed, - paletteEntries[i].peGreen, - paletteEntries[i].peBlue); - } -} - -void QColormap::cleanup() -{ - if (!screenMap) - return; - - if (screenMap->hpal) { // delete application global - DeleteObject(screenMap->hpal); // palette - screenMap->hpal = 0; - } - - delete screenMap; - screenMap = 0; -} - -QColormap QColormap::instance(int) -{ - Q_ASSERT_X(screenMap, "QColormap", - "A QApplication object needs to be constructed before QColormap is used."); - return QColormap(); -} - -QColormap::QColormap() - : d(screenMap) -{ d->ref.ref(); } - -QColormap::QColormap(const QColormap &colormap) - :d (colormap.d) -{ d->ref.ref(); } - -QColormap::~QColormap() -{ - if (!d->ref.deref()) - delete d; -} - -QColormap::Mode QColormap::mode() const -{ return d->mode; } - -int QColormap::depth() const -{ return d->depth; } - -int QColormap::size() const -{ return d->numcolors; } - -uint QColormap::pixel(const QColor &color) const -{ - const QColor c = color.toRgb(); - COLORREF rgb = RGB(c.red(), c.green(), c.blue()); - if (d->hpal) - return PALETTEINDEX(GetNearestPaletteIndex(d->hpal, rgb)); - return rgb; -} - -const QColor QColormap::colorAt(uint pixel) const -{ - if (d->hpal) { - if (pixel < uint(d->numcolors)) - return d->palette.at(pixel); - return QColor(); - } - return QColor(GetRValue(pixel), GetGValue(pixel), GetBValue(pixel)); -} - - -HPALETTE QColormap::hPal() -{ return screenMap ? screenMap->hpal : 0; } - - -const QVector<QColor> QColormap::colormap() const -{ return d->palette; } - -QColormap &QColormap::operator=(const QColormap &colormap) -{ qAtomicAssign(d, colormap.d); return *this; } - - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qcursor_win.cpp b/src/gui/platforms/win/qcursor_win.cpp deleted file mode 100644 index 8a9362ebfc..0000000000 --- a/src/gui/platforms/win/qcursor_win.cpp +++ /dev/null @@ -1,492 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qcursor_p.h> -#include <qbitmap.h> -#include <qcursor.h> - -#ifndef QT_NO_CURSOR - -#include <qimage.h> -#include <qt_windows.h> -#include <private/qapplication_p.h> - -QT_BEGIN_NAMESPACE - -/***************************************************************************** - Internal QCursorData class - *****************************************************************************/ - -QCursorData::QCursorData(Qt::CursorShape s) - : cshape(s), bm(0), bmm(0), hx(0), hy(0), hcurs(0) -{ - ref = 1; -} - -QCursorData::~QCursorData() -{ - delete bm; - delete bmm; -#if !defined(Q_WS_WINCE) || defined(GWES_ICONCURS) - if (hcurs) - DestroyCursor(hcurs); -#endif -} - - -QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) -{ - if (!QCursorData::initialized) - QCursorData::initialize(); - if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) { - qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)"); - QCursorData *c = qt_cursorTable[0]; - c->ref.ref(); - return c; - } - QCursorData *d = new QCursorData; - d->bm = new QBitmap(bitmap); - d->bmm = new QBitmap(mask); - d->hcurs = 0; - d->cshape = Qt::BitmapCursor; - d->hx = hotX >= 0 ? hotX : bitmap.width()/2; - d->hy = hotY >= 0 ? hotY : bitmap.height()/2; - return d; -} - -HCURSOR QCursor::handle() const -{ - if (!QCursorData::initialized) - QCursorData::initialize(); - if (!d->hcurs) - d->update(); - return d->hcurs; -} - -QCursor::QCursor(HCURSOR handle) -{ - d = new QCursorData(Qt::CustomCursor); - d->hcurs = handle; -} - -#endif //QT_NO_CURSOR - -QPoint QCursor::pos() -{ - POINT p; - GetCursorPos(&p); - return QPoint(p.x, p.y); -} - -void QCursor::setPos(int x, int y) -{ - SetCursorPos(x, y); -} - -#ifndef QT_NO_CURSOR - -extern HBITMAP qt_createIconMask(const QBitmap &bitmap); - -static HCURSOR create32BitCursor(const QPixmap &pixmap, int hx, int hy) -{ - HCURSOR cur = 0; -#if !defined(Q_WS_WINCE) - QBitmap mask = pixmap.mask(); - if (mask.isNull()) { - mask = QBitmap(pixmap.size()); - mask.fill(Qt::color1); - } - - HBITMAP ic = pixmap.toWinHBITMAP(QPixmap::Alpha); - HBITMAP im = qt_createIconMask(mask); - - ICONINFO ii; - ii.fIcon = 0; - ii.xHotspot = hx; - ii.yHotspot = hy; - ii.hbmMask = im; - ii.hbmColor = ic; - - cur = CreateIconIndirect(&ii); - - DeleteObject(ic); - DeleteObject(im); -#elif defined(GWES_ICONCURS) - QImage bbits, mbits; - bool invb, invm; - bbits = pixmap.toImage().convertToFormat(QImage::Format_Mono); - mbits = pixmap.toImage().convertToFormat(QImage::Format_Mono); - invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1)); - invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1)); - - int sysW = GetSystemMetrics(SM_CXCURSOR); - int sysH = GetSystemMetrics(SM_CYCURSOR); - int sysN = qMax(1, sysW / 8); - int n = qMax(1, bbits.width() / 8); - int h = bbits.height(); - - uchar* xBits = new uchar[sysH * sysN]; - uchar* xMask = new uchar[sysH * sysN]; - int x = 0; - for (int i = 0; i < sysH; ++i) { - if (i >= h) { - memset(&xBits[x] , 255, sysN); - memset(&xMask[x] , 0, sysN); - x += sysN; - } else { - int fillWidth = n > sysN ? sysN : n; - uchar *bits = bbits.scanLine(i); - uchar *mask = mbits.scanLine(i); - for (int j = 0; j < fillWidth; ++j) { - uchar b = bits[j]; - uchar m = mask[j]; - if (invb) - b ^= 0xFF; - if (invm) - m ^= 0xFF; - xBits[x] = ~m; - xMask[x] = b ^ m; - ++x; - } - for (int j = fillWidth; j < sysN; ++j ) { - xBits[x] = 255; - xMask[x] = 0; - ++x; - } - } - } - - cur = CreateCursor(qWinAppInst(), hx, hy, sysW, sysH, - xBits, xMask); -#else - Q_UNUSED(pixmap); - Q_UNUSED(hx); - Q_UNUSED(hy); -#endif - return cur; -} - -void QCursorData::update() -{ - if (!QCursorData::initialized) - QCursorData::initialize(); - if (hcurs) - return; - - if (cshape == Qt::BitmapCursor && !pixmap.isNull()) { - hcurs = create32BitCursor(pixmap, hx, hy); - if (hcurs) - return; - } - - - // Non-standard Windows cursors are created from bitmaps - - static const uchar vsplit_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, - 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const uchar vsplitm_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, - 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00, - 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, - 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, - 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, - 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, - 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00, - 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const uchar hsplit_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, - 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, - 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03, - 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00, - 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, - 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const uchar hsplitm_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, - 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00, - 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07, - 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00, - 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, - 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const uchar phand_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, - 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, - 0x80, 0x1c, 0x00, 0x00, 0x80, 0xe4, 0x00, 0x00, 0x80, 0x24, 0x03, 0x00, - 0x80, 0x24, 0x05, 0x00, 0xb8, 0x24, 0x09, 0x00, 0xc8, 0x00, 0x09, 0x00, - 0x88, 0x00, 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0xa0, 0x00, 0x08, 0x00, - 0x20, 0x00, 0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 0x04, 0x00, - 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x00, 0x01, 0x02, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - static const uchar phandm_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, - 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, - 0x80, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00, - 0x80, 0xff, 0x07, 0x00, 0xb8, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0f, 0x00, - 0xf8, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00, - 0xe0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x07, 0x00, - 0x80, 0xff, 0x07, 0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0xff, 0x03, 0x00, - 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - static const uchar openhand_bits[] = { - 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92, - 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20, - 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00}; - static const uchar openhandm_bits[] = { - 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff, - 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f, - 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00}; - static const uchar closedhand_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50, - 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10, - 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00}; - static const uchar closedhandm_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f, - 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f, - 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00}; - - static const uchar * const cursor_bits32[] = { - vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits, - phand_bits, phandm_bits - }; - - wchar_t *sh = 0; - switch (cshape) { // map to windows cursor - case Qt::ArrowCursor: - sh = IDC_ARROW; - break; - case Qt::UpArrowCursor: - sh = IDC_UPARROW; - break; - case Qt::CrossCursor: - sh = IDC_CROSS; - break; - case Qt::WaitCursor: - sh = IDC_WAIT; - break; - case Qt::IBeamCursor: - sh = IDC_IBEAM; - break; - case Qt::SizeVerCursor: - sh = IDC_SIZENS; - break; - case Qt::SizeHorCursor: - sh = IDC_SIZEWE; - break; - case Qt::SizeBDiagCursor: - sh = IDC_SIZENESW; - break; - case Qt::SizeFDiagCursor: - sh = IDC_SIZENWSE; - break; - case Qt::SizeAllCursor: - sh = IDC_SIZEALL; - break; - case Qt::ForbiddenCursor: - sh = IDC_NO; - break; - case Qt::WhatsThisCursor: - sh = IDC_HELP; - break; - case Qt::BusyCursor: - sh = IDC_APPSTARTING; - break; - case Qt::PointingHandCursor: - sh = IDC_HAND; - break; - case Qt::BlankCursor: - case Qt::SplitVCursor: - case Qt::SplitHCursor: - case Qt::OpenHandCursor: - case Qt::ClosedHandCursor: - case Qt::BitmapCursor: { - QImage bbits, mbits; - bool invb, invm; - if (cshape == Qt::BlankCursor) { - bbits = QImage(32, 32, QImage::Format_Mono); - bbits.fill(0); // ignore color table - mbits = bbits.copy(); - hx = hy = 16; - invb = invm = false; - } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) { - bool open = cshape == Qt::OpenHandCursor; - QBitmap cb = QBitmap::fromData(QSize(16, 16), open ? openhand_bits : closedhand_bits); - QBitmap cm = QBitmap::fromData(QSize(16, 16), open ? openhandm_bits : closedhandm_bits); - bbits = cb.toImage().convertToFormat(QImage::Format_Mono); - mbits = cm.toImage().convertToFormat(QImage::Format_Mono); - hx = hy = 8; - invb = invm = false; - } else if (cshape != Qt::BitmapCursor) { - int i = cshape - Qt::SplitVCursor; - QBitmap cb = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2]); - QBitmap cm = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2 + 1]); - bbits = cb.toImage().convertToFormat(QImage::Format_Mono); - mbits = cm.toImage().convertToFormat(QImage::Format_Mono); - if (cshape == Qt::PointingHandCursor) { - hx = 7; - hy = 0; - } else - hx = hy = 16; - invb = invm = false; - } else { - bbits = bm->toImage().convertToFormat(QImage::Format_Mono); - mbits = bmm->toImage().convertToFormat(QImage::Format_Mono); - invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1)); - invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1)); - } - int n = qMax(1, bbits.width() / 8); - int h = bbits.height(); -#if !defined(Q_WS_WINCE) - uchar* xBits = new uchar[h * n]; - uchar* xMask = new uchar[h * n]; - int x = 0; - for (int i = 0; i < h; ++i) { - uchar *bits = bbits.scanLine(i); - uchar *mask = mbits.scanLine(i); - for (int j = 0; j < n; ++j) { - uchar b = bits[j]; - uchar m = mask[j]; - if (invb) - b ^= 0xff; - if (invm) - m ^= 0xff; - xBits[x] = ~m; - xMask[x] = b ^ m; - ++x; - } - } - hcurs = CreateCursor(qWinAppInst(), hx, hy, bbits.width(), bbits.height(), - xBits, xMask); - delete [] xBits; - delete [] xMask; -#elif defined(GWES_ICONCURS) // Q_WS_WINCE - // Windows CE only supports fixed cursor size. - int sysW = GetSystemMetrics(SM_CXCURSOR); - int sysH = GetSystemMetrics(SM_CYCURSOR); - int sysN = qMax(1, sysW / 8); - uchar* xBits = new uchar[sysH * sysN]; - uchar* xMask = new uchar[sysH * sysN]; - int x = 0; - for (int i = 0; i < sysH; ++i) { - if (i >= h) { - memset(&xBits[x] , 255, sysN); - memset(&xMask[x] , 0, sysN); - x += sysN; - } else { - int fillWidth = n > sysN ? sysN : n; - uchar *bits = bbits.scanLine(i); - uchar *mask = mbits.scanLine(i); - for (int j = 0; j < fillWidth; ++j) { - uchar b = bits[j]; - uchar m = mask[j]; - if (invb) - b ^= 0xFF; - if (invm) - m ^= 0xFF; - xBits[x] = ~m; - xMask[x] = b ^ m; - ++x; - } - for (int j = fillWidth; j < sysN; ++j ) { - xBits[x] = 255; - xMask[x] = 0; - ++x; - } - } - } - - hcurs = CreateCursor(qWinAppInst(), hx, hy, sysW, sysH, - xBits, xMask); - delete [] xBits; - delete [] xMask; -#else - Q_UNUSED(n); - Q_UNUSED(h); -#endif - return; - } - case Qt::DragCopyCursor: - case Qt::DragMoveCursor: - case Qt::DragLinkCursor: { - QPixmap pixmap = QApplicationPrivate::instance()->getPixmapCursor(cshape); - hcurs = create32BitCursor(pixmap, hx, hy); - } - default: - qWarning("QCursor::update: Invalid cursor shape %d", cshape); - return; - } -#ifdef Q_WS_WINCE - hcurs = LoadCursor(0, sh); -#else - hcurs = (HCURSOR)LoadImage(0, sh, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); -#endif -} - -QT_END_NAMESPACE -#endif // QT_NO_CURSOR diff --git a/src/gui/platforms/win/qdesktopwidget_win.cpp b/src/gui/platforms/win/qdesktopwidget_win.cpp deleted file mode 100644 index d57b355ef4..0000000000 --- a/src/gui/platforms/win/qdesktopwidget_win.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdesktopwidget.h" -#include "qt_windows.h" -#include "qapplication_p.h" -#include <private/qsystemlibrary_p.h> -#include <qvector.h> -#include <limits.h> -#ifdef Q_WS_WINCE -#include <sipapi.h> -#endif -#include "qwidget_p.h" -#include "qdebug.h" - -QT_BEGIN_NAMESPACE - -class QDesktopWidgetPrivate : public QWidgetPrivate -{ -public: - QDesktopWidgetPrivate(); - ~QDesktopWidgetPrivate(); - - static void init(QDesktopWidget *that); - static void cleanup(); - static int screenCount; - static int primaryScreen; - - static QVector<QRect> *rects; - static QVector<QRect> *workrects; - - struct MONITORINFO - { - DWORD cbSize; - RECT rcMonitor; - RECT rcWork; - DWORD dwFlags; - }; - - typedef BOOL (WINAPI *InfoFunc)(HMONITOR, MONITORINFO*); - typedef BOOL (QT_WIN_CALLBACK *EnumProc)(HMONITOR, HDC, LPRECT, LPARAM); - typedef BOOL (WINAPI *EnumFunc)(HDC, LPCRECT, EnumProc, LPARAM); - - static EnumFunc enumDisplayMonitors; - static InfoFunc getMonitorInfo; - static int refcount; -}; - -int QDesktopWidgetPrivate::screenCount = 1; -int QDesktopWidgetPrivate::primaryScreen = 0; -QDesktopWidgetPrivate::EnumFunc QDesktopWidgetPrivate::enumDisplayMonitors = 0; -QDesktopWidgetPrivate::InfoFunc QDesktopWidgetPrivate::getMonitorInfo = 0; -QVector<QRect> *QDesktopWidgetPrivate::rects = 0; -QVector<QRect> *QDesktopWidgetPrivate::workrects = 0; -static int screen_number = 0; -int QDesktopWidgetPrivate::refcount = 0; -#ifdef Q_WS_WINCE_WM -// Use SIP information, if available -// SipGetInfo is not supported by SSDK (no definition!). -static inline void qt_get_sip_info(QRect &rect) -{ - SIPINFO sip; - memset(&sip, 0, sizeof(SIPINFO)); - sip.cbSize = sizeof(SIPINFO); - if (SipGetInfo(&sip)) - rect = QRect(QPoint(sip.rcVisibleDesktop.left, sip.rcVisibleDesktop.top), - QPoint(sip.rcVisibleDesktop.right - 1, sip.rcVisibleDesktop.bottom - 1)); -} -#endif - - -BOOL QT_WIN_CALLBACK enumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM) -{ - QDesktopWidgetPrivate::screenCount++; - QDesktopWidgetPrivate::rects->resize(QDesktopWidgetPrivate::screenCount); - QDesktopWidgetPrivate::workrects->resize(QDesktopWidgetPrivate::screenCount); - // Get the MONITORINFO block - QDesktopWidgetPrivate::MONITORINFO info; - memset(&info, 0, sizeof(QDesktopWidgetPrivate::MONITORINFO)); - info.cbSize = sizeof(QDesktopWidgetPrivate::MONITORINFO); - BOOL res = QDesktopWidgetPrivate::getMonitorInfo(hMonitor, &info); - if (!res) { - (*QDesktopWidgetPrivate::rects)[screen_number] = QRect(); - (*QDesktopWidgetPrivate::workrects)[screen_number] = QRect(); - return true; - } - - // Fill list of rects - RECT r = info.rcMonitor; - QRect qr(QPoint(r.left, r.top), QPoint(r.right - 1, r.bottom - 1)); - (*QDesktopWidgetPrivate::rects)[screen_number] = qr; - - r = info.rcWork; - qr = QRect(QPoint(r.left, r.top), QPoint(r.right - 1, r.bottom - 1)); - (*QDesktopWidgetPrivate::workrects)[screen_number] = qr; - - if (info.dwFlags & 0x00000001) //MONITORINFOF_PRIMARY - QDesktopWidgetPrivate::primaryScreen = screen_number; - - ++screen_number; - // Stop the enumeration if we have them all - return true; -} - -QDesktopWidgetPrivate::QDesktopWidgetPrivate() -{ - ++refcount; -} - -void QDesktopWidgetPrivate::init(QDesktopWidget *that) -{ - if (rects) - return; - - rects = new QVector<QRect>(); - workrects = new QVector<QRect>(); - screenCount = 0; - -#ifndef Q_OS_WINCE - QSystemLibrary user32Lib(QLatin1String("user32")); - enumDisplayMonitors = (EnumFunc)user32Lib.resolve("EnumDisplayMonitors"); - getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW"); - - if (!enumDisplayMonitors || !getMonitorInfo) { - screenCount = GetSystemMetrics(80); // SM_CMONITORS - rects->resize(screenCount); - for (int i = 0; i < screenCount; ++i) - rects->replace(i, that->rect()); - return; - } - // Calls enumCallback - enumDisplayMonitors(0, 0, enumCallback, 0); - enumDisplayMonitors = 0; - getMonitorInfo = 0; -#else - QSystemLibrary coreLib(QLatin1String("coredll")); - // CE >= 4.0 case - enumDisplayMonitors = (EnumFunc)coreLib.resolve("EnumDisplayMonitors"); - getMonitorInfo = (InfoFunc)coreLib.resolve("GetMonitorInfo"); - - if ((!enumDisplayMonitors || !getMonitorInfo)) { - screenCount = GetSystemMetrics(SM_CMONITORS); - return; - } - - if (!coreLib.isLoaded() || !enumDisplayMonitors || !getMonitorInfo) { - rects->resize(screenCount); - for (int i = 0; i < screenCount; ++i) - (*rects)[i] = that->rect(); - - RECT r; - SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); - QRect qr = QRect(QPoint(r.left, r.top), QPoint(r.right - 1, r.bottom - 1)); - -#if defined(Q_WS_WINCE_WM) - qt_get_sip_info(qr); -#endif - - workrects->resize(screenCount); - for (int j = 0; j < screenCount; ++j) - (*workrects)[j] = qr; - return; - } - - // Calls enumCallback - enumDisplayMonitors(0, 0, enumCallback, 0); - enumDisplayMonitors = 0; - getMonitorInfo = 0; -#endif // Q_WS_WINCE -} - -QDesktopWidgetPrivate::~QDesktopWidgetPrivate() -{ - if (!--refcount) - cleanup(); -} - -void QDesktopWidgetPrivate::cleanup() -{ - screen_number = 0; - screenCount = 1; - primaryScreen = 0; - enumDisplayMonitors = 0; - getMonitorInfo = 0; - delete rects; - rects = 0; - delete workrects; - workrects = 0; -} - -/* - \omit - Function is commented out in header - \fn void *QDesktopWidget::handle(int screen) const - - Returns the window system handle of the display device with the - index \a screen, for low-level access. Using this function is not - portable. - - The return type varies with platform; see qwindowdefs.h for details. - - \sa x11Display(), QPaintDevice::handle() - \endomit -*/ - -QDesktopWidget::QDesktopWidget() - : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop) -{ - setObjectName(QLatin1String("desktop")); - QDesktopWidgetPrivate::init(this); -} - -QDesktopWidget::~QDesktopWidget() -{ -} - -bool QDesktopWidget::isVirtualDesktop() const -{ - return true; -} - -int QDesktopWidget::primaryScreen() const -{ - return d_func()->primaryScreen; -} - -int QDesktopWidget::numScreens() const -{ - return d_func()->screenCount; -} - -QWidget *QDesktopWidget::screen(int /* screen */) -{ - // It seems that a Qt::WType_Desktop cannot be moved? - return this; -} - -// -// MSVC 7.10 warns that d (the result of the expanded Q_D macro) as a local variable that is not referenced. -// Therefore, we ignore that warning with the following pragmas -// I've also tried to eliminate the macro, but to no use... -// We pop it further down -#ifdef Q_CC_MSVC -# pragma warning(push) -# pragma warning(disable : 4189) -#endif -const QRect QDesktopWidget::availableGeometry(int screen) const -{ - Q_D(const QDesktopWidget); -#ifdef Q_WS_WINCE_WM - for(int i=0; i < d->workrects->size(); ++i) - qt_get_sip_info((*d->workrects)[i]); -#endif - if (screen < 0 || screen >= d->screenCount) - screen = d->primaryScreen; - - return d->workrects->at(screen); -} - -const QRect QDesktopWidget::screenGeometry(int screen) const -{ - const QDesktopWidgetPrivate *d = d_func(); - if (screen < 0 || screen >= d->screenCount) - screen = d->primaryScreen; - - return d->rects->at(screen); -} - -int QDesktopWidget::screenNumber(const QWidget *widget) const -{ - Q_D(const QDesktopWidget); - if (!widget) - return d->primaryScreen; - - QRect frame = widget->frameGeometry(); - if (!widget->isWindow()) - frame.moveTopLeft(widget->mapToGlobal(QPoint(0,0))); - - int maxSize = -1; - int maxScreen = -1; - - for (int i = 0; i < d->screenCount; ++i) { - QRect sect = d->rects->at(i).intersected(frame); - int size = sect.width() * sect.height(); - if (size > maxSize && sect.width() > 0 && sect.height() > 0) { - maxSize = size; - maxScreen = i; - } - } - - return maxScreen; -} - -int QDesktopWidget::screenNumber(const QPoint &point) const -{ - Q_D(const QDesktopWidget); - - int closestScreen = -1; - int shortestDistance = INT_MAX; - - for (int i = 0; i < d->screenCount; ++i) { - int thisDistance = d->pointToRect(point, d->rects->at(i)); - if (thisDistance < shortestDistance) { - shortestDistance = thisDistance; - closestScreen = i; - } - } - - return closestScreen; -} - -void QDesktopWidget::resizeEvent(QResizeEvent *) -{ - Q_D(QDesktopWidget); - const QVector<QRect> oldrects(*d->rects); - const QVector<QRect> oldworkrects(*d->workrects); - int oldscreencount = d->screenCount; - - QDesktopWidgetPrivate::cleanup(); - QDesktopWidgetPrivate::init(this); -#ifdef Q_WS_WINCE_WM - for(int i=0; i < d->workrects->size(); ++i) - qt_get_sip_info((*d->workrects)[i]); -#endif - - for (int i = 0; i < qMin(oldscreencount, d->screenCount); ++i) { - const QRect oldrect = oldrects[i]; - const QRect newrect = d->rects->at(i); - if (oldrect != newrect) - emit resized(i); - } - - for (int j = 0; j < qMin(oldscreencount, d->screenCount); ++j) { - const QRect oldrect = oldworkrects[j]; - const QRect newrect = d->workrects->at(j); - if (oldrect != newrect) - emit workAreaResized(j); - } - - if (oldscreencount != d->screenCount) { - emit screenCountChanged(d->screenCount); - } -} - -#ifdef Q_CC_MSVC -# pragma warning(pop) -#endif - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qdnd_win.cpp b/src/gui/platforms/win/qdnd_win.cpp deleted file mode 100644 index 176e3cef7f..0000000000 --- a/src/gui/platforms/win/qdnd_win.cpp +++ /dev/null @@ -1,1027 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qapplication.h" - -#include "qapplication_p.h" -#include "qevent.h" -#include "qpainter.h" -#include "qwidget.h" -#include "qbuffer.h" -#include "qdatastream.h" -#include "qcursor.h" -#include "qt_windows.h" -#include <shlobj.h> -#ifndef QT_NO_ACCESSIBILITY -#include "qaccessible.h" -#endif -#include "qdnd_p.h" -#include "qdebug.h" - -#if defined(Q_OS_WINCE) -#include "qguifunctions_wince.h" -#endif - -// support for xbuttons -#ifndef MK_XBUTTON1 -#define MK_XBUTTON1 0x0020 -#define MK_XBUTTON2 0x0040 -#endif - -QT_BEGIN_NAMESPACE - -#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD)) - -//--------------------------------------------------------------------- -// QOleDataObject Constructor -//--------------------------------------------------------------------- - -QOleDataObject::QOleDataObject(QMimeData *mimeData) -{ - m_refs = 1; - data = mimeData; - CF_PERFORMEDDROPEFFECT = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT); - performedEffect = DROPEFFECT_NONE; -} - -QOleDataObject::~QOleDataObject() -{ -} - -void QOleDataObject::releaseQt() -{ - data = 0; -} - -const QMimeData *QOleDataObject::mimeData() const -{ - return data; -} - -DWORD QOleDataObject::reportedPerformedEffect() const -{ - return performedEffect; -} - -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - -STDMETHODIMP -QOleDataObject::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if (iid == IID_IUnknown || iid == IID_IDataObject) { - *ppv = this; - AddRef(); - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - -STDMETHODIMP_(ULONG) -QOleDataObject::AddRef(void) -{ - return ++m_refs; -} - -STDMETHODIMP_(ULONG) -QOleDataObject::Release(void) -{ - if (--m_refs == 0) { - releaseQt(); - delete this; - return 0; - } - return m_refs; -} - -//--------------------------------------------------------------------- -// IDataObject Methods -// -// The following methods are NOT supported for data transfer using the -// clipboard or drag-drop: -// -// IDataObject::SetData -- return E_NOTIMPL -// IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED -// ::DUnadvise -// ::EnumDAdvise -// IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL -// (NOTE: must set pformatetcOut->ptd = NULL) -//--------------------------------------------------------------------- - -STDMETHODIMP -QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) -{ -#ifdef QDND_DEBUG - qDebug("QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)"); -#ifndef Q_OS_WINCE - wchar_t buf[256] = {0}; - GetClipboardFormatName(pformatetc->cfFormat, buf, 255); - qDebug("CF = %d : %s", pformatetc->cfFormat, QString::fromWCharArray(buf)); -#endif -#endif - - if (!data) - return ResultFromScode(DATA_E_FORMATETC); - - QWindowsMime *converter = QWindowsMime::converterFromMime(*pformatetc, data); - - if (converter && converter->convertFromMime(*pformatetc, data, pmedium)) - return ResultFromScode(S_OK); - else - return ResultFromScode(DATA_E_FORMATETC); -} - -STDMETHODIMP -QOleDataObject::GetDataHere(LPFORMATETC, LPSTGMEDIUM) -{ - return ResultFromScode(DATA_E_FORMATETC); -} - -STDMETHODIMP -QOleDataObject::QueryGetData(LPFORMATETC pformatetc) -{ -#ifdef QDND_DEBUG - qDebug("QOleDataObject::QueryGetData(LPFORMATETC pformatetc)"); -#endif - - if (!data) - return ResultFromScode(DATA_E_FORMATETC); - - if (QWindowsMime::converterFromMime(*pformatetc, data)) - return ResultFromScode(S_OK); - return ResultFromScode(S_FALSE); -} - -STDMETHODIMP -QOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetcOut) -{ - pformatetcOut->ptd = NULL; - return ResultFromScode(E_NOTIMPL); -} - -STDMETHODIMP -QOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease) -{ - if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) { - DWORD * val = (DWORD*)GlobalLock(pMedium->hGlobal); - performedEffect = *val; - GlobalUnlock(pMedium->hGlobal); - if (fRelease) - ReleaseStgMedium(pMedium); - return ResultFromScode(S_OK); - } - return ResultFromScode(E_NOTIMPL); -} - - -STDMETHODIMP -QOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc) -{ -#ifdef QDND_DEBUG - qDebug("QOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)"); -#endif - - if (!data) - return ResultFromScode(DATA_E_FORMATETC); - - SCODE sc = S_OK; - - QVector<FORMATETC> fmtetcs; - if (dwDirection == DATADIR_GET) { - fmtetcs = QWindowsMime::allFormatsForMime(data); - } else { - FORMATETC formatetc; - formatetc.cfFormat = CF_PERFORMEDDROPEFFECT; - formatetc.dwAspect = DVASPECT_CONTENT; - formatetc.lindex = -1; - formatetc.ptd = NULL; - formatetc.tymed = TYMED_HGLOBAL; - fmtetcs.append(formatetc); - } - - QOleEnumFmtEtc *enumFmtEtc = new QOleEnumFmtEtc(fmtetcs); - *ppenumFormatEtc = enumFmtEtc; - if (enumFmtEtc->isNull()) { - delete enumFmtEtc; - *ppenumFormatEtc = NULL; - sc = E_OUTOFMEMORY; - } - - return ResultFromScode(sc); -} - -STDMETHODIMP -QOleDataObject::DAdvise(FORMATETC FAR*, DWORD, - LPADVISESINK, DWORD FAR*) -{ - return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); -} - - -STDMETHODIMP -QOleDataObject::DUnadvise(DWORD) -{ - return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); -} - -STDMETHODIMP -QOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*) -{ - return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); -} - -#endif // QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD - -#ifndef QT_NO_DRAGANDDROP - -//#define QDND_DEBUG - -#ifdef QDND_DEBUG -extern QString dragActionsToString(Qt::DropActions actions); -#endif - -Qt::DropActions translateToQDragDropActions(DWORD pdwEffects) -{ - Qt::DropActions actions = Qt::IgnoreAction; - if (pdwEffects & DROPEFFECT_LINK) - actions |= Qt::LinkAction; - if (pdwEffects & DROPEFFECT_COPY) - actions |= Qt::CopyAction; - if (pdwEffects & DROPEFFECT_MOVE) - actions |= Qt::MoveAction; - return actions; -} - -Qt::DropAction translateToQDragDropAction(DWORD pdwEffect) -{ - if (pdwEffect & DROPEFFECT_LINK) - return Qt::LinkAction; - if (pdwEffect & DROPEFFECT_COPY) - return Qt::CopyAction; - if (pdwEffect & DROPEFFECT_MOVE) - return Qt::MoveAction; - return Qt::IgnoreAction; -} - -DWORD translateToWinDragEffects(Qt::DropActions action) -{ - DWORD effect = DROPEFFECT_NONE; - if (action & Qt::LinkAction) - effect |= DROPEFFECT_LINK; - if (action & Qt::CopyAction) - effect |= DROPEFFECT_COPY; - if (action & Qt::MoveAction) - effect |= DROPEFFECT_MOVE; - return effect; -} - -Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState) -{ - Qt::KeyboardModifiers modifiers = Qt::NoModifier; - - if (keyState & MK_SHIFT) - modifiers |= Qt::ShiftModifier; - if (keyState & MK_CONTROL) - modifiers |= Qt::ControlModifier; - if (keyState & MK_ALT) - modifiers |= Qt::AltModifier; - - return modifiers; -} - -Qt::MouseButtons toQtMouseButtons(DWORD keyState) -{ - Qt::MouseButtons buttons = Qt::NoButton; - - if (keyState & MK_LBUTTON) - buttons |= Qt::LeftButton; - if (keyState & MK_RBUTTON) - buttons |= Qt::RightButton; - if (keyState & MK_MBUTTON) - buttons |= Qt::MidButton; - - return buttons; -} - -class QOleDropSource : public IDropSource -{ -public: - QOleDropSource(); - virtual ~QOleDropSource(); - - void createCursors(); - - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj); - STDMETHOD_(ULONG,AddRef)(void); - STDMETHOD_(ULONG,Release)(void); - - // IDropSource methods - STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState); - STDMETHOD(GiveFeedback)(DWORD dwEffect); - -private: - Qt::MouseButtons currentButtons; - Qt::DropAction currentAction; - QMap <Qt::DropAction, QCursor> cursors; - - ULONG m_refs; -}; - - -QOleDropSource::QOleDropSource() -{ - currentButtons = Qt::NoButton; - m_refs = 1; - currentAction = Qt::IgnoreAction; -} - -QOleDropSource::~QOleDropSource() -{ -} - -void QOleDropSource::createCursors() -{ - QDragManager *manager = QDragManager::self(); - if (manager && manager->object - && (!manager->object->pixmap().isNull() - || manager->hasCustomDragCursors())) { - QPixmap pm = manager->object->pixmap(); - QList<Qt::DropAction> actions; - actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction; - if (!manager->object->pixmap().isNull()) - actions << Qt::IgnoreAction; - QPoint hotSpot = manager->object->hotSpot(); - for (int cnum = 0; cnum < actions.size(); ++cnum) { - QPixmap cpm = manager->dragCursor(actions.at(cnum)); - int w = cpm.width(); - int h = cpm.height(); - - if (!pm.isNull()) { - int x1 = qMin(-hotSpot.x(), 0); - int x2 = qMax(pm.width() - hotSpot.x(), cpm.width()); - int y1 = qMin(-hotSpot.y(), 0); - int y2 = qMax(pm.height() - hotSpot.y(), cpm.height()); - - w = x2 - x1 + 1; - h = y2 - y1 + 1; - } - - QRect srcRect = pm.rect(); - QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y())); - QPoint newHotSpot = hotSpot; - -#if defined(Q_OS_WINCE) - // Limited cursor size - int reqw = GetSystemMetrics(SM_CXCURSOR); - int reqh = GetSystemMetrics(SM_CYCURSOR); - - QPoint hotspotInPM = newHotSpot - pmDest; - if (reqw < w) { - // Not wide enough - move objectpm right - qreal r = qreal(newHotSpot.x()) / w; - newHotSpot = QPoint(int(r * reqw), newHotSpot.y()); - if (newHotSpot.x() + cpm.width() > reqw) - newHotSpot.setX(reqw - cpm.width()); - - srcRect = QRect(QPoint(hotspotInPM.x() - newHotSpot.x(), srcRect.top()), QSize(reqw, srcRect.height())); - } - if (reqh < h) { - qreal r = qreal(newHotSpot.y()) / h; - newHotSpot = QPoint(newHotSpot.x(), int(r * reqh)); - if (newHotSpot.y() + cpm.height() > reqh) - newHotSpot.setY(reqh - cpm.height()); - - srcRect = QRect(QPoint(srcRect.left(), hotspotInPM.y() - newHotSpot.y()), QSize(srcRect.width(), reqh)); - } - // Always use system cursor size - w = reqw; - h = reqh; -#endif - - QPixmap newCursor(w, h); - if (!pm.isNull()) { - newCursor.fill(QColor(0, 0, 0, 0)); - QPainter p(&newCursor); - p.drawPixmap(pmDest, pm, srcRect); - p.drawPixmap(qMax(0,newHotSpot.x()),qMax(0,newHotSpot.y()),cpm); - } else { - newCursor = cpm; - } - -#ifndef QT_NO_CURSOR - cursors[actions.at(cnum)] = QCursor(newCursor, pm.isNull() ? 0 : qMax(0,newHotSpot.x()), - pm.isNull() ? 0 : qMax(0,newHotSpot.y())); -#endif - } - } -} - - - -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - - -STDMETHODIMP -QOleDropSource::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if(iid == IID_IUnknown || iid == IID_IDropSource) - { - *ppv = this; - ++m_refs; - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - - -STDMETHODIMP_(ULONG) -QOleDropSource::AddRef(void) -{ - return ++m_refs; -} - - -STDMETHODIMP_(ULONG) -QOleDropSource::Release(void) -{ - if(--m_refs == 0) - { - delete this; - return 0; - } - return m_refs; -} - -static inline Qt::MouseButtons keystate_to_mousebutton(DWORD grfKeyState) -{ - Qt::MouseButtons result; - if (grfKeyState & MK_LBUTTON) - result |= Qt::LeftButton; - if (grfKeyState & MK_MBUTTON) - result |= Qt::MidButton; - if (grfKeyState & MK_RBUTTON) - result |= Qt::RightButton; - if (grfKeyState & MK_XBUTTON1) - result |= Qt::XButton1; - if (grfKeyState & MK_XBUTTON2) - result |= Qt::XButton2; - return result; -} - -//--------------------------------------------------------------------- -// IDropSource Methods -//--------------------------------------------------------------------- -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropSource::QueryContinueDrag(fEscapePressed %d, grfKeyState %d)", fEscapePressed, grfKeyState); -#endif - - if (fEscapePressed) { - return ResultFromScode(DRAGDROP_S_CANCEL); - } else if ((GetAsyncKeyState(VK_LBUTTON) == 0) - && (GetAsyncKeyState(VK_MBUTTON) == 0) - && (GetAsyncKeyState(VK_RBUTTON) == 0)) { - // grfKeyState is broken on CE & some Windows XP versions, - // therefore we need to check the state manually - return ResultFromScode(DRAGDROP_S_DROP); - } else { -#if !defined(Q_OS_WINCE) - if (currentButtons == Qt::NoButton) { - currentButtons = keystate_to_mousebutton(grfKeyState); - } else { - Qt::MouseButtons buttons = keystate_to_mousebutton(grfKeyState); - if (!(currentButtons & buttons)) - return ResultFromScode(DRAGDROP_S_DROP); - } -#endif - QApplication::processEvents(); - return NOERROR; - } -} - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropSource::GiveFeedback(DWORD dwEffect) -{ - Qt::DropAction action = translateToQDragDropAction(dwEffect); - -#ifdef QDND_DEBUG - qDebug("QOleDropSource::GiveFeedback(DWORD dwEffect)"); - qDebug("dwEffect = %s", dragActionsToString(action).toLatin1().data()); -#endif - - if (currentAction != action) { - currentAction = action; - QDragManager::self()->emitActionChanged(currentAction); - } - - if (cursors.contains(currentAction)) { -#ifndef QT_NO_CURSOR - SetCursor(cursors[currentAction].handle()); -#endif - return ResultFromScode(S_OK); - } - - return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS); -} - -//--------------------------------------------------------------------- -// QOleDropTarget -//--------------------------------------------------------------------- - -QOleDropTarget::QOleDropTarget(QWidget* w) -: widget(w) -{ - m_refs = 1; -} - -void QOleDropTarget::releaseQt() -{ - widget = 0; -} - -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - - -STDMETHODIMP -QOleDropTarget::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if(iid == IID_IUnknown || iid == IID_IDropTarget) - { - *ppv = this; - AddRef(); - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - - -STDMETHODIMP_(ULONG) -QOleDropTarget::AddRef(void) -{ - return ++m_refs; -} - - -STDMETHODIMP_(ULONG) -QOleDropTarget::Release(void) -{ - if(--m_refs == 0) - { - delete this; - return 0; - } - return m_refs; -} - -//--------------------------------------------------------------------- -// IDropTarget Methods -//--------------------------------------------------------------------- - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)"); -#endif - - if (!QApplicationPrivate::tryModalHelper(widget)) { - *pdwEffect = DROPEFFECT_NONE; - return NOERROR; - } - - QDragManager *manager = QDragManager::self(); - manager->dropData->currentDataObject = pDataObj; - manager->dropData->currentDataObject->AddRef(); - sendDragEnterEvent(widget, grfKeyState, pt, pdwEffect); - *pdwEffect = chosenEffect; - - return NOERROR; -} - -void QOleDropTarget::sendDragEnterEvent(QWidget *dragEnterWidget, DWORD grfKeyState, - POINTL pt, LPDWORD pdwEffect) -{ - Q_ASSERT(dragEnterWidget); - lastPoint = dragEnterWidget->mapFromGlobal(QPoint(pt.x,pt.y)); - lastKeyState = grfKeyState; - - chosenEffect = DROPEFFECT_NONE; - currentWidget = dragEnterWidget; - - QDragManager *manager = QDragManager::self(); - QMimeData * md = manager->source() ? manager->dragPrivate()->data : manager->dropData; - QDragEnterEvent enterEvent(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - QApplication::sendEvent(dragEnterWidget, &enterEvent); - answerRect = enterEvent.answerRect(); - - if (enterEvent.isAccepted()) { - chosenEffect = translateToWinDragEffects(enterEvent.dropAction()); - } - - // Documentation states that a drag move event is sendt immidiatly after - // a drag enter event. This will honor widgets overriding dragMoveEvent only: - if (enterEvent.isAccepted()) { - QDragMoveEvent moveEvent(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - answerRect = enterEvent.answerRect(); - moveEvent.setDropAction(enterEvent.dropAction()); - moveEvent.accept(); // accept by default, since enter event was accepted. - - QApplication::sendEvent(dragEnterWidget, &moveEvent); - if (moveEvent.isAccepted()) { - answerRect = moveEvent.answerRect(); - chosenEffect = translateToWinDragEffects(moveEvent.dropAction()); - } else { - chosenEffect = DROPEFFECT_NONE; - } - } - -} - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::DragOver(grfKeyState %d, pt (%d,%d), pdwEffect %d)", grfKeyState, pt.x, pt.y, pdwEffect); -#endif - - QWidget *dragOverWidget = widget->childAt(widget->mapFromGlobal(QPoint(pt.x, pt.y))); - if (!dragOverWidget) - dragOverWidget = widget; - - - if (!QApplicationPrivate::tryModalHelper(dragOverWidget) - || !dragOverWidget->testAttribute(Qt::WA_DropSiteRegistered)) { - *pdwEffect = DROPEFFECT_NONE; - return NOERROR; - } - - QPoint tmpPoint = dragOverWidget->mapFromGlobal(QPoint(pt.x, pt.y)); - // see if we should compress this event - if ((tmpPoint == lastPoint || answerRect.contains(tmpPoint)) && lastKeyState == grfKeyState) { - *pdwEffect = chosenEffect; - return NOERROR; - } - - if (!dragOverWidget->internalWinId() && dragOverWidget != currentWidget) { - QPointer<QWidget> dragOverWidgetGuard(dragOverWidget); - // Send drag leave event to the previous drag widget. - QDragLeaveEvent dragLeave; - if (currentWidget) - QApplication::sendEvent(currentWidget, &dragLeave); - if (!dragOverWidgetGuard) { - dragOverWidget = widget->childAt(widget->mapFromGlobal(QPoint(pt.x, pt.y))); - if (!dragOverWidget) - dragOverWidget = widget; - } - // Send drag enter event to the current drag widget. - sendDragEnterEvent(dragOverWidget, grfKeyState, pt, pdwEffect); - } - - QDragManager *manager = QDragManager::self(); - QMimeData *md = manager->source() ? manager->dragPrivate()->data : manager->dropData; - - QDragMoveEvent oldEvent(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(lastKeyState), toQtKeyboardModifiers(lastKeyState)); - - - lastPoint = tmpPoint; - lastKeyState = grfKeyState; - - QDragMoveEvent e(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - if (chosenEffect != DROPEFFECT_NONE) { - if (oldEvent.dropAction() == e.dropAction() && - oldEvent.keyboardModifiers() == e.keyboardModifiers()) - e.setDropAction(translateToQDragDropAction(chosenEffect)); - e.accept(); - } - QApplication::sendEvent(dragOverWidget, &e); - - answerRect = e.answerRect(); - if (e.isAccepted()) - chosenEffect = translateToWinDragEffects(e.dropAction()); - else - chosenEffect = DROPEFFECT_NONE; - *pdwEffect = chosenEffect; - - return NOERROR; -} - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::DragLeave() -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::DragLeave()"); -#endif - - if (!QApplicationPrivate::tryModalHelper(widget)) { - return NOERROR; - } - - currentWidget = 0; - QDragLeaveEvent e; - QApplication::sendEvent(widget, &e); - - QDragManager *manager = QDragManager::self(); - - if (manager->dropData->currentDataObject) { // Sanity - manager->dropData->currentDataObject->Release(); - manager->dropData->currentDataObject = 0; - } - - return NOERROR; -} - -#define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, grfKeyState %d, POINTL pt, LPDWORD pdwEffect)", grfKeyState); -#endif - - QWidget *dropWidget = widget->childAt(widget->mapFromGlobal(QPoint(pt.x, pt.y))); - if (!dropWidget) - dropWidget = widget; - - if (!QApplicationPrivate::tryModalHelper(dropWidget) - || !dropWidget->testAttribute(Qt::WA_DropSiteRegistered)) { - *pdwEffect = DROPEFFECT_NONE; - return NOERROR; - } - - lastPoint = dropWidget->mapFromGlobal(QPoint(pt.x,pt.y)); - // grfKeyState does not all ways contain button state in the drop so if - // it doesn't then use the last known button state; - if ((grfKeyState & KEY_STATE_BUTTON_MASK) == 0) - grfKeyState |= lastKeyState & KEY_STATE_BUTTON_MASK; - lastKeyState = grfKeyState; - - QDragManager *manager = QDragManager::self(); - QMimeData *md = manager->source() ? manager->dragPrivate()->data : manager->dropData; - QDropEvent e(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - if (chosenEffect != DROPEFFECT_NONE) { - e.setDropAction(translateToQDragDropAction(chosenEffect)); - } - QApplication::sendEvent(dropWidget, &e); - - if (chosenEffect != DROPEFFECT_NONE) { - e.accept(); - } - - - if (e.isAccepted()) { - if (e.dropAction() == Qt::MoveAction || e.dropAction() == Qt::TargetMoveAction) { - if (e.dropAction() == Qt::MoveAction) - chosenEffect = DROPEFFECT_MOVE; - else - chosenEffect = DROPEFFECT_COPY; - HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD)); - if (hData) { - DWORD *moveEffect = (DWORD *)GlobalLock(hData);; - *moveEffect = DROPEFFECT_MOVE; - GlobalUnlock(hData); - STGMEDIUM medium; - memset(&medium, 0, sizeof(STGMEDIUM)); - medium.tymed = TYMED_HGLOBAL; - medium.hGlobal = hData; - FORMATETC format; - format.cfFormat = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT); - format.tymed = TYMED_HGLOBAL; - format.ptd = 0; - format.dwAspect = 1; - format.lindex = -1; - manager->dropData->currentDataObject->SetData(&format, &medium, true); - } - } else { - chosenEffect = translateToWinDragEffects(e.dropAction()); - } - } else { - chosenEffect = DROPEFFECT_NONE; - } - *pdwEffect = chosenEffect; - - - if (manager->dropData->currentDataObject) { - manager->dropData->currentDataObject->Release(); - manager->dropData->currentDataObject = 0; - } - - return NOERROR; - - // We won't get any mouserelease-event, so manually adjust qApp state: -///### test this QApplication::winMouseButtonUp(); -} - -//--------------------------------------------------------------------- -// QDropData -//--------------------------------------------------------------------- - -bool QDropData::hasFormat_sys(const QString &mimeType) const -{ - if (!currentDataObject) // Sanity - return false; - - return QWindowsMime::converterToMime(mimeType, currentDataObject) != 0; -} - -QStringList QDropData::formats_sys() const -{ - QStringList fmts; - if (!currentDataObject) // Sanity - return fmts; - - fmts = QWindowsMime::allMimesForFormats(currentDataObject); - - return fmts; -} - -QVariant QDropData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const -{ - QVariant result; - - if (!currentDataObject) // Sanity - return result; - - QWindowsMime *converter = QWindowsMime::converterToMime(mimeType, currentDataObject); - - if (converter) - result = converter->convertToMime(mimeType, currentDataObject, type); - - return result; -} - -Qt::DropAction QDragManager::drag(QDrag *o) - -{ -#ifdef QDND_DEBUG - qDebug("QDragManager::drag(QDrag *drag)"); -#endif - - if (object == o || !o || !o->d_func()->source) - return Qt::IgnoreAction; - - if (object) { - cancel(); - qApp->removeEventFilter(this); - beingCancelled = false; - } - - object = o; - -#ifdef QDND_DEBUG - qDebug("actions = %s", dragActionsToString(dragPrivate()->possible_actions).toLatin1().data()); -#endif - - dragPrivate()->target = 0; - -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::DragDropStart); -#endif - - DWORD resultEffect; - QOleDropSource *src = new QOleDropSource(); - src->createCursors(); - QOleDataObject *obj = new QOleDataObject(o->mimeData()); - DWORD allowedEffects = translateToWinDragEffects(dragPrivate()->possible_actions); - -#if !defined(Q_OS_WINCE) || defined(GWES_ICONCURS) - HRESULT r = DoDragDrop(obj, src, allowedEffects, &resultEffect); -#else - HRESULT r = DRAGDROP_S_CANCEL; - resultEffect = DROPEFFECT_MOVE; -#endif - - Qt::DropAction ret = Qt::IgnoreAction; - if (r == DRAGDROP_S_DROP) { - if (obj->reportedPerformedEffect() == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) { - ret = Qt::TargetMoveAction; - resultEffect = DROPEFFECT_MOVE; - } else { - ret = translateToQDragDropAction(resultEffect); - } - // Force it to be a copy if an unsupported operation occurred. - // This indicates a bug in the drop target. - if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects)) - ret = Qt::CopyAction; - } else { - dragPrivate()->target = 0; - } - - // clean up - obj->releaseQt(); - obj->Release(); // Will delete obj if refcount becomes 0 - src->Release(); // Will delete src if refcount becomes 0 - object = 0; - o->setMimeData(0); - o->deleteLater(); - -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::DragDropEnd); -#endif - - return ret; -} - -void QDragManager::cancel(bool /* deleteSource */) -{ - if (object) { - beingCancelled = true; - object = 0; - } - -#ifndef QT_NO_CURSOR - // insert cancel code here ######## todo - - if (restoreCursor) { - QApplication::restoreOverrideCursor(); - restoreCursor = false; - } -#endif -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::DragDropEnd); -#endif -} - -void QDragManager::updatePixmap() -{ - // not used in windows implementation -} - -bool QDragManager::eventFilter(QObject *, QEvent *) -{ - // not used in windows implementation - return false; -} - -void QDragManager::timerEvent(QTimerEvent*) -{ - // not used in windows implementation -} - -void QDragManager::move(const QPoint &) -{ - // not used in windows implementation -} - -void QDragManager::drop() -{ - // not used in windows implementation -} - -QT_END_NAMESPACE - -#endif // QT_NO_DRAGANDDROP diff --git a/src/gui/platforms/win/qfont_win.cpp b/src/gui/platforms/win/qfont_win.cpp deleted file mode 100644 index 3ef761bfa5..0000000000 --- a/src/gui/platforms/win/qfont_win.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qfont.h" -#include "qfont_p.h" -#include "qfontengine_p.h" -#include "qtextengine_p.h" -#include "qfontmetrics.h" -#include "qfontinfo.h" - -#include "qwidget.h" -#include "qpainter.h" -#include <limits.h> -#include "qt_windows.h" -#include <private/qapplication_p.h> -#include "qapplication.h" -#include <private/qunicodetables_p.h> -#include <qfontdatabase.h> - -QT_BEGIN_NAMESPACE - -extern HDC shared_dc(); // common dc for all fonts -extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp - -// ### maybe move to qapplication_win -QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/) -{ - QString family = QString::fromWCharArray(lf.lfFaceName); - QFont qf(family); - qf.setItalic(lf.lfItalic); - if (lf.lfWeight != FW_DONTCARE) - qf.setWeight(weightFromInteger(lf.lfWeight)); - int lfh = qAbs(lf.lfHeight); - qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY)); - qf.setUnderline(false); - qf.setOverline(false); - qf.setStrikeOut(false); - return qf; -} - - -static inline float pixelSize(const QFontDef &request, int dpi) -{ - float pSize; - if (request.pointSize != -1) - pSize = request.pointSize * dpi/ 72.; - else - pSize = request.pixelSize; - return pSize; -} - -static inline float pointSize(const QFontDef &fd, int dpi) -{ - float pSize; - if (fd.pointSize < 0) - pSize = fd.pixelSize * 72. / ((float)dpi); - else - pSize = fd.pointSize; - return pSize; -} - -/***************************************************************************** - QFont member functions - *****************************************************************************/ - -void QFont::initialize() -{ -} - -void QFont::cleanup() -{ - QFontCache::cleanup(); -} - -HFONT QFont::handle() const -{ - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); - Q_ASSERT(engine != 0); - if (engine->type() == QFontEngine::Multi) - engine = static_cast<QFontEngineMulti *>(engine)->engine(0); - if (engine->type() == QFontEngine::Win) - return static_cast<QFontEngineWin *>(engine)->hfont; - return 0; -} - -QString QFont::rawName() const -{ - return family(); -} - -void QFont::setRawName(const QString &name) -{ - setFamily(name); -} - -QString QFont::defaultFamily() const -{ - switch(d->request.styleHint) { - case QFont::Times: - return QString::fromLatin1("Times New Roman"); - case QFont::Courier: - case QFont::Monospace: - return QString::fromLatin1("Courier New"); - case QFont::Decorative: - return QString::fromLatin1("Bookman Old Style"); - case QFont::Cursive: - return QString::fromLatin1("Comic Sans MS"); - case QFont::Fantasy: - return QString::fromLatin1("Impact"); - case QFont::Helvetica: - return QString::fromLatin1("Arial"); - case QFont::System: - default: - return QString::fromLatin1("MS Sans Serif"); - } -} - -QString QFont::lastResortFamily() const -{ - return QString::fromLatin1("helvetica"); -} - -QString QFont::lastResortFont() const -{ - return QString::fromLatin1("arial"); -} - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qfontdatabase_win.cpp b/src/gui/platforms/win/qfontdatabase_win.cpp deleted file mode 100644 index 05b7509bf6..0000000000 --- a/src/gui/platforms/win/qfontdatabase_win.cpp +++ /dev/null @@ -1,1348 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qt_windows.h" -#include <qmath.h> -#include <private/qapplication_p.h> -#include "qfont_p.h" -#include "qfontengine_p.h" -#include "qpaintdevice.h" -#include <private/qsystemlibrary_p.h> -#include "qabstractfileengine.h" -#include "qendian.h" - -#if !defined(QT_NO_DIRECTWRITE) -# include "qsettings.h" -# include "qfontenginedirectwrite_p.h" -#endif - -#ifdef Q_OS_WINCE -# include <QTemporaryFile> -#endif - -QT_BEGIN_NAMESPACE - -extern HDC shared_dc(); // common dc for all fonts - -#ifdef MAKE_TAG -#undef MAKE_TAG -#endif -// GetFontData expects the tags in little endian ;( -#define MAKE_TAG(ch1, ch2, ch3, ch4) (\ - (((quint32)(ch4)) << 24) | \ - (((quint32)(ch3)) << 16) | \ - (((quint32)(ch2)) << 8) | \ - ((quint32)(ch1)) \ - ) - -static HFONT stock_sysfont = 0; - -static bool localizedName(const QString &name) -{ - const QChar *c = name.unicode(); - for(int i = 0; i < name.length(); ++i) { - if(c[i].unicode() >= 0x100) - return true; - } - return false; -} - -static inline quint16 getUShort(const unsigned char *p) -{ - quint16 val; - val = *p++ << 8; - val |= *p; - - return val; -} - -static QString getEnglishName(const uchar *table, quint32 bytes) -{ - QString i18n_name; - enum { - NameRecordSize = 12, - FamilyId = 1, - MS_LangIdEnglish = 0x009 - }; - - // get the name table - quint16 count; - quint16 string_offset; - const unsigned char *names; - - int microsoft_id = -1; - int apple_id = -1; - int unicode_id = -1; - - if(getUShort(table) != 0) - goto error; - - count = getUShort(table+2); - string_offset = getUShort(table+4); - names = table + 6; - - if(string_offset >= bytes || 6 + count*NameRecordSize > string_offset) - goto error; - - for(int i = 0; i < count; ++i) { - // search for the correct name entry - - quint16 platform_id = getUShort(names + i*NameRecordSize); - quint16 encoding_id = getUShort(names + 2 + i*NameRecordSize); - quint16 language_id = getUShort(names + 4 + i*NameRecordSize); - quint16 name_id = getUShort(names + 6 + i*NameRecordSize); - - if(name_id != FamilyId) - continue; - - enum { - PlatformId_Unicode = 0, - PlatformId_Apple = 1, - PlatformId_Microsoft = 3 - }; - - quint16 length = getUShort(names + 8 + i*NameRecordSize); - quint16 offset = getUShort(names + 10 + i*NameRecordSize); - if(DWORD(string_offset + offset + length) >= bytes) - continue; - - if ((platform_id == PlatformId_Microsoft - && (encoding_id == 0 || encoding_id == 1)) - && (language_id & 0x3ff) == MS_LangIdEnglish - && microsoft_id == -1) - microsoft_id = i; - // not sure if encoding id 4 for Unicode is utf16 or ucs4... - else if(platform_id == PlatformId_Unicode && encoding_id < 4 && unicode_id == -1) - unicode_id = i; - else if(platform_id == PlatformId_Apple && encoding_id == 0 && language_id == 0) - apple_id = i; - } - { - bool unicode = false; - int id = -1; - if(microsoft_id != -1) { - id = microsoft_id; - unicode = true; - } else if(apple_id != -1) { - id = apple_id; - unicode = false; - } else if (unicode_id != -1) { - id = unicode_id; - unicode = true; - } - if(id != -1) { - quint16 length = getUShort(names + 8 + id*NameRecordSize); - quint16 offset = getUShort(names + 10 + id*NameRecordSize); - if(unicode) { - // utf16 - - length /= 2; - i18n_name.resize(length); - QChar *uc = (QChar *) i18n_name.unicode(); - const unsigned char *string = table + string_offset + offset; - for(int i = 0; i < length; ++i) - uc[i] = getUShort(string + 2*i); - } else { - // Apple Roman - - i18n_name.resize(length); - QChar *uc = (QChar *) i18n_name.unicode(); - const unsigned char *string = table + string_offset + offset; - for(int i = 0; i < length; ++i) - uc[i] = QLatin1Char(string[i]); - } - } - } - error: - //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data()); - return i18n_name; -} - -static QString getEnglishName(const QString &familyName) -{ - QString i18n_name; - - HDC hdc = GetDC( 0 ); - LOGFONT lf; - memset(&lf, 0, sizeof(LOGFONT)); - memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t)); - lf.lfCharSet = DEFAULT_CHARSET; - HFONT hfont = CreateFontIndirect(&lf); - - if(!hfont) { - ReleaseDC(0, hdc); - return QString(); - } - - HGDIOBJ oldobj = SelectObject( hdc, hfont ); - - const DWORD name_tag = MAKE_TAG( 'n', 'a', 'm', 'e' ); - - // get the name table - unsigned char *table = 0; - - DWORD bytes = GetFontData( hdc, name_tag, 0, 0, 0 ); - if ( bytes == GDI_ERROR ) { - // ### Unused variable - /* int err = GetLastError(); */ - goto error; - } - - table = new unsigned char[bytes]; - GetFontData(hdc, name_tag, 0, table, bytes); - if ( bytes == GDI_ERROR ) - goto error; - - i18n_name = getEnglishName(table, bytes); -error: - delete [] table; - SelectObject( hdc, oldobj ); - DeleteObject( hfont ); - ReleaseDC( 0, hdc ); - - //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data()); - return i18n_name; -} - -extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp - -static -void addFontToDatabase(QString familyName, const QString &scriptName, - TEXTMETRIC *textmetric, - const FONTSIGNATURE *signature, - int type) -{ - const int script = -1; - const QString foundryName; - Q_UNUSED(script); - - bool italic = false; - int weight; - bool fixed; - bool ttf; - bool scalable; - int size; - -// QString escript = QString::fromWCharArray(f->elfScript); -// qDebug("script=%s", escript.latin1()); - - NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - italic = tm->tmItalic; - weight = tm->tmWeight; - - // the "@family" fonts are just the same as "family". Ignore them. - if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) { - QtFontStyle::Key styleKey; - styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal; - styleKey.weight = weightFromInteger(weight); - - QtFontFamily *family = privateDb()->family(familyName, true); - - if(ttf && localizedName(familyName) && family->english_name.isEmpty()) - family->english_name = getEnglishName(familyName); - - QtFontFoundry *foundry = family->foundry(foundryName, true); - QtFontStyle *style = foundry->style(styleKey, true); - style->smoothScalable = scalable; - style->pixelSize( size, TRUE); - - // add fonts windows can generate for us: - if (styleKey.weight <= QFont::DemiBold) { - QtFontStyle::Key key(styleKey); - key.weight = QFont::Bold; - QtFontStyle *style = foundry->style(key, true); - style->smoothScalable = scalable; - style->pixelSize( size, TRUE); - } - if (styleKey.style != QFont::StyleItalic) { - QtFontStyle::Key key(styleKey); - key.style = QFont::StyleItalic; - QtFontStyle *style = foundry->style(key, true); - style->smoothScalable = scalable; - style->pixelSize( size, TRUE); - } - if (styleKey.weight <= QFont::DemiBold && styleKey.style != QFont::StyleItalic) { - QtFontStyle::Key key(styleKey); - key.weight = QFont::Bold; - key.style = QFont::StyleItalic; - QtFontStyle *style = foundry->style(key, true); - style->smoothScalable = scalable; - style->pixelSize( size, TRUE); - } - - family->fixedPitch = fixed; - - if (!family->writingSystemCheck && type & TRUETYPE_FONTTYPE) { - quint32 unicodeRange[4] = { - signature->fsUsb[0], signature->fsUsb[1], - signature->fsUsb[2], signature->fsUsb[3] - }; -#ifdef Q_WS_WINCE - if (signature->fsUsb[0] == 0) { - // If the unicode ranges bit mask is zero then - // EnumFontFamiliesEx failed to determine it properly. - // In this case we just pretend that the font supports all languages. - unicodeRange[0] = 0xbfffffff; // second most significant bit must be zero - unicodeRange[1] = 0xffffffff; - unicodeRange[2] = 0xffffffff; - unicodeRange[3] = 0xffffffff; - } -#endif - quint32 codePageRange[2] = { - signature->fsCsb[0], signature->fsCsb[1] - }; - QList<QFontDatabase::WritingSystem> systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); - - for (int i = 0; i < systems.count(); ++i) { - QFontDatabase::WritingSystem writingSystem = systems.at(i); - - // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains - // the symbol for Baht, and Windows thus reports that it supports the Thai script. - // Since it's the default UI font on this platform, most widgets will be unable to - // display Thai text by default. As a temporary work around, we special case Segoe UI - // and remove the Thai script from its list of supported writing systems. - if (writingSystem != QFontDatabase::Thai || familyName != QLatin1String("Segoe UI")) - family->writingSystems[writingSystem] = QtFontFamily::Supported; - } - } else if (!family->writingSystemCheck) { - //qDebug("family='%s' script=%s", family->name.latin1(), script.latin1()); - if (scriptName == QLatin1String("Western") - || scriptName == QLatin1String("Baltic") - || scriptName == QLatin1String("Central European") - || scriptName == QLatin1String("Turkish") - || scriptName == QLatin1String("Vietnamese")) - family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Thai")) - family->writingSystems[QFontDatabase::Thai] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Symbol") - || scriptName == QLatin1String("Other")) - family->writingSystems[QFontDatabase::Symbol] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("OEM/Dos")) - family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("CHINESE_GB2312")) - family->writingSystems[QFontDatabase::SimplifiedChinese] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("CHINESE_BIG5")) - family->writingSystems[QFontDatabase::TraditionalChinese] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Cyrillic")) - family->writingSystems[QFontDatabase::Cyrillic] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Hangul")) - family->writingSystems[QFontDatabase::Korean] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Hebrew")) - family->writingSystems[QFontDatabase::Hebrew] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Greek")) - family->writingSystems[QFontDatabase::Greek] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Japanese")) - family->writingSystems[QFontDatabase::Japanese] = QtFontFamily::Supported; - else if (scriptName == QLatin1String("Arabic")) - family->writingSystems[QFontDatabase::Arabic] = QtFontFamily::Supported; - } - } -} - -static -int CALLBACK -storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, int type, LPARAM /*p*/) -{ - QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName); - QString script = QString::fromWCharArray(f->elfScript); - - FONTSIGNATURE signature = textmetric->ntmFontSig; - - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is - // identical to a TEXTMETRIC except for the last four members, which we don't use - // anyway - addFontToDatabase(familyName, script, (TEXTMETRIC *)textmetric, &signature, type); - // keep on enumerating - return 1; -} - -static -void populate_database(const QString& fam) -{ - QFontDatabasePrivate *d = privateDb(); - if (!d) - return; - - QtFontFamily *family = 0; - if(!fam.isEmpty()) { - family = d->family(fam); - if(family && family->loaded) - return; - } else if (d->count) { - return; - } - - HDC dummy = GetDC(0); - - LOGFONT lf; - lf.lfCharSet = DEFAULT_CHARSET; - if (fam.isNull()) { - lf.lfFaceName[0] = 0; - } else { - memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded - } - lf.lfPitchAndFamily = 0; - - EnumFontFamiliesEx(dummy, &lf, - (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0); - - ReleaseDC(0, dummy); - - for (int i = 0; i < d->applicationFonts.count(); ++i) { - QFontDatabasePrivate::ApplicationFont fnt = d->applicationFonts.at(i); - if (!fnt.memoryFont) - continue; - for (int j = 0; j < fnt.families.count(); ++j) { - const QString familyName = fnt.families.at(j); - HDC hdc = GetDC(0); - LOGFONT lf; - memset(&lf, 0, sizeof(LOGFONT)); - memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size())); - lf.lfCharSet = DEFAULT_CHARSET; - HFONT hfont = CreateFontIndirect(&lf); - HGDIOBJ oldobj = SelectObject(hdc, hfont); - - TEXTMETRIC textMetrics; - GetTextMetrics(hdc, &textMetrics); - - addFontToDatabase(familyName, QString(), - &textMetrics, - &fnt.signatures.at(j), - TRUETYPE_FONTTYPE); - - SelectObject(hdc, oldobj); - DeleteObject(hfont); - ReleaseDC(0, hdc); - } - } - - if(!fam.isEmpty()) { - family = d->family(fam); - if(family) { - if(!family->writingSystemCheck) { - } - family->loaded = true; - } - } -} - -static void initializeDb() -{ - QFontDatabasePrivate *db = privateDb(); - if (!db || db->count) - return; - - populate_database(QString()); - -#ifdef QFONTDATABASE_DEBUG - // print the database - for (int f = 0; f < db->count; f++) { - QtFontFamily *family = db->families[f]; - qDebug(" %s: %p", qPrintable(family->name), family); - populate_database(family->name); - -#if 0 - qDebug(" scripts supported:"); - for (int i = 0; i < QUnicodeTables::ScriptCount; i++) - if(family->writingSystems[i] & QtFontFamily::Supported) - qDebug(" %d", i); - for (int fd = 0; fd < family->count; fd++) { - QtFontFoundry *foundry = family->foundries[fd]; - qDebug(" %s", foundry->name.latin1()); - for (int s = 0; s < foundry->count; s++) { - QtFontStyle *style = foundry->styles[s]; - qDebug(" style: style=%d weight=%d smooth=%d", style->key.style, - style->key.weight, style->smoothScalable ); - if(!style->smoothScalable) { - for(int i = 0; i < style->count; ++i) { - qDebug(" %d", style->pixelSizes[i].pixelSize); - } - } - } - } -#endif - } -#endif // QFONTDATABASE_DEBUG - -} - -static inline void load(const QString &family = QString(), int = -1) -{ - populate_database(family); -} - - - - - -// -------------------------------------------------------------------------------------- -// font loader -// -------------------------------------------------------------------------------------- - - - -static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, HDC fontHdc, int dpi) -{ - fe->fontDef = request; // most settings are equal - - HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fontHdc) ? fontHdc : shared_dc(); - SelectObject(dc, fe->hfont); - wchar_t n[64]; - GetTextFace(dc, 64, n); - fe->fontDef.family = QString::fromWCharArray(n); - fe->fontDef.fixedPitch = !(fe->tm.tmPitchAndFamily & TMPF_FIXED_PITCH); - if (fe->fontDef.pointSize < 0) { - fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi; - } else if (fe->fontDef.pixelSize == -1) { - fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.); - } -} - -#if !defined(QT_NO_DIRECTWRITE) -static void initFontInfo(QFontEngineDirectWrite *fe, const QFontDef &request, - int dpi, IDWriteFont *font) -{ - fe->fontDef = request; - - IDWriteFontFamily *fontFamily = NULL; - HRESULT hr = font->GetFontFamily(&fontFamily); - - IDWriteLocalizedStrings *familyNames = NULL; - if (SUCCEEDED(hr)) - hr = fontFamily->GetFamilyNames(&familyNames); - - UINT32 index = 0; - BOOL exists = false; - - wchar_t localeName[LOCALE_NAME_MAX_LENGTH]; - - if (SUCCEEDED(hr)) { - int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH); - - if (defaultLocaleSuccess) - hr = familyNames->FindLocaleName(localeName, &index, &exists); - - if (SUCCEEDED(hr) && !exists) - hr = familyNames->FindLocaleName(L"en-us", &index, &exists); - } - - if (!exists) - index = 0; - - UINT32 length = 0; - if (SUCCEEDED(hr)) - hr = familyNames->GetStringLength(index, &length); - - wchar_t *name = new (std::nothrow) wchar_t[length+1]; - if (name == NULL) - hr = E_OUTOFMEMORY; - - // Get the family name. - if (SUCCEEDED(hr)) - hr = familyNames->GetString(index, name, length + 1); - - if (SUCCEEDED(hr)) - fe->fontDef.family = QString::fromWCharArray(name); - - delete[] name; - if (familyNames != NULL) - familyNames->Release(); - - if (FAILED(hr)) - qErrnoWarning(hr, "initFontInfo: Failed to get family name"); - - if (fe->fontDef.pointSize < 0) - fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi; - else if (fe->fontDef.pixelSize == -1) - fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.); -} -#endif - -static const char *other_tryFonts[] = { - "Arial", - "MS UI Gothic", - "Gulim", - "SimSun", - "PMingLiU", - "Arial Unicode MS", - 0 -}; - -static const char *jp_tryFonts [] = { - "MS UI Gothic", - "Arial", - "Gulim", - "SimSun", - "PMingLiU", - "Arial Unicode MS", - 0 -}; - -static const char *ch_CN_tryFonts [] = { - "SimSun", - "Arial", - "PMingLiU", - "Gulim", - "MS UI Gothic", - "Arial Unicode MS", - 0 -}; - -static const char *ch_TW_tryFonts [] = { - "PMingLiU", - "Arial", - "SimSun", - "Gulim", - "MS UI Gothic", - "Arial Unicode MS", - 0 -}; - -static const char *kr_tryFonts[] = { - "Gulim", - "Arial", - "PMingLiU", - "SimSun", - "MS UI Gothic", - "Arial Unicode MS", - 0 -}; - -static const char **tryFonts = 0; - -#if !defined(QT_NO_DIRECTWRITE) -static QString fontNameSubstitute(const QString &familyName) -{ - QLatin1String key("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\" - "FontSubstitutes"); - return QSettings(key, QSettings::NativeFormat).value(familyName, familyName).toString(); -} -#endif - -static inline HFONT systemFont() -{ - if (stock_sysfont == 0) - stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT); - return stock_sysfont; -} - -#if !defined(DEFAULT_GUI_FONT) -#define DEFAULT_GUI_FONT 17 -#endif - -static QFontEngine *loadEngine(int script, const QFontDef &request, - HDC fontHdc, int dpi, bool rawMode, - const QtFontDesc *desc, - const QStringList &family_list) -{ - LOGFONT lf; - memset(&lf, 0, sizeof(LOGFONT)); - - bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc; - - HDC hdc = shared_dc(); - QString font_name = desc != 0 ? desc->family->name : request.family; - - if (useDevice) { - hdc = fontHdc; - font_name = request.family; - } - - bool stockFont = false; - bool preferClearTypeAA = false; - - HFONT hfont = 0; - - -#if !defined(QT_NO_DIRECTWRITE) - bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting) - || (request.hintingPreference == QFont::PreferVerticalHinting); - IDWriteFont *directWriteFont = 0; -#else - bool useDirectWrite = false; -#endif - - if (rawMode) { // will choose a stock font - int f, deffnt = SYSTEM_FONT; - QString fam = desc != 0 ? desc->family->name.toLower() : request.family.toLower(); - if (fam == QLatin1String("default")) - f = deffnt; - else if (fam == QLatin1String("system")) - f = SYSTEM_FONT; -#ifndef Q_WS_WINCE - else if (fam == QLatin1String("system_fixed")) - f = SYSTEM_FIXED_FONT; - else if (fam == QLatin1String("ansi_fixed")) - f = ANSI_FIXED_FONT; - else if (fam == QLatin1String("ansi_var")) - f = ANSI_VAR_FONT; - else if (fam == QLatin1String("device_default")) - f = DEVICE_DEFAULT_FONT; - else if (fam == QLatin1String("oem_fixed")) - f = OEM_FIXED_FONT; -#endif - else if (fam[0] == QLatin1Char('#')) - f = fam.right(fam.length()-1).toInt(); - else - f = deffnt; - hfont = (HFONT)GetStockObject(f); - if (!hfont) { - qErrnoWarning("QFontEngine::loadEngine: GetStockObject failed"); - hfont = systemFont(); - } - stockFont = true; - } else { - - int hint = FF_DONTCARE; - switch (request.styleHint) { - case QFont::Helvetica: - hint = FF_SWISS; - break; - case QFont::Times: - hint = FF_ROMAN; - break; - case QFont::Courier: - hint = FF_MODERN; - break; - case QFont::OldEnglish: - hint = FF_DECORATIVE; - break; - case QFont::System: - hint = FF_MODERN; - break; - default: - break; - } - - lf.lfHeight = -qRound(request.pixelSize); - lf.lfWidth = 0; - lf.lfEscapement = 0; - lf.lfOrientation = 0; - if (desc == 0 || desc->style->key.weight == 50) - lf.lfWeight = FW_DONTCARE; - else - lf.lfWeight = (desc->style->key.weight*900)/99; - lf.lfItalic = (desc != 0 && desc->style->key.style != QFont::StyleNormal); - lf.lfCharSet = DEFAULT_CHARSET; - - int strat = OUT_DEFAULT_PRECIS; - if (request.styleStrategy & QFont::PreferBitmap) { - strat = OUT_RASTER_PRECIS; -#ifndef Q_WS_WINCE - } else if (request.styleStrategy & QFont::PreferDevice) { - strat = OUT_DEVICE_PRECIS; - } else if (request.styleStrategy & QFont::PreferOutline) { - strat = OUT_OUTLINE_PRECIS; - } else if (request.styleStrategy & QFont::ForceOutline) { - strat = OUT_TT_ONLY_PRECIS; -#endif - } - - lf.lfOutPrecision = strat; - - int qual = DEFAULT_QUALITY; - - if (request.styleStrategy & QFont::PreferMatch) - qual = DRAFT_QUALITY; -#ifndef Q_WS_WINCE - else if (request.styleStrategy & QFont::PreferQuality) - qual = PROOF_QUALITY; -#endif - - if (request.styleStrategy & QFont::PreferAntialias) { - if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) { - qual = CLEARTYPE_QUALITY; - preferClearTypeAA = true; - } else { - qual = ANTIALIASED_QUALITY; - } - } else if (request.styleStrategy & QFont::NoAntialias) { - qual = NONANTIALIASED_QUALITY; - } - - lf.lfQuality = qual; - - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfPitchAndFamily = DEFAULT_PITCH | hint; - - QString fam = font_name; - - if(fam.isEmpty()) - fam = QLatin1String("MS Sans Serif"); - - if ((fam == QLatin1String("MS Sans Serif")) - && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) { - fam = QLatin1String("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale - } - if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap)) - fam = QLatin1String("Courier New"); - - memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded - - hfont = CreateFontIndirect(&lf); - if (!hfont) - qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect failed"); - - stockFont = (hfont == 0); - bool ttf = false; - int avWidth = 0; - BOOL res; - HGDIOBJ oldObj = SelectObject(hdc, hfont); - - TEXTMETRIC tm; - res = GetTextMetrics(hdc, &tm); - avWidth = tm.tmAveCharWidth; - ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; - SelectObject(hdc, oldObj); - - if (!ttf || !useDirectWrite) { - useDirectWrite = false; - - if (hfont && (!ttf || request.stretch != 100)) { - DeleteObject(hfont); - if (!res) - qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed"); - lf.lfWidth = avWidth * request.stretch/100; - hfont = CreateFontIndirect(&lf); - if (!hfont) - qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed"); - } - -#ifndef Q_WS_WINCE - if (hfont == 0) { - hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); - stockFont = true; - } -#else - if (hfont == 0) { - hfont = (HFONT)GetStockObject(SYSTEM_FONT); - stockFont = true; - } -#endif - - } - -#if !defined(QT_NO_DIRECTWRITE) - else { - // Default to false for DirectWrite (and re-enable once/if everything - // turns out okay) - useDirectWrite = false; - - QFontDatabasePrivate *db = privateDb(); - if (db->directWriteFactory == 0) { - HRESULT hr = DWriteCreateFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast<IUnknown **>(&db->directWriteFactory) - ); - if (FAILED(hr)) { - qErrnoWarning("QFontEngine::loadEngine: DWriteCreateFactory failed"); - } else { - hr = db->directWriteFactory->GetGdiInterop(&db->directWriteGdiInterop); - if (FAILED(hr)) - qErrnoWarning("QFontEngine::loadEngine: GetGdiInterop failed"); - } - } - - if (db->directWriteGdiInterop != 0) { - QString nameSubstitute = fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName)); - memcpy(lf.lfFaceName, nameSubstitute.utf16(), - sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE)); - - HRESULT hr = db->directWriteGdiInterop->CreateFontFromLOGFONT( - &lf, - &directWriteFont); - if (FAILED(hr)) { -#ifndef QT_NO_DEBUG - qErrnoWarning("QFontEngine::loadEngine: CreateFontFromLOGFONT failed " - "for %ls (0x%lx)", - lf.lfFaceName, hr); -#endif - } else { - DeleteObject(hfont); - useDirectWrite = true; - } - } - } -#endif - - } - - QFontEngine *fe = 0; - if (!useDirectWrite) { - QFontEngineWin *few = new QFontEngineWin(font_name, hfont, stockFont, lf); - if (preferClearTypeAA) - few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask; - - // Also check for OpenType tables when using complex scripts - // ### TODO: This only works for scripts that require OpenType. More generally - // for scripts that do not require OpenType we should just look at the list of - // supported writing systems in the font's OS/2 table. - if (scriptRequiresOpenType(script)) { - HB_Face hbFace = few->harfbuzzFace(); - if (!hbFace || !hbFace->supported_scripts[script]) { - FM_DEBUG(" OpenType support missing for script\n"); - delete few; - return 0; - } - } - - initFontInfo(few, request, fontHdc, dpi); - fe = few; - } - -#if !defined(QT_NO_DIRECTWRITE) - else { - QFontDatabasePrivate *db = privateDb(); - - IDWriteFontFace *directWriteFontFace = NULL; - HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace); - if (SUCCEEDED(hr)) { - QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(db->directWriteFactory, - directWriteFontFace, - request.pixelSize); - - initFontInfo(fedw, request, dpi, directWriteFont); - - fe = fedw; - } else { - qErrnoWarning(hr, "QFontEngine::loadEngine: CreateFontFace failed"); - } - } - - if (directWriteFont != 0) - directWriteFont->Release(); -#endif - - if(script == QUnicodeTables::Common - && !(request.styleStrategy & QFont::NoFontMerging) - && desc != 0 - && !(desc->family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) { - if(!tryFonts) { - LANGID lid = GetUserDefaultLangID(); - switch( lid&0xff ) { - case LANG_CHINESE: // Chinese (Taiwan) - if ( lid == 0x0804 ) // Taiwan - tryFonts = ch_TW_tryFonts; - else - tryFonts = ch_CN_tryFonts; - break; - case LANG_JAPANESE: - tryFonts = jp_tryFonts; - break; - case LANG_KOREAN: - tryFonts = kr_tryFonts; - break; - default: - tryFonts = other_tryFonts; - break; - } - } - QStringList fm = QFontDatabase().families(); - QStringList list = family_list; - const char **tf = tryFonts; - while(tf && *tf) { - if(fm.contains(QLatin1String(*tf))) - list << QLatin1String(*tf); - ++tf; - } - QFontEngine *mfe = new QFontEngineMultiWin(fe, list); - mfe->fontDef = fe->fontDef; - fe = mfe; - } - return fe; -} - -QFontEngine *qt_load_font_engine_win(const QFontDef &request) -{ - // From qfont.cpp - extern int qt_defaultDpi(); - - QFontCache::Key key(request, QUnicodeTables::Common); - QFontEngine *fe = QFontCache::instance()->findEngine(key); - if (fe != 0) - return fe; - else - return loadEngine(QUnicodeTables::Common, request, 0, qt_defaultDpi(), false, 0, - QStringList()); -} - -const char *styleHint(const QFontDef &request) -{ - const char *stylehint = 0; - switch (request.styleHint) { - case QFont::SansSerif: - stylehint = "Arial"; - break; - case QFont::Serif: - stylehint = "Times New Roman"; - break; - case QFont::TypeWriter: - stylehint = "Courier New"; - break; - default: - if (request.fixedPitch) - stylehint = "Courier New"; - break; - } - return stylehint; -} - -static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &req) -{ - // list of families to try - QStringList family_list = familyList(req); - - const char *stylehint = styleHint(d->request); - if (stylehint) - family_list << QLatin1String(stylehint); - - // append the default fallback font for the specified script - // family_list << ... ; ########### - - // add the default family - QString defaultFamily = QApplication::font().family(); - if (! family_list.contains(defaultFamily)) - family_list << defaultFamily; - - // add QFont::defaultFamily() to the list, for compatibility with - // previous versions - family_list << QApplication::font().defaultFamily(); - - // null family means find the first font matching the specified script - family_list << QString(); - - QtFontDesc desc; - QFontEngine *fe = 0; - QList<int> blacklistedFamilies; - - while (!fe) { - for (int i = 0; i < family_list.size(); ++i) { - QString family, foundry; - parseFontName(family_list.at(i), foundry, family); - FM_DEBUG("loadWin: >>>>>>>>>>>>>>trying to match '%s'", family.toLatin1().data()); - QT_PREPEND_NAMESPACE(match)(script, req, family, foundry, -1, &desc, blacklistedFamilies); - if (desc.family) - break; - } - if (!desc.family) - break; - fe = loadEngine(script, req, d->hdc, d->dpi, d->rawMode, &desc, family_list); - if (!fe) - blacklistedFamilies.append(desc.familyIndex); - } - return fe; -} - -void QFontDatabase::load(const QFontPrivate *d, int script) -{ - // sanity checks - if (!qApp) - qWarning("QFontDatabase::load: Must construct QApplication first"); - Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount); - - // normalize the request to get better caching - QFontDef req = d->request; - if (req.pixelSize <= 0) - req.pixelSize = floor((100.0 * req.pointSize * d->dpi) / 72. + 0.5) / 100; - if (req.pixelSize < 1) - req.pixelSize = 1; - if (req.weight == 0) - req.weight = QFont::Normal; - if (req.stretch == 0) - req.stretch = 100; - - QFontCache::Key key(req, d->rawMode ? QUnicodeTables::Common : script, d->screen); - if (!d->engineData) - getEngineData(d, key); - - // the cached engineData could have already loaded the engine we want - if (d->engineData->engines[script]) - return; - - QFontEngine *fe = QFontCache::instance()->findEngine(key); - - // set it to the actual pointsize, so QFontInfo will do the right thing - if (req.pointSize < 0) - req.pointSize = req.pixelSize*72./d->dpi; - - if (!fe) { - if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) { - fe = new QTestFontEngine(req.pixelSize); - fe->fontDef = req; - } else { - QMutexLocker locker(fontDatabaseMutex()); - if (!privateDb()->count) - initializeDb(); - fe = loadWin(d, script, req); - } - if (!fe) { - fe = new QFontEngineBox(req.pixelSize); - fe->fontDef = QFontDef(); - } - } - d->engineData->engines[script] = fe; - fe->ref.ref(); - QFontCache::instance()->insertEngine(key, fe); -} - -#if !defined(FR_PRIVATE) -#define FR_PRIVATE 0x10 -#endif - -typedef int (WINAPI *PtrAddFontResourceExW)(LPCWSTR, DWORD, PVOID); -typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *); -typedef BOOL (WINAPI *PtrRemoveFontResourceExW)(LPCWSTR, DWORD, PVOID); -typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE); - -static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData) -{ - QList<quint32> offsets; - const quint32 headerTag = *reinterpret_cast<const quint32 *>(fontData); - if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) { - if (headerTag != MAKE_TAG(0, 1, 0, 0) - && headerTag != MAKE_TAG('O', 'T', 'T', 'O') - && headerTag != MAKE_TAG('t', 'r', 'u', 'e') - && headerTag != MAKE_TAG('t', 'y', 'p', '1')) - return offsets; - offsets << 0; - return offsets; - } - const quint32 numFonts = qFromBigEndian<quint32>(fontData + 8); - for (uint i = 0; i < numFonts; ++i) { - offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4); - } - return offsets; -} - -static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length) -{ - const quint16 numTables = qFromBigEndian<quint16>(data + 4); - for (uint i = 0; i < numTables; ++i) { - const quint32 offset = 12 + 16 * i; - if (*reinterpret_cast<const quint32 *>(data + offset) == tag) { - *table = fileBegin + qFromBigEndian<quint32>(data + offset + 8); - *length = qFromBigEndian<quint32>(data + offset + 12); - return; - } - } - *table = 0; - *length = 0; - return; -} - -static void getFamiliesAndSignatures(const QByteArray &fontData, QFontDatabasePrivate::ApplicationFont *appFont) -{ - const uchar *data = reinterpret_cast<const uchar *>(fontData.constData()); - - QList<quint32> offsets = getTrueTypeFontOffsets(data); - if (offsets.isEmpty()) - return; - - for (int i = 0; i < offsets.count(); ++i) { - const uchar *font = data + offsets.at(i); - const uchar *table; - quint32 length; - getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length); - if (!table) - continue; - QString name = getEnglishName(table, length); - if (name.isEmpty()) - continue; - - appFont->families << name; - FONTSIGNATURE signature; - getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); - if (table && length >= 86) { - // See also qfontdatabase_mac.cpp, offsets taken from OS/2 table in the TrueType spec - signature.fsUsb[0] = qFromBigEndian<quint32>(table + 42); - signature.fsUsb[1] = qFromBigEndian<quint32>(table + 46); - signature.fsUsb[2] = qFromBigEndian<quint32>(table + 50); - signature.fsUsb[3] = qFromBigEndian<quint32>(table + 54); - - signature.fsCsb[0] = qFromBigEndian<quint32>(table + 78); - signature.fsCsb[1] = qFromBigEndian<quint32>(table + 82); - } else { - memset(&signature, 0, sizeof(signature)); - } - appFont->signatures << signature; - } -} - -static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) -{ - if(!fnt->data.isEmpty()) { -#ifndef Q_OS_WINCE - PtrAddFontMemResourceEx ptrAddFontMemResourceEx = (PtrAddFontMemResourceEx)QSystemLibrary::resolve(QLatin1String("gdi32"), - "AddFontMemResourceEx"); - if (!ptrAddFontMemResourceEx) - return; -#endif - getFamiliesAndSignatures(fnt->data, fnt); - if (fnt->families.isEmpty()) - return; - -#ifdef Q_OS_WINCE - HANDLE handle = 0; - - { -#ifdef QT_NO_TEMPORARYFILE - wchar_t lpBuffer[MAX_PATH]; - GetTempPath(MAX_PATH, lpBuffer); - QString s = QString::fromWCharArray(lpBuffer); - QFile tempfile(s + QLatin1String("/font") + QString::number(GetTickCount()) + QLatin1String(".ttf")); - if (!tempfile.open(QIODevice::ReadWrite)) -#else - QTemporaryFile tempfile(QLatin1String("XXXXXXXX.ttf")); - if (!tempfile.open()) -#endif // QT_NO_TEMPORARYFILE - return; - if (tempfile.write(fnt->data) == -1) - return; - -#ifndef QT_NO_TEMPORARYFILE - tempfile.setAutoRemove(false); -#endif - fnt->fileName = QFileInfo(tempfile.fileName()).absoluteFilePath(); - } - - if (AddFontResource((LPCWSTR)fnt->fileName.utf16()) == 0) { - QFile(fnt->fileName).remove(); - return; - } -#else - DWORD dummy = 0; - HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(), fnt->data.size(), 0, - &dummy); - if (handle == 0) - return; -#endif // Q_OS_WINCE - - fnt->handle = handle; - fnt->data = QByteArray(); - fnt->memoryFont = true; - } else { - QFile f(fnt->fileName); - if (!f.open(QIODevice::ReadOnly)) - return; - QByteArray data = f.readAll(); - f.close(); - getFamiliesAndSignatures(data, fnt); - -#ifdef Q_OS_WINCE - QFileInfo fileinfo(fnt->fileName); - fnt->fileName = fileinfo.absoluteFilePath(); - if (AddFontResource((LPCWSTR)fnt->fileName.utf16()) == 0) - return; -#else - PtrAddFontResourceExW ptrAddFontResourceExW = (PtrAddFontResourceExW)QSystemLibrary::resolve(QLatin1String("gdi32"), - "AddFontResourceExW"); - if (!ptrAddFontResourceExW - || ptrAddFontResourceExW((wchar_t*)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0) - return; -#endif // Q_OS_WINCE - - fnt->memoryFont = false; - } -} - -bool QFontDatabase::removeApplicationFont(int handle) -{ - QMutexLocker locker(fontDatabaseMutex()); - - QFontDatabasePrivate *db = privateDb(); - if (handle < 0 || handle >= db->applicationFonts.count()) - return false; - - const QFontDatabasePrivate::ApplicationFont font = db->applicationFonts.at(handle); - db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont(); - if (font.memoryFont) { -#ifdef Q_OS_WINCE - bool removeSucceeded = RemoveFontResource((LPCWSTR)font.fileName.utf16()); - QFile tempfile(font.fileName); - tempfile.remove(); - if (!removeSucceeded) - return false; -#else - PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)QSystemLibrary::resolve(QLatin1String("gdi32"), - "RemoveFontMemResourceEx"); - if (!ptrRemoveFontMemResourceEx - || !ptrRemoveFontMemResourceEx(font.handle)) - return false; -#endif // Q_OS_WINCE - } else { -#ifdef Q_OS_WINCE - if (!RemoveFontResource((LPCWSTR)font.fileName.utf16())) - return false; -#else - PtrRemoveFontResourceExW ptrRemoveFontResourceExW = (PtrRemoveFontResourceExW)QSystemLibrary::resolve(QLatin1String("gdi32"), - "RemoveFontResourceExW"); - if (!ptrRemoveFontResourceExW - || !ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0)) - return false; -#endif // Q_OS_WINCE - } - - db->invalidate(); - return true; -} - -bool QFontDatabase::removeAllApplicationFonts() -{ - QMutexLocker locker(fontDatabaseMutex()); - - QFontDatabasePrivate *db = privateDb(); - for (int i = 0; i < db->applicationFonts.count(); ++i) - if (!removeApplicationFont(i)) - return false; - return true; -} - -bool QFontDatabase::supportsThreadedFontRendering() -{ - return true; -} - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qfontengine_win.cpp b/src/gui/platforms/win/qfontengine_win.cpp deleted file mode 100644 index 54d7ec2980..0000000000 --- a/src/gui/platforms/win/qfontengine_win.cpp +++ /dev/null @@ -1,1339 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#if _WIN32_WINNT < 0x0500 -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif - -#include "qfontengine_p.h" -#include "qtextengine_p.h" -#include <qglobal.h> -#include "qt_windows.h" -#include <private/qapplication_p.h> - -#include <private/qsystemlibrary_p.h> -#include <qpaintdevice.h> -#include <qpainter.h> -#include <limits.h> - -#include <qendian.h> -#include <qmath.h> -#include <qthreadstorage.h> - -#include <private/qunicodetables_p.h> -#include <qbitmap.h> - -#include <private/qpainter_p.h> -#include "qpaintengine.h" -#include "qvarlengtharray.h" -#include <private/qpaintengine_raster_p.h> -#include <private/qnativeimage_p.h> - -#if defined(Q_WS_WINCE) -#include "qguifunctions_wince.h" -#endif - -//### mingw needed define -#ifndef TT_PRIM_CSPLINE -#define TT_PRIM_CSPLINE 3 -#endif - -#ifdef MAKE_TAG -#undef MAKE_TAG -#endif -// GetFontData expects the tags in little endian ;( -#define MAKE_TAG(ch1, ch2, ch3, ch4) (\ - (((quint32)(ch4)) << 24) | \ - (((quint32)(ch3)) << 16) | \ - (((quint32)(ch2)) << 8) | \ - ((quint32)(ch1)) \ - ) - -// common DC for all fonts - -QT_BEGIN_NAMESPACE - -class QtHDC -{ - HDC _hdc; -public: - QtHDC() - { - HDC displayDC = GetDC(0); - _hdc = CreateCompatibleDC(displayDC); - ReleaseDC(0, displayDC); - } - ~QtHDC() - { - if (_hdc) - DeleteDC(_hdc); - } - HDC hdc() const - { - return _hdc; - } -}; - -#ifndef QT_NO_THREAD -Q_GLOBAL_STATIC(QThreadStorage<QtHDC *>, local_shared_dc) -HDC shared_dc() -{ - QtHDC *&hdc = local_shared_dc()->localData(); - if (!hdc) - hdc = new QtHDC; - return hdc->hdc(); -} -#else -HDC shared_dc() -{ - return 0; -} -#endif - -#ifndef Q_WS_WINCE -typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); -static PtrGetCharWidthI ptrGetCharWidthI = 0; -static bool resolvedGetCharWidthI = false; - -static void resolveGetCharWidthI() -{ - if (resolvedGetCharWidthI) - return; - resolvedGetCharWidthI = true; - ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI"); -} -#endif // !defined(Q_WS_WINCE) - -// defined in qtextengine_win.cpp -typedef void *SCRIPT_CACHE; -typedef HRESULT (WINAPI *fScriptFreeCache)(SCRIPT_CACHE *); -extern fScriptFreeCache ScriptFreeCache; - -static inline quint32 getUInt(unsigned char *p) -{ - quint32 val; - val = *p++ << 24; - val |= *p++ << 16; - val |= *p++ << 8; - val |= *p; - - return val; -} - -static inline quint16 getUShort(unsigned char *p) -{ - quint16 val; - val = *p++ << 8; - val |= *p; - - return val; -} - -// general font engine - -QFixed QFontEngineWin::lineThickness() const -{ - if(lineWidth > 0) - return lineWidth; - - return QFontEngine::lineThickness(); -} - -static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc) -{ - int size; - size = GetOutlineTextMetrics(hdc, 0, 0); - OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size); - GetOutlineTextMetrics(hdc, size, otm); - return otm; -} - -void QFontEngineWin::getCMap() -{ - ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE); - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - bool symb = false; - if (ttf) { - cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p'))); - int size = 0; - cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), - cmapTable.size(), &symb, &size); - } - if (!cmap) { - ttf = false; - symb = false; - } - symbol = symb; - designToDevice = 1; - _faceId.index = 0; - if(cmap) { - OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); - designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight); - unitsPerEm = otm->otmEMSquare; - x_height = (int)otm->otmsXHeight; - loadKerningPairs(designToDevice); - _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName)).toLatin1(); - lineWidth = otm->otmsUnderscoreSize; - fsType = otm->otmfsType; - free(otm); - } else { - unitsPerEm = tm.tmHeight; - } -} - - -inline unsigned int getChar(const QChar *str, int &i, const int len) -{ - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } - } - return uc; -} - -int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const -{ - int i = 0; - int glyph_pos = 0; - if (mirrored) { -#if defined(Q_WS_WINCE) - { -#else - if (symbol) { - for (; i < numChars; ++i, ++glyph_pos) { - unsigned int uc = getChar(str, i, numChars); - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); - if (!glyphs->glyphs[glyph_pos] && uc < 0x100) - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000); - } - } else if (ttf) { - for (; i < numChars; ++i, ++glyph_pos) { - unsigned int uc = getChar(str, i, numChars); - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc)); - } - } else { -#endif - wchar_t first = tm.tmFirstChar; - wchar_t last = tm.tmLastChar; - - for (; i < numChars; ++i, ++glyph_pos) { - uint ucs = QChar::mirroredChar(getChar(str, i, numChars)); - if ( -#ifdef Q_WS_WINCE - tm.tmFirstChar > 60000 || // see line 375 -#endif - ucs >= first && ucs <= last) - glyphs->glyphs[glyph_pos] = ucs; - else - glyphs->glyphs[glyph_pos] = 0; - } - } - } else { -#if defined(Q_WS_WINCE) - { -#else - if (symbol) { - for (; i < numChars; ++i, ++glyph_pos) { - unsigned int uc = getChar(str, i, numChars); - glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc); - if(!glyphs->glyphs[glyph_pos] && uc < 0x100) - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000); - } - } else if (ttf) { - for (; i < numChars; ++i, ++glyph_pos) { - unsigned int uc = getChar(str, i, numChars); - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); - } - } else { -#endif - wchar_t first = tm.tmFirstChar; - wchar_t last = tm.tmLastChar; - - for (; i < numChars; ++i, ++glyph_pos) { - uint uc = getChar(str, i, numChars); - if ( -#ifdef Q_WS_WINCE - tm.tmFirstChar > 60000 || // see comment in QFontEngineWin -#endif - uc >= first && uc <= last) - glyphs->glyphs[glyph_pos] = uc; - else - glyphs->glyphs[glyph_pos] = 0; - } - } - } - glyphs->numGlyphs = glyph_pos; - return glyph_pos; -} - - -QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont, LOGFONT lf) -{ - //qDebug("regular windows font engine created: font='%s', size=%d", name, lf.lfHeight); - - _name = name; - - cmap = 0; - hfont = _hfont; - logfont = lf; - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - this->stockFont = stockFont; - fontDef.pixelSize = -lf.lfHeight; - - lbearing = SHRT_MIN; - rbearing = SHRT_MIN; - synthesized_flags = -1; - lineWidth = -1; - x_height = -1; - - BOOL res = GetTextMetrics(hdc, &tm); - fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); - if (!res) { - qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); - ZeroMemory(&tm, sizeof(TEXTMETRIC)); - } - - cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000; - getCMap(); - - widthCache = 0; - widthCacheSize = 0; - designAdvances = 0; - designAdvancesSize = 0; - -#ifndef Q_WS_WINCE - if (!resolvedGetCharWidthI) - resolveGetCharWidthI(); -#endif -} - -QFontEngineWin::~QFontEngineWin() -{ - if (designAdvances) - free(designAdvances); - - if (widthCache) - free(widthCache); - - // make sure we aren't by accident still selected - SelectObject(shared_dc(), (HFONT)GetStockObject(SYSTEM_FONT)); - - if (!stockFont) { - if (!DeleteObject(hfont)) - qErrnoWarning("QFontEngineWin: failed to delete non-stock font..."); - } -} - -HGDIOBJ QFontEngineWin::selectDesignFont() const -{ - LOGFONT f = logfont; - f.lfHeight = unitsPerEm; - HFONT designFont = CreateFontIndirect(&f); - return SelectObject(shared_dc(), designFont); -} - -bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const -{ - if (*nglyphs < len) { - *nglyphs = len; - return false; - } - - *nglyphs = getGlyphIndexes(str, len, glyphs, flags & QTextEngine::RightToLeft); - - if (flags & QTextEngine::GlyphIndicesOnly) - return true; - - recalcAdvances(glyphs, flags); - return true; -} - -inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width) -{ -#if defined(Q_WS_WINCE) - GetCharWidth32(hdc, glyph, glyph, &width); -#else - if (ptrGetCharWidthI) - ptrGetCharWidthI(hdc, glyph, 1, 0, &width); -#endif -} - -void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const -{ - HGDIOBJ oldFont = 0; - HDC hdc = shared_dc(); - if (ttf && (flags & QTextEngine::DesignMetrics)) { - for(int i = 0; i < glyphs->numGlyphs; i++) { - unsigned int glyph = glyphs->glyphs[i]; - if(int(glyph) >= designAdvancesSize) { - int newSize = (glyph + 256) >> 8 << 8; - designAdvances = q_check_ptr((QFixed *)realloc(designAdvances, - newSize*sizeof(QFixed))); - for(int i = designAdvancesSize; i < newSize; ++i) - designAdvances[i] = -1000000; - designAdvancesSize = newSize; - } - if (designAdvances[glyph] < -999999) { - if (!oldFont) - oldFont = selectDesignFont(); - - int width = 0; - calculateTTFGlyphWidth(hdc, glyph, width); - designAdvances[glyph] = QFixed(width) / designToDevice; - } - glyphs->advances_x[i] = designAdvances[glyph]; - glyphs->advances_y[i] = 0; - } - if(oldFont) - DeleteObject(SelectObject(hdc, oldFont)); - } else { - for(int i = 0; i < glyphs->numGlyphs; i++) { - unsigned int glyph = glyphs->glyphs[i]; - - glyphs->advances_y[i] = 0; - - if (glyph >= widthCacheSize) { - int newSize = (glyph + 256) >> 8 << 8; - widthCache = q_check_ptr((unsigned char *)realloc(widthCache, - newSize*sizeof(QFixed))); - memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize); - widthCacheSize = newSize; - } - glyphs->advances_x[i] = widthCache[glyph]; - // font-width cache failed - if (glyphs->advances_x[i] == 0) { - int width = 0; - if (!oldFont) - oldFont = SelectObject(hdc, hfont); - - if (!ttf) { - QChar ch[2] = { ushort(glyph), 0 }; - int chrLen = 1; - if (glyph > 0xffff) { - ch[0] = QChar::highSurrogate(glyph); - ch[1] = QChar::lowSurrogate(glyph); - ++chrLen; - } - SIZE size = {0, 0}; - GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size); - width = size.cx; - } else { - calculateTTFGlyphWidth(hdc, glyph, width); - } - glyphs->advances_x[i] = width; - // if glyph's within cache range, store it for later - if (width > 0 && width < 0x100) - widthCache[glyph] = width; - } - } - - if (oldFont) - SelectObject(hdc, oldFont); - } -} - -glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs) -{ - if (glyphs.numGlyphs == 0) - return glyph_metrics_t(); - - QFixed w = 0; - for (int i = 0; i < glyphs.numGlyphs; ++i) - w += glyphs.effectiveAdvance(i); - - return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0); -} - -#ifndef Q_WS_WINCE -bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const -{ - Q_ASSERT(metrics != 0); - - HDC hdc = shared_dc(); - - GLYPHMETRICS gm; - DWORD res = 0; - MAT2 mat; - mat.eM11.value = mat.eM22.value = 1; - mat.eM11.fract = mat.eM22.fract = 0; - mat.eM21.value = mat.eM12.value = 0; - mat.eM21.fract = mat.eM12.fract = 0; - - if (t.type() > QTransform::TxTranslate) { - // We need to set the transform using the HDC's world - // matrix rather than using the MAT2 above, because the - // results provided when transforming via MAT2 does not - // match the glyphs that are drawn using a WorldTransform - XFORM xform; - xform.eM11 = t.m11(); - xform.eM12 = t.m12(); - xform.eM21 = t.m21(); - xform.eM22 = t.m22(); - xform.eDx = 0; - xform.eDy = 0; - SetGraphicsMode(hdc, GM_ADVANCED); - SetWorldTransform(hdc, &xform); - } - - uint format = GGO_METRICS; - if (ttf) - format |= GGO_GLYPH_INDEX; - res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat); - - if (t.type() > QTransform::TxTranslate) { - XFORM xform; - xform.eM11 = xform.eM22 = 1; - xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0; - SetWorldTransform(hdc, &xform); - SetGraphicsMode(hdc, GM_COMPATIBLE); - } - - if (res != GDI_ERROR) { - *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, - (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); - return true; - } else { - return false; - } -} -#endif - -glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) -{ -#ifndef Q_WS_WINCE - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - - glyph_metrics_t glyphMetrics; - bool success = getOutlineMetrics(glyph, t, &glyphMetrics); - - if (!ttf && !success) { - // Bitmap fonts - wchar_t ch = glyph; - ABCFLOAT abc; - GetCharABCWidthsFloat(hdc, ch, ch, &abc); - int width = qRound(abc.abcfB); - - return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); - } - - return glyphMetrics; -#else - HDC hdc = shared_dc(); - HGDIOBJ oldFont = SelectObject(hdc, hfont); - - ABC abc; - int width; - int advance; -#ifdef GWES_MGTT // true type fonts - if (GetCharABCWidths(hdc, glyph, glyph, &abc)) { - width = qAbs(abc.abcA) + abc.abcB + qAbs(abc.abcC); - advance = abc.abcA + abc.abcB + abc.abcC; - } - else -#endif -#if defined(GWES_MGRAST) || defined(GWES_MGRAST2) // raster fonts - if (GetCharWidth32(hdc, glyph, glyph, &width)) { - advance = width; - } - else -#endif - { // fallback - width = tm.tmMaxCharWidth; - advance = width; - } - - SelectObject(hdc, oldFont); - return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, advance, 0).transformed(t); -#endif -} - -QFixed QFontEngineWin::ascent() const -{ - return tm.tmAscent; -} - -QFixed QFontEngineWin::descent() const -{ - // ### we substract 1 to even out the historical +1 in QFontMetrics's - // ### height=asc+desc+1 equation. Fix in Qt5. - return tm.tmDescent - 1; -} - -QFixed QFontEngineWin::leading() const -{ - return tm.tmExternalLeading; -} - - -QFixed QFontEngineWin::xHeight() const -{ - if(x_height >= 0) - return x_height; - return QFontEngine::xHeight(); -} - -QFixed QFontEngineWin::averageCharWidth() const -{ - return tm.tmAveCharWidth; -} - -qreal QFontEngineWin::maxCharWidth() const -{ - return tm.tmMaxCharWidth; -} - -enum { max_font_count = 256 }; -static const ushort char_table[] = { - 40, - 67, - 70, - 75, - 86, - 88, - 89, - 91, - 102, - 114, - 124, - 127, - 205, - 645, - 884, - 922, - 1070, - 12386, - 0 -}; - -static const int char_table_entries = sizeof(char_table)/sizeof(ushort); - -#ifndef Q_CC_MINGW -void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing) -{ - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - -#ifndef Q_WS_WINCE - if (ttf) -#endif - - { - ABC abcWidths; - GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths); - if (leftBearing) - *leftBearing = abcWidths.abcA; - if (rightBearing) - *rightBearing = abcWidths.abcC; - } - -#ifndef Q_WS_WINCE - else { - QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing); - } -#endif -} -#endif // Q_CC_MINGW - -qreal QFontEngineWin::minLeftBearing() const -{ - if (lbearing == SHRT_MIN) - minRightBearing(); // calculates both - - return lbearing; -} - -qreal QFontEngineWin::minRightBearing() const -{ -#ifdef Q_WS_WINCE - if (rbearing == SHRT_MIN) { - int ml = 0; - int mr = 0; - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - if (ttf) { - ABC *abc = 0; - int n = tm.tmLastChar - tm.tmFirstChar; - if (n <= max_font_count) { - abc = new ABC[n+1]; - GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); - } else { - abc = new ABC[char_table_entries+1]; - for(int i = 0; i < char_table_entries; i++) - GetCharABCWidths(hdc, char_table[i], char_table[i], abc+i); - n = char_table_entries; - } - ml = abc[0].abcA; - mr = abc[0].abcC; - for (int i = 1; i < n; i++) { - if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) { - ml = qMin(ml,abc[i].abcA); - mr = qMin(mr,abc[i].abcC); - } - } - delete [] abc; - } - lbearing = ml; - rbearing = mr; - } - - return rbearing; -#else - if (rbearing == SHRT_MIN) { - int ml = 0; - int mr = 0; - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - if (ttf) { - ABC *abc = 0; - int n = tm.tmLastChar - tm.tmFirstChar; - if (n <= max_font_count) { - abc = new ABC[n+1]; - GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); - } else { - abc = new ABC[char_table_entries+1]; - for(int i = 0; i < char_table_entries; i++) - GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i); - n = char_table_entries; - } - ml = abc[0].abcA; - mr = abc[0].abcC; - for (int i = 1; i < n; i++) { - if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) { - ml = qMin(ml,abc[i].abcA); - mr = qMin(mr,abc[i].abcC); - } - } - delete [] abc; - } else { - ABCFLOAT *abc = 0; - int n = tm.tmLastChar - tm.tmFirstChar+1; - if (n <= max_font_count) { - abc = new ABCFLOAT[n]; - GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc); - } else { - abc = new ABCFLOAT[char_table_entries]; - for(int i = 0; i < char_table_entries; i++) - GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i); - n = char_table_entries; - } - float fml = abc[0].abcfA; - float fmr = abc[0].abcfC; - for (int i=1; i<n; i++) { - if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) { - fml = qMin(fml,abc[i].abcfA); - fmr = qMin(fmr,abc[i].abcfC); - } - } - ml = int(fml - 0.9999); - mr = int(fmr - 0.9999); - delete [] abc; - } - lbearing = ml; - rbearing = mr; - } - - return rbearing; -#endif -} - - -const char *QFontEngineWin::name() const -{ - return 0; -} - -bool QFontEngineWin::canRender(const QChar *string, int len) -{ - if (symbol) { - for (int i = 0; i < len; ++i) { - unsigned int uc = getChar(string, i, len); - if (getTrueTypeGlyphIndex(cmap, uc) == 0) { - if (uc < 0x100) { - if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0) - return false; - } else { - return false; - } - } - } - } else if (ttf) { - for (int i = 0; i < len; ++i) { - unsigned int uc = getChar(string, i, len); - if (getTrueTypeGlyphIndex(cmap, uc) == 0) - return false; - } - } else { - while(len--) { - if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode()) - return false; - } - } - return true; -} - -QFontEngine::Type QFontEngineWin::type() const -{ - return QFontEngine::Win; -} - -static inline double qt_fixed_to_double(const FIXED &p) { - return ((p.value << 16) + p.fract) / 65536.0; -} - -static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) { - return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale); -} - -#ifndef GGO_UNHINTED -#define GGO_UNHINTED 0x0100 -#endif - -static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, - QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1) -{ -#if defined(Q_WS_WINCE) - Q_UNUSED(glyph); - Q_UNUSED(hdc); -#endif - MAT2 mat; - mat.eM11.value = mat.eM22.value = 1; - mat.eM11.fract = mat.eM22.fract = 0; - mat.eM21.value = mat.eM12.value = 0; - mat.eM21.fract = mat.eM12.fract = 0; - uint glyphFormat = GGO_NATIVE; - - if (ttf) - glyphFormat |= GGO_GLYPH_INDEX; - - GLYPHMETRICS gMetric; - memset(&gMetric, 0, sizeof(GLYPHMETRICS)); - int bufferSize = GDI_ERROR; -#if !defined(Q_WS_WINCE) - bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); -#endif - if ((DWORD)bufferSize == GDI_ERROR) { - return false; - } - - void *dataBuffer = new char[bufferSize]; - DWORD ret = GDI_ERROR; -#if !defined(Q_WS_WINCE) - ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat); -#endif - if (ret == GDI_ERROR) { - delete [](char *)dataBuffer; - return false; - } - - if(metric) { - // #### obey scale - *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y, - (int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY, - gMetric.gmCellIncX, gMetric.gmCellIncY); - } - - int offset = 0; - int headerOffset = 0; - TTPOLYGONHEADER *ttph = 0; - - QPointF oset = position.toPointF(); - while (headerOffset < bufferSize) { - ttph = (TTPOLYGONHEADER*)((char *)dataBuffer + headerOffset); - - QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale)); - path->moveTo(lastPoint + oset); - offset += sizeof(TTPOLYGONHEADER); - TTPOLYCURVE *curve; - while (offset<int(headerOffset + ttph->cb)) { - curve = (TTPOLYCURVE*)((char*)(dataBuffer) + offset); - switch (curve->wType) { - case TT_PRIM_LINE: { - for (int i=0; i<curve->cpfx; ++i) { - QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset; - path->lineTo(p); - } - break; - } - case TT_PRIM_QSPLINE: { - const QPainterPath::Element &elm = path->elementAt(path->elementCount()-1); - QPointF prev(elm.x, elm.y); - QPointF endPoint; - for (int i=0; i<curve->cpfx - 1; ++i) { - QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset; - QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset; - if (i < curve->cpfx - 2) { - endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2); - } else { - endPoint = p2; - } - - path->quadTo(p1, endPoint); - prev = endPoint; - } - - break; - } - case TT_PRIM_CSPLINE: { - for (int i=0; i<curve->cpfx; ) { - QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset; - QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset; - QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset; - path->cubicTo(p2, p3, p4); - } - break; - } - default: - qWarning("QFontEngineWin::addOutlineToPath, unhandled switch case"); - } - offset += sizeof(TTPOLYCURVE) + (curve->cpfx-1) * sizeof(POINTFX); - } - path->closeSubpath(); - headerOffset += ttph->cb; - } - delete [] (char*)dataBuffer; - - return true; -} - -void QFontEngineWin::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, - QPainterPath *path, QTextItem::RenderFlags) -{ - LOGFONT lf = logfont; - // The sign must be negative here to make sure we match against character height instead of - // hinted cell height. This ensures that we get linear matching, and we need this for - // paths since we later on apply a scaling transform to the glyph outline to get the - // font at the correct pixel size. - lf.lfHeight = -unitsPerEm; - lf.lfWidth = 0; - HFONT hf = CreateFontIndirect(&lf); - HDC hdc = shared_dc(); - HGDIOBJ oldfont = SelectObject(hdc, hf); - - for(int i = 0; i < nglyphs; ++i) { - if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0, - qreal(fontDef.pixelSize) / unitsPerEm)) { - // Some windows fonts, like "Modern", are vector stroke - // fonts, which are reported as TMPF_VECTOR but do not - // support GetGlyphOutline, and thus we set this bit so - // that addOutLineToPath can check it and return safely... - hasOutline = false; - break; - } - } - DeleteObject(SelectObject(hdc, oldfont)); -} - -void QFontEngineWin::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, - QPainterPath *path, QTextItem::RenderFlags flags) -{ -#if !defined(Q_WS_WINCE) - if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { - hasOutline = true; - QFontEngine::addOutlineToPath(x, y, glyphs, path, flags); - if (hasOutline) { - // has_outline is set to false if addGlyphToPath gets - // false from GetGlyphOutline, meaning its not an outline - // font. - return; - } - } -#endif - QFontEngine::addBitmapFontToPath(x, y, glyphs, path, flags); -} - -QFontEngine::FaceId QFontEngineWin::faceId() const -{ - return _faceId; -} - -QT_BEGIN_INCLUDE_NAMESPACE -#include <qdebug.h> -QT_END_INCLUDE_NAMESPACE - -int QFontEngineWin::synthesized() const -{ - if(synthesized_flags == -1) { - synthesized_flags = 0; - if(ttf) { - const DWORD HEAD = MAKE_TAG('h', 'e', 'a', 'd'); - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - uchar data[4]; - GetFontData(hdc, HEAD, 44, &data, 4); - USHORT macStyle = getUShort(data); - if (tm.tmItalic && !(macStyle & 2)) - synthesized_flags = SynthesizedItalic; - if (fontDef.stretch != 100 && ttf) - synthesized_flags |= SynthesizedStretch; - if (tm.tmWeight >= 500 && !(macStyle & 1)) - synthesized_flags |= SynthesizedBold; - //qDebug() << "font is" << _name << - // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags; - } - } - return synthesized_flags; -} - -QFixed QFontEngineWin::emSquareSize() const -{ - return unitsPerEm; -} - -QFontEngine::Properties QFontEngineWin::properties() const -{ - LOGFONT lf = logfont; - lf.lfHeight = unitsPerEm; - HFONT hf = CreateFontIndirect(&lf); - HDC hdc = shared_dc(); - HGDIOBJ oldfont = SelectObject(hdc, hf); - OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); - Properties p; - p.emSquare = unitsPerEm; - p.italicAngle = otm->otmItalicAngle; - p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1(); - p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1(); - p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(p.postscriptName); - p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top, - otm->otmrcFontBox.right - otm->otmrcFontBox.left, - otm->otmrcFontBox.top - otm->otmrcFontBox.bottom); - p.ascent = otm->otmAscent; - p.descent = -otm->otmDescent; - p.leading = (int)otm->otmLineGap; - p.capHeight = 0; - p.lineWidth = otm->otmsUnderscoreSize; - free(otm); - DeleteObject(SelectObject(hdc, oldfont)); - return p; -} - -void QFontEngineWin::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) -{ - LOGFONT lf = logfont; - lf.lfHeight = unitsPerEm; - int flags = synthesized(); - if(flags & SynthesizedItalic) - lf.lfItalic = false; - lf.lfWidth = 0; - HFONT hf = CreateFontIndirect(&lf); - HDC hdc = shared_dc(); - HGDIOBJ oldfont = SelectObject(hdc, hf); - QFixedPoint p; - p.x = 0; - p.y = 0; - addGlyphToPath(glyph, p, hdc, path, ttf, metrics); - DeleteObject(SelectObject(hdc, oldfont)); -} - -bool QFontEngineWin::getSfntTableData(uint tag, uchar *buffer, uint *length) const -{ - if (!ttf) - return false; - HDC hdc = shared_dc(); - SelectObject(hdc, hfont); - DWORD t = qbswap<quint32>(tag); - *length = GetFontData(hdc, t, 0, buffer, *length); - return *length != GDI_ERROR; -} - -#if !defined(CLEARTYPE_QUALITY) -# define CLEARTYPE_QUALITY 5 -#endif - -extern bool qt_cleartype_enabled; - -QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin, - const QTransform &t, QImage::Format mask_format) -{ - Q_UNUSED(mask_format) - glyph_metrics_t gm = boundingBox(glyph); - -// printf(" -> for glyph %4x\n", glyph); - - int gx = gm.x.toInt(); - int gy = gm.y.toInt(); - int iw = gm.width.toInt(); - int ih = gm.height.toInt(); - - if (iw <= 0 || iw <= 0) - return 0; - - bool has_transformation = t.type() > QTransform::TxTranslate; - -#ifndef Q_WS_WINCE - unsigned int options = ttf ? ETO_GLYPH_INDEX : 0; - XFORM xform; - - if (has_transformation) { - xform.eM11 = t.m11(); - xform.eM12 = t.m12(); - xform.eM21 = t.m21(); - xform.eM22 = t.m22(); - xform.eDx = margin; - xform.eDy = margin; - - QtHDC qthdc; - HDC hdc = qthdc.hdc(); - - SetGraphicsMode(hdc, GM_ADVANCED); - SetWorldTransform(hdc, &xform); - HGDIOBJ old_font = SelectObject(hdc, font); - - int ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0); - GLYPHMETRICS tgm; - MAT2 mat; - memset(&mat, 0, sizeof(mat)); - mat.eM11.value = mat.eM22.value = 1; - - if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) { - qWarning("QWinFontEngine: unable to query transformed glyph metrics..."); - return 0; - } - - iw = tgm.gmBlackBoxX; - ih = tgm.gmBlackBoxY; - - xform.eDx -= tgm.gmptGlyphOrigin.x; - xform.eDy += tgm.gmptGlyphOrigin.y; - - SetGraphicsMode(hdc, GM_COMPATIBLE); - SelectObject(hdc, old_font); - } -#else // else winc - unsigned int options = 0; -#ifdef DEBUG - Q_ASSERT(!has_transformation); -#else - Q_UNUSED(has_transformation); -#endif -#endif - - QNativeImage *ni = new QNativeImage(iw + 2 * margin + 4, - ih + 2 * margin + 4, - QNativeImage::systemFormat(), !qt_cleartype_enabled); - - /*If cleartype is enabled we use the standard system format even on Windows CE - and not the special textbuffer format we have to use if cleartype is disabled*/ - - ni->image.fill(0xffffffff); - - HDC hdc = ni->hdc; - - SelectObject(hdc, GetStockObject(NULL_BRUSH)); - SelectObject(hdc, GetStockObject(BLACK_PEN)); - SetTextColor(hdc, RGB(0,0,0)); - SetBkMode(hdc, TRANSPARENT); - SetTextAlign(hdc, TA_BASELINE); - - HGDIOBJ old_font = SelectObject(hdc, font); - -#ifndef Q_OS_WINCE - if (has_transformation) { - SetGraphicsMode(hdc, GM_ADVANCED); - SetWorldTransform(hdc, &xform); - ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0); - } else -#endif - { - ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); - } - - SelectObject(hdc, old_font); - return ni; -} - - -extern uint qt_pow_gamma[256]; - -QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform) -{ - HFONT font = hfont; - if (qt_cleartype_enabled) { - LOGFONT lf = logfont; - lf.lfQuality = ANTIALIASED_QUALITY; - font = CreateFontIndirect(&lf); - } - QImage::Format mask_format = QNativeImage::systemFormat(); -#ifndef Q_OS_WINCE - mask_format = QImage::Format_RGB32; -#endif - - QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format); - if (mask == 0) - return QImage(); - - QImage indexed(mask->width(), mask->height(), QImage::Format_Indexed8); - - // ### This part is kinda pointless, but we'll crash later if we don't because some - // code paths expects there to be colortables for index8-bit... - QVector<QRgb> colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgba(0, 0, 0, i); - indexed.setColorTable(colors); - - // Copy data... Cannot use QPainter here as GDI has messed up the - // Alpha channel of the ni.image pixels... - for (int y=0; y<mask->height(); ++y) { - uchar *dest = indexed.scanLine(y); - if (mask->image.format() == QImage::Format_RGB16) { - const qint16 *src = (qint16 *) ((const QImage &) mask->image).scanLine(y); - for (int x=0; x<mask->width(); ++x) - dest[x] = 255 - qGray(src[x]); - } else { - const uint *src = (uint *) ((const QImage &) mask->image).scanLine(y); - for (int x=0; x<mask->width(); ++x) { -#ifdef Q_OS_WINCE - dest[x] = 255 - qGray(src[x]); -#else - if (QNativeImage::systemFormat() == QImage::Format_RGB16) - dest[x] = 255 - qGray(src[x]); - else - dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.); -#endif - } - } - } - - // Cleanup... - delete mask; - if (qt_cleartype_enabled) { - DeleteObject(font); - } - - return indexed; -} - -#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C -#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D - -QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t) -{ - HFONT font = hfont; - - int contrast; - SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0); - SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0); - - QNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32); - SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0); - - if (mask == 0) - return QImage(); - - // Gracefully handle the odd case when the display is 16-bit - const QImage source = mask->image.depth() == 32 - ? mask->image - : mask->image.convertToFormat(QImage::Format_RGB32); - - QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32); - for (int y=0; y<mask->height(); ++y) { - uint *dest = (uint *) rgbMask.scanLine(y); - const uint *src = (uint *) source.scanLine(y); - for (int x=0; x<mask->width(); ++x) { - dest[x] = 0xffffffff - (0x00ffffff & src[x]); - } - } - - delete mask; - - return rgbMask; -} - -// From qfontdatabase_win.cpp -extern QFontEngine *qt_load_font_engine_win(const QFontDef &request); -QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const -{ - QFontDef request = fontDef; - QString actualFontName = request.family; - if (!uniqueFamilyName.isEmpty()) - request.family = uniqueFamilyName; - request.pixelSize = pixelSize; - - QFontEngine *fontEngine = qt_load_font_engine_win(request); - if (fontEngine != NULL) - fontEngine->fontDef.family = actualFontName; - - return fontEngine; -} - -// -------------------------------------- Multi font engine - -QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks) - : QFontEngineMulti(fallbacks.size()+1), - fallbacks(fallbacks) -{ - engines[0] = first; - first->ref.ref(); - fontDef = engines[0]->fontDef; - cache_cost = first->cache_cost; -} - -void QFontEngineMultiWin::loadEngine(int at) -{ - Q_ASSERT(at < engines.size()); - Q_ASSERT(engines.at(at) == 0); - - QString fam = fallbacks.at(at-1); - - LOGFONT lf = static_cast<QFontEngineWin *>(engines.at(0))->logfont; - memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded - HFONT hfont = CreateFontIndirect(&lf); - - bool stockFont = false; - if (hfont == 0) { - hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); - stockFont = true; - } - engines[at] = new QFontEngineWin(fam, hfont, stockFont, lf); - engines[at]->ref.ref(); - engines[at]->fontDef = fontDef; - - // TODO: increase cost in QFontCache for the font engine loaded here -} - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qfontengine_win_p.h b/src/gui/platforms/win/qfontengine_win_p.h deleted file mode 100644 index 114149d61f..0000000000 --- a/src/gui/platforms/win/qfontengine_win_p.h +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QFONTENGINE_WIN_P_H -#define QFONTENGINE_WIN_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qconfig.h> - -QT_BEGIN_NAMESPACE - -class QNativeImage; - -class QFontEngineWin : public QFontEngine -{ -public: - QFontEngineWin(const QString &name, HFONT, bool, LOGFONT); - ~QFontEngineWin(); - - virtual QFixed lineThickness() const; - virtual Properties properties() const; - virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual FaceId faceId() const; - virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; - virtual int synthesized() const; - virtual QFixed emSquareSize() const; - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; - virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const; - - virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags); - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, - QPainterPath *path, QTextItem::RenderFlags flags); - - HGDIOBJ selectDesignFont() const; - - virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); - virtual glyph_metrics_t boundingBox(glyph_t g) { return boundingBox(g, QTransform()); } - virtual glyph_metrics_t boundingBox(glyph_t g, const QTransform &t); - - - virtual QFixed ascent() const; - virtual QFixed descent() const; - virtual QFixed leading() const; - virtual QFixed xHeight() const; - virtual QFixed averageCharWidth() const; - virtual qreal maxCharWidth() const; - virtual qreal minLeftBearing() const; - virtual qreal minRightBearing() const; - - virtual const char *name() const; - - bool canRender(const QChar *string, int len); - - Type type() const; - - virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); } - virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform); - virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); - - virtual QFontEngine *cloneWithSize(qreal pixelSize) const; - -#ifndef Q_CC_MINGW - virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0); -#endif - - int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const; - void getCMap(); - -#ifndef Q_WS_WINCE - bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const; -#endif - - QString _name; - QString uniqueFamilyName; - HFONT hfont; - LOGFONT logfont; - uint stockFont : 1; - uint ttf : 1; - uint hasOutline : 1; - TEXTMETRIC tm; - int lw; - const unsigned char *cmap; - QByteArray cmapTable; - mutable qreal lbearing; - mutable qreal rbearing; - QFixed designToDevice; - int unitsPerEm; - QFixed x_height; - FaceId _faceId; - - mutable int synthesized_flags; - mutable QFixed lineWidth; - mutable unsigned char *widthCache; - mutable uint widthCacheSize; - mutable QFixed *designAdvances; - mutable int designAdvancesSize; - -private: - QNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform, - QImage::Format mask_format); - -}; - -class QFontEngineMultiWin : public QFontEngineMulti -{ -public: - QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks); - void loadEngine(int at); - - QStringList fallbacks; -}; - -QT_END_NAMESPACE - -#endif // QFONTENGINE_WIN_P_H diff --git a/src/gui/platforms/win/qguifunctions_wince.cpp b/src/gui/platforms/win/qguifunctions_wince.cpp deleted file mode 100644 index bb4ed11589..0000000000 --- a/src/gui/platforms/win/qguifunctions_wince.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "qguifunctions_wince.h" -#include <shellapi.h> -#include <QtCore/qlibrary.h> - -QT_USE_NAMESPACE - -struct AygSHINITDLGINFO -{ - DWORD dwMask; - HWND hDlg; - DWORD dwFlags; -}; - -struct AygSIPINFO -{ - DWORD cbSize; - DWORD fdwFlags; - RECT rcVisibleDesktop; - RECT rcSipRect; - DWORD dwImDataSize; - void *pvImData; -}; - -#ifndef SHIDIF_CANCELBUTTON -#define SHIDIF_CANCELBUTTON 0x0080 -#endif - -#ifndef SHIDIM_FLAGS -#define SHIDIM_FLAGS 0x0001 -#endif - -#ifndef SHIDIF_DONEBUTTON -#define SHIDIF_DONEBUTTON 0x0001 -#endif -#ifndef SHIDIF_SIZEDLGFULLSCREEN -#define SHIDIF_SIZEDLGFULLSCREEN 0x0004 -#endif - -#ifndef SHDB_HIDE -#define SHDB_HIDE 0x0002 -#endif - -#ifndef SHFS_SHOWTASKBAR -#define SHFS_SHOWTASKBAR 0x0001 -#endif -#ifndef SHFS_HIDETASKBAR -#define SHFS_HIDETASKBAR 0x0002 -#endif -#ifndef SHFS_SHOWSIPBUTTON -#define SHFS_SHOWSIPBUTTON 0x0004 -#endif -#ifndef SHFS_HIDESIPBUTTON -#define SHFS_HIDESIPBUTTON 0x0008 -#endif -#ifndef SHFS_SHOWSTARTICON -#define SHFS_SHOWSTARTICON 0x0010 -#endif -#ifndef SHFS_HIDESTARTICON -#define SHFS_HIDESTARTICON 0x0020 -#endif - -#ifndef SIPF_OFF -#define SIPF_OFF 0x00000000 -#endif -#ifndef SIPF_ON -#define SIPF_ON 0x00000001 -#endif - -#ifndef SPI_SETSIPINFO -#define SPI_SETSIPINFO 224 -#endif -#ifndef SPI_GETSIPINFO -#define SPI_GETSIPINFO 225 -#endif -#ifndef SPI_GETPLATFORMTYPE -#define SPI_GETPLATFORMTYPE 257 -#endif - -typedef BOOL (*AygInitDialog)(AygSHINITDLGINFO*); -typedef BOOL (*AygFullScreen)(HWND, DWORD); -typedef BOOL (*AygSHSipInfo)(UINT, UINT, PVOID, UINT); -typedef BOOL (*AygSHDoneButton)(HWND, DWORD); - -static AygInitDialog ptrAygInitDialog = 0; -static AygFullScreen ptrAygFullScreen = 0; -static AygSHSipInfo ptrAygSHSipInfo = 0; -static AygSHDoneButton ptrAygSHDoneButton = 0; -static bool aygResolved = false; - -static void resolveAygLibs() -{ - if (!aygResolved) { - aygResolved = true; - QLibrary ayglib(QLatin1String("aygshell")); - ptrAygInitDialog = (AygInitDialog) ayglib.resolve("SHInitDialog"); - ptrAygFullScreen = (AygFullScreen) ayglib.resolve("SHFullScreen"); - ptrAygSHSipInfo = (AygSHSipInfo) ayglib.resolve("SHSipInfo"); - ptrAygSHDoneButton = (AygSHDoneButton) ayglib.resolve("SHDoneButton"); - } -} - -int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID lpvBits, LPBITMAPINFO, uint) -{ - if (!lpvBits) { - qWarning("::GetDIBits(), lpvBits NULL"); - return 0; - } - BITMAP bm; - GetObject(hSourceBitmap, sizeof(BITMAP), &bm); - bm.bmHeight = qAbs(bm.bmHeight); - - HBITMAP hTargetBitmap; - void *pixels; - - BITMAPINFO dibInfo; - memset(&dibInfo, 0, sizeof(dibInfo)); - dibInfo.bmiHeader.biBitCount = 32; - dibInfo.bmiHeader.biClrImportant = 0; - dibInfo.bmiHeader.biClrUsed = 0; - dibInfo.bmiHeader.biCompression = BI_RGB;; - dibInfo.bmiHeader.biHeight = -bm.bmHeight; - dibInfo.bmiHeader.biWidth = bm.bmWidth; - dibInfo.bmiHeader.biPlanes = 1; - dibInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - dibInfo.bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight * 4; - - HDC displayDC = GetDC(NULL); - if (!displayDC) { - qWarning("::GetDIBits(), failed to GetDC"); - return 0; - } - - int ret = bm.bmHeight; - - hTargetBitmap = CreateDIBSection(displayDC, (const BITMAPINFO*) &dibInfo, DIB_RGB_COLORS, - (void**)&pixels, NULL, 0); - if (!hTargetBitmap) { - qWarning("::GetDIBits(), failed to CreateDIBSection"); - return 0; - } - - HDC hdcSrc = CreateCompatibleDC(displayDC); - HDC hdcDst = CreateCompatibleDC(displayDC); - - if (!(hdcDst && hdcSrc)) { - qWarning("::GetDIBits(), failed to CreateCompatibleDC"); - ret = 0; - } - - HBITMAP hOldBitmap1 = (HBITMAP) SelectObject(hdcSrc, hSourceBitmap); - HBITMAP hOldBitmap2 = (HBITMAP) SelectObject(hdcDst, hTargetBitmap); - - if (!(hOldBitmap1 && hOldBitmap2)) { - qWarning("::GetDIBits(), failed to SelectObject for bitmaps"); - ret = 0; - } - - if (!BitBlt(hdcDst, 0, 0, bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, SRCCOPY)) { - qWarning("::GetDIBits(), BitBlt failed"); - ret = 0; - } - - SelectObject(hdcSrc, hOldBitmap1); - SelectObject(hdcDst, hOldBitmap2); - - DeleteDC(hdcSrc); - DeleteDC(hdcDst); - - ReleaseDC(NULL, displayDC); - - memcpy(lpvBits, pixels, dibInfo.bmiHeader.biSizeImage); - - DeleteObject(hTargetBitmap); - return ret; -} - -HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd) -{ - SHELLEXECUTEINFO info; - info.hwnd = hwnd; - info.lpVerb = L"Open"; - info.lpFile = file; - info.lpParameters = params; - info.lpDirectory = dir; - info.nShow = showCmd; - info.cbSize = sizeof(info); - ShellExecuteEx(&info); - return info.hInstApp; -} - -// Clipboard -------------------------------------------------------- -BOOL qt_wince_ChangeClipboardChain( HWND /*hWndRemove*/, HWND /*hWndNewNext*/ ) -{ - return FALSE; -} - -HWND qt_wince_SetClipboardViewer( HWND /*hWndNewViewer*/ ) -{ - return NULL; -} - - -// Graphics --------------------------------------------------------- -COLORREF qt_wince_PALETTEINDEX( WORD /*wPaletteIndex*/) -{ - return 0; -} - -// Internal Qt ----------------------------------------------------- -bool qt_wince_is_platform(const QString &platformString) { - wchar_t tszPlatform[64]; - if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(tszPlatform) / sizeof(wchar_t), tszPlatform, 0)) - if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform)) - return true; - return false; -} - -int qt_wince_get_build() -{ - OSVERSIONINFO osvi; - osvi.dwOSVersionInfoSize = sizeof(osvi); - if (GetVersionEx(&osvi)) { - return osvi.dwBuildNumber; - } - return 0; -} - -int qt_wince_get_version() -{ - OSVERSIONINFO osvi; - osvi.dwOSVersionInfoSize = sizeof(osvi); - if (GetVersionEx(&osvi)) { - return (osvi.dwMajorVersion * 10 + osvi.dwMinorVersion); - } - return 0; -} - -bool qt_wince_is_windows_mobile_65() -{ - const DWORD dwFirstWM65BuildNumber = 21139; - OSVERSIONINFO osvi; - osvi.dwOSVersionInfoSize = sizeof(osvi); - if (!GetVersionEx(&osvi)) - return false; - return osvi.dwMajorVersion > 5 - || (osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion > 2 || - (osvi.dwMinorVersion == 2 && osvi.dwBuildNumber >= dwFirstWM65BuildNumber))); -} - -bool qt_wince_is_pocket_pc() { - return qt_wince_is_platform(QString::fromLatin1("PocketPC")); -} - -bool qt_wince_is_smartphone() { - return qt_wince_is_platform(QString::fromLatin1("Smartphone")); -} -bool qt_wince_is_mobile() { - return (qt_wince_is_smartphone() || qt_wince_is_pocket_pc()); -} - -bool qt_wince_is_high_dpi() { - if (!qt_wince_is_pocket_pc()) - return false; - HDC deviceContext = GetDC(0); - int dpi = GetDeviceCaps(deviceContext, LOGPIXELSX); - ReleaseDC(0, deviceContext); - if ((dpi < 1000) && (dpi > 0)) - return dpi > 96; - else - return false; -} - -void qt_wince_maximize(QWidget *widget) -{ - HWND hwnd = widget->winId(); - if (qt_wince_is_mobile()) { - AygSHINITDLGINFO shidi; - shidi.dwMask = SHIDIM_FLAGS; - shidi.hDlg = hwnd; - shidi.dwFlags = SHIDIF_SIZEDLGFULLSCREEN; - if (widget->windowFlags() & Qt::WindowCancelButtonHint) - shidi.dwFlags |= SHIDIF_CANCELBUTTON; - if (widget->windowFlags() & Qt::WindowOkButtonHint) - shidi.dwFlags |= SHIDIF_DONEBUTTON; - if (!(widget->windowFlags() & (Qt::WindowCancelButtonHint | Qt::WindowOkButtonHint))) - shidi.dwFlags |= SHIDIF_CANCELBUTTON; - resolveAygLibs(); - if (ptrAygInitDialog) - ptrAygInitDialog(&shidi); - } else { - RECT r; - SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); - MoveWindow(hwnd, r.top, r.left, r.right - r.left, r.bottom - r.top, true); - SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) | WS_EX_NODRAG); - } -} - -void qt_wince_unmaximize(QWidget *widget) -{ - if (ptrAygSHDoneButton && qt_wince_is_mobile() - && !(widget->windowFlags() & (Qt::WindowCancelButtonHint | Qt::WindowOkButtonHint))) - { - // Hide the [X] button, we've added in qt_wince_maximize. - ptrAygSHDoneButton(widget->winId(), SHDB_HIDE); - } -} - -void qt_wince_minimize(HWND hwnd) -{ -#ifdef Q_OS_WINCE_WM - ShowWindow(hwnd, SW_HIDE); -#else - if (!IsWindowVisible(hwnd)) { - // Hack for an initial showMinimized. - // Without it, our widget doesn't appear in the task bar. - ShowWindow(hwnd, SW_SHOW); - } - ShowWindow(hwnd, SW_MINIMIZE); -#endif -} - -void qt_wince_hide_taskbar(HWND hwnd) { - if (ptrAygFullScreen) - ptrAygFullScreen(hwnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON); -} - -void qt_wince_full_screen(HWND hwnd, bool fullScreen, UINT swpf) { - resolveAygLibs(); - if (fullScreen) { - QRect r = qApp->desktop()->screenGeometry(QWidget::find(hwnd)); - SetWindowPos(hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf); - if (ptrAygFullScreen) - ptrAygFullScreen(hwnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON); - if (!qt_wince_is_mobile()) { - HWND handle = FindWindow(L"HHTaskBar", L""); - if (handle) { - ShowWindow(handle, 0); - EnableWindow(handle, false); - } - } - } else { - if (ptrAygFullScreen) - ptrAygFullScreen(hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON); - SetWindowPos(hwnd, 0, 0, 0, 0, 0, swpf); - if (!qt_wince_is_mobile()) { - HWND handle = FindWindow(L"HHTaskBar", L""); - if (handle) { - ShowWindow(handle, 1); - EnableWindow(handle, true); - } - } - } -} - -void qt_wince_show_SIP(bool show) -{ - resolveAygLibs(); - if (!ptrAygSHSipInfo) - return; - - AygSIPINFO si; - memset(&si, 0, sizeof(si)); - si.cbSize = sizeof(si); - ptrAygSHSipInfo(SPI_GETSIPINFO, 0, &si, 0); - si.cbSize = sizeof(si); - si.fdwFlags = (show ? SIPF_ON : SIPF_OFF); - ptrAygSHSipInfo(SPI_SETSIPINFO, 0, &si, 0); -} diff --git a/src/gui/platforms/win/qguifunctions_wince.h b/src/gui/platforms/win/qguifunctions_wince.h deleted file mode 100644 index 2e14de0693..0000000000 --- a/src/gui/platforms/win/qguifunctions_wince.h +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QGUIFUNCTIONS_WCE_H -#define QGUIFUNCTIONS_WCE_H -#ifdef Q_OS_WINCE -#include <QtCore/qfunctions_wince.h> -#define UNDER_NT -#include <wingdi.h> - -#ifdef QT_BUILD_GUI_LIB -QT_BEGIN_HEADER -QT_BEGIN_NAMESPACE -QT_MODULE(Gui) -QT_END_NAMESPACE -QT_END_HEADER -#endif - -// application defines -#define SPI_SETNONCLIENTMETRICS 72 -#define SPI_SETICONTITLELOGFONT 0x0022 -#define WM_ACTIVATEAPP 0x001c -#define SW_PARENTCLOSING 1 -#define SW_OTHERMAXIMIZED 2 -#define SW_PARENTOPENING 3 -#define SW_OTHERRESTORED 4 -#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) - -// drag n drop -#ifndef CFSTR_PERFORMEDDROPEFFECT -#define CFSTR_PERFORMEDDROPEFFECT TEXT("Performed DropEffect") -#endif -int qt_wince_GetDIBits(HDC, HBITMAP, uint, uint, void*, LPBITMAPINFO, uint); -#define GetDIBits(a,b,c,d,e,f,g) qt_wince_GetDIBits(a,b,c,d,e,f,g) - -// QWidget -#define SW_SHOWMINIMIZED SW_MINIMIZE - -// QRegion -#define ALTERNATE 0 -#define WINDING 1 - -// QFontEngine -typedef struct _FIXED { - WORD fract; - short value; -} FIXED; - -typedef struct tagPOINTFX { - FIXED x; - FIXED y; -} POINTFX; - -typedef struct _MAT2 { - FIXED eM11; - FIXED eM12; - FIXED eM21; - FIXED eM22; -} MAT2; - -typedef struct _GLYPHMETRICS { - UINT gmBlackBoxX; - UINT gmBlackBoxY; - POINT gmptGlyphOrigin; - short gmCellIncX; - short gmCellIncY; -} GLYPHMETRICS; - -typedef struct tagTTPOLYGONHEADER -{ - DWORD cb; - DWORD dwType; - POINTFX pfxStart; -} TTPOLYGONHEADER; - -typedef struct tagTTPOLYCURVE -{ - WORD wType; - WORD cpfx; - POINTFX apfx[1]; -} TTPOLYCURVE; - -#define GGO_NATIVE 2 -#define GGO_GLYPH_INDEX 0x0080 -#define TT_PRIM_LINE 1 -#define TT_PRIM_QSPLINE 2 -#define TT_PRIM_CSPLINE 3 -#define ANSI_VAR_FONT 12 - -HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR operation, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd); -#define ShellExecute(a,b,c,d,e,f) qt_wince_ShellExecute(a,b,c,d,e,f) - - -// Clipboard -------------------------------------------------------- -#define WM_CHANGECBCHAIN 1 -#define WM_DRAWCLIPBOARD 2 - -BOOL qt_wince_ChangeClipboardChain( - HWND hWndRemove, // handle to window to remove - HWND hWndNewNext // handle to next window -); -#define ChangeClipboardChain(a,b) qt_wince_ChangeClipboardChain(a,b); - -HWND qt_wince_SetClipboardViewer( - HWND hWndNewViewer // handle to clipboard viewer window -); -#define SetClipboardViewer(a) qt_wince_SetClipboardViewer(a) - -// Graphics --------------------------------------------------------- -COLORREF qt_wince_PALETTEINDEX( WORD wPaletteIndex ); -#define PALETTEINDEX(a) qt_wince_PALETTEINDEX(a) - -#endif // Q_OS_WINCE -#endif // QGUIFUNCTIONS_WCE_H diff --git a/src/gui/platforms/win/qkeymapper_win.cpp b/src/gui/platforms/win/qkeymapper_win.cpp deleted file mode 100644 index 92fa582617..0000000000 --- a/src/gui/platforms/win/qkeymapper_win.cpp +++ /dev/null @@ -1,1207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkeymapper_p.h" - -#include <qt_windows.h> -#include <qdebug.h> -#include <private/qevent_p.h> -#include <private/qlocale_p.h> -#include <private/qapplication_p.h> -#include <qwidget.h> -#include <qapplication.h> -#include <ctype.h> - -QT_BEGIN_NAMESPACE - -// Uncommend, to show debugging information for the keymapper -//#define DEBUG_KEYMAPPER - -// Implemented elsewhere -extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); - -extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); -#ifndef LANG_PASHTO -#define LANG_PASHTO 0x63 -#endif -#ifndef LANG_SYRIAC -#define LANG_SYRIAC 0x5a -#endif -#ifndef LANG_DIVEHI -#define LANG_DIVEHI 0x65 -#endif -#ifndef VK_OEM_PLUS -#define VK_OEM_PLUS 0xBB -#endif -#ifndef VK_OEM_3 -#define VK_OEM_3 0xC0 -#endif - -#if defined(Q_OS_WINCE) -bool GetKeyboardState(unsigned char* kbuffer) -{ - for (int i=0; i< 256; ++i) - kbuffer[i] = GetAsyncKeyState(i); - return true; -} -#endif -// Key recorder ------------------------------------------------------------------------[ start ] -- -struct KeyRecord { - KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {} - KeyRecord() {} - - int code; - int ascii; - int state; - QString text; -}; - -static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers... -struct KeyRecorder -{ - KeyRecorder() : nrecs(0) {} - - inline KeyRecord *findKey(int code, bool remove); - inline void storeKey(int code, int ascii, int state, const QString& text); - inline void clearKeys(); - - int nrecs; - KeyRecord deleted_record; // A copy of last entry removed from records[] - KeyRecord records[QT_MAX_KEY_RECORDINGS]; -}; -static KeyRecorder key_recorder; - -KeyRecord *KeyRecorder::findKey(int code, bool remove) -{ - KeyRecord *result = 0; - for (int i = 0; i < nrecs; ++i) { - if (records[i].code == code) { - if (remove) { - deleted_record = records[i]; - // Move rest down, and decrease count - while (i + 1 < nrecs) { - records[i] = records[i + 1]; - ++i; - } - --nrecs; - result = &deleted_record; - } else { - result = &records[i]; - } - break; - } - } - return result; -} - -void KeyRecorder::storeKey(int code, int ascii, int state, const QString& text) -{ - Q_ASSERT_X(nrecs != QT_MAX_KEY_RECORDINGS, - "Internal KeyRecorder", - "Keyboard recorder buffer overflow, consider increasing QT_MAX_KEY_RECORDINGS"); - - if (nrecs == QT_MAX_KEY_RECORDINGS) { - qWarning("Qt: Internal keyboard buffer overflow"); - return; - } - records[nrecs++] = KeyRecord(code,ascii,state,text); -} - -void KeyRecorder::clearKeys() -{ - nrecs = 0; -} -// Key recorder --------------------------------------------------------------------------[ end ] -- - - -// Key translation ---------------------------------------------------------------------[ start ] -- -// Meaning of values: -// 0 = Character output key, needs keyboard driver mapping -// Key_unknown = Unknown Virtual Key, no translation possible, ignore -static const uint KeyTbl[] = { // Keyboard mapping table - // Dec | Hex | Windows Virtual key - Qt::Key_unknown, // 0 0x00 - Qt::Key_unknown, // 1 0x01 VK_LBUTTON | Left mouse button - Qt::Key_unknown, // 2 0x02 VK_RBUTTON | Right mouse button - Qt::Key_Cancel, // 3 0x03 VK_CANCEL | Control-Break processing - Qt::Key_unknown, // 4 0x04 VK_MBUTTON | Middle mouse button - Qt::Key_unknown, // 5 0x05 VK_XBUTTON1 | X1 mouse button - Qt::Key_unknown, // 6 0x06 VK_XBUTTON2 | X2 mouse button - Qt::Key_unknown, // 7 0x07 -- unassigned -- - Qt::Key_Backspace, // 8 0x08 VK_BACK | BackSpace key - Qt::Key_Tab, // 9 0x09 VK_TAB | Tab key - Qt::Key_unknown, // 10 0x0A -- reserved -- - Qt::Key_unknown, // 11 0x0B -- reserved -- - Qt::Key_Clear, // 12 0x0C VK_CLEAR | Clear key - Qt::Key_Return, // 13 0x0D VK_RETURN | Enter key - Qt::Key_unknown, // 14 0x0E -- unassigned -- - Qt::Key_unknown, // 15 0x0F -- unassigned -- - Qt::Key_Shift, // 16 0x10 VK_SHIFT | Shift key - Qt::Key_Control, // 17 0x11 VK_CONTROL | Ctrl key - Qt::Key_Alt, // 18 0x12 VK_MENU | Alt key - Qt::Key_Pause, // 19 0x13 VK_PAUSE | Pause key - Qt::Key_CapsLock, // 20 0x14 VK_CAPITAL | Caps-Lock - Qt::Key_unknown, // 21 0x15 VK_KANA / VK_HANGUL | IME Kana or Hangul mode - Qt::Key_unknown, // 22 0x16 -- unassigned -- - Qt::Key_unknown, // 23 0x17 VK_JUNJA | IME Junja mode - Qt::Key_unknown, // 24 0x18 VK_FINAL | IME final mode - Qt::Key_unknown, // 25 0x19 VK_HANJA / VK_KANJI | IME Hanja or Kanji mode - Qt::Key_unknown, // 26 0x1A -- unassigned -- - Qt::Key_Escape, // 27 0x1B VK_ESCAPE | Esc key - Qt::Key_unknown, // 28 0x1C VK_CONVERT | IME convert - Qt::Key_unknown, // 29 0x1D VK_NONCONVERT | IME non-convert - Qt::Key_unknown, // 30 0x1E VK_ACCEPT | IME accept - Qt::Key_Mode_switch,// 31 0x1F VK_MODECHANGE | IME mode change request - Qt::Key_Space, // 32 0x20 VK_SPACE | Spacebar - Qt::Key_PageUp, // 33 0x21 VK_PRIOR | Page Up key - Qt::Key_PageDown, // 34 0x22 VK_NEXT | Page Down key - Qt::Key_End, // 35 0x23 VK_END | End key - Qt::Key_Home, // 36 0x24 VK_HOME | Home key - Qt::Key_Left, // 37 0x25 VK_LEFT | Left arrow key - Qt::Key_Up, // 38 0x26 VK_UP | Up arrow key - Qt::Key_Right, // 39 0x27 VK_RIGHT | Right arrow key - Qt::Key_Down, // 40 0x28 VK_DOWN | Down arrow key - Qt::Key_Select, // 41 0x29 VK_SELECT | Select key - Qt::Key_Printer, // 42 0x2A VK_PRINT | Print key - Qt::Key_Execute, // 43 0x2B VK_EXECUTE | Execute key - Qt::Key_Print, // 44 0x2C VK_SNAPSHOT | Print Screen key - Qt::Key_Insert, // 45 0x2D VK_INSERT | Ins key - Qt::Key_Delete, // 46 0x2E VK_DELETE | Del key - Qt::Key_Help, // 47 0x2F VK_HELP | Help key - 0, // 48 0x30 (VK_0) | 0 key - 0, // 49 0x31 (VK_1) | 1 key - 0, // 50 0x32 (VK_2) | 2 key - 0, // 51 0x33 (VK_3) | 3 key - 0, // 52 0x34 (VK_4) | 4 key - 0, // 53 0x35 (VK_5) | 5 key - 0, // 54 0x36 (VK_6) | 6 key - 0, // 55 0x37 (VK_7) | 7 key - 0, // 56 0x38 (VK_8) | 8 key - 0, // 57 0x39 (VK_9) | 9 key - Qt::Key_unknown, // 58 0x3A -- unassigned -- - Qt::Key_unknown, // 59 0x3B -- unassigned -- - Qt::Key_unknown, // 60 0x3C -- unassigned -- - Qt::Key_unknown, // 61 0x3D -- unassigned -- - Qt::Key_unknown, // 62 0x3E -- unassigned -- - Qt::Key_unknown, // 63 0x3F -- unassigned -- - Qt::Key_unknown, // 64 0x40 -- unassigned -- - 0, // 65 0x41 (VK_A) | A key - 0, // 66 0x42 (VK_B) | B key - 0, // 67 0x43 (VK_C) | C key - 0, // 68 0x44 (VK_D) | D key - 0, // 69 0x45 (VK_E) | E key - 0, // 70 0x46 (VK_F) | F key - 0, // 71 0x47 (VK_G) | G key - 0, // 72 0x48 (VK_H) | H key - 0, // 73 0x49 (VK_I) | I key - 0, // 74 0x4A (VK_J) | J key - 0, // 75 0x4B (VK_K) | K key - 0, // 76 0x4C (VK_L) | L key - 0, // 77 0x4D (VK_M) | M key - 0, // 78 0x4E (VK_N) | N key - 0, // 79 0x4F (VK_O) | O key - 0, // 80 0x50 (VK_P) | P key - 0, // 81 0x51 (VK_Q) | Q key - 0, // 82 0x52 (VK_R) | R key - 0, // 83 0x53 (VK_S) | S key - 0, // 84 0x54 (VK_T) | T key - 0, // 85 0x55 (VK_U) | U key - 0, // 86 0x56 (VK_V) | V key - 0, // 87 0x57 (VK_W) | W key - 0, // 88 0x58 (VK_X) | X key - 0, // 89 0x59 (VK_Y) | Y key - 0, // 90 0x5A (VK_Z) | Z key - Qt::Key_Meta, // 91 0x5B VK_LWIN | Left Windows - MS Natural kbd - Qt::Key_Meta, // 92 0x5C VK_RWIN | Right Windows - MS Natural kbd - Qt::Key_Menu, // 93 0x5D VK_APPS | Application key-MS Natural kbd - Qt::Key_unknown, // 94 0x5E -- reserved -- - Qt::Key_Sleep, // 95 0x5F VK_SLEEP - Qt::Key_0, // 96 0x60 VK_NUMPAD0 | Numeric keypad 0 key - Qt::Key_1, // 97 0x61 VK_NUMPAD1 | Numeric keypad 1 key - Qt::Key_2, // 98 0x62 VK_NUMPAD2 | Numeric keypad 2 key - Qt::Key_3, // 99 0x63 VK_NUMPAD3 | Numeric keypad 3 key - Qt::Key_4, // 100 0x64 VK_NUMPAD4 | Numeric keypad 4 key - Qt::Key_5, // 101 0x65 VK_NUMPAD5 | Numeric keypad 5 key - Qt::Key_6, // 102 0x66 VK_NUMPAD6 | Numeric keypad 6 key - Qt::Key_7, // 103 0x67 VK_NUMPAD7 | Numeric keypad 7 key - Qt::Key_8, // 104 0x68 VK_NUMPAD8 | Numeric keypad 8 key - Qt::Key_9, // 105 0x69 VK_NUMPAD9 | Numeric keypad 9 key - Qt::Key_Asterisk, // 106 0x6A VK_MULTIPLY | Multiply key - Qt::Key_Plus, // 107 0x6B VK_ADD | Add key - Qt::Key_Comma, // 108 0x6C VK_SEPARATOR | Separator key - Qt::Key_Minus, // 109 0x6D VK_SUBTRACT | Subtract key - Qt::Key_Period, // 110 0x6E VK_DECIMAL | Decimal key - Qt::Key_Slash, // 111 0x6F VK_DIVIDE | Divide key - Qt::Key_F1, // 112 0x70 VK_F1 | F1 key - Qt::Key_F2, // 113 0x71 VK_F2 | F2 key - Qt::Key_F3, // 114 0x72 VK_F3 | F3 key - Qt::Key_F4, // 115 0x73 VK_F4 | F4 key - Qt::Key_F5, // 116 0x74 VK_F5 | F5 key - Qt::Key_F6, // 117 0x75 VK_F6 | F6 key - Qt::Key_F7, // 118 0x76 VK_F7 | F7 key - Qt::Key_F8, // 119 0x77 VK_F8 | F8 key - Qt::Key_F9, // 120 0x78 VK_F9 | F9 key - Qt::Key_F10, // 121 0x79 VK_F10 | F10 key - Qt::Key_F11, // 122 0x7A VK_F11 | F11 key - Qt::Key_F12, // 123 0x7B VK_F12 | F12 key - Qt::Key_F13, // 124 0x7C VK_F13 | F13 key - Qt::Key_F14, // 125 0x7D VK_F14 | F14 key - Qt::Key_F15, // 126 0x7E VK_F15 | F15 key - Qt::Key_F16, // 127 0x7F VK_F16 | F16 key - Qt::Key_F17, // 128 0x80 VK_F17 | F17 key - Qt::Key_F18, // 129 0x81 VK_F18 | F18 key - Qt::Key_F19, // 130 0x82 VK_F19 | F19 key - Qt::Key_F20, // 131 0x83 VK_F20 | F20 key - Qt::Key_F21, // 132 0x84 VK_F21 | F21 key - Qt::Key_F22, // 133 0x85 VK_F22 | F22 key - Qt::Key_F23, // 134 0x86 VK_F23 | F23 key - Qt::Key_F24, // 135 0x87 VK_F24 | F24 key - Qt::Key_unknown, // 136 0x88 -- unassigned -- - Qt::Key_unknown, // 137 0x89 -- unassigned -- - Qt::Key_unknown, // 138 0x8A -- unassigned -- - Qt::Key_unknown, // 139 0x8B -- unassigned -- - Qt::Key_unknown, // 140 0x8C -- unassigned -- - Qt::Key_unknown, // 141 0x8D -- unassigned -- - Qt::Key_unknown, // 142 0x8E -- unassigned -- - Qt::Key_unknown, // 143 0x8F -- unassigned -- - Qt::Key_NumLock, // 144 0x90 VK_NUMLOCK | Num Lock key - Qt::Key_ScrollLock, // 145 0x91 VK_SCROLL | Scroll Lock key - // Fujitsu/OASYS kbd -------------------- - 0, //Qt::Key_Jisho, // 146 0x92 VK_OEM_FJ_JISHO | 'Dictionary' key / - // VK_OEM_NEC_EQUAL = key on numpad on NEC PC-9800 kbd - Qt::Key_Massyo, // 147 0x93 VK_OEM_FJ_MASSHOU | 'Unregister word' key - Qt::Key_Touroku, // 148 0x94 VK_OEM_FJ_TOUROKU | 'Register word' key - 0, //Qt::Key_Oyayubi_Left,//149 0x95 VK_OEM_FJ_LOYA | 'Left OYAYUBI' key - 0, //Qt::Key_Oyayubi_Right,//150 0x96 VK_OEM_FJ_ROYA | 'Right OYAYUBI' key - Qt::Key_unknown, // 151 0x97 -- unassigned -- - Qt::Key_unknown, // 152 0x98 -- unassigned -- - Qt::Key_unknown, // 153 0x99 -- unassigned -- - Qt::Key_unknown, // 154 0x9A -- unassigned -- - Qt::Key_unknown, // 155 0x9B -- unassigned -- - Qt::Key_unknown, // 156 0x9C -- unassigned -- - Qt::Key_unknown, // 157 0x9D -- unassigned -- - Qt::Key_unknown, // 158 0x9E -- unassigned -- - Qt::Key_unknown, // 159 0x9F -- unassigned -- - Qt::Key_Shift, // 160 0xA0 VK_LSHIFT | Left Shift key - Qt::Key_Shift, // 161 0xA1 VK_RSHIFT | Right Shift key - Qt::Key_Control, // 162 0xA2 VK_LCONTROL | Left Ctrl key - Qt::Key_Control, // 163 0xA3 VK_RCONTROL | Right Ctrl key - Qt::Key_Alt, // 164 0xA4 VK_LMENU | Left Menu key - Qt::Key_Alt, // 165 0xA5 VK_RMENU | Right Menu key - Qt::Key_Back, // 166 0xA6 VK_BROWSER_BACK | Browser Back key - Qt::Key_Forward, // 167 0xA7 VK_BROWSER_FORWARD | Browser Forward key - Qt::Key_Refresh, // 168 0xA8 VK_BROWSER_REFRESH | Browser Refresh key - Qt::Key_Stop, // 169 0xA9 VK_BROWSER_STOP | Browser Stop key - Qt::Key_Search, // 170 0xAA VK_BROWSER_SEARCH | Browser Search key - Qt::Key_Favorites, // 171 0xAB VK_BROWSER_FAVORITES| Browser Favorites key - Qt::Key_HomePage, // 172 0xAC VK_BROWSER_HOME | Browser Start and Home key - Qt::Key_VolumeMute, // 173 0xAD VK_VOLUME_MUTE | Volume Mute key - Qt::Key_VolumeDown, // 174 0xAE VK_VOLUME_DOWN | Volume Down key - Qt::Key_VolumeUp, // 175 0xAF VK_VOLUME_UP | Volume Up key - Qt::Key_MediaNext, // 176 0xB0 VK_MEDIA_NEXT_TRACK | Next Track key - Qt::Key_MediaPrevious, //177 0xB1 VK_MEDIA_PREV_TRACK | Previous Track key - Qt::Key_MediaStop, // 178 0xB2 VK_MEDIA_STOP | Stop Media key - Qt::Key_MediaPlay, // 179 0xB3 VK_MEDIA_PLAY_PAUSE | Play/Pause Media key - Qt::Key_LaunchMail, // 180 0xB4 VK_LAUNCH_MAIL | Start Mail key - Qt::Key_LaunchMedia,// 181 0xB5 VK_LAUNCH_MEDIA_SELECT Select Media key - Qt::Key_Launch0, // 182 0xB6 VK_LAUNCH_APP1 | Start Application 1 key - Qt::Key_Launch1, // 183 0xB7 VK_LAUNCH_APP2 | Start Application 2 key - Qt::Key_unknown, // 184 0xB8 -- reserved -- - Qt::Key_unknown, // 185 0xB9 -- reserved -- - 0, // 186 0xBA VK_OEM_1 | ';:' for US - 0, // 187 0xBB VK_OEM_PLUS | '+' any country - 0, // 188 0xBC VK_OEM_COMMA | ',' any country - 0, // 189 0xBD VK_OEM_MINUS | '-' any country - 0, // 190 0xBE VK_OEM_PERIOD | '.' any country - 0, // 191 0xBF VK_OEM_2 | '/?' for US - 0, // 192 0xC0 VK_OEM_3 | '`~' for US - Qt::Key_unknown, // 193 0xC1 -- reserved -- - Qt::Key_unknown, // 194 0xC2 -- reserved -- - Qt::Key_unknown, // 195 0xC3 -- reserved -- - Qt::Key_unknown, // 196 0xC4 -- reserved -- - Qt::Key_unknown, // 197 0xC5 -- reserved -- - Qt::Key_unknown, // 198 0xC6 -- reserved -- - Qt::Key_unknown, // 199 0xC7 -- reserved -- - Qt::Key_unknown, // 200 0xC8 -- reserved -- - Qt::Key_unknown, // 201 0xC9 -- reserved -- - Qt::Key_unknown, // 202 0xCA -- reserved -- - Qt::Key_unknown, // 203 0xCB -- reserved -- - Qt::Key_unknown, // 204 0xCC -- reserved -- - Qt::Key_unknown, // 205 0xCD -- reserved -- - Qt::Key_unknown, // 206 0xCE -- reserved -- - Qt::Key_unknown, // 207 0xCF -- reserved -- - Qt::Key_unknown, // 208 0xD0 -- reserved -- - Qt::Key_unknown, // 209 0xD1 -- reserved -- - Qt::Key_unknown, // 210 0xD2 -- reserved -- - Qt::Key_unknown, // 211 0xD3 -- reserved -- - Qt::Key_unknown, // 212 0xD4 -- reserved -- - Qt::Key_unknown, // 213 0xD5 -- reserved -- - Qt::Key_unknown, // 214 0xD6 -- reserved -- - Qt::Key_unknown, // 215 0xD7 -- reserved -- - Qt::Key_unknown, // 216 0xD8 -- unassigned -- - Qt::Key_unknown, // 217 0xD9 -- unassigned -- - Qt::Key_unknown, // 218 0xDA -- unassigned -- - 0, // 219 0xDB VK_OEM_4 | '[{' for US - 0, // 220 0xDC VK_OEM_5 | '\|' for US - 0, // 221 0xDD VK_OEM_6 | ']}' for US - 0, // 222 0xDE VK_OEM_7 | ''"' for US - 0, // 223 0xDF VK_OEM_8 - Qt::Key_unknown, // 224 0xE0 -- reserved -- - Qt::Key_unknown, // 225 0xE1 VK_OEM_AX | 'AX' key on Japanese AX kbd - Qt::Key_unknown, // 226 0xE2 VK_OEM_102 | "<>" or "\|" on RT 102-key kbd - Qt::Key_unknown, // 227 0xE3 VK_ICO_HELP | Help key on ICO - Qt::Key_unknown, // 228 0xE4 VK_ICO_00 | 00 key on ICO - Qt::Key_unknown, // 229 0xE5 VK_PROCESSKEY | IME Process key - Qt::Key_unknown, // 230 0xE6 VK_ICO_CLEAR | - Qt::Key_unknown, // 231 0xE7 VK_PACKET | Unicode char as keystrokes - Qt::Key_unknown, // 232 0xE8 -- unassigned -- - // Nokia/Ericsson definitions --------------- - Qt::Key_unknown, // 233 0xE9 VK_OEM_RESET - Qt::Key_unknown, // 234 0xEA VK_OEM_JUMP - Qt::Key_unknown, // 235 0xEB VK_OEM_PA1 - Qt::Key_unknown, // 236 0xEC VK_OEM_PA2 - Qt::Key_unknown, // 237 0xED VK_OEM_PA3 - Qt::Key_unknown, // 238 0xEE VK_OEM_WSCTRL - Qt::Key_unknown, // 239 0xEF VK_OEM_CUSEL - Qt::Key_unknown, // 240 0xF0 VK_OEM_ATTN - Qt::Key_unknown, // 241 0xF1 VK_OEM_FINISH - Qt::Key_unknown, // 242 0xF2 VK_OEM_COPY - Qt::Key_unknown, // 243 0xF3 VK_OEM_AUTO - Qt::Key_unknown, // 244 0xF4 VK_OEM_ENLW - Qt::Key_unknown, // 245 0xF5 VK_OEM_BACKTAB - Qt::Key_unknown, // 246 0xF6 VK_ATTN | Attn key - Qt::Key_unknown, // 247 0xF7 VK_CRSEL | CrSel key - Qt::Key_unknown, // 248 0xF8 VK_EXSEL | ExSel key - Qt::Key_unknown, // 249 0xF9 VK_EREOF | Erase EOF key - Qt::Key_Play, // 250 0xFA VK_PLAY | Play key - Qt::Key_Zoom, // 251 0xFB VK_ZOOM | Zoom key - Qt::Key_unknown, // 252 0xFC VK_NONAME | Reserved - Qt::Key_unknown, // 253 0xFD VK_PA1 | PA1 key - Qt::Key_Clear, // 254 0xFE VK_OEM_CLEAR | Clear key - 0 -}; - -// Possible modifier states. -// NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()! -static const Qt::KeyboardModifiers ModsTbl[] = { - Qt::NoModifier, // 0 - Qt::ShiftModifier, // 1 - Qt::ControlModifier, // 2 - Qt::ControlModifier | Qt::ShiftModifier, // 3 - Qt::AltModifier, // 4 - Qt::AltModifier | Qt::ShiftModifier, // 5 - Qt::AltModifier | Qt::ControlModifier, // 6 - Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7 - Qt::NoModifier, // Fall-back to raw Key_* -}; - -/** - Remap return or action key to select key for windows mobile. -*/ -inline int winceKeyBend(int keyCode) -{ -#if defined(Q_OS_WINCE_WM) && defined(QT_KEYPAD_NAVIGATION) - // remap return or action key to select key for windows mobile. - // will be changed to a table remapping function in the next version (4.6/7). - if (keyCode == VK_RETURN && QApplication::keypadNavigationEnabled()) - return Qt::Key_Select; - else - return KeyTbl[keyCode]; -#else - return KeyTbl[keyCode]; -#endif -} - -#if defined(Q_OS_WINCE) - // Use the KeyTbl to resolve a Qt::Key out of the virtual keys. - // In case it is not resolvable, continue using the virtual key itself. - -QT_BEGIN_INCLUDE_NAMESPACE - -int ToUnicode(UINT vk, int /*scancode*/, unsigned char* /*kbdBuffer*/, LPWSTR unicodeBuffer, int, int) -{ - QT_USE_NAMESPACE - QChar* buf = reinterpret_cast< QChar*>(unicodeBuffer); - if (KeyTbl[vk] == 0) { - buf[0] = vk; - return 1; - } - return 0; -} - -int ToAscii(UINT vk, int scancode, unsigned char *kbdBuffer, LPWORD unicodeBuffer, int flag) -{ - return ToUnicode(vk, scancode, kbdBuffer, (LPWSTR) unicodeBuffer, 0, flag); - -} -QT_END_INCLUDE_NAMESPACE - -#endif - -// Translate a VK into a Qt key code, or unicode character -static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0) -{ - Q_ASSERT(vk > 0 && vk < 256); - int code = 0; - QChar unicodeBuffer[5]; - int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0); - if (res) - code = unicodeBuffer[0].toUpper().unicode(); - - // Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a - // proper Qt::Key_ code - if (code < 0x20 || code == 0x7f) // Handles res==0 too - code = winceKeyBend(vk); - - if (isDeadkey) - *isDeadkey = (res == -1); - - return code == Qt::Key_unknown ? 0 : code; -} - -Q_GUI_EXPORT int qt_translateKeyCode(int vk) -{ - int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk); - return code == Qt::Key_unknown ? 0 : code; -} - -static inline int asciiToKeycode(char a, int state) -{ - if (a >= 'a' && a <= 'z') - a = toupper(a); - if ((state & Qt::ControlModifier) != 0) { - if (a >= 0 && a <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_ - a += '@'; // to @..A..Z.._ - } - return a & 0xff; -} - -static inline bool isModifierKey(int code) -{ - return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock); -} -// Key translation -----------------------------------------------------------------------[ end ]--- - - -static void qt_show_system_menu(QWidget* tlw) -{ - Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created)); - HMENU menu = GetSystemMenu(tlw->internalWinId(), FALSE); - if (!menu) - return; // no menu for this window - -#define enabled (MF_BYCOMMAND | MF_ENABLED) -#define disabled (MF_BYCOMMAND | MF_GRAYED) - -#ifndef Q_OS_WINCE - EnableMenuItem(menu, SC_MINIMIZE, (tlw->windowFlags() & Qt::WindowMinimizeButtonHint)?enabled:disabled); - bool maximized = IsZoomed(tlw->internalWinId()); - - EnableMenuItem(menu, SC_MAXIMIZE, ! (tlw->windowFlags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled); - EnableMenuItem(menu, SC_RESTORE, maximized?enabled:disabled); - - // We should _not_ check with the setFixedSize(x,y) case here, since Windows is not able to check - // this and our menu here would be out-of-sync with the menu produced by mouse-click on the - // System Menu, or right-click on the title bar. - EnableMenuItem(menu, SC_SIZE, (tlw->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled); - EnableMenuItem(menu, SC_MOVE, maximized?disabled:enabled); - EnableMenuItem(menu, SC_CLOSE, enabled); - // Set bold on close menu item - MENUITEMINFO closeItem; - closeItem.cbSize = sizeof(MENUITEMINFO); - closeItem.fMask = MIIM_STATE; - closeItem.fState = MFS_DEFAULT; - SetMenuItemInfo(menu, SC_CLOSE, FALSE, &closeItem); -#endif - -#undef enabled -#undef disabled - int ret = TrackPopupMenuEx(menu, - TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD, - tlw->geometry().x(), tlw->geometry().y(), - tlw->internalWinId(), - 0); - if (ret) - QtWndProc(tlw->internalWinId(), WM_SYSCOMMAND, ret, 0); -} - - -// QETWidget class is only for accessing the sendSpontaneousEvent function in QApplication -class QETWidget : public QWidget { -public: - static bool sendSpontaneousEvent(QObject *r, QEvent *e) - { return QApplication::sendSpontaneousEvent(r, e); } -}; - - -// Keyboard map private ----------------------------------------------------------------[ start ]--- - -/* - \internal - A Windows KeyboardLayoutItem has 8 possible states: - 1. Unmodified - 2. Shift - 3. Control - 4. Control + Shift - 5. Alt - 6. Alt + Shift - 7. Alt + Control - 8. Alt + Control + Shift -*/ -struct KeyboardLayoutItem { - bool dirty; - quint8 deadkeys; - quint32 qtKey[9]; // Can by any Qt::Key_<foo>, or unicode character -}; - -QKeyMapperPrivate::QKeyMapperPrivate() -{ - memset(keyLayout, 0, sizeof(keyLayout)); -} - -QKeyMapperPrivate::~QKeyMapperPrivate() -{ - deleteLayouts(); -} - -void QKeyMapperPrivate::deleteLayouts() -{ - for (int i = 0; i < 255; ++i) { - if (keyLayout[i]) { - delete keyLayout[i]; - keyLayout[i] = 0; - } - } -} - -void QKeyMapperPrivate::clearMappings() -{ - deleteLayouts(); - - /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout() - * returns a DWORD. */ - - LCID newLCID = MAKELCID((quintptr)GetKeyboardLayout(0), SORT_DEFAULT); -// keyboardInputLocale = qt_localeFromLCID(newLCID); - - bool bidi = false; - wchar_t LCIDFontSig[16]; - if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t)) - && (LCIDFontSig[7] & (wchar_t)0x0800)) - bidi = true; - - keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight; -} - -void QKeyMapperPrivate::clearRecordedKeys() -{ - key_recorder.clearKeys(); -} - - -inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt) -{ - kbd[VK_LSHIFT ] = (shift ? 0x80 : 0); - kbd[VK_SHIFT ] = (shift ? 0x80 : 0); - kbd[VK_LCONTROL] = (ctrl ? 0x80 : 0); - kbd[VK_CONTROL ] = (ctrl ? 0x80 : 0); - kbd[VK_RMENU ] = (alt ? 0x80 : 0); - kbd[VK_MENU ] = (alt ? 0x80 : 0); -} - -void QKeyMapperPrivate::updateKeyMap(const MSG &msg) -{ - unsigned char kbdBuffer[256]; // Will hold the complete keyboard state - GetKeyboardState(kbdBuffer); - quint32 scancode = (msg.lParam >> 16) & 0xfff; - updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam); -} - -void QKeyMapperPrivate::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode, - quint32 vk_key) -{ - if (!vk_key || (keyLayout[vk_key] && !keyLayout[vk_key]->dirty)) - return; - - if (!keyLayout[vk_key]) - keyLayout[vk_key] = new KeyboardLayoutItem; - - // Copy keyboard state, so we can modify and query output for each possible permutation - unsigned char buffer[256]; - memcpy(buffer, kbdBuffer, sizeof(buffer)); - // Always 0, as Windows doesn't treat these as modifiers; - buffer[VK_LWIN ] = 0; - buffer[VK_RWIN ] = 0; - buffer[VK_CAPITAL ] = 0; - buffer[VK_NUMLOCK ] = 0; - buffer[VK_SCROLL ] = 0; - // Always 0, since we'll only change the other versions - buffer[VK_RSHIFT ] = 0; - buffer[VK_RCONTROL] = 0; - buffer[VK_LMENU ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph - - bool isDeadKey = false; - keyLayout[vk_key]->deadkeys = 0; - keyLayout[vk_key]->dirty = false; - setKbdState(buffer, false, false, false); - keyLayout[vk_key]->qtKey[0] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x01 : 0; - setKbdState(buffer, true, false, false); - keyLayout[vk_key]->qtKey[1] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x02 : 0; - setKbdState(buffer, false, true, false); - keyLayout[vk_key]->qtKey[2] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x04 : 0; - setKbdState(buffer, true, true, false); - keyLayout[vk_key]->qtKey[3] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x08 : 0; - setKbdState(buffer, false, false, true); - keyLayout[vk_key]->qtKey[4] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x10 : 0; - setKbdState(buffer, true, false, true); - keyLayout[vk_key]->qtKey[5] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x20 : 0; - setKbdState(buffer, false, true, true); - keyLayout[vk_key]->qtKey[6] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x40 : 0; - setKbdState(buffer, true, true, true); - keyLayout[vk_key]->qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); - keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x80 : 0; - // Add a fall back key for layouts which don't do composition and show non-latin1 characters - int fallbackKey = winceKeyBend(vk_key); - if (!fallbackKey || fallbackKey == Qt::Key_unknown) { - fallbackKey = 0; - if (vk_key != keyLayout[vk_key]->qtKey[0] && vk_key < 0x5B && vk_key > 0x2F) - fallbackKey = vk_key; - } - keyLayout[vk_key]->qtKey[8] = fallbackKey; - - // If this vk_key a Dead Key - if (MapVirtualKey(vk_key, 2) & 0x80000000) { - // Push a Space, then the original key through the low-level ToAscii functions. - // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of - // the keyboard driver By doing the following, we set the keyboard driver state back to what - // it was before we wrecked it with the code above. - // We need to push the space with an empty keystate map, since the driver checks the map for - // transitions in modifiers, so this helps us capture all possible deadkeys. - unsigned char emptyBuffer[256]; - memset(emptyBuffer, 0, sizeof(emptyBuffer)); - ::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0); - ::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0); - } - -#ifdef DEBUG_KEYMAPPER - qDebug("updatePossibleKeyCodes for virtual key = 0x%02x!", vk_key); - for (int i = 0; i < 9; ++i) { - qDebug(" [%d] (%d,0x%02x,'%c') %s", i, - keyLayout[vk_key]->qtKey[i], - keyLayout[vk_key]->qtKey[i], - keyLayout[vk_key]->qtKey[i] ? keyLayout[vk_key]->qtKey[i] : 0x03, - keyLayout[vk_key]->deadkeys & (1<<i) ? "deadkey" : ""); - } -#endif // DEBUG_KEYMAPPER -} - -bool QKeyMapperPrivate::isADeadKey(unsigned int vk_key, unsigned int modifiers) -{ - if (keyLayout && (vk_key < 256) && keyLayout[vk_key]) { - for(register int i = 0; i < 9; ++i) { - if (uint(ModsTbl[i]) == modifiers) - return bool(keyLayout[vk_key]->deadkeys & 1<<i); - } - } - return false; -} - -extern bool qt_use_rtl_extensions; - -QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e) -{ - QList<int> result; - - KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()]; - if(!kbItem) - return result; - - quint32 baseKey = kbItem->qtKey[0]; - Qt::KeyboardModifiers keyMods = e->modifiers(); - if (baseKey == Qt::Key_Return && (e->nativeModifiers() & ExtendedKey)) { - result << int(Qt::Key_Enter + keyMods); - return result; - } - result << int(baseKey + keyMods); // The base key is _always_ valid, of course - - for(int i = 1; i < 9; ++i) { - Qt::KeyboardModifiers neededMods = ModsTbl[i]; - quint32 key = kbItem->qtKey[i]; - if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) - result << int(key + (keyMods & ~neededMods)); - } - - return result; -} - -bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool grab) -{ - Q_Q(QKeyMapper); - Q_UNUSED(q); // Strange, but the compiler complains on q not being referenced, even if it is.. - bool k0 = false; - bool k1 = false; - int msgType = msg.message; - - quint32 scancode = (msg.lParam >> 16) & 0xfff; - quint32 vk_key = MapVirtualKey(scancode, 1); - bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9); - quint32 nModifiers = 0; - -#if defined(Q_OS_WINCE) - nModifiers |= (GetKeyState(VK_SHIFT ) < 0 ? ShiftAny : 0); - nModifiers |= (GetKeyState(VK_CONTROL) < 0 ? ControlAny : 0); - nModifiers |= (GetKeyState(VK_MENU ) < 0 ? AltAny : 0); - nModifiers |= (GetKeyState(VK_LWIN ) < 0 ? MetaLeft : 0); - nModifiers |= (GetKeyState(VK_RWIN ) < 0 ? MetaRight : 0); -#else - // Map native modifiers to some bit representation - nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0); - nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0); - nModifiers |= (GetKeyState(VK_LCONTROL) & 0x80 ? ControlLeft : 0); - nModifiers |= (GetKeyState(VK_RCONTROL) & 0x80 ? ControlRight : 0); - nModifiers |= (GetKeyState(VK_LMENU ) & 0x80 ? AltLeft : 0); - nModifiers |= (GetKeyState(VK_RMENU ) & 0x80 ? AltRight : 0); - nModifiers |= (GetKeyState(VK_LWIN ) & 0x80 ? MetaLeft : 0); - nModifiers |= (GetKeyState(VK_RWIN ) & 0x80 ? MetaRight : 0); - // Add Lock keys to the same bits - nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0); - nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0); - nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0); -#endif // Q_OS_WINCE - - if (msg.lParam & ExtendedKey) - nModifiers |= msg.lParam & ExtendedKey; - - // Get the modifier states (may be altered later, depending on key code) - int state = 0; - state |= (nModifiers & ShiftAny ? Qt::ShiftModifier : 0); - state |= (nModifiers & ControlAny ? Qt::ControlModifier : 0); - state |= (nModifiers & AltAny ? Qt::AltModifier : 0); - state |= (nModifiers & MetaAny ? Qt::MetaModifier : 0); - - // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey - bool isDeadKey = isADeadKey(msg.wParam, state) - || MapVirtualKey(msg.wParam, 2) & 0x80000000; - - // A multi-character key not found by our look-ahead - if (msgType == WM_CHAR) { - QString s; - QChar ch = QChar((ushort)msg.wParam); - if (!ch.isNull()) - s += ch; - - k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers); - k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers); - } - - // Input method characters not found by our look-ahead - else if (msgType == WM_IME_CHAR) { - QString s; - QChar ch = QChar((ushort)msg.wParam); - if (!ch.isNull()) - s += ch; - - k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers); - k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers); - } - - else { - // handle Directionality changes (BiDi) with RTL extensions - if (qt_use_rtl_extensions) { - static int dirStatus = 0; - if (!dirStatus && state == Qt::ControlModifier - && msg.wParam == VK_CONTROL - && msgType == WM_KEYDOWN) { - if (GetKeyState(VK_LCONTROL) < 0) - dirStatus = VK_LCONTROL; - else if (GetKeyState(VK_RCONTROL) < 0) - dirStatus = VK_RCONTROL; - } else if (dirStatus) { - if (msgType == WM_KEYDOWN) { - if (msg.wParam == VK_SHIFT) { - if (dirStatus == VK_LCONTROL && GetKeyState(VK_LSHIFT) < 0) - dirStatus = VK_LSHIFT; - else if (dirStatus == VK_RCONTROL && GetKeyState(VK_RSHIFT) < 0) - dirStatus = VK_RSHIFT; - } else { - dirStatus = 0; - } - } else if (msgType == WM_KEYUP) { - if (dirStatus == VK_LSHIFT - && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL)) - || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) { - k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_L, 0, - QString(), false, 0, - scancode, msg.wParam, nModifiers); - k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_L, 0, - QString(), false, 0, - scancode, msg.wParam, nModifiers); - dirStatus = 0; - } else if (dirStatus == VK_RSHIFT - && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL)) - || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) { - k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_R, - 0, QString(), false, 0, - scancode, msg.wParam, nModifiers); - k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_R, - 0, QString(), false, 0, - scancode, msg.wParam, nModifiers); - dirStatus = 0; - } else { - dirStatus = 0; - } - } else { - dirStatus = 0; - } - } - } - - // IME will process these keys, so simply return - if(msg.wParam == VK_PROCESSKEY) - return true; - - // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630) - if (msg.wParam == 0 || msg.wParam == 0xFF) - return true; - - // Translate VK_* (native) -> Key_* (Qt) keys - // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change - // the internal state of the keyboard driver, resulting in that dead keys no longer works. - // ..also if we're typing numbers on the keypad, while holding down the Alt modifier. - int code = 0; - if (isNumpad && (nModifiers & AltAny)) { - code = winceKeyBend(msg.wParam); - } else if (!isDeadKey) { - unsigned char kbdBuffer[256]; // Will hold the complete keyboard state - GetKeyboardState(kbdBuffer); - code = toKeyOrUnicode(msg.wParam, scancode, kbdBuffer); - } - - // Invert state logic: - // If the key actually pressed is a modifier key, then we remove its modifier key from the - // state, since a modifier-key can't have itself as a modifier - if (code == Qt::Key_Control) - state = state ^ Qt::ControlModifier; - else if (code == Qt::Key_Shift) - state = state ^ Qt::ShiftModifier; - else if (code == Qt::Key_Alt) - state = state ^ Qt::AltModifier; - - // If the bit 24 of lParm is set you received a enter, - // otherwise a Return. (This is the extended key bit) - if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000)) - code = Qt::Key_Enter; - - // All cursor keys without extended bit - if (!(msg.lParam & 0x1000000)) { - switch (code) { - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_PageUp: - case Qt::Key_PageDown: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Insert: - case Qt::Key_Delete: - case Qt::Key_Asterisk: - case Qt::Key_Plus: - case Qt::Key_Minus: - case Qt::Key_Period: - case Qt::Key_0: - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - case Qt::Key_8: - case Qt::Key_9: - state |= ((msg.wParam >= '0' && msg.wParam <= '9') - || (msg.wParam >= VK_OEM_PLUS && msg.wParam <= VK_OEM_3)) - ? 0 : Qt::KeypadModifier; - default: - if ((uint)msg.lParam == 0x004c0001 || (uint)msg.lParam == 0xc04c0001) - state |= Qt::KeypadModifier; - break; - } - } - // Other keys with with extended bit - else { - switch (code) { - case Qt::Key_Enter: - case Qt::Key_Slash: - case Qt::Key_NumLock: - state |= Qt::KeypadModifier; - default: - break; - } - } - - // KEYDOWN --------------------------------------------------------------------------------- - if (msgType == WM_KEYDOWN || msgType == WM_IME_KEYDOWN || msgType == WM_SYSKEYDOWN) { - // Get the last record of this key press, so we can validate the current state - // The record is not removed from the list - KeyRecord *rec = key_recorder.findKey(msg.wParam, false); - - // If rec's state doesn't match the current state, something has changed behind our back - // (Consumed by modal widget is one possibility) So, remove the record from the list - // This will stop the auto-repeat of the key, should a modifier change, for example - if (rec && rec->state != state) { - key_recorder.findKey(msg.wParam, true); - rec = 0; - } - - // Find unicode character from Windows Message Queue - MSG wm_char; - UINT charType = (msgType == WM_KEYDOWN - ? WM_CHAR - : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR); - - QChar uch; - if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { - // Found a ?_CHAR - uch = QChar((ushort)wm_char.wParam); - if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN)) - uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter - if (!code && !uch.row()) - code = asciiToKeycode(uch.cell(), state); - } - - // Special handling for the WM_IME_KEYDOWN message. Microsoft IME (Korean) will not - // generate a WM_IME_CHAR message corresponding to this message. We might get wrong - // results, if we map this virtual key-code directly (for eg '?' US layouts). So try - // to find the correct key using the current message parameters & keyboard state. - if (uch.isNull() && msgType == WM_IME_KEYDOWN) { - BYTE keyState[256]; - wchar_t newKey[3] = {0}; - GetKeyboardState(keyState); - int val = ToUnicode(vk_key, scancode, keyState, newKey, 2, 0); - if (val == 1) { - uch = QChar(newKey[0]); - } else { - // If we are still not able to find a unicode key, pass the WM_IME_KEYDOWN - // message to DefWindowProc() for generating a proper WM_KEYDOWN. - return false; - } - } - - // If no ?_CHAR was found in the queue; deduct character from the ?_KEYDOWN parameters - if (uch.isNull()) { - if (msg.wParam == VK_DELETE) { - uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one. - } else { - if (msgType != WM_SYSKEYDOWN || !code) { - UINT map = MapVirtualKey(msg.wParam, 2); - // If the high bit of the return value is set, it's a deadkey - if (!(map & 0x80000000)) - uch = QChar((ushort)map); - } - } - if (!code && !uch.row()) - code = asciiToKeycode(uch.cell(), state); - } - - // Special handling of global Windows hotkeys - if (state == Qt::AltModifier) { - switch (code) { - case Qt::Key_Escape: - case Qt::Key_Tab: - case Qt::Key_Enter: - case Qt::Key_F4: - return false; // Send the event on to Windows - case Qt::Key_Space: - // do not pass this key to windows, we will process it ourselves - qt_show_system_menu(widget->window()); - return true; - default: - break; - } - } - - // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation - if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier) - code = Qt::Key_Backtab; - - // If we have a record, it means that the key is already pressed, the state is the same - // so, we have an auto-repeating key - if (rec) { - if (code < Qt::Key_Shift || code > Qt::Key_ScrollLock) { - k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code, - Qt::KeyboardModifier(state), rec->text, true, 0, - scancode, msg.wParam, nModifiers); - k1 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code, - Qt::KeyboardModifier(state), rec->text, true, 0, - scancode, msg.wParam, nModifiers); - } - } - // No record of the key being previous pressed, so we now send a QEvent::KeyPress event, - // and store the key data into our records. - else { - QString text; - if (!uch.isNull()) - text += uch; - char a = uch.row() ? 0 : uch.cell(); - key_recorder.storeKey(msg.wParam, a, state, text); - k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code, Qt::KeyboardModifier(state), - text, false, 0, scancode, msg.wParam, nModifiers); - - bool store = true; - // Alt+<alphanumerical> go to the Win32 menu system if unhandled by Qt -#if !defined(Q_OS_WINCE) - if (msgType == WM_SYSKEYDOWN && !k0 && a) { - HWND parent = GetParent(widget->internalWinId()); - while (parent) { - if (GetMenu(parent)) { - SendMessage(parent, WM_SYSCOMMAND, SC_KEYMENU, a); - store = false; - k0 = true; - break; - } - parent = GetParent(parent); - } - } -#endif - if (!store) - key_recorder.findKey(msg.wParam, true); - } - } - - // KEYUP ----------------------------------------------------------------------------------- - else { - // Try to locate the key in our records, and remove it if it exists. - // The key may not be in our records if, for example, the down event was handled by - // win32 natively, or our window gets focus while a key is already press, but now gets - // the key release event. - KeyRecord* rec = key_recorder.findKey(msg.wParam, true); - if (!rec && !(code == Qt::Key_Shift - || code == Qt::Key_Control - || code == Qt::Key_Meta - || code == Qt::Key_Alt)) { - // Someone ate the key down event - } else { - if (!code) - code = asciiToKeycode(rec->ascii ? rec->ascii : msg.wParam, state); - - // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation - if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier) - code = Qt::Key_Backtab; - - k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code, Qt::KeyboardModifier(state), - (rec ? rec->text : QString()), false, 0, scancode, msg.wParam, nModifiers); - - // don't pass Alt to Windows unless we are embedded in a non-Qt window -#if !defined(Q_OS_WINCE) - if (code == Qt::Key_Alt) { - k0 = true; - HWND parent = GetParent(widget->internalWinId()); - while (parent) { - if (!QWidget::find(parent) && GetMenu(parent)) { - k0 = false; - break; - } - parent = GetParent(parent); - } - } -#endif - } - } - } - - // Return true, if a QKeyEvent was sent to a widget - return k0 || k1; -} - - -// QKeyMapper (Windows) implementation -------------------------------------------------[ start ]--- - -bool QKeyMapper::sendKeyEvent(QWidget *widget, bool grab, - QEvent::Type type, int code, Qt::KeyboardModifiers modifiers, - const QString &text, bool autorepeat, int count, - quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, - bool *) -{ -#if defined(Q_OS_WINCE) - Q_UNUSED(grab); -#endif - Q_UNUSED(count); -#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT) - if (type == QEvent::KeyPress - && !grab - && QApplicationPrivate::instance()->use_compat()) { - // send accel events if the keyboard is not grabbed - QKeyEventEx a(type, code, modifiers, - text, autorepeat, qMax(1, int(text.length())), - nativeScanCode, nativeVirtualKey, nativeModifiers); - if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &a)) - return true; - } -#else - Q_UNUSED(grab); -#endif - if (!widget->isEnabled()) - return false; - - QKeyEventEx e(type, code, modifiers, - text, autorepeat, qMax(1, int(text.length())), - nativeScanCode, nativeVirtualKey, nativeModifiers); - QETWidget::sendSpontaneousEvent(widget, &e); - - if (!isModifierKey(code) - && modifiers == Qt::AltModifier - && ((code >= Qt::Key_A && code <= Qt::Key_Z) || (code >= Qt::Key_0 && code <= Qt::Key_9)) - && type == QEvent::KeyPress - && !e.isAccepted()) - QApplication::beep(); // Emulate windows behavior - - return e.isAccepted(); -} - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qmime_win.cpp b/src/gui/platforms/win/qmime_win.cpp deleted file mode 100644 index feb8b78eca..0000000000 --- a/src/gui/platforms/win/qmime_win.cpp +++ /dev/null @@ -1,1556 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmime.h" - -#include "qimagereader.h" -#include "qimagewriter.h" -#include "qdatastream.h" -#include "qbuffer.h" -#include "qt_windows.h" -#include "qapplication_p.h" -#include "qtextcodec.h" -#include "qregexp.h" -#include "qalgorithms.h" -#include "qmap.h" -#include "qdnd_p.h" -#include <shlobj.h> -#include "qurl.h" -#include "qvariant.h" -#include "qtextdocument.h" -#include "qdir.h" - -#if defined(Q_OS_WINCE) -#include "qguifunctions_wince.h" -#endif - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_IMAGEFORMAT_BMP -#ifndef CF_DIBV5 -#define CF_DIBV5 17 -#endif -/* The MSVC compilers allows multi-byte characters, that has the behavior of - * that each character gets shifted into position. 0x73524742 below is for MSVC - * equivalent to doing 'sRGB', but this does of course not work - * on conformant C++ compilers. */ -#define BMP_LCS_sRGB 0x73524742 -#define BMP_LCS_GM_IMAGES 0x00000004L - -struct _CIEXYZ { - long ciexyzX, ciexyzY, ciexyzZ; -}; - -struct _CIEXYZTRIPLE { - _CIEXYZ ciexyzRed, ciexyzGreen, ciexyzBlue; -}; - -struct BMP_BITMAPV5HEADER { - DWORD bV5Size; - LONG bV5Width; - LONG bV5Height; - WORD bV5Planes; - WORD bV5BitCount; - DWORD bV5Compression; - DWORD bV5SizeImage; - LONG bV5XPelsPerMeter; - LONG bV5YPelsPerMeter; - DWORD bV5ClrUsed; - DWORD bV5ClrImportant; - DWORD bV5RedMask; - DWORD bV5GreenMask; - DWORD bV5BlueMask; - DWORD bV5AlphaMask; - DWORD bV5CSType; - _CIEXYZTRIPLE bV5Endpoints; - DWORD bV5GammaRed; - DWORD bV5GammaGreen; - DWORD bV5GammaBlue; - DWORD bV5Intent; - DWORD bV5ProfileData; - DWORD bV5ProfileSize; - DWORD bV5Reserved; -}; -static const int BMP_BITFIELDS = 3; - -extern bool qt_read_dib(QDataStream&, QImage&); // qimage.cpp -extern bool qt_write_dib(QDataStream&, QImage); // qimage.cpp -static bool qt_write_dibv5(QDataStream &s, QImage image); -static bool qt_read_dibv5(QDataStream &s, QImage &image); -#endif - -//#define QMIME_DEBUG - - -// helpers for using global memory - -static int getCf(const FORMATETC &formatetc) -{ - return formatetc.cfFormat; -} - -static FORMATETC setCf(int cf) -{ - FORMATETC formatetc; - formatetc.cfFormat = cf; - formatetc.dwAspect = DVASPECT_CONTENT; - formatetc.lindex = -1; - formatetc.ptd = NULL; - formatetc.tymed = TYMED_HGLOBAL; - return formatetc; -} - -static bool setData(const QByteArray &data, STGMEDIUM *pmedium) -{ - HGLOBAL hData = GlobalAlloc(0, data.size()); - if (!hData) - return false; - - void *out = GlobalLock(hData); - memcpy(out, data.data(), data.size()); - GlobalUnlock(hData); - pmedium->tymed = TYMED_HGLOBAL; - pmedium->hGlobal = hData; - pmedium->pUnkForRelease = 0; - return true; -} - -static QByteArray getData(int cf, IDataObject *pDataObj) -{ - QByteArray data; - FORMATETC formatetc = setCf(cf); - STGMEDIUM s; - if (pDataObj->GetData(&formatetc, &s) == S_OK) { - DWORD * val = (DWORD*)GlobalLock(s.hGlobal); - data = QByteArray::fromRawData((char*)val, GlobalSize(s.hGlobal)); - data.detach(); - GlobalUnlock(s.hGlobal); - ReleaseStgMedium(&s); - } else { - //Try reading IStream data - formatetc.tymed = TYMED_ISTREAM; - if (pDataObj->GetData(&formatetc, &s) == S_OK) { - char szBuffer[4096]; - ULONG actualRead = 0; - LARGE_INTEGER pos = {{0, 0}}; - //Move to front (can fail depending on the data model implemented) - HRESULT hr = s.pstm->Seek(pos, STREAM_SEEK_SET, NULL); - while(SUCCEEDED(hr)){ - hr = s.pstm->Read(szBuffer, sizeof(szBuffer), &actualRead); - if (SUCCEEDED(hr) && actualRead > 0) { - data += QByteArray::fromRawData(szBuffer, actualRead); - } - if (actualRead != sizeof(szBuffer)) - break; - } - data.detach(); - ReleaseStgMedium(&s); - } - } - return data; -} - -static bool canGetData(int cf, IDataObject * pDataObj) -{ - FORMATETC formatetc = setCf(cf); - if (pDataObj->QueryGetData(&formatetc) != S_OK){ - formatetc.tymed = TYMED_ISTREAM; - return pDataObj->QueryGetData(&formatetc) == S_OK; - } - return true; -} - -class QWindowsMimeList -{ -public: - QWindowsMimeList(); - ~QWindowsMimeList(); - void addWindowsMime(QWindowsMime * mime); - void removeWindowsMime(QWindowsMime * mime); - QList<QWindowsMime*> windowsMimes(); - -private: - void init(); - bool initialized; - QList<QWindowsMime*> mimes; -}; - -Q_GLOBAL_STATIC(QWindowsMimeList, theMimeList); - - -/*! - \class QWindowsMime - \brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats. - \ingroup draganddrop - - Qt's drag-and-drop and clipboard facilities use the MIME standard. - On X11, this maps trivially to the Xdnd protocol, but on Windows - although some applications use MIME types to describe clipboard - formats, others use arbitrary non-standardized naming conventions, - or unnamed built-in formats of Windows. - - By instantiating subclasses of QWindowsMime that provide conversions - between Windows Clipboard and MIME formats, you can convert - proprietary clipboard formats to MIME formats. - - Qt has predefined support for the following Windows Clipboard formats: - - \table - \header \o Windows Format \o Equivalent MIME type - \row \o \c CF_UNICODETEXT \o \c text/plain - \row \o \c CF_TEXT \o \c text/plain - \row \o \c CF_DIB \o \c{image/xyz}, where \c xyz is - a \l{QImageWriter::supportedImageFormats()}{Qt image format} - \row \o \c CF_HDROP \o \c text/uri-list - \row \o \c CF_INETURL \o \c text/uri-list - \row \o \c CF_HTML \o \c text/html - \endtable - - An example use of this class would be to map the Windows Metafile - clipboard format (\c CF_METAFILEPICT) to and from the MIME type - \c{image/x-wmf}. This conversion might simply be adding or removing - a header, or even just passing on the data. See \l{Drag and Drop} - for more information on choosing and definition MIME types. - - You can check if a MIME type is convertible using canConvertFromMime() and - can perform conversions with convertToMime() and convertFromMime(). -*/ - -/*! -Constructs a new conversion object, adding it to the globally accessed -list of available converters. -*/ -QWindowsMime::QWindowsMime() -{ - theMimeList()->addWindowsMime(this); -} - -/*! -Destroys a conversion object, removing it from the global -list of available converters. -*/ -QWindowsMime::~QWindowsMime() -{ - theMimeList()->removeWindowsMime(this); -} - - -/*! - Registers the MIME type \a mime, and returns an ID number - identifying the format on Windows. -*/ -int QWindowsMime::registerMimeType(const QString &mime) -{ - int f = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (mime.utf16())); - if (!f) - qErrnoWarning("QWindowsMime::registerMimeType: Failed to register clipboard format"); - - return f; -} - - -/*! -\fn bool QWindowsMime::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const - - Returns true if the converter can convert from the \a mimeData to - the format specified in \a formatetc. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! - \fn bool QWindowsMime::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const - - Returns true if the converter can convert to the \a mimeType from - the available formats in \a pDataObj. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! -\fn QString QWindowsMime::mimeForFormat(const FORMATETC &formatetc) const - - Returns the mime type that will be created form the format specified - in \a formatetc, or an empty string if this converter does not support - \a formatetc. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! -\fn QVector<FORMATETC> QWindowsMime::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const - - Returns a QVector of FORMATETC structures representing the different windows clipboard - formats that can be provided for the \a mimeType from the \a mimeData. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! - \fn QVariant QWindowsMime::convertToMime(const QString &mimeType, IDataObject *pDataObj, - QVariant::Type preferredType) const - - Returns a QVariant containing the converted data for \a mimeType from \a pDataObj. - If possible the QVariant should be of the \a preferredType to avoid needless conversions. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! -\fn bool QWindowsMime::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const - - Convert the \a mimeData to the format specified in \a formatetc. - The converted data should then be placed in \a pmedium structure. - - Return true if the conversion was successful. - - All subclasses must reimplement this pure virtual function. -*/ - - -QWindowsMime *QWindowsMime::converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) -{ - QList<QWindowsMime*> mimes = theMimeList()->windowsMimes(); - for (int i=mimes.size()-1; i>=0; --i) { - if (mimes.at(i)->canConvertFromMime(formatetc, mimeData)) - return mimes.at(i); - } - return 0; -} - -QWindowsMime *QWindowsMime::converterToMime(const QString &mimeType, IDataObject *pDataObj) -{ - QList<QWindowsMime*> mimes = theMimeList()->windowsMimes(); - for (int i=mimes.size()-1; i>=0; --i) { - if (mimes.at(i)->canConvertToMime(mimeType, pDataObj)) - return mimes.at(i); - } - return 0; -} - -QVector<FORMATETC> QWindowsMime::allFormatsForMime(const QMimeData *mimeData) -{ - QList<QWindowsMime*> mimes = theMimeList()->windowsMimes(); - QVector<FORMATETC> formatics; - formatics.reserve(20); -#ifndef QT_NO_DRAGANDDROP - QStringList formats = QInternalMimeData::formatsHelper(mimeData); - for (int f=0; f<formats.size(); ++f) { - for (int i=mimes.size()-1; i>=0; --i) - formatics += mimes.at(i)->formatsForMime(formats.at(f), mimeData); - } -#else - Q_UNUSED(mimeData); -#endif //QT_NO_DRAGANDDROP - return formatics; -} - -QStringList QWindowsMime::allMimesForFormats(IDataObject *pDataObj) -{ - QList<QWindowsMime*> mimes = theMimeList()->windowsMimes(); - QStringList formats; - LPENUMFORMATETC FAR fmtenum; - HRESULT hr = pDataObj->EnumFormatEtc(DATADIR_GET, &fmtenum); - - if (hr == NOERROR) { - FORMATETC fmtetc; - while (S_OK == fmtenum->Next(1, &fmtetc, 0)) { -#if defined(QMIME_DEBUG) && !defined(Q_OS_WINCE) - qDebug("QWindowsMime::allMimesForFormats()"); - wchar_t buf[256] = {0}; - GetClipboardFormatName(fmtetc.cfFormat, buf, 255); - qDebug("CF = %d : %s", fmtetc.cfFormat, QString::fromWCharArray(buf)); -#endif - for (int i=mimes.size()-1; i>=0; --i) { - QString format = mimes.at(i)->mimeForFormat(fmtetc); - if (!format.isEmpty() && !formats.contains(format)) { - formats += format; - } - } - // as documented in MSDN to avoid possible memleak - if (fmtetc.ptd) - CoTaskMemFree(fmtetc.ptd); - } - fmtenum->Release(); - } - - return formats; -} - - -class QWindowsMimeText : public QWindowsMime -{ -public: - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const; - QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const; - QString mimeForFormat(const FORMATETC &formatetc) const; - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const; -}; - -bool QWindowsMimeText::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const -{ - int cf = getCf(formatetc); - return (cf == CF_UNICODETEXT || cf == CF_TEXT) && mimeData->hasText(); -} - -/* -text/plain is defined as using CRLF, but so many programs don't, -and programmers just look for '\n' in strings. -Windows really needs CRLF, so we ensure it here. -*/ -bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const -{ - if (canConvertFromMime(formatetc, mimeData)) { - QByteArray data; - int cf = getCf(formatetc); - if (cf == CF_TEXT) { - data = mimeData->text().toLocal8Bit(); - // Anticipate required space for CRLFs at 1/40 - int maxsize=data.size()+data.size()/40+3; - QByteArray r(maxsize, '\0'); - char* o = r.data(); - const char* d = data.data(); - const int s = data.size(); - bool cr=false; - int j=0; - for (int i=0; i<s; i++) { - char c = d[i]; - if (c=='\r') - cr=true; - else { - if (c=='\n') { - if (!cr) - o[j++]='\r'; - } - cr=false; - } - o[j++]=c; - if (j+3 >= maxsize) { - maxsize += maxsize/4; - r.resize(maxsize); - o = r.data(); - } - } - o[j]=0; - return setData(r, pmedium); - } else if (cf == CF_UNICODETEXT) { - QString str = mimeData->text(); - const QChar *u = str.unicode(); - QString res; - const int s = str.length(); - int maxsize = s + s/40 + 3; - res.resize(maxsize); - int ri = 0; - bool cr = false; - for (int i=0; i < s; ++i) { - if (*u == QLatin1Char('\r')) - cr = true; - else { - if (*u == QLatin1Char('\n') && !cr) - res[ri++] = QLatin1Char('\r'); - cr = false; - } - res[ri++] = *u; - if (ri+3 >= maxsize) { - maxsize += maxsize/4; - res.resize(maxsize); - } - ++u; - } - res.truncate(ri); - const int byteLength = res.length() * sizeof(ushort); - QByteArray r(byteLength + 2, '\0'); - memcpy(r.data(), res.unicode(), byteLength); - r[byteLength] = 0; - r[byteLength+1] = 0; - return setData(r, pmedium); - } - } - return false; -} - -bool QWindowsMimeText::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const -{ - return mimeType.startsWith(QLatin1String("text/plain")) - && (canGetData(CF_UNICODETEXT, pDataObj) - || canGetData(CF_TEXT, pDataObj)); -} - -QString QWindowsMimeText::mimeForFormat(const FORMATETC &formatetc) const -{ - int cf = getCf(formatetc); - if (cf == CF_UNICODETEXT || cf == CF_TEXT) - return QLatin1String("text/plain"); - return QString(); -} - - -QVector<FORMATETC> QWindowsMimeText::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const -{ - QVector<FORMATETC> formatics; - if (mimeType.startsWith(QLatin1String("text/plain")) && mimeData->hasText()) { - formatics += setCf(CF_UNICODETEXT); - formatics += setCf(CF_TEXT); - } - return formatics; -} - -QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const -{ - QVariant ret; - - if (canConvertToMime(mime, pDataObj)) { - QString str; - QByteArray data = getData(CF_UNICODETEXT, pDataObj); - if (!data.isEmpty()) { - str = QString::fromWCharArray((const wchar_t *)data.data()); - str.replace(QLatin1String("\r\n"), QLatin1String("\n")); - } else { - data = getData(CF_TEXT, pDataObj); - if (!data.isEmpty()) { - const char* d = data.data(); - const int s = qstrlen(d); - QByteArray r(data.size()+1, '\0'); - char* o = r.data(); - int j=0; - for (int i=0; i<s; i++) { - char c = d[i]; - if (c!='\r') - o[j++]=c; - } - o[j]=0; - str = QString::fromLocal8Bit(r); - } - } - if (preferredType == QVariant::String) - ret = str; - else - ret = str.toUtf8(); - } - - return ret; -} - -class QWindowsMimeURI : public QWindowsMime -{ -public: - QWindowsMimeURI(); - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const; - QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const; - QString mimeForFormat(const FORMATETC &formatetc) const; - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const; -private: - int CF_INETURL_W; // wide char version - int CF_INETURL; -}; - -QWindowsMimeURI::QWindowsMimeURI() -{ - CF_INETURL_W = QWindowsMime::registerMimeType(QLatin1String("UniformResourceLocatorW")); - CF_INETURL = QWindowsMime::registerMimeType(QLatin1String("UniformResourceLocator")); -} - -bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const -{ - if (getCf(formatetc) == CF_HDROP) { - QList<QUrl> urls = mimeData->urls(); - for (int i=0; i<urls.size(); i++) { - if (!urls.at(i).toLocalFile().isEmpty()) - return true; - } - } - return (getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL) && mimeData->hasFormat(QLatin1String("text/uri-list")); -} - -bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const -{ - if (canConvertFromMime(formatetc, mimeData)) { - if (getCf(formatetc) == CF_HDROP) { - QList<QUrl> urls = mimeData->urls(); - QStringList fileNames; - int size = sizeof(DROPFILES)+2; - for (int i=0; i<urls.size(); i++) { - QString fn = QDir::toNativeSeparators(urls.at(i).toLocalFile()); - if (!fn.isEmpty()) { - size += sizeof(ushort) * (fn.length() + 1); - fileNames.append(fn); - } - } - - QByteArray result(size, '\0'); - DROPFILES* d = (DROPFILES*)result.data(); - d->pFiles = sizeof(DROPFILES); - GetCursorPos(&d->pt); // try - d->fNC = true; - char* files = ((char*)d) + d->pFiles; - - d->fWide = true; - wchar_t* f = (wchar_t*)files; - for (int i=0; i<fileNames.size(); i++) { - int l = fileNames.at(i).length(); - memcpy(f, fileNames.at(i).utf16(), l * sizeof(ushort)); - f += l; - *f++ = 0; - } - *f = 0; - - return setData(result, pmedium); - } else if (getCf(formatetc) == CF_INETURL_W) { - QList<QUrl> urls = mimeData->urls(); - QByteArray result; - if (!urls.isEmpty()) { - QString url = urls.at(0).toString(); - result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort)); - } - result.append('\0'); - result.append('\0'); - return setData(result, pmedium); - } else if (getCf(formatetc) == CF_INETURL) { - QList<QUrl> urls = mimeData->urls(); - QByteArray result; - if (!urls.isEmpty()) - result = urls.at(0).toString().toLocal8Bit(); - return setData(result, pmedium); - } - } - - return false; -} - -bool QWindowsMimeURI::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const -{ - return mimeType == QLatin1String("text/uri-list") - && (canGetData(CF_HDROP, pDataObj) || canGetData(CF_INETURL_W, pDataObj) || canGetData(CF_INETURL, pDataObj)); -} - -QString QWindowsMimeURI::mimeForFormat(const FORMATETC &formatetc) const -{ - QString format; - if (getCf(formatetc) == CF_HDROP || getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL) - format = QLatin1String("text/uri-list"); - return format; -} - -QVector<FORMATETC> QWindowsMimeURI::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const -{ - QVector<FORMATETC> formatics; - if (mimeType == QLatin1String("text/uri-list")) { - if (canConvertFromMime(setCf(CF_HDROP), mimeData)) - formatics += setCf(CF_HDROP); - if (canConvertFromMime(setCf(CF_INETURL_W), mimeData)) - formatics += setCf(CF_INETURL_W); - if (canConvertFromMime(setCf(CF_INETURL), mimeData)) - formatics += setCf(CF_INETURL); - } - return formatics; -} - -QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const -{ - if (mimeType == QLatin1String("text/uri-list")) { - if (canGetData(CF_HDROP, pDataObj)) { - QByteArray texturi; - QList<QVariant> urls; - - QByteArray data = getData(CF_HDROP, pDataObj); - if (data.isEmpty()) - return QVariant(); - - LPDROPFILES hdrop = (LPDROPFILES)data.data(); - if (hdrop->fWide) { - const wchar_t* filesw = (const wchar_t *)(data.data() + hdrop->pFiles); - int i = 0; - while (filesw[i]) { - QString fileurl = QString::fromWCharArray(filesw + i); - urls += QUrl::fromLocalFile(fileurl); - i += fileurl.length()+1; - } - } else { - const char* files = (const char *)data.data() + hdrop->pFiles; - int i=0; - while (files[i]) { - urls += QUrl::fromLocalFile(QString::fromLocal8Bit(files+i)); - i += int(strlen(files+i))+1; - } - } - - if (preferredType == QVariant::Url && urls.size() == 1) - return urls.at(0); - else if (!urls.isEmpty()) - return urls; - } else if (canGetData(CF_INETURL_W, pDataObj)) { - QByteArray data = getData(CF_INETURL_W, pDataObj); - if (data.isEmpty()) - return QVariant(); - return QUrl(QString::fromWCharArray((const wchar_t *)data.constData())); - } else if (canGetData(CF_INETURL, pDataObj)) { - QByteArray data = getData(CF_INETURL, pDataObj); - if (data.isEmpty()) - return QVariant(); - return QUrl(QString::fromLocal8Bit(data.constData())); - } - } - return QVariant(); -} - -class QWindowsMimeHtml : public QWindowsMime -{ -public: - QWindowsMimeHtml(); - - // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const; - - // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const; - QString mimeForFormat(const FORMATETC &formatetc) const; - -private: - int CF_HTML; -}; - -QWindowsMimeHtml::QWindowsMimeHtml() -{ - CF_HTML = QWindowsMime::registerMimeType(QLatin1String("HTML Format")); -} - -QVector<FORMATETC> QWindowsMimeHtml::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const -{ - QVector<FORMATETC> formatetcs; - if (mimeType == QLatin1String("text/html") && (!mimeData->html().isEmpty())) - formatetcs += setCf(CF_HTML); - return formatetcs; -} - -QString QWindowsMimeHtml::mimeForFormat(const FORMATETC &formatetc) const -{ - if (getCf(formatetc) == CF_HTML) - return QLatin1String("text/html"); - return QString(); -} - -bool QWindowsMimeHtml::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const -{ - return mimeType == QLatin1String("text/html") && canGetData(CF_HTML, pDataObj); -} - - -bool QWindowsMimeHtml::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const -{ - return getCf(formatetc) == CF_HTML && (!mimeData->html().isEmpty()); -} - -/* -The windows HTML clipboard format is as follows (xxxxxxxxxx is a 10 integer number giving the positions -in bytes). Charset used is mostly utf8, but can be different, ie. we have to look for the <meta> charset tag - - Version: 1.0 - StartHTML:xxxxxxxxxx - EndHTML:xxxxxxxxxx - StartFragment:xxxxxxxxxx - EndFragment:xxxxxxxxxx - ...html... - -*/ -QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const -{ - Q_UNUSED(preferredType); - QVariant result; - if (canConvertToMime(mime, pDataObj)) { - QByteArray html = getData(CF_HTML, pDataObj); -#ifdef QMIME_DEBUG - qDebug("QWindowsMimeHtml::convertToMime"); - qDebug("raw :"); - qDebug(html); -#endif - int start = html.indexOf("StartFragment:"); - int end = html.indexOf("EndFragment:"); - - if (start != -1) { - int startOffset = start + 14; - int i = startOffset; - while (html.at(i) != '\r' && html.at(i) != '\n') - ++i; - QByteArray bytecount = html.mid(startOffset, i - startOffset); - start = bytecount.toInt(); - } - - if (end != -1) { - int endOffset = end + 12; - int i = endOffset ; - while (html.at(i) != '\r' && html.at(i) != '\n') - ++i; - QByteArray bytecount = html.mid(endOffset , i - endOffset); - end = bytecount.toInt(); - } - - if (end > start && start > 0) { - html = "<!--StartFragment-->" + html.mid(start, end - start); - html += "<!--EndFragment-->"; - html.replace('\r', ""); - result = QString::fromUtf8(html); - } - } - return result; -} - -bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const -{ - if (canConvertFromMime(formatetc, mimeData)) { - QByteArray data = mimeData->html().toUtf8(); - QByteArray result = - "Version:1.0\r\n" // 0-12 - "StartHTML:0000000105\r\n" // 13-35 - "EndHTML:0000000000\r\n" // 36-55 - "StartFragment:0000000000\r\n" // 58-86 - "EndFragment:0000000000\r\n\r\n"; // 87-105 - - if (data.indexOf("<!--StartFragment-->") == -1) - result += "<!--StartFragment-->"; - result += data; - if (data.indexOf("<!--EndFragment-->") == -1) - result += "<!--EndFragment-->"; - - // set the correct number for EndHTML - QByteArray pos = QString::number(result.size()).toLatin1(); - memcpy((char *)(result.data() + 53 - pos.length()), pos.constData(), pos.length()); - - // set correct numbers for StartFragment and EndFragment - pos = QString::number(result.indexOf("<!--StartFragment-->") + 20).toLatin1(); - memcpy((char *)(result.data() + 79 - pos.length()), pos.constData(), pos.length()); - pos = QString::number(result.indexOf("<!--EndFragment-->")).toLatin1(); - memcpy((char *)(result.data() + 103 - pos.length()), pos.constData(), pos.length()); - - return setData(result, pmedium); - } - return false; -} - - -#ifndef QT_NO_IMAGEFORMAT_BMP -class QWindowsMimeImage : public QWindowsMime -{ -public: - QWindowsMimeImage(); - // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const; - - // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const; - QString mimeForFormat(const FORMATETC &formatetc) const; -private: - bool hasOriginalDIBV5(IDataObject *pDataObj) const; - UINT CF_PNG; -}; - -QWindowsMimeImage::QWindowsMimeImage() -{ - CF_PNG = RegisterClipboardFormat(L"PNG"); -} - -QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const -{ - QVector<FORMATETC> formatetcs; - if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) { - //add DIBV5 if image has alpha channel - QImage image = qvariant_cast<QImage>(mimeData->imageData()); - if (!image.isNull() && image.hasAlphaChannel()) - formatetcs += setCf(CF_DIBV5); - formatetcs += setCf(CF_DIB); - } - return formatetcs; -} - -QString QWindowsMimeImage::mimeForFormat(const FORMATETC &formatetc) const -{ - int cf = getCf(formatetc); - if (cf == CF_DIB || cf == CF_DIBV5 || cf == int(CF_PNG)) - return QLatin1String("application/x-qt-image"); - return QString(); -} - -bool QWindowsMimeImage::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const -{ - if ((mimeType == QLatin1String("application/x-qt-image")) && - (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj))) - return true; - return false; -} - -bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const -{ - int cf = getCf(formatetc); - if (mimeData->hasImage()) { - if (cf == CF_DIB) - return true; - else if (cf == CF_DIBV5) { - //support DIBV5 conversion only if the image has alpha channel - QImage image = qvariant_cast<QImage>(mimeData->imageData()); - if (!image.isNull() && image.hasAlphaChannel()) - return true; - } - } - return false; -} - -bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const -{ - int cf = getCf(formatetc); - if ((cf == CF_DIB || cf == CF_DIBV5) && mimeData->hasImage()) { - QImage img = qvariant_cast<QImage>(mimeData->imageData()); - if (img.isNull()) - return false; - QByteArray ba; - QDataStream s(&ba, QIODevice::WriteOnly); - s.setByteOrder(QDataStream::LittleEndian);// Intel byte order #### - if (cf == CF_DIB) { - if (img.format() > QImage::Format_ARGB32) - img = img.convertToFormat(QImage::Format_RGB32); - if (qt_write_dib(s, img)) - return setData(ba, pmedium); - } else { - if (qt_write_dibv5(s, img)) - return setData(ba, pmedium); - } - } - return false; -} - -bool QWindowsMimeImage::hasOriginalDIBV5(IDataObject *pDataObj) const -{ - bool isSynthesized = true; - IEnumFORMATETC *pEnum =NULL; - HRESULT res = pDataObj->EnumFormatEtc(1, &pEnum); - if (res == S_OK && pEnum) { - FORMATETC fc; - while ((res = pEnum->Next(1, &fc, 0)) == S_OK) { - if (fc.ptd) - CoTaskMemFree(fc.ptd); - if (fc.cfFormat == CF_DIB) - break; - else if (fc.cfFormat == CF_DIBV5) { - isSynthesized = false; - break; - } - } - pEnum->Release(); - } - return !isSynthesized; -} - -QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const -{ - Q_UNUSED(preferredType); - QVariant result; - if (mimeType != QLatin1String("application/x-qt-image")) - return result; - //Try to convert from a format which has more data - //DIBV5, use only if its is not synthesized - if (canGetData(CF_DIBV5, pDataObj) && hasOriginalDIBV5(pDataObj)) { - QImage img; - QByteArray data = getData(CF_DIBV5, pDataObj); - QDataStream s(&data, QIODevice::ReadOnly); - s.setByteOrder(QDataStream::LittleEndian); - if (qt_read_dibv5(s, img)) { // #### supports only 32bit DIBV5 - return img; - } - } - //PNG, MS Office place this (undocumented) - if (canGetData(CF_PNG, pDataObj)) { - QImage img; - QByteArray data = getData(CF_PNG, pDataObj); - if (img.loadFromData(data, "PNG")) { - return img; - } - } - //Fallback to DIB - if (canGetData(CF_DIB, pDataObj)) { - QImage img; - QByteArray data = getData(CF_DIB, pDataObj); - QDataStream s(&data, QIODevice::ReadOnly); - s.setByteOrder(QDataStream::LittleEndian);// Intel byte order #### - if (qt_read_dib(s, img)) { // ##### encaps "-14" - return img; - } - } - // Failed - return result; -} -#endif - -class QBuiltInMimes : public QWindowsMime -{ -public: - QBuiltInMimes(); - - // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const; - - // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const; - QString mimeForFormat(const FORMATETC &formatetc) const; - -private: - QMap<int, QString> outFormats; - QMap<int, QString> inFormats; -}; - -QBuiltInMimes::QBuiltInMimes() -: QWindowsMime() -{ - outFormats.insert(QWindowsMime::registerMimeType(QLatin1String("application/x-color")), QLatin1String("application/x-color")); - inFormats.insert(QWindowsMime::registerMimeType(QLatin1String("application/x-color")), QLatin1String("application/x-color")); -} - -bool QBuiltInMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const -{ - // really check - return formatetc.tymed & TYMED_HGLOBAL - && outFormats.contains(formatetc.cfFormat) - && mimeData->formats().contains(outFormats.value(formatetc.cfFormat)); -} - -bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const -{ - if (canConvertFromMime(formatetc, mimeData)) { - QByteArray data; - if (outFormats.value(getCf(formatetc)) == QLatin1String("text/html")) { - // text/html is in wide chars on windows (compatible with mozillia) - QString html = mimeData->html(); - // same code as in the text converter up above - const QChar *u = html.unicode(); - QString res; - const int s = html.length(); - int maxsize = s + s/40 + 3; - res.resize(maxsize); - int ri = 0; - bool cr = false; - for (int i=0; i < s; ++i) { - if (*u == QLatin1Char('\r')) - cr = true; - else { - if (*u == QLatin1Char('\n') && !cr) - res[ri++] = QLatin1Char('\r'); - cr = false; - } - res[ri++] = *u; - if (ri+3 >= maxsize) { - maxsize += maxsize/4; - res.resize(maxsize); - } - ++u; - } - res.truncate(ri); - const int byteLength = res.length() * sizeof(ushort); - QByteArray r(byteLength + 2, '\0'); - memcpy(r.data(), res.unicode(), byteLength); - r[byteLength] = 0; - r[byteLength+1] = 0; - data = r; - } else { -#ifndef QT_NO_DRAGANDDROP - data = QInternalMimeData::renderDataHelper(outFormats.value(getCf(formatetc)), mimeData); -#endif //QT_NO_DRAGANDDROP - } - return setData(data, pmedium); - } - return false; -} - -QVector<FORMATETC> QBuiltInMimes::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const -{ - QVector<FORMATETC> formatetcs; - if (!outFormats.keys(mimeType).isEmpty() && mimeData->formats().contains(mimeType)) - formatetcs += setCf(outFormats.key(mimeType)); - return formatetcs; -} - -bool QBuiltInMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const -{ - return (!inFormats.keys(mimeType).isEmpty()) - && canGetData(inFormats.key(mimeType), pDataObj); -} - -QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const -{ - QVariant val; - if (canConvertToMime(mimeType, pDataObj)) { - QByteArray data = getData(inFormats.key(mimeType), pDataObj); - if (!data.isEmpty()) { -#ifdef QMIME_DEBUG - qDebug("QBuiltInMimes::convertToMime()"); -#endif - if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) { - // text/html is in wide chars on windows (compatible with Mozilla) - val = QString::fromWCharArray((const wchar_t *)data.data()); - } else { - val = data; // it should be enough to return the data and let QMimeData do the rest. - } - } - } - return val; -} - -QString QBuiltInMimes::mimeForFormat(const FORMATETC &formatetc) const -{ - return inFormats.value(getCf(formatetc)); -} - - -class QLastResortMimes : public QWindowsMime -{ -public: - - QLastResortMimes(); - // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const; - - // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const; - QString mimeForFormat(const FORMATETC &formatetc) const; - -private: - QMap<int, QString> formats; - static QStringList ianaTypes; - static QStringList excludeList; -}; - -QStringList QLastResortMimes::ianaTypes; -QStringList QLastResortMimes::excludeList; - -QLastResortMimes::QLastResortMimes() -{ - //MIME Media-Types - if (!ianaTypes.size()) { - ianaTypes.append(QLatin1String("application/")); - ianaTypes.append(QLatin1String("audio/")); - ianaTypes.append(QLatin1String("example/")); - ianaTypes.append(QLatin1String("image/")); - ianaTypes.append(QLatin1String("message/")); - ianaTypes.append(QLatin1String("model/")); - ianaTypes.append(QLatin1String("multipart/")); - ianaTypes.append(QLatin1String("text/")); - ianaTypes.append(QLatin1String("video/")); - } - //Types handled by other classes - if (!excludeList.size()) { - excludeList.append(QLatin1String("HTML Format")); - excludeList.append(QLatin1String("UniformResourceLocator")); - excludeList.append(QLatin1String("text/html")); - excludeList.append(QLatin1String("text/plain")); - excludeList.append(QLatin1String("text/uri-list")); - excludeList.append(QLatin1String("application/x-qt-image")); - excludeList.append(QLatin1String("application/x-color")); - } -} - -bool QLastResortMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const -{ - // really check -#ifndef QT_NO_DRAGANDDROP - return formatetc.tymed & TYMED_HGLOBAL - && (formats.contains(formatetc.cfFormat) - && QInternalMimeData::hasFormatHelper(formats.value(formatetc.cfFormat), mimeData)); -#else - Q_UNUSED(mimeData); - Q_UNUSED(formatetc); - return formatetc.tymed & TYMED_HGLOBAL - && formats.contains(formatetc.cfFormat); -#endif //QT_NO_DRAGANDDROP -} - -bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const -{ -#ifndef QT_NO_DRAGANDDROP - return canConvertFromMime(formatetc, mimeData) - && setData(QInternalMimeData::renderDataHelper(formats.value(getCf(formatetc)), mimeData), pmedium); -#else - Q_UNUSED(mimeData); - Q_UNUSED(formatetc); - Q_UNUSED(pmedium); - return false; -#endif //QT_NO_DRAGANDDROP -} - -QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, const QMimeData * /*mimeData*/) const -{ - QVector<FORMATETC> formatetcs; - if (!formats.keys(mimeType).isEmpty()) { - formatetcs += setCf(formats.key(mimeType)); - } else if (!excludeList.contains(mimeType, Qt::CaseInsensitive)){ - // register any other available formats - int cf = QWindowsMime::registerMimeType(mimeType); - QLastResortMimes *that = const_cast<QLastResortMimes *>(this); - that->formats.insert(cf, mimeType); - formatetcs += setCf(cf); - } - return formatetcs; -} -static const char x_qt_windows_mime[] = "application/x-qt-windows-mime;value=\""; - -static bool isCustomMimeType(const QString &mimeType) -{ - return mimeType.startsWith(QLatin1String(x_qt_windows_mime), Qt::CaseInsensitive); -} - -static QString customMimeType(const QString &mimeType) -{ - int len = sizeof(x_qt_windows_mime) - 1; - int n = mimeType.lastIndexOf(QLatin1Char('\"'))-len; - return mimeType.mid(len, n); -} - -bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const -{ - if (isCustomMimeType(mimeType)) { - QString clipFormat = customMimeType(mimeType); - int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); - return canGetData(cf, pDataObj); - } else if (formats.keys(mimeType).isEmpty()) { - // if it is not in there then register it an see if we can get it - int cf = QWindowsMime::registerMimeType(mimeType); - return canGetData(cf, pDataObj); - } else { - return canGetData(formats.key(mimeType), pDataObj); - } - return false; -} - -QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const -{ - Q_UNUSED(preferredType); - QVariant val; - if (canConvertToMime(mimeType, pDataObj)) { - QByteArray data; - if (isCustomMimeType(mimeType)) { - QString clipFormat = customMimeType(mimeType); - int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); - data = getData(cf, pDataObj); - } else if (formats.keys(mimeType).isEmpty()) { - int cf = QWindowsMime::registerMimeType(mimeType); - data = getData(cf, pDataObj); - } else { - data = getData(formats.key(mimeType), pDataObj); - } - if (!data.isEmpty()) - val = data; // it should be enough to return the data and let QMimeData do the rest. - } - return val; -} - -QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const -{ - QString format = formats.value(getCf(formatetc)); - if (!format.isEmpty()) - return format; - - wchar_t buffer[256]; - int len = GetClipboardFormatName(getCf(formatetc), buffer, 256); - - if (len) { - QString clipFormat = QString::fromWCharArray(buffer, len); -#ifndef QT_NO_DRAGANDDROP - if (QInternalMimeData::canReadData(clipFormat)) - format = clipFormat; - else if((formatetc.cfFormat >= 0xC000)){ - //create the mime as custom. not registered. - if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) { - //check if this is a mime type - bool ianaType = false; - int sz = ianaTypes.size(); - for (int i = 0; i < sz; i++) { - if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) { - ianaType = true; - break; - } - } - if (!ianaType) - format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"'); - else - format = clipFormat; - } - } -#endif //QT_NO_DRAGANDDROP - } - - return format; -} - -QWindowsMimeList::QWindowsMimeList() - : initialized(false) -{ -} - -QWindowsMimeList::~QWindowsMimeList() -{ - while (mimes.size()) - delete mimes.first(); -} - - -void QWindowsMimeList::init() -{ - if (!initialized) { - initialized = true; -#ifndef QT_NO_IMAGEFORMAT_BMP - new QWindowsMimeImage; -#endif - new QLastResortMimes; - new QWindowsMimeText; - new QWindowsMimeURI; - - new QWindowsMimeHtml; - new QBuiltInMimes; - } -} - -void QWindowsMimeList::addWindowsMime(QWindowsMime * mime) -{ - init(); - mimes.append(mime); -} - -void QWindowsMimeList::removeWindowsMime(QWindowsMime * mime) -{ - init(); - mimes.removeAll(mime); -} - -QList<QWindowsMime*> QWindowsMimeList::windowsMimes() -{ - init(); - return mimes; -} - -#ifndef QT_NO_IMAGEFORMAT_BMP -static bool qt_write_dibv5(QDataStream &s, QImage image) -{ - QIODevice* d = s.device(); - if (!d->isWritable()) - return false; - - //depth will be always 32 - int bpl_bmp = image.width()*4; - - BMP_BITMAPV5HEADER bi ={0}; - bi.bV5Size = sizeof(BMP_BITMAPV5HEADER); - bi.bV5Width = image.width(); - bi.bV5Height = image.height(); - bi.bV5Planes = 1; - bi.bV5BitCount = 32; - bi.bV5Compression = BI_BITFIELDS; - bi.bV5SizeImage = bpl_bmp*image.height(); - bi.bV5XPelsPerMeter = 0; - bi.bV5YPelsPerMeter = 0; - bi.bV5ClrUsed = 0; - bi.bV5ClrImportant = 0; - bi.bV5BlueMask = 0x000000ff; - bi.bV5GreenMask = 0x0000ff00; - bi.bV5RedMask = 0x00ff0000; - bi.bV5AlphaMask = 0xff000000; - bi.bV5CSType = BMP_LCS_sRGB; //LCS_sRGB - bi.bV5Intent = BMP_LCS_GM_IMAGES; //LCS_GM_IMAGES - - d->write(reinterpret_cast<const char*>(&bi), bi.bV5Size); - if (s.status() != QDataStream::Ok) - return false; - - DWORD colorSpace[3] = {0x00ff0000,0x0000ff00,0x000000ff}; - d->write(reinterpret_cast<const char*>(colorSpace), sizeof(colorSpace)); - if (s.status() != QDataStream::Ok) - return false; - - if (image.format() != QImage::Format_ARGB32) - image = image.convertToFormat(QImage::Format_ARGB32); - - uchar *buf = new uchar[bpl_bmp]; - uchar *b; - - memset(buf, 0, bpl_bmp); - for (int y=image.height()-1; y>=0; y--) { - // write the image bits - QRgb *p = (QRgb *)image.scanLine(y); - QRgb *end = p + image.width(); - b = buf; - while (p < end) { - int alpha = qAlpha(*p); - if (alpha) { - *b++ = qBlue(*p); - *b++ = qGreen(*p); - *b++ = qRed(*p); - } else { - //white for fully transparent pixels. - *b++ = 0xff; - *b++ = 0xff; - *b++ = 0xff; - } - *b++ = alpha; - p++; - } - d->write((char*)buf, bpl_bmp); - if (s.status() != QDataStream::Ok) { - delete[] buf; - return false; - } - } - delete[] buf; - return true; -} - -static int calc_shift(int mask) -{ - int result = 0; - while (!(mask & 1)) { - result++; - mask >>= 1; - } - return result; -} - -//Supports only 32 bit DIBV5 -static bool qt_read_dibv5(QDataStream &s, QImage &image) -{ - BMP_BITMAPV5HEADER bi; - QIODevice* d = s.device(); - if (d->atEnd()) - return false; - - d->read((char *)&bi, sizeof(bi)); // read BITMAPV5HEADER header - if (s.status() != QDataStream::Ok) - return false; - - int nbits = bi.bV5BitCount; - int comp = bi.bV5Compression; - if (nbits != 32 || bi.bV5Planes != 1 || comp != BMP_BITFIELDS) - return false; //Unsupported DIBV5 format - - int w = bi.bV5Width, h = bi.bV5Height; - int red_mask = bi.bV5RedMask; - int green_mask = bi.bV5GreenMask; - int blue_mask = bi.bV5BlueMask; - int alpha_mask = bi.bV5AlphaMask; - int red_shift = 0; - int green_shift = 0; - int blue_shift = 0; - int alpha_shift = 0; - QImage::Format format = QImage::Format_ARGB32; - - if (bi.bV5Height < 0) - h = -h; // support images with negative height - if (image.size() != QSize(w, h) || image.format() != format) { - image = QImage(w, h, format); - if (image.isNull()) // could not create image - return false; - } - image.setDotsPerMeterX(bi.bV5XPelsPerMeter); - image.setDotsPerMeterY(bi.bV5YPelsPerMeter); - // read color table - DWORD colorSpace[3]; - if (d->read((char *)colorSpace, sizeof(colorSpace)) != sizeof(colorSpace)) - return false; - - red_shift = calc_shift(red_mask); - green_shift = calc_shift(green_mask); - blue_shift = calc_shift(blue_mask); - if (alpha_mask) { - alpha_shift = calc_shift(alpha_mask); - } - - int bpl = image.bytesPerLine(); - uchar *data = image.bits(); - register QRgb *p; - QRgb *end; - uchar *buf24 = new uchar[bpl]; - int bpl24 = ((w*nbits+31)/32)*4; - uchar *b; - unsigned int c; - - while (--h >= 0) { - p = (QRgb *)(data + h*bpl); - end = p + w; - if (d->read((char *)buf24,bpl24) != bpl24) - break; - b = buf24; - while (p < end) { - c = *b | (*(b+1))<<8 | (*(b+2))<<16 | (*(b+3))<<24; - *p++ = qRgba(((c & red_mask) >> red_shift) , - ((c & green_mask) >> green_shift), - ((c & blue_mask) >> blue_shift), - ((c & alpha_mask) >> alpha_shift)); - b += 4; - } - } - delete[] buf24; - - if (bi.bV5Height < 0) { - // Flip the image - uchar *buf = new uchar[bpl]; - h = -bi.bV5Height; - for (int y = 0; y < h/2; ++y) { - memcpy(buf, data + y*bpl, bpl); - memcpy(data + y*bpl, data + (h-y-1)*bpl, bpl); - memcpy(data + (h-y-1)*bpl, buf, bpl); - } - delete [] buf; - } - - return true; -} - -#endif - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qole_win.cpp b/src/gui/platforms/win/qole_win.cpp deleted file mode 100644 index 24e2d5b292..0000000000 --- a/src/gui/platforms/win/qole_win.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdnd_p.h" - -#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD)) - -#if defined(Q_OS_WINCE) -#include <shlobj.h> -#include "qguifunctions_wince.h" -#endif - -QT_BEGIN_NAMESPACE - -QOleEnumFmtEtc::QOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) -{ - m_isNull = false; - m_dwRefs = 1; - m_nIndex = 0; - - for (int idx = 0; idx < fmtetcs.count(); ++idx) { - LPFORMATETC destetc = new FORMATETC(); - if (copyFormatEtc(destetc, (LPFORMATETC)&(fmtetcs.at(idx)))) { - m_lpfmtetcs.append(destetc); - } else { - m_isNull = true; - delete destetc; - break; - } - } -} - -QOleEnumFmtEtc::QOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) -{ - m_isNull = false; - m_dwRefs = 1; - m_nIndex = 0; - - for (int idx = 0; idx < lpfmtetcs.count(); ++idx) { - LPFORMATETC srcetc = lpfmtetcs.at(idx); - LPFORMATETC destetc = new FORMATETC(); - if (copyFormatEtc(destetc, srcetc)) { - m_lpfmtetcs.append(destetc); - } else { - m_isNull = true; - delete destetc; - break; - } - } -} - -QOleEnumFmtEtc::~QOleEnumFmtEtc() -{ - LPMALLOC pmalloc; - -#if !defined(Q_OS_WINCE) - if (CoGetMalloc(MEMCTX_TASK, &pmalloc) == NOERROR) { -#else - if (SHGetMalloc(&pmalloc) == NOERROR) { -#endif - for (int idx = 0; idx < m_lpfmtetcs.count(); ++idx) { - LPFORMATETC tmpetc = m_lpfmtetcs.at(idx); - if (tmpetc->ptd) - pmalloc->Free(tmpetc->ptd); - delete tmpetc; - } - - pmalloc->Release(); - } - m_lpfmtetcs.clear(); -} - -bool QOleEnumFmtEtc::isNull() const -{ - return m_isNull; -} - -// IUnknown methods -STDMETHODIMP -QOleEnumFmtEtc::QueryInterface(REFIID riid, void FAR* FAR* ppvObj) -{ - if (riid == IID_IUnknown || riid == IID_IEnumFORMATETC) { - *ppvObj = this; - AddRef(); - return NOERROR; - } - *ppvObj = NULL; - return ResultFromScode(E_NOINTERFACE); -} - -STDMETHODIMP_(ULONG) -QOleEnumFmtEtc::AddRef(void) -{ - return ++m_dwRefs; -} - -STDMETHODIMP_(ULONG) -QOleEnumFmtEtc::Release(void) -{ - if (--m_dwRefs == 0) { - delete this; - return 0; - } - return m_dwRefs; -} - -// IEnumFORMATETC methods -STDMETHODIMP -QOleEnumFmtEtc::Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched) -{ - ULONG i=0; - ULONG nOffset; - - if (rgelt == NULL) - return ResultFromScode(E_INVALIDARG); - - while (i < celt) { - nOffset = m_nIndex + i; - - if (nOffset < ULONG(m_lpfmtetcs.count())) { - copyFormatEtc((LPFORMATETC)&(rgelt[i]), m_lpfmtetcs.at(nOffset)); - i++; - } else { - break; - } - } - - m_nIndex += (WORD)i; - - if (pceltFetched != NULL) - *pceltFetched = i; - - if (i != celt) - return ResultFromScode(S_FALSE); - - return NOERROR; -} - -STDMETHODIMP -QOleEnumFmtEtc::Skip(ULONG celt) -{ - ULONG i=0; - ULONG nOffset; - - while (i < celt) { - nOffset = m_nIndex + i; - - if (nOffset < ULONG(m_lpfmtetcs.count())) { - i++; - } else { - break; - } - } - - m_nIndex += (WORD)i; - - if (i != celt) - return ResultFromScode(S_FALSE); - - return NOERROR; -} - -STDMETHODIMP -QOleEnumFmtEtc::Reset() -{ - m_nIndex = 0; - return NOERROR; -} - -STDMETHODIMP -QOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum) -{ - if (newEnum == NULL) - return ResultFromScode(E_INVALIDARG); - - QOleEnumFmtEtc *result = new QOleEnumFmtEtc(m_lpfmtetcs); - result->m_nIndex = m_nIndex; - - if (result->isNull()) { - delete result; - return ResultFromScode(E_OUTOFMEMORY); - } else { - *newEnum = result; - } - - return NOERROR; -} - -bool QOleEnumFmtEtc::copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const -{ - if (dest == NULL || src == NULL) - return false; - - *dest = *src; - - if (src->ptd) { - LPVOID pout; - LPMALLOC pmalloc; - -#if !defined(Q_OS_WINCE) - if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR) -#else - if (SHGetMalloc(&pmalloc) != NOERROR) -#endif - return false; - - pout = (LPVOID)pmalloc->Alloc(src->ptd->tdSize); - memcpy(dest->ptd, src->ptd, size_t(src->ptd->tdSize)); - - pmalloc->Release(); - } - - return true; -} - -QT_END_NAMESPACE -#endif // QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD diff --git a/src/gui/platforms/win/qpaintdevice_win.cpp b/src/gui/platforms/win/qpaintdevice_win.cpp deleted file mode 100644 index 3dbe97492a..0000000000 --- a/src/gui/platforms/win/qpaintdevice_win.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpaintdevice.h" -#include "qpainter.h" -#include "qwidget.h" -#include "qbitmap.h" -#include "qapplication.h" -#include <private/qapplication_p.h> -#include "qt_windows.h" -#include "qprinter.h" - -QT_BEGIN_NAMESPACE - -HDC QPaintDevice::getDC() const -{ - return 0; -} - -void QPaintDevice::releaseDC(HDC) const -{ -} - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qpixmap_win.cpp b/src/gui/platforms/win/qpixmap_win.cpp deleted file mode 100644 index 9c14ac7726..0000000000 --- a/src/gui/platforms/win/qpixmap_win.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpixmap.h" -#include "qpixmap_raster_p.h" - -#include "qbitmap.h" -#include "qimage.h" -#include "qwidget.h" -#include "qpainter.h" -#include "qdatastream.h" -#include "qbuffer.h" -#include "qapplication.h" -#include "qevent.h" -#include "qfile.h" -#include "qfileinfo.h" -#include "qdatetime.h" -#include "qpixmapcache.h" -#include "qimagereader.h" -#include "qimagewriter.h" -#include "qdebug.h" -#include "qt_windows.h" - -#if defined(Q_WS_WINCE) -#include <winbase.h> -#include "qguifunctions_wince.h" -extern bool qt_wince_is_high_dpi(); -extern bool qt_wince_is_pocket_pc(); -#endif - -#ifndef CAPTUREBLT -#define CAPTUREBLT ((DWORD)0x40000000) -#endif - -QT_BEGIN_NAMESPACE - -QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) -{ - RECT r; - GetClientRect(winId, &r); - - if (w < 0) w = r.right - r.left; - if (h < 0) h = r.bottom - r.top; - -#ifdef Q_WS_WINCE_WM - if (qt_wince_is_pocket_pc()) { - QWidget *widget = QWidget::find(winId); - if (qobject_cast<QDesktopWidget *>(widget)) { - RECT rect = {0,0,0,0}; - AdjustWindowRectEx(&rect, WS_BORDER | WS_CAPTION, FALSE, 0); - int magicNumber = qt_wince_is_high_dpi() ? 4 : 2; - y += rect.top - magicNumber; - } - } -#endif - - // Create and setup bitmap - HDC display_dc = GetDC(0); - HDC bitmap_dc = CreateCompatibleDC(display_dc); - HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h); - HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap); - - // copy data - HDC window_dc = GetDC(winId); - BitBlt(bitmap_dc, 0, 0, w, h, window_dc, x, y, SRCCOPY -#ifndef Q_WS_WINCE - | CAPTUREBLT -#endif - ); - - // clean up all but bitmap - ReleaseDC(winId, window_dc); - SelectObject(bitmap_dc, null_bitmap); - DeleteDC(bitmap_dc); - - QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap); - - DeleteObject(bitmap); - ReleaseDC(0, display_dc); - - return pixmap; -} - -HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const -{ - if (isNull()) - return 0; - - HBITMAP bitmap = 0; - if (data->classId() == QPixmapData::RasterClass) { - QRasterPixmapData* d = static_cast<QRasterPixmapData*>(data.data()); - int w = d->image.width(); - int h = d->image.height(); - - HDC display_dc = GetDC(0); - - // Define the header - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - - // Create the pixmap - uchar *pixels = 0; - bitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0); - ReleaseDC(0, display_dc); - if (!bitmap) { - qErrnoWarning("QPixmap::toWinHBITMAP(), failed to create dibsection"); - return 0; - } - if (!pixels) { - qErrnoWarning("QPixmap::toWinHBITMAP(), did not allocate pixel data"); - return 0; - } - - // Copy over the data - QImage::Format imageFormat = QImage::Format_ARGB32; - if (format == NoAlpha) - imageFormat = QImage::Format_RGB32; - else if (format == PremultipliedAlpha) - imageFormat = QImage::Format_ARGB32_Premultiplied; - const QImage image = d->image.convertToFormat(imageFormat); - int bytes_per_line = w * 4; - for (int y=0; y<h; ++y) - memcpy(pixels + y * bytes_per_line, image.scanLine(y), bytes_per_line); - - } else { - QPixmapData *data = new QRasterPixmapData(depth() == 1 ? - QPixmapData::BitmapType : QPixmapData::PixmapType); - data->fromImage(toImage(), Qt::AutoColor); - return QPixmap(data).toWinHBITMAP(format); - } - return bitmap; -} - -QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format) -{ - // Verify size - BITMAP bitmap_info; - memset(&bitmap_info, 0, sizeof(BITMAP)); - - int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info); - if (!res) { - qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info"); - return QPixmap(); - } - int w = bitmap_info.bmWidth; - int h = bitmap_info.bmHeight; - - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - - QImage result; - // Get bitmap bits - uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage); - - HDC display_dc = GetDC(0); - if (GetDIBits(display_dc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) { - - QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied; - uint mask = 0; - if (format == NoAlpha) { - imageFormat = QImage::Format_RGB32; - mask = 0xff000000; - } - - // Create image and copy data into image. - QImage image(w, h, imageFormat); - if (!image.isNull()) { // failed to alloc? - int bytes_per_line = w * sizeof(QRgb); - for (int y=0; y<h; ++y) { - QRgb *dest = (QRgb *) image.scanLine(y); - const QRgb *src = (const QRgb *) (data + y * bytes_per_line); - for (int x=0; x<w; ++x) { - const uint pixel = src[x]; - if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0) - dest[x] = pixel | 0xff000000; - else - dest[x] = pixel | mask; - } - } - } - result = image; - } else { - qWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap bits"); - } - ReleaseDC(0, display_dc); - qFree(data); - return fromImage(result); -} - -HBITMAP qt_createIconMask(const QBitmap &bitmap) -{ - QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono); - int w = bm.width(); - int h = bm.height(); - int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment - uchar *bits = new uchar[bpl*h]; - bm.invertPixels(); - for (int y=0; y<h; y++) - memcpy(bits+y*bpl, bm.scanLine(y), bpl); - HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits); - delete [] bits; - return hbm; -} - -HICON QPixmap::toWinHICON() const -{ - QBitmap maskBitmap = mask(); - if (maskBitmap.isNull()) { - maskBitmap= QBitmap(size()); - maskBitmap.fill(Qt::color1); - } - - ICONINFO ii; - ii.fIcon = true; - ii.hbmMask = qt_createIconMask(maskBitmap); - ii.hbmColor = toWinHBITMAP(QPixmap::Alpha); - ii.xHotspot = 0; - ii.yHotspot = 0; - - HICON hIcon = CreateIconIndirect(&ii); - - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask); - - return hIcon; -} - -#ifdef Q_WS_WIN -#ifndef Q_WS_WINCE - -static QImage qt_fromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) -{ - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - - QImage image(w, h, QImage::Format_ARGB32_Premultiplied); - if (image.isNull()) - return image; - - // Get bitmap bits - uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage); - - if (GetDIBits(hdc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) { - // Create image and copy data into image. - for (int y=0; y<h; ++y) { - void *dest = (void *) image.scanLine(y); - void *src = data + y * image.bytesPerLine(); - memcpy(dest, src, image.bytesPerLine()); - } - } else { - qWarning("qt_fromWinHBITMAP(), failed to get bitmap bits"); - } - qFree(data); - - return image; -} - -QPixmap QPixmap::fromWinHICON(HICON icon) -{ - bool foundAlpha = false; - HDC screenDevice = GetDC(0); - HDC hdc = CreateCompatibleDC(screenDevice); - ReleaseDC(0, screenDevice); - - ICONINFO iconinfo; - bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center - if (!result) - qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); - - int w = iconinfo.xHotspot * 2; - int h = iconinfo.yHotspot * 2; - - BITMAPINFOHEADER bitmapInfo; - bitmapInfo.biSize = sizeof(BITMAPINFOHEADER); - bitmapInfo.biWidth = w; - bitmapInfo.biHeight = h; - bitmapInfo.biPlanes = 1; - bitmapInfo.biBitCount = 32; - bitmapInfo.biCompression = BI_RGB; - bitmapInfo.biSizeImage = 0; - bitmapInfo.biXPelsPerMeter = 0; - bitmapInfo.biYPelsPerMeter = 0; - bitmapInfo.biClrUsed = 0; - bitmapInfo.biClrImportant = 0; - DWORD* bits; - - HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0); - HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap); - DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL); - QImage image = qt_fromWinHBITMAP(hdc, winBitmap, w, h); - - for (int y = 0 ; y < h && !foundAlpha ; y++) { - QRgb *scanLine= reinterpret_cast<QRgb *>(image.scanLine(y)); - for (int x = 0; x < w ; x++) { - if (qAlpha(scanLine[x]) != 0) { - foundAlpha = true; - break; - } - } - } - if (!foundAlpha) { - //If no alpha was found, we use the mask to set alpha values - DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK); - QImage mask = qt_fromWinHBITMAP(hdc, winBitmap, w, h); - - for (int y = 0 ; y < h ; y++){ - QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y)); - QRgb *scanlineMask = mask.isNull() ? 0 : reinterpret_cast<QRgb *>(mask.scanLine(y)); - for (int x = 0; x < w ; x++){ - if (scanlineMask && qRed(scanlineMask[x]) != 0) - scanlineImage[x] = 0; //mask out this pixel - else - scanlineImage[x] |= 0xff000000; // set the alpha channel to 255 - } - } - } - //dispose resources created by iconinfo call - DeleteObject(iconinfo.hbmMask); - DeleteObject(iconinfo.hbmColor); - - SelectObject(hdc, oldhdc); //restore state - DeleteObject(winBitmap); - DeleteDC(hdc); - return QPixmap::fromImage(image); -} -#else //ifndef Q_WS_WINCE -QPixmap QPixmap::fromWinHICON(HICON icon) -{ - HDC screenDevice = GetDC(0); - HDC hdc = CreateCompatibleDC(screenDevice); - ReleaseDC(0, screenDevice); - - ICONINFO iconinfo; - bool result = GetIconInfo(icon, &iconinfo); - if (!result) - qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); - - int w = 0; - int h = 0; - if (!iconinfo.xHotspot || !iconinfo.yHotspot) { - // We could not retrieve the icon size via GetIconInfo, - // so we try again using the icon bitmap. - BITMAP bm; - int result = GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bm); - if (!result) result = GetObject(iconinfo.hbmMask, sizeof(BITMAP), &bm); - if (!result) { - qWarning("QPixmap::fromWinHICON(), failed to retrieve icon size"); - return QPixmap(); - } - w = bm.bmWidth; - h = bm.bmHeight; - } else { - // x and y Hotspot describes the icon center - w = iconinfo.xHotspot * 2; - h = iconinfo.yHotspot * 2; - } - const DWORD dwImageSize = w * h * 4; - - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFO); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = dwImageSize; - - uchar* bits; - - HBITMAP winBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &bits, 0, 0); - if (winBitmap ) - memset(bits, 0xff, dwImageSize); - if (!winBitmap) { - qWarning("QPixmap::fromWinHICON(), failed to CreateDIBSection()"); - return QPixmap(); - } - - HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap); - if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_NORMAL)) - qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); - - uint mask = 0xff000000; - // Create image and copy data into image. - QImage image(w, h, QImage::Format_ARGB32); - - if (!image.isNull()) { // failed to alloc? - int bytes_per_line = w * sizeof(QRgb); - for (int y=0; y < h; ++y) { - QRgb *dest = (QRgb *) image.scanLine(y); - const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); - for (int x=0; x < w; ++x) { - dest[x] = src[x]; - } - } - } - if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK)) - qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); - if (!image.isNull()) { // failed to alloc? - int bytes_per_line = w * sizeof(QRgb); - for (int y=0; y < h; ++y) { - QRgb *dest = (QRgb *) image.scanLine(y); - const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); - for (int x=0; x < w; ++x) { - if (!src[x]) - dest[x] = dest[x] | mask; - } - } - } - SelectObject(hdc, oldhdc); //restore state - DeleteObject(winBitmap); - DeleteDC(hdc); - return QPixmap::fromImage(image); -} -#endif //ifndef Q_WS_WINCE -#endif //ifdef Q_WS_WIN - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qprintengine_win.cpp b/src/gui/platforms/win/qprintengine_win.cpp deleted file mode 100644 index 07d66f5bd0..0000000000 --- a/src/gui/platforms/win/qprintengine_win.cpp +++ /dev/null @@ -1,1776 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_PRINTER - -#include "qprinter_p.h" -#include "qprintengine_win_p.h" - -#include <limits.h> - -#include <private/qfont_p.h> -#include <private/qfontengine_p.h> -#include <private/qpainter_p.h> - -#include <qbitmap.h> -#include <qdebug.h> -#include <qvector.h> -#include <qpicture.h> -#include <private/qpicture_p.h> - -QT_BEGIN_NAMESPACE - -extern QPainterPath qt_regionToPath(const QRegion ®ion); - -// #define QT_DEBUG_DRAW - -static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc, - bool convertToText, const QTransform &xform, const QPointF &topLeft); - -static const struct { - int winSizeName; - QPrinter::PaperSize qtSizeName; -} dmMapping[] = { - { DMPAPER_LETTER, QPrinter::Letter }, - { DMPAPER_LETTERSMALL, QPrinter::Letter }, - { DMPAPER_TABLOID, QPrinter::Tabloid }, - { DMPAPER_LEDGER, QPrinter::Ledger }, - { DMPAPER_LEGAL, QPrinter::Legal }, - { DMPAPER_EXECUTIVE, QPrinter::Executive }, - { DMPAPER_A3, QPrinter::A3 }, - { DMPAPER_A4, QPrinter::A4 }, - { DMPAPER_A4SMALL, QPrinter::A4 }, - { DMPAPER_A5, QPrinter::A5 }, - { DMPAPER_B4, QPrinter::B4 }, - { DMPAPER_B5, QPrinter::B5 }, - { DMPAPER_FOLIO, QPrinter::Folio }, - { DMPAPER_ENV_10, QPrinter::Comm10E }, - { DMPAPER_ENV_DL, QPrinter::DLE }, - { DMPAPER_ENV_C3, QPrinter::C5E }, - { DMPAPER_LETTER_EXTRA, QPrinter::Letter }, - { DMPAPER_LEGAL_EXTRA, QPrinter::Legal }, - { DMPAPER_TABLOID_EXTRA, QPrinter::Tabloid }, - { DMPAPER_A4_EXTRA, QPrinter::A4}, - { DMPAPER_LETTER_TRANSVERSE, QPrinter::Letter}, - { DMPAPER_A4_TRANSVERSE, QPrinter::A4}, - { DMPAPER_LETTER_EXTRA_TRANSVERSE, QPrinter::Letter }, - { DMPAPER_A_PLUS, QPrinter::A4 }, - { DMPAPER_B_PLUS, QPrinter::A3 }, - { DMPAPER_LETTER_PLUS, QPrinter::Letter }, - { DMPAPER_A4_PLUS, QPrinter::A4 }, - { DMPAPER_A5_TRANSVERSE, QPrinter::A5 }, - { DMPAPER_B5_TRANSVERSE, QPrinter::B5 }, - { DMPAPER_A3_EXTRA, QPrinter::A3 }, - { DMPAPER_A5_EXTRA, QPrinter::A5 }, - { DMPAPER_B5_EXTRA, QPrinter::B5 }, - { DMPAPER_A2, QPrinter::A2 }, - { DMPAPER_A3_TRANSVERSE, QPrinter::A3 }, - { DMPAPER_A3_EXTRA_TRANSVERSE,QPrinter::A3 }, - { 0, QPrinter::Custom } -}; - -QPrinter::PaperSize mapDevmodePaperSize(int s) -{ - int i = 0; - while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].winSizeName != s)) - i++; - return dmMapping[i].qtSizeName; -} - -static int mapPaperSizeDevmode(QPrinter::PaperSize s) -{ - int i = 0; - while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].qtSizeName != s)) - i++; - return dmMapping[i].winSizeName; -} - -static const struct { - int winSourceName; - QPrinter::PaperSource qtSourceName; -} sources[] = { - { DMBIN_ONLYONE, QPrinter::OnlyOne }, - { DMBIN_LOWER, QPrinter::Lower }, - { DMBIN_MIDDLE, QPrinter::Middle }, - { DMBIN_MANUAL, QPrinter::Manual }, - { DMBIN_ENVELOPE, QPrinter::Envelope }, - { DMBIN_ENVMANUAL, QPrinter::EnvelopeManual }, - { DMBIN_AUTO, QPrinter::Auto }, - { DMBIN_TRACTOR, QPrinter::Tractor }, - { DMBIN_SMALLFMT, QPrinter::SmallFormat }, - { DMBIN_LARGEFMT, QPrinter::LargeFormat }, - { DMBIN_LARGECAPACITY, QPrinter::LargeCapacity }, - { DMBIN_CASSETTE, QPrinter::Cassette }, - { DMBIN_FORMSOURCE, QPrinter::FormSource }, - { 0, (QPrinter::PaperSource) -1 } -}; - -static QPrinter::PaperSource mapDevmodePaperSource(int s) -{ - int i = 0; - while ((sources[i].winSourceName > 0) && (sources[i].winSourceName != s)) - i++; - return sources[i].winSourceName ? sources[i].qtSourceName : (QPrinter::PaperSource) s; -} - -static int mapPaperSourceDevmode(QPrinter::PaperSource s) -{ - int i = 0; - while ((sources[i].qtSourceName >= 0) && (sources[i].qtSourceName != s)) - i++; - return sources[i].winSourceName ? sources[i].winSourceName : s; -} - -QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode mode) - : QAlphaPaintEngine(*(new QWin32PrintEnginePrivate), - PaintEngineFeatures(PrimitiveTransform - | PixmapTransform - | PerspectiveTransform - | PainterPaths - | Antialiasing - | PaintOutsidePaintEvent)) -{ - Q_D(QWin32PrintEngine); - d->docName = QLatin1String("document1"); - d->mode = mode; - d->queryDefault(); - d->initialize(); -} - -bool QWin32PrintEngine::begin(QPaintDevice *pdev) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::begin(pdev); - if (!continueCall()) - return true; - - if (d->reinit) { - d->resetDC(); - d->reinit = false; - } - - // ### set default colors and stuff... - - bool ok = d->state == QPrinter::Idle; - - if (!d->hdc) - return false; - - // Assign the FILE: to get the query... - if (d->printToFile && d->fileName.isEmpty()) - d->fileName = d->port; - - d->devMode->dmCopies = d->num_copies; - - DOCINFO di; - memset(&di, 0, sizeof(DOCINFO)); - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = reinterpret_cast<const wchar_t *>(d->docName.utf16()); - if (d->printToFile && !d->fileName.isEmpty()) - di.lpszOutput = reinterpret_cast<const wchar_t *>(d->fileName.utf16()); - if (ok && StartDoc(d->hdc, &di) == SP_ERROR) { - qErrnoWarning("QWin32PrintEngine::begin: StartDoc failed"); - ok = false; - } - - if (StartPage(d->hdc) <= 0) { - qErrnoWarning("QWin32PrintEngine::begin: StartPage failed"); - ok = false; - } - - if (!ok) { - d->state = QPrinter::Idle; - } else { - d->state = QPrinter::Active; - } - - d->matrix = QTransform(); - d->has_pen = true; - d->pen = QColor(Qt::black); - d->has_brush = false; - - d->complex_xform = false; - - updateMatrix(d->matrix); - - if (!ok) - cleanUp(); - - return ok; -} - -bool QWin32PrintEngine::end() -{ - Q_D(QWin32PrintEngine); - - if (d->hdc) { - if (d->state == QPrinter::Aborted) { - cleanUp(); - AbortDoc(d->hdc); - return true; - } - } - - QAlphaPaintEngine::end(); - if (!continueCall()) - return true; - - if (d->hdc) { - EndPage(d->hdc); // end; printing done - EndDoc(d->hdc); - } - - d->state = QPrinter::Idle; - d->reinit = true; - return true; -} - -bool QWin32PrintEngine::newPage() -{ - Q_D(QWin32PrintEngine); - Q_ASSERT(isActive()); - - Q_ASSERT(d->hdc); - - flushAndInit(); - - bool transparent = GetBkMode(d->hdc) == TRANSPARENT; - - if (!EndPage(d->hdc)) { - qErrnoWarning("QWin32PrintEngine::newPage: EndPage failed"); - return false; - } - - if (d->reinit) { - if (!d->resetDC()) { - qErrnoWarning("QWin32PrintEngine::newPage: ResetDC failed"); - return false; - } - d->reinit = false; - } - - if (!StartPage(d->hdc)) { - qErrnoWarning("Win32PrintEngine::newPage: StartPage failed"); - return false; - } - - SetTextAlign(d->hdc, TA_BASELINE); - if (transparent) - SetBkMode(d->hdc, TRANSPARENT); - - // ### - return true; - - bool success = false; - if (d->hdc && d->state == QPrinter::Active) { - if (EndPage(d->hdc) != SP_ERROR) { - // reinitialize the DC before StartPage if needed, - // because resetdc is disabled between calls to the StartPage and EndPage functions - // (see StartPage documentation in the Platform SDK:Windows GDI) -// state = PST_ACTIVEDOC; -// reinit(); -// state = PST_ACTIVE; - // start the new page now - if (d->reinit) { - if (!d->resetDC()) - qErrnoWarning("QWin32PrintEngine::newPage(), ResetDC failed (2)"); - d->reinit = false; - } - success = (StartPage(d->hdc) != SP_ERROR); - } - if (!success) { - d->state = QPrinter::Aborted; - return false; - } - } - return true; -} - -bool QWin32PrintEngine::abort() -{ - // do nothing loop. - return false; -} - -void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) -{ - Q_D(const QWin32PrintEngine); - - QAlphaPaintEngine::drawTextItem(p, textItem); - if (!continueCall()) - return; - - const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); - QRgb brushColor = state->pen().brush().color().rgb(); - bool fallBack = state->pen().brush().style() != Qt::SolidPattern - || qAlpha(brushColor) != 0xff - || d->txop >= QTransform::TxProject - || ti.fontEngine->type() != QFontEngine::Win; - - - if (!fallBack) { - QFontEngineWin *fe = static_cast<QFontEngineWin *>(ti.fontEngine); - - // Try selecting the font to see if we get a substitution font - SelectObject(d->hdc, fe->hfont); - - if (GetDeviceCaps(d->hdc, TECHNOLOGY) != DT_CHARSTREAM) { - wchar_t n[64]; - GetTextFace(d->hdc, 64, n); - fallBack = QString::fromWCharArray(n) - != QString::fromWCharArray(fe->logfont.lfFaceName); - } - } - - - if (fallBack) { - QPaintEngine::drawTextItem(p, textItem); - return ; - } - - // We only want to convert the glyphs to text if the entire string is compatible with ASCII - // and if we actually have access to the chars. - bool convertToText = ti.chars != 0; - for (int i=0; i < ti.num_chars; ++i) { - if (ti.chars[i].unicode() >= 0x80) { - convertToText = false; - break; - } - - if (ti.logClusters[i] != i) { - convertToText = false; - break; - } - } - - COLORREF cf = RGB(qRed(brushColor), qGreen(brushColor), qBlue(brushColor)); - SelectObject(d->hdc, CreateSolidBrush(cf)); - SelectObject(d->hdc, CreatePen(PS_SOLID, 1, cf)); - SetTextColor(d->hdc, cf); - - draw_text_item_win(p, ti, d->hdc, convertToText, d->matrix, d->devPaperRect.topLeft()); - DeleteObject(SelectObject(d->hdc,GetStockObject(HOLLOW_BRUSH))); - DeleteObject(SelectObject(d->hdc,GetStockObject(BLACK_PEN))); -} - -static inline qreal mmToInches(double mm) -{ - return mm*0.039370147; -} - -static inline qreal inchesToMM(double in) -{ - return in/0.039370147; -} - -int QWin32PrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const -{ - Q_D(const QWin32PrintEngine); - - if (!d->hdc) - return 0; - - int val; - int res = d->resolution; - - switch (m) { - case QPaintDevice::PdmWidth: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.width() * res / 72.0); - } else { - int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX); - if (logPixelsX == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsX = 600; // Reasonable default - } - val = res - * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALWIDTH : HORZRES) - / logPixelsX; - } - if (d->pageMarginsSet) - val -= int(mmToInches((d->previousDialogMargins.left() + - d->previousDialogMargins.width()) / 100.0) * res); - break; - case QPaintDevice::PdmHeight: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.height() * res / 72.0); - } else { - int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY); - if (logPixelsY == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsY = 600; // Reasonable default - } - val = res - * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALHEIGHT : VERTRES) - / logPixelsY; - } - if (d->pageMarginsSet) - val -= int(mmToInches((d->previousDialogMargins.top() + - d->previousDialogMargins.height()) / 100.0) * res); - break; - case QPaintDevice::PdmDpiX: - val = res; - break; - case QPaintDevice::PdmDpiY: - val = res; - break; - case QPaintDevice::PdmPhysicalDpiX: - val = GetDeviceCaps(d->hdc, LOGPIXELSX); - break; - case QPaintDevice::PdmPhysicalDpiY: - val = GetDeviceCaps(d->hdc, LOGPIXELSY); - break; - case QPaintDevice::PdmWidthMM: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.width()*25.4/72); - } else { - if (!d->fullPage) { - val = GetDeviceCaps(d->hdc, HORZSIZE); - } else { - float wi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALWIDTH); - int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX); - if (logPixelsX == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsX = 600; // Reasonable default - } - val = qRound(wi / logPixelsX); - } - } - if (d->pageMarginsSet) - val -= (d->previousDialogMargins.left() + - d->previousDialogMargins.width()) / 100.0; - break; - case QPaintDevice::PdmHeightMM: - if (d->has_custom_paper_size) { - val = qRound(d->paper_size.height()*25.4/72); - } else { - if (!d->fullPage) { - val = GetDeviceCaps(d->hdc, VERTSIZE); - } else { - float hi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALHEIGHT); - int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY); - if (logPixelsY == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - logPixelsY = 600; // Reasonable default - } - val = qRound(hi / logPixelsY); - } - } - if (d->pageMarginsSet) - val -= (d->previousDialogMargins.top() + - d->previousDialogMargins.height()) / 100.0; - break; - case QPaintDevice::PdmNumColors: - { - int bpp = GetDeviceCaps(d->hdc, BITSPIXEL); - if(bpp==32) - val = INT_MAX; - else if(bpp<=8) - val = GetDeviceCaps(d->hdc, NUMCOLORS); - else - val = 1 << (bpp * GetDeviceCaps(d->hdc, PLANES)); - } - break; - case QPaintDevice::PdmDepth: - val = GetDeviceCaps(d->hdc, PLANES); - break; - default: - qWarning("QPrinter::metric: Invalid metric command"); - return 0; - } - return val; -} - -void QWin32PrintEngine::updateState(const QPaintEngineState &state) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::updateState(state); - if (!continueCall()) - return; - - if (state.state() & DirtyTransform) { - updateMatrix(state.transform()); - } - - if (state.state() & DirtyPen) { - d->pen = state.pen(); - d->has_pen = d->pen.style() != Qt::NoPen && d->pen.isSolid(); - } - - if (state.state() & DirtyBrush) { - QBrush brush = state.brush(); - d->has_brush = brush.style() == Qt::SolidPattern; - d->brush_color = brush.color(); - } - - if (state.state() & DirtyClipEnabled) { - if (state.isClipEnabled()) - updateClipPath(painter()->clipPath(), Qt::ReplaceClip); - else - updateClipPath(QPainterPath(), Qt::NoClip); - } - - if (state.state() & DirtyClipPath) { - updateClipPath(state.clipPath(), state.clipOperation()); - } - - if (state.state() & DirtyClipRegion) { - QRegion clipRegion = state.clipRegion(); - QPainterPath clipPath = qt_regionToPath(clipRegion); - updateClipPath(clipPath, state.clipOperation()); - } -} - -void QWin32PrintEngine::updateClipPath(const QPainterPath &clipPath, Qt::ClipOperation op) -{ - Q_D(QWin32PrintEngine); - - bool doclip = true; - if (op == Qt::NoClip) { - SelectClipRgn(d->hdc, 0); - doclip = false; - } - - if (doclip) { - QPainterPath xformed = clipPath * d->matrix; - - if (xformed.isEmpty()) { - QRegion empty(-0x1000000, -0x1000000, 1, 1); - SelectClipRgn(d->hdc, empty.handle()); - } else { - d->composeGdiPath(xformed); - const int ops[] = { - -1, // Qt::NoClip, covered above - RGN_COPY, // Qt::ReplaceClip - RGN_AND, // Qt::IntersectClip - RGN_OR // Qt::UniteClip - }; - Q_ASSERT(op > 0 && unsigned(op) <= sizeof(ops) / sizeof(int)); - SelectClipPath(d->hdc, ops[op]); - } - } - - QPainterPath aclip = qt_regionToPath(alphaClipping()); - if (!aclip.isEmpty()) { - QTransform tx(d->stretch_x, 0, 0, d->stretch_y, d->origin_x, d->origin_y); - d->composeGdiPath(tx.map(aclip)); - SelectClipPath(d->hdc, RGN_DIFF); - } -} - -void QWin32PrintEngine::updateMatrix(const QTransform &m) -{ - Q_D(QWin32PrintEngine); - - QTransform stretch(d->stretch_x, 0, 0, d->stretch_y, d->origin_x, d->origin_y); - d->painterMatrix = m; - d->matrix = d->painterMatrix * stretch; - d->txop = d->matrix.type(); - d->complex_xform = (d->txop > QTransform::TxScale); -} - -void QWin32PrintEngine::drawPixmap(const QRectF &targetRect, - const QPixmap &originalPixmap, - const QRectF &sourceRect) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::drawPixmap(targetRect, originalPixmap, sourceRect); - if (!continueCall()) - return; - - const int tileSize = 2048; - - QRectF r = targetRect; - QRectF sr = sourceRect; - - QPixmap pixmap = originalPixmap; - if (sr.size() != pixmap.size()) { - pixmap = pixmap.copy(sr.toRect()); - } - - qreal scaleX = 1.0f; - qreal scaleY = 1.0f; - - QTransform scaleMatrix = QTransform::fromScale(r.width() / pixmap.width(), r.height() / pixmap.height()); - QTransform adapted = QPixmap::trueMatrix(d->painterMatrix * scaleMatrix, - pixmap.width(), pixmap.height()); - - qreal xform_offset_x = adapted.dx(); - qreal xform_offset_y = adapted.dy(); - - if (d->complex_xform) { - pixmap = pixmap.transformed(adapted); - scaleX = d->stretch_x; - scaleY = d->stretch_y; - } else { - scaleX = d->stretch_x * (r.width() / pixmap.width()) * d->painterMatrix.m11(); - scaleY = d->stretch_y * (r.height() / pixmap.height()) * d->painterMatrix.m22(); - } - - QPointF topLeft = r.topLeft() * d->painterMatrix; - int tx = int(topLeft.x() * d->stretch_x + d->origin_x); - int ty = int(topLeft.y() * d->stretch_y + d->origin_y); - int tw = qAbs(int(pixmap.width() * scaleX)); - int th = qAbs(int(pixmap.height() * scaleY)); - - xform_offset_x *= d->stretch_x; - xform_offset_y *= d->stretch_y; - - int dc_state = SaveDC(d->hdc); - - int tilesw = pixmap.width() / tileSize; - int tilesh = pixmap.height() / tileSize; - ++tilesw; - ++tilesh; - - int txinc = tileSize*scaleX; - int tyinc = tileSize*scaleY; - - for (int y = 0; y < tilesh; ++y) { - int tposy = ty + (y * tyinc); - int imgh = tileSize; - int height = tyinc; - if (y == (tilesh - 1)) { - imgh = pixmap.height() - (y * tileSize); - height = (th - (y * tyinc)); - } - for (int x = 0; x < tilesw; ++x) { - int tposx = tx + (x * txinc); - int imgw = tileSize; - int width = txinc; - if (x == (tilesw - 1)) { - imgw = pixmap.width() - (x * tileSize); - width = (tw - (x * txinc)); - } - - QPixmap p = pixmap.copy(tileSize * x, tileSize * y, imgw, imgh); - HBITMAP hbitmap = p.toWinHBITMAP(QPixmap::NoAlpha); - HDC display_dc = GetDC(0); - HDC hbitmap_hdc = CreateCompatibleDC(display_dc); - HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap); - - ReleaseDC(0, display_dc); - - if (!StretchBlt(d->hdc, qRound(tposx - xform_offset_x), qRound(tposy - xform_offset_y), width, height, - hbitmap_hdc, 0, 0, p.width(), p.height(), SRCCOPY)) - qErrnoWarning("QWin32PrintEngine::drawPixmap, StretchBlt failed"); - - SelectObject(hbitmap_hdc, null_bitmap); - DeleteObject(hbitmap); - DeleteDC(hbitmap_hdc); - } - } - - RestoreDC(d->hdc, dc_state); -} - - -void QWin32PrintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &pos) -{ - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::drawTiledPixmap(r, pm, pos); - if (!continueCall()) - return; - - if (d->complex_xform || !pos.isNull()) { - QPaintEngine::drawTiledPixmap(r, pm, pos); - } else { - int dc_state = SaveDC(d->hdc); - - HDC display_dc = GetDC(0); - HBITMAP hbitmap = pm.toWinHBITMAP(QPixmap::NoAlpha); - HDC hbitmap_hdc = CreateCompatibleDC(display_dc); - HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap); - - ReleaseDC(0, display_dc); - - QRectF trect = d->painterMatrix.mapRect(r); - int tx = int(trect.left() * d->stretch_x + d->origin_x); - int ty = int(trect.top() * d->stretch_y + d->origin_y); - - int xtiles = int(trect.width() / pm.width()) + 1; - int ytiles = int(trect.height() / pm.height()) + 1; - int xinc = int(pm.width() * d->stretch_x); - int yinc = int(pm.height() * d->stretch_y); - - for (int y = 0; y < ytiles; ++y) { - int ity = ty + (yinc * y); - int ith = pm.height(); - if (y == (ytiles - 1)) { - ith = int(trect.height() - (pm.height() * y)); - } - - for (int x = 0; x < xtiles; ++x) { - int itx = tx + (xinc * x); - int itw = pm.width(); - if (x == (xtiles - 1)) { - itw = int(trect.width() - (pm.width() * x)); - } - - if (!StretchBlt(d->hdc, itx, ity, int(itw * d->stretch_x), int(ith * d->stretch_y), - hbitmap_hdc, 0, 0, itw, ith, SRCCOPY)) - qErrnoWarning("QWin32PrintEngine::drawPixmap, StretchBlt failed"); - - } - } - - SelectObject(hbitmap_hdc, null_bitmap); - DeleteObject(hbitmap); - DeleteDC(hbitmap_hdc); - - RestoreDC(d->hdc, dc_state); - } -} - - -void QWin32PrintEnginePrivate::composeGdiPath(const QPainterPath &path) -{ - if (!BeginPath(hdc)) - qErrnoWarning("QWin32PrintEnginePrivate::drawPath: BeginPath failed"); - - // Drawing the subpaths - int start = -1; - for (int i=0; i<path.elementCount(); ++i) { - const QPainterPath::Element &elm = path.elementAt(i); - switch (elm.type) { - case QPainterPath::MoveToElement: - if (start >= 0 - && path.elementAt(start).x == path.elementAt(i-1).x - && path.elementAt(start).y == path.elementAt(i-1).y) - CloseFigure(hdc); - start = i; - MoveToEx(hdc, qRound(elm.x), qRound(elm.y), 0); - break; - case QPainterPath::LineToElement: - LineTo(hdc, qRound(elm.x), qRound(elm.y)); - break; - case QPainterPath::CurveToElement: { - POINT pts[3] = { - { qRound(elm.x), qRound(elm.y) }, - { qRound(path.elementAt(i+1).x), qRound(path.elementAt(i+1).y) }, - { qRound(path.elementAt(i+2).x), qRound(path.elementAt(i+2).y) } - }; - i+=2; - PolyBezierTo(hdc, pts, 3); - break; - } - default: - qFatal("QWin32PaintEngine::drawPath: Unhandled type: %d", elm.type); - } - } - - if (start >= 0 - && path.elementAt(start).x == path.elementAt(path.elementCount()-1).x - && path.elementAt(start).y == path.elementAt(path.elementCount()-1).y) - CloseFigure(hdc); - - if (!EndPath(hdc)) - qErrnoWarning("QWin32PaintEngine::drawPath: EndPath failed"); - - SetPolyFillMode(hdc, path.fillRule() == Qt::WindingFill ? WINDING : ALTERNATE); -} - - -void QWin32PrintEnginePrivate::fillPath_dev(const QPainterPath &path, const QColor &color) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " --- QWin32PrintEnginePrivate::fillPath() bound:" << path.boundingRect() << color; -#endif - - composeGdiPath(path); - - HBRUSH brush = CreateSolidBrush(RGB(color.red(), color.green(), color.blue())); - HGDIOBJ old_brush = SelectObject(hdc, brush); - FillPath(hdc); - DeleteObject(SelectObject(hdc, old_brush)); -} - -void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QColor &color, qreal penWidth) -{ - composeGdiPath(path); - LOGBRUSH brush; - brush.lbStyle = BS_SOLID; - brush.lbColor = RGB(color.red(), color.green(), color.blue()); - DWORD capStyle = PS_ENDCAP_SQUARE; - DWORD joinStyle = PS_JOIN_BEVEL; - if (pen.capStyle() == Qt::FlatCap) - capStyle = PS_ENDCAP_FLAT; - else if (pen.capStyle() == Qt::RoundCap) - capStyle = PS_ENDCAP_ROUND; - - if (pen.joinStyle() == Qt::MiterJoin) - joinStyle = PS_JOIN_MITER; - else if (pen.joinStyle() == Qt::RoundJoin) - joinStyle = PS_JOIN_ROUND; - - HPEN pen = ExtCreatePen(((penWidth == 0) ? PS_COSMETIC : PS_GEOMETRIC) - | PS_SOLID | capStyle | joinStyle, - (penWidth == 0) ? 1 : penWidth, &brush, 0, 0); - - HGDIOBJ old_pen = SelectObject(hdc, pen); - StrokePath(hdc); - DeleteObject(SelectObject(hdc, old_pen)); -} - - -void QWin32PrintEnginePrivate::fillPath(const QPainterPath &path, const QColor &color) -{ - fillPath_dev(path * matrix, color); -} - -void QWin32PrintEnginePrivate::strokePath(const QPainterPath &path, const QColor &color) -{ - QPainterPathStroker stroker; - if (pen.style() == Qt::CustomDashLine) { - stroker.setDashPattern(pen.dashPattern()); - stroker.setDashOffset(pen.dashOffset()); - } else { - stroker.setDashPattern(pen.style()); - } - stroker.setCapStyle(pen.capStyle()); - stroker.setJoinStyle(pen.joinStyle()); - stroker.setMiterLimit(pen.miterLimit()); - - QPainterPath stroke; - qreal width = pen.widthF(); - if (pen.style() == Qt::SolidLine && (pen.isCosmetic() || matrix.type() < QTransform::TxScale)) { - strokePath_dev(path * matrix, color, width); - } else { - stroker.setWidth(width); - if (pen.isCosmetic()) { - stroke = stroker.createStroke(path * matrix); - } else { - stroke = stroker.createStroke(path) * painterMatrix; - QTransform stretch(stretch_x, 0, 0, stretch_y, origin_x, origin_y); - stroke = stroke * stretch; - } - - if (stroke.isEmpty()) - return; - - fillPath_dev(stroke, color); - } -} - - -void QWin32PrintEngine::drawPath(const QPainterPath &path) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " - QWin32PrintEngine::drawPath(), bounds: " << path.boundingRect(); -#endif - - Q_D(QWin32PrintEngine); - - QAlphaPaintEngine::drawPath(path); - if (!continueCall()) - return; - - if (d->has_brush) - d->fillPath(path, d->brush_color); - - if (d->has_pen) - d->strokePath(path, d->pen.color()); -} - - -void QWin32PrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " - QWin32PrintEngine::drawPolygon(), pointCount: " << pointCount; -#endif - - QAlphaPaintEngine::drawPolygon(points, pointCount, mode); - if (!continueCall()) - return; - - Q_ASSERT(pointCount > 1); - - QPainterPath path(points[0]); - - for (int i=1; i<pointCount; ++i) { - path.lineTo(points[i]); - } - - Q_D(QWin32PrintEngine); - - bool has_brush = d->has_brush; - - if (mode == PolylineMode) - d->has_brush = false; // No brush for polylines - else - path.closeSubpath(); // polygons are should always be closed. - - drawPath(path); - d->has_brush = has_brush; -} - -void QWin32PrintEnginePrivate::queryDefault() -{ - /* Read the default printer name, driver and port with the intuitive function - * Strings "windows" and "device" are specified in the MSDN under EnumPrinters() - */ - QString noPrinters(QLatin1String("qt_no_printers")); - wchar_t buffer[256]; - GetProfileString(L"windows", L"device", - reinterpret_cast<const wchar_t *>(noPrinters.utf16()), - buffer, 256); - QString output = QString::fromWCharArray(buffer); - if (output.isEmpty() || output == noPrinters) // no printers - return; - - QStringList info = output.split(QLatin1Char(',')); - int infoSize = info.size(); - if (infoSize > 0) { - if (name.isEmpty()) - name = info.at(0); - if (program.isEmpty() && infoSize > 1) - program = info.at(1); - if (port.isEmpty() && infoSize > 2) - port = info.at(2); - } -} - -QWin32PrintEnginePrivate::~QWin32PrintEnginePrivate() -{ - if (hdc) - release(); -} - -void QWin32PrintEnginePrivate::initialize() -{ - if (hdc) - release(); - Q_ASSERT(!hPrinter); - Q_ASSERT(!hdc); - Q_ASSERT(!devMode); - Q_ASSERT(!pInfo); - - if (name.isEmpty()) - return; - - txop = QTransform::TxNone; - - bool ok = OpenPrinter((LPWSTR)name.utf16(), (LPHANDLE)&hPrinter, 0); - if (!ok) { - qErrnoWarning("QWin32PrintEngine::initialize: OpenPrinter failed"); - return; - } - - // Fetch the PRINTER_INFO_2 with DEVMODE data containing the - // printer settings. - DWORD infoSize, numBytes; - GetPrinter(hPrinter, 2, NULL, 0, &infoSize); - hMem = GlobalAlloc(GHND, infoSize); - pInfo = (PRINTER_INFO_2*) GlobalLock(hMem); - ok = GetPrinter(hPrinter, 2, (LPBYTE)pInfo, infoSize, &numBytes); - - if (!ok) { - qErrnoWarning("QWin32PrintEngine::initialize: GetPrinter failed"); - GlobalUnlock(pInfo); - GlobalFree(hMem); - ClosePrinter(hPrinter); - pInfo = 0; - hMem = 0; - hPrinter = 0; - return; - } - - devMode = pInfo->pDevMode; - hdc = CreateDC(reinterpret_cast<const wchar_t *>(program.utf16()), - reinterpret_cast<const wchar_t *>(name.utf16()), 0, devMode); - - Q_ASSERT(hPrinter); - Q_ASSERT(pInfo); - - if (devMode) { - num_copies = devMode->dmCopies; - } - - initHDC(); - -#ifdef QT_DEBUG_DRAW - qDebug() << "QWin32PrintEngine::initialize()" << endl - << " - paperRect" << devPaperRect << endl - << " - pageRect" << devPageRect << endl - << " - stretch_x" << stretch_x << endl - << " - stretch_y" << stretch_y << endl - << " - origin_x" << origin_x << endl - << " - origin_y" << origin_y << endl; -#endif -} - -void QWin32PrintEnginePrivate::initHDC() -{ - Q_ASSERT(hdc); - - HDC display_dc = GetDC(0); - dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); - dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); - dpi_display = GetDeviceCaps(display_dc, LOGPIXELSY); - ReleaseDC(0, display_dc); - if (dpi_display == 0) { - qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " - "might be a driver problem"); - dpi_display = 96; // Reasonable default - } - - switch(mode) { - case QPrinter::ScreenResolution: - resolution = dpi_display; - stretch_x = dpi_x / double(dpi_display); - stretch_y = dpi_y / double(dpi_display); - break; - case QPrinter::PrinterResolution: - case QPrinter::HighResolution: - resolution = dpi_y; - stretch_x = 1; - stretch_y = 1; - break; - default: - break; - } - - initDevRects(); -} - -void QWin32PrintEnginePrivate::initDevRects() -{ - devPaperRect = QRect(0, 0, - GetDeviceCaps(hdc, PHYSICALWIDTH), - GetDeviceCaps(hdc, PHYSICALHEIGHT)); - devPhysicalPageRect = QRect(GetDeviceCaps(hdc, PHYSICALOFFSETX), - GetDeviceCaps(hdc, PHYSICALOFFSETY), - GetDeviceCaps(hdc, HORZRES), - GetDeviceCaps(hdc, VERTRES)); - if (!pageMarginsSet) - devPageRect = devPhysicalPageRect; - else - devPageRect = devPaperRect.adjusted(qRound(mmToInches(previousDialogMargins.left() / 100.0) * dpi_x), - qRound(mmToInches(previousDialogMargins.top() / 100.0) * dpi_y), - -qRound(mmToInches(previousDialogMargins.width() / 100.0) * dpi_x), - -qRound(mmToInches(previousDialogMargins.height() / 100.0) * dpi_y)); - updateOrigin(); -} - -void QWin32PrintEnginePrivate::setPageMargins(int marginLeft, int marginTop, int marginRight, int marginBottom) -{ - pageMarginsSet = true; - previousDialogMargins = QRect(marginLeft, marginTop, marginRight, marginBottom); - - devPageRect = devPaperRect.adjusted(qRound(mmToInches(marginLeft / 100.0) * dpi_x), - qRound(mmToInches(marginTop / 100.0) * dpi_y), - - qRound(mmToInches(marginRight / 100.0) * dpi_x), - - qRound(mmToInches(marginBottom / 100.0) * dpi_y)); - updateOrigin(); -} - -QRect QWin32PrintEnginePrivate::getPageMargins() const -{ - if (pageMarginsSet) - return previousDialogMargins; - else - return QRect(qRound(inchesToMM(devPhysicalPageRect.left()) * 100.0 / dpi_x), - qRound(inchesToMM(devPhysicalPageRect.top()) * 100.0 / dpi_y), - qRound(inchesToMM(devPaperRect.right() - devPhysicalPageRect.right()) * 100.0 / dpi_x), - qRound(inchesToMM(devPaperRect.bottom() - devPhysicalPageRect.bottom()) * 100.0 / dpi_y)); -} - -void QWin32PrintEnginePrivate::release() -{ - if (hdc == 0) - return; - - if (globalDevMode) { // Devmode comes from print dialog - GlobalUnlock(globalDevMode); - } else { // Devmode comes from initialize... - // devMode is a part of the same memory block as pInfo so one free is enough... - GlobalUnlock(hMem); - GlobalFree(hMem); - } - if (hPrinter) - ClosePrinter(hPrinter); - DeleteDC(hdc); - - hdc = 0; - hPrinter = 0; - pInfo = 0; - hMem = 0; - devMode = 0; -} - -QList<QVariant> QWin32PrintEnginePrivate::queryResolutions() const -{ - // Read the supported resolutions of the printer. - QList<QVariant> list; - - DWORD numRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()), - reinterpret_cast<const wchar_t *>(port.utf16()), - DC_ENUMRESOLUTIONS, 0, 0); - if (numRes == (DWORD)-1) - return list; - - LONG *enumRes = (LONG*)malloc(numRes * 2 * sizeof(LONG)); - DWORD errRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()), - reinterpret_cast<const wchar_t *>(port.utf16()), - DC_ENUMRESOLUTIONS, (LPWSTR)enumRes, 0); - - if (errRes == (DWORD)-1) { - qErrnoWarning("QWin32PrintEngine::queryResolutions: DeviceCapabilities failed"); - return list; - } - - for (uint i=0; i<numRes; ++i) - list.append(int(enumRes[i * 2])); - - return list; -} - -void QWin32PrintEnginePrivate::doReinit() -{ - if (state == QPrinter::Active) { - reinit = true; - } else { - resetDC(); - initDevRects(); - reinit = false; - } -} - -void QWin32PrintEnginePrivate::updateOrigin() -{ - if (fullPage) { - // subtract physical margins to make (0,0) absolute top corner of paper - // then add user defined margins - origin_x = -devPhysicalPageRect.x(); - origin_y = -devPhysicalPageRect.y(); - if (pageMarginsSet) { - origin_x += devPageRect.left(); - origin_y += devPageRect.top(); - } - } else { - origin_x = 0; - origin_y = 0; - if (pageMarginsSet) { - origin_x = devPageRect.left() - devPhysicalPageRect.x(); - origin_y = devPageRect.top() - devPhysicalPageRect.y(); - } - } -} - -void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) -{ - Q_D(QWin32PrintEngine); - switch (key) { - case PPK_CollateCopies: - { - if (!d->devMode) - break; - d->devMode->dmCollate = value.toBool() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE; - d->doReinit(); - } - break; - - case PPK_ColorMode: - { - if (!d->devMode) - break; - d->devMode->dmColor = (value.toInt() == QPrinter::Color) ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; - d->doReinit(); - } - break; - - case PPK_Creator: - - break; - - case PPK_DocumentName: - if (isActive()) { - qWarning("QWin32PrintEngine: Cannot change document name while printing is active"); - return; - } - d->docName = value.toString(); - break; - - case PPK_FullPage: - d->fullPage = value.toBool(); - d->updateOrigin(); - break; - - case PPK_CopyCount: // fallthrough - case PPK_NumberOfCopies: - if (!d->devMode) - break; - d->num_copies = value.toInt(); - d->devMode->dmCopies = d->num_copies; - d->doReinit(); - break; - - case PPK_Orientation: - { - if (!d->devMode) - break; - int orientation = value.toInt() == QPrinter::Landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT; - int old_orientation = d->devMode->dmOrientation; - d->devMode->dmOrientation = orientation; - if (d->has_custom_paper_size && old_orientation != orientation) - d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width()); - d->doReinit(); - } - break; - - case PPK_OutputFileName: - if (isActive()) { - qWarning("QWin32PrintEngine: Cannot change filename while printing"); - } else { - d->fileName = value.toString(); - d->printToFile = !value.toString().isEmpty(); - } - break; - - case PPK_PaperSize: - if (!d->devMode) - break; - d->devMode->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt())); - d->has_custom_paper_size = (QPrinter::PaperSize(value.toInt()) == QPrinter::Custom); - d->doReinit(); - break; - - case PPK_PaperSource: - { - if (!d->devMode) - break; - int dmMapped = DMBIN_AUTO; - - QList<QVariant> v = property(PPK_PaperSources).toList(); - if (v.contains(value)) - dmMapped = mapPaperSourceDevmode(QPrinter::PaperSource(value.toInt())); - - d->devMode->dmDefaultSource = dmMapped; - d->doReinit(); - } - break; - - case PPK_PrinterName: - d->name = value.toString(); - if(d->name.isEmpty()) - d->queryDefault(); - d->initialize(); - break; - - case PPK_Resolution: - { - d->resolution = value.toInt(); - - d->stretch_x = d->dpi_x / double(d->resolution); - d->stretch_y = d->dpi_y / double(d->resolution); - } - break; - - case PPK_SelectionOption: - - break; - - case PPK_SupportedResolutions: - - break; - - - case PPK_WindowsPageSize: - if (!d->devMode) - break; - d->has_custom_paper_size = false; - d->devMode->dmPaperSize = value.toInt(); - d->doReinit(); - break; - - case PPK_CustomPaperSize: - { - d->has_custom_paper_size = true; - d->paper_size = value.toSizeF(); - if (!d->devMode) - break; - int orientation = d->devMode->dmOrientation; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(d->hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(d->hPrinter, 1, forms, needed, &needed, &returned)) { - for (DWORD i=0; i< returned; ++i) { - FORM_INFO_1 *formArray = reinterpret_cast<FORM_INFO_1 *>(forms); - // the form sizes are specified in 1000th of a mm, - // convert the size to Points - QSizeF size((formArray[i].Size.cx * 72/25.4)/1000.0, - (formArray[i].Size.cy * 72/25.4)/1000.0); - if (qAbs(d->paper_size.width() - size.width()) <= 2 - && qAbs(d->paper_size.height() - size.height()) <= 2) - { - d->devMode->dmPaperSize = i + 1; - break; - } - } - } - free(forms); - } - if (orientation != DMORIENT_PORTRAIT) - d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width()); - break; - } - - case PPK_PageMargins: - { - QList<QVariant> margins(value.toList()); - Q_ASSERT(margins.size() == 4); - int left, top, right, bottom; - // specified in 1/100 mm - left = (margins.at(0).toReal()*25.4/72.0) * 100; - top = (margins.at(1).toReal()*25.4/72.0) * 100; - right = (margins.at(2).toReal()*25.4/72.0) * 100; - bottom = (margins.at(3).toReal()*25.4/72.0) * 100; - d->setPageMargins(left, top, right, bottom); - break; - } - default: - // Do nothing - break; - } -} - -QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const -{ - Q_D(const QWin32PrintEngine); - QVariant value; - switch (key) { - - case PPK_CollateCopies: - value = false; - break; - - case PPK_ColorMode: - { - if (!d->devMode) { - value = QPrinter::Color; - } else { - value = (d->devMode->dmColor == DMCOLOR_COLOR) ? QPrinter::Color : QPrinter::GrayScale; - } - } - break; - - case PPK_DocumentName: - value = d->docName; - break; - - case PPK_FullPage: - value = d->fullPage; - break; - - case PPK_CopyCount: - value = d->num_copies; - break; - - case PPK_SupportsMultipleCopies: - value = true; - break; - - case PPK_NumberOfCopies: - value = 1; - break; - - case PPK_Orientation: - { - if (!d->devMode) { - value = QPrinter::Portrait; - } else { - value = (d->devMode->dmOrientation == DMORIENT_LANDSCAPE) ? QPrinter::Landscape : QPrinter::Portrait; - } - } - break; - - case PPK_OutputFileName: - value = d->fileName; - break; - - case PPK_PageRect: - if (d->has_custom_paper_size) { - QRect rect(0, 0, - qRound(d->paper_size.width() * d->resolution / 72.0), - qRound(d->paper_size.height() * d->resolution / 72.0)); - if (d->pageMarginsSet) { - rect = rect.adjusted(qRound(mmToInches(d->previousDialogMargins.left()/100.0) * d->resolution), - qRound(mmToInches(d->previousDialogMargins.top()/100.0) * d->resolution), - -qRound(mmToInches(d->previousDialogMargins.width()/100.0) * d->resolution), - -qRound(mmToInches(d->previousDialogMargins.height()/100.0) * d->resolution)); - } - value = rect; - } else { - value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0) - .mapRect(d->fullPage ? d->devPhysicalPageRect : d->devPageRect); - } - break; - - case PPK_PaperSize: - if (d->has_custom_paper_size) { - value = QPrinter::Custom; - } else { - if (!d->devMode) { - value = QPrinter::A4; - } else { - value = mapDevmodePaperSize(d->devMode->dmPaperSize); - } - } - break; - - case PPK_PaperRect: - if (d->has_custom_paper_size) { - value = QRect(0, 0, - qRound(d->paper_size.width() * d->resolution / 72.0), - qRound(d->paper_size.height() * d->resolution / 72.0)); - } else { - value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0).mapRect(d->devPaperRect); - } - break; - - case PPK_PaperSource: - if (!d->devMode) { - value = QPrinter::Auto; - } else { - value = mapDevmodePaperSource(d->devMode->dmDefaultSource); - } - break; - - case PPK_PrinterName: - value = d->name; - break; - - case PPK_Resolution: - if (d->resolution || !d->name.isEmpty()) - value = d->resolution; - break; - - case PPK_SupportedResolutions: - value = d->queryResolutions(); - break; - - case PPK_WindowsPageSize: - if (!d->devMode) { - value = -1; - } else { - value = d->devMode->dmPaperSize; - } - break; - - case PPK_PaperSources: - { - int available = DeviceCapabilities((const wchar_t *)d->name.utf16(), - (const wchar_t *)d->port.utf16(), DC_BINS, 0, d->devMode); - - if (available <= 0) - break; - - wchar_t *data = new wchar_t[available]; - int count = DeviceCapabilities((const wchar_t *)d->name.utf16(), - (const wchar_t *)d->port.utf16(), DC_BINS, data, d->devMode); - - QList<QVariant> out; - for (int i=0; i<count; ++i) { - QPrinter::PaperSource src = mapDevmodePaperSource(data[i]); - if (src != -1) - out << (int) src; - } - value = out; - - delete [] data; - } - break; - - case PPK_CustomPaperSize: - value = d->paper_size; - break; - - case PPK_PageMargins: - { - QList<QVariant> margins; - QRect pageMargins(d->getPageMargins()); - - // specified in 1/100 mm - margins << (mmToInches(pageMargins.left()/100.0) * 72) - << (mmToInches(pageMargins.top()/100.0) * 72) - << (mmToInches(pageMargins.width()/100.0) * 72) - << (mmToInches(pageMargins.height()/100.0) * 72); - value = margins; - break; - } - default: - // Do nothing - break; - } - return value; -} - -QPrinter::PrinterState QWin32PrintEngine::printerState() const -{ - return d_func()->state; -} - -HDC QWin32PrintEngine::getDC() const -{ - return d_func()->hdc; -} - -void QWin32PrintEngine::releaseDC(HDC) const -{ - -} - -HGLOBAL *QWin32PrintEnginePrivate::createDevNames() -{ - int size = sizeof(DEVNAMES) - + program.length() * 2 + 2 - + name.length() * 2 + 2 - + port.length() * 2 + 2; - HGLOBAL *hGlobal = (HGLOBAL *) GlobalAlloc(GMEM_MOVEABLE, size); - DEVNAMES *dn = (DEVNAMES*) GlobalLock(hGlobal); - - dn->wDriverOffset = sizeof(DEVNAMES) / sizeof(wchar_t); - dn->wDeviceOffset = dn->wDriverOffset + program.length() + 1; - dn->wOutputOffset = dn->wDeviceOffset + name.length() + 1; - - memcpy((ushort*)dn + dn->wDriverOffset, program.utf16(), program.length() * 2 + 2); - memcpy((ushort*)dn + dn->wDeviceOffset, name.utf16(), name.length() * 2 + 2); - memcpy((ushort*)dn + dn->wOutputOffset, port.utf16(), port.length() * 2 + 2); - dn->wDefault = 0; - - GlobalUnlock(hGlobal); - -// printf("QPrintDialogWinPrivate::createDevNames()\n" -// " -> wDriverOffset: %d\n" -// " -> wDeviceOffset: %d\n" -// " -> wOutputOffset: %d\n", -// dn->wDriverOffset, -// dn->wDeviceOffset, -// dn->wOutputOffset); - -// printf("QPrintDialogWinPrivate::createDevNames(): %s, %s, %s\n", -// QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset).latin1(), -// QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset).latin1(), -// QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset).latin1()); - - return hGlobal; -} - -void QWin32PrintEnginePrivate::readDevnames(HGLOBAL globalDevnames) -{ - if (globalDevnames) { - DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevnames); - name = QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset); - port = QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset); - program = QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset); - GlobalUnlock(globalDevnames); - } -} - -void QWin32PrintEnginePrivate::readDevmode(HGLOBAL globalDevmode) -{ - if (globalDevmode) { - DEVMODE *dm = (DEVMODE*) GlobalLock(globalDevmode); - release(); - globalDevMode = globalDevmode; - devMode = dm; - hdc = CreateDC(reinterpret_cast<const wchar_t *>(program.utf16()), - reinterpret_cast<const wchar_t *>(name.utf16()), 0, dm); - - num_copies = devMode->dmCopies; - if (!OpenPrinter((wchar_t*)name.utf16(), &hPrinter, 0)) - qWarning("QPrinter: OpenPrinter() failed after reading DEVMODE."); - } - - if (hdc) - initHDC(); -} - -static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC hdc, - bool convertToText, const QTransform &xform, const QPointF &topLeft) -{ - QFontEngine *fe = ti.fontEngine; - QPointF baseline_pos = xform.inverted().map(xform.map(pos) - topLeft); - - SetTextAlign(hdc, TA_BASELINE); - SetBkMode(hdc, TRANSPARENT); - - bool has_kerning = ti.f && ti.f->kerning(); - QFontEngineWin *winfe = (fe->type() == QFontEngine::Win) ? static_cast<QFontEngineWin *>(fe) : 0; - - HFONT hfont; - bool ttf = false; - - if (winfe) { - hfont = winfe->hfont; - ttf = winfe->ttf; - } else { - hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); - } - - HGDIOBJ old_font = SelectObject(hdc, hfont); - unsigned int options = (ttf && !convertToText) ? ETO_GLYPH_INDEX : 0; - wchar_t *convertedGlyphs = (wchar_t *)ti.chars; - QGlyphLayout glyphs = ti.glyphs; - - bool fast = !has_kerning && !(ti.flags & QTextItem::RightToLeft); - for (int i = 0; fast && i < glyphs.numGlyphs; i++) { - if (glyphs.offsets[i].x != 0 || glyphs.offsets[i].y != 0 || glyphs.justifications[i].space_18d6 != 0 - || glyphs.attributes[i].dontPrint) { - fast = false; - break; - } - } - -#if !defined(Q_OS_WINCE) - // Scale, rotate and translate here. - XFORM win_xform; - win_xform.eM11 = xform.m11(); - win_xform.eM12 = xform.m12(); - win_xform.eM21 = xform.m21(); - win_xform.eM22 = xform.m22(); - win_xform.eDx = xform.dx(); - win_xform.eDy = xform.dy(); - - SetGraphicsMode(hdc, GM_ADVANCED); - SetWorldTransform(hdc, &win_xform); -#endif - - if (fast) { - // fast path - QVarLengthArray<wchar_t> g(glyphs.numGlyphs); - for (int i = 0; i < glyphs.numGlyphs; ++i) - g[i] = glyphs.glyphs[i]; - ExtTextOut(hdc, - qRound(baseline_pos.x() + glyphs.offsets[0].x.toReal()), - qRound(baseline_pos.y() + glyphs.offsets[0].y.toReal()), - options, 0, convertToText ? convertedGlyphs : g.data(), glyphs.numGlyphs, 0); - } else { - QVarLengthArray<QFixedPoint> positions; - QVarLengthArray<glyph_t> _glyphs; - - QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y()); - ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, - _glyphs, positions); - if (_glyphs.size() == 0) { - SelectObject(hdc, old_font); - return; - } - - convertToText = convertToText && glyphs.numGlyphs == _glyphs.size(); - bool outputEntireItem = _glyphs.size() > 0; - - if (outputEntireItem) { - options |= ETO_PDY; - QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2); - QVarLengthArray<wchar_t> g(_glyphs.size()); - for (int i=0; i<_glyphs.size() - 1; ++i) { - glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x); - glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y); - g[i] = _glyphs[i]; - } - glyphDistances[(_glyphs.size() - 1) * 2] = 0; - glyphDistances[(_glyphs.size() - 1) * 2 + 1] = 0; - g[_glyphs.size() - 1] = _glyphs[_glyphs.size() - 1]; - ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, 0, - convertToText ? convertedGlyphs : g.data(), _glyphs.size(), - glyphDistances.data()); - } else { - int i = 0; - while(i < _glyphs.size()) { - wchar_t g = _glyphs[i]; - - ExtTextOut(hdc, qRound(positions[i].x), - qRound(positions[i].y), options, 0, - convertToText ? convertedGlyphs + i : &g, 1, 0); - ++i; - } - } - } - -#if !defined(Q_OS_WINCE) - win_xform.eM11 = win_xform.eM22 = 1.0; - win_xform.eM12 = win_xform.eM21 = win_xform.eDx = win_xform.eDy = 0.0; - SetWorldTransform(hdc, &win_xform); -#endif - - SelectObject(hdc, old_font); -} - - -void QWin32PrintEnginePrivate::updateCustomPaperSize() -{ - uint paperSize = devMode->dmPaperSize; - if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) { - has_custom_paper_size = true; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(hPrinter, 1, forms, needed, &needed, &returned)) { - if (paperSize <= returned) { - FORM_INFO_1 *formArray = (FORM_INFO_1 *) forms; - int width = formArray[paperSize - 1].Size.cx; // 1/1000 of a mm - int height = formArray[paperSize - 1].Size.cy; // 1/1000 of a mm - paper_size = QSizeF((width * 72 /25.4) / 1000.0, (height * 72 / 25.4) / 1000.0); - } else { - has_custom_paper_size = false; - } - } - free(forms); - } - } else { - has_custom_paper_size = false; - } -} - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER diff --git a/src/gui/platforms/win/qprintengine_win_p.h b/src/gui/platforms/win/qprintengine_win_p.h deleted file mode 100644 index b4d0670e7b..0000000000 --- a/src/gui/platforms/win/qprintengine_win_p.h +++ /dev/null @@ -1,261 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPRINTENGINE_WIN_P_H -#define QPRINTENGINE_WIN_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QT_NO_PRINTER - -#include "QtGui/qprinter.h" -#include "QtGui/qprintengine.h" -#include "QtGui/qpaintengine.h" -#include "QtCore/qt_windows.h" -#include "private/qpaintengine_alpha_p.h" - -QT_BEGIN_NAMESPACE - -class QWin32PrintEnginePrivate; -class QPrinterPrivate; -class QPainterState; - -class QWin32PrintEngine : public QAlphaPaintEngine, public QPrintEngine -{ - Q_DECLARE_PRIVATE(QWin32PrintEngine) -public: - QWin32PrintEngine(QPrinter::PrinterMode mode); - - // override QWin32PaintEngine - bool begin(QPaintDevice *dev); - bool end(); - - void updateState(const QPaintEngineState &state); - - void updateMatrix(const QTransform &matrix); - void updateClipPath(const QPainterPath &clip, Qt::ClipOperation op); - - void drawPath(const QPainterPath &path); - void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); - void drawTextItem(const QPointF &p, const QTextItem &textItem); - - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p); - void setProperty(PrintEnginePropertyKey key, const QVariant &value); - QVariant property(PrintEnginePropertyKey key) const; - - bool newPage(); - bool abort(); - int metric(QPaintDevice::PaintDeviceMetric) const; - - QPrinter::PrinterState printerState() const; - - QPaintEngine::Type type() const { return Windows; } - - HDC getDC() const; - void releaseDC(HDC) const; - - HDC getPrinterDC() const { return getDC(); } - void releasePrinterDC(HDC dc) const { releaseDC(dc); } - -private: - friend class QPrintDialog; - friend class QPageSetupDialog; -}; - -class QWin32PrintEnginePrivate : public QAlphaPaintEnginePrivate -{ - Q_DECLARE_PUBLIC(QWin32PrintEngine) -public: - QWin32PrintEnginePrivate() : - hPrinter(0), - globalDevMode(0), - devMode(0), - pInfo(0), - hdc(0), - mode(QPrinter::ScreenResolution), - state(QPrinter::Idle), - resolution(0), - pageMarginsSet(false), - num_copies(1), - printToFile(false), - fullPage(false), - reinit(false), - has_custom_paper_size(false) - { - } - - ~QWin32PrintEnginePrivate(); - - - /* Reads the default printer name and its driver (printerProgram) into - the engines private data. */ - void queryDefault(); - - /* Initializes the printer data based on the current printer name. This - function creates a DEVMODE struct, HDC and a printer handle. If these - structures are already in use, they are freed using release - */ - void initialize(); - - /* Initializes data in the print engine whenever the HDC has been renewed - */ - void initHDC(); - - /* Releases all the handles the printer currently holds, HDC, DEVMODE, - etc and resets the corresponding members to 0. */ - void release(); - - /* Queries the resolutions for the current printer, and returns them - in a list. */ - QList<QVariant> queryResolutions() const; - - /* Resets the DC with changes in devmode. If the printer is active - this function only sets the reinit variable to true so it - is handled in the next begin or newpage. */ - void doReinit(); - - /* Used by print/page setup dialogs */ - HGLOBAL *createDevNames(); - - void readDevmode(HGLOBAL globalDevmode); - void readDevnames(HGLOBAL globalDevnames); - - inline bool resetDC() { - hdc = ResetDC(hdc, devMode); - return hdc != 0; - } - - void strokePath(const QPainterPath &path, const QColor &color); - void fillPath(const QPainterPath &path, const QColor &color); - - void composeGdiPath(const QPainterPath &path); - void fillPath_dev(const QPainterPath &path, const QColor &color); - void strokePath_dev(const QPainterPath &path, const QColor &color, qreal width); - - void updateOrigin(); - - void initDevRects(); - void setPageMargins(int margin_left, int margin_top, int margin_right, int margin_bottom); - QRect getPageMargins() const; - void updateCustomPaperSize(); - - // Windows GDI printer references. - HANDLE hPrinter; - - HGLOBAL globalDevMode; - DEVMODE *devMode; - PRINTER_INFO_2 *pInfo; - HGLOBAL hMem; - - HDC hdc; - - QPrinter::PrinterMode mode; - - // Printer info - QString name; - QString program; - QString port; - - // Document info - QString docName; - QString fileName; - - QPrinter::PrinterState state; - int resolution; - - // This QRect is used to store the exact values - // entered into the PageSetup Dialog because those are - // entered in mm but are since converted to device coordinates. - // If they were to be converted back when displaying the dialog - // again, there would be inaccuracies so when the user entered 10 - // it may show up as 9.99 the next time the dialog is opened. - // We don't want that confusion. - QRect previousDialogMargins; - - bool pageMarginsSet; - QRect devPageRect; - QRect devPhysicalPageRect; - QRect devPaperRect; - qreal stretch_x; - qreal stretch_y; - int origin_x; - int origin_y; - - int dpi_x; - int dpi_y; - int dpi_display; - int num_copies; - - uint printToFile : 1; - uint fullPage : 1; - uint reinit : 1; - - uint complex_xform : 1; - uint has_pen : 1; - uint has_brush : 1; - uint has_custom_paper_size : 1; - - uint txop; - - QColor brush_color; - QPen pen; - QColor pen_color; - QSizeF paper_size; - - QTransform painterMatrix; - QTransform matrix; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_PRINTER - -#endif // QPRINTENGINE_WIN_P_H diff --git a/src/gui/platforms/win/qprinterinfo_win.cpp b/src/gui/platforms/win/qprinterinfo_win.cpp deleted file mode 100644 index 2c4014d8dc..0000000000 --- a/src/gui/platforms/win/qprinterinfo_win.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qprinterinfo.h" -#include "qprinterinfo_p.h" - -#include <qstringlist.h> - -#include <qt_windows.h> - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PRINTER - -extern QPrinter::PaperSize mapDevmodePaperSize(int s); - -QList<QPrinterInfo> QPrinterInfo::availablePrinters() -{ - QList<QPrinterInfo> printers; - - DWORD needed = 0; - DWORD returned = 0; - if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) { - LPBYTE buffer = new BYTE[needed]; - if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) { - PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer); - QPrinterInfo defPrn = defaultPrinter(); - for (uint i = 0; i < returned; ++i) { - QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); - - QPrinterInfo printerInfo(printerName); - if (printerInfo.printerName() == defPrn.printerName()) - printerInfo.d_ptr->isDefault = true; - printers.append(printerInfo); - } - } - delete [] buffer; - } - - return printers; -} - -QPrinterInfo QPrinterInfo::defaultPrinter() -{ - QString noPrinters(QLatin1String("qt_no_printers")); - wchar_t buffer[256]; - GetProfileString(L"windows", L"device", (wchar_t*)noPrinters.utf16(), buffer, 256); - QString output = QString::fromWCharArray(buffer); - if (output != noPrinters) { - // Filter out the name of the printer, which should be everything before a comma. - QString printerName = output.split(QLatin1Char(',')).value(0); - QPrinterInfo printerInfo(printerName); - printerInfo.d_ptr->isDefault = true; - return printerInfo; - } - - return QPrinterInfo(); -} - -QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const -{ - const Q_D(QPrinterInfo); - - QList<QPrinter::PaperSize> paperSizes; - if (isNull()) - return paperSizes; - - DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()), - NULL, DC_PAPERS, NULL, NULL); - if ((int)size != -1) { - wchar_t *papers = new wchar_t[size]; - size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()), - NULL, DC_PAPERS, papers, NULL); - for (int c = 0; c < (int)size; ++c) - paperSizes.append(mapDevmodePaperSize(papers[c])); - delete [] papers; - } - - return paperSizes; -} - -#endif // QT_NO_PRINTER - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qrawfont_win.cpp b/src/gui/platforms/win/qrawfont_win.cpp deleted file mode 100644 index d8acf57431..0000000000 --- a/src/gui/platforms/win/qrawfont_win.cpp +++ /dev/null @@ -1,707 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qrawfont_p.h" -#include <private/qsystemlibrary_p.h> - -#if !defined(QT_NO_DIRECTWRITE) -# include "qfontenginedirectwrite_p.h" -# include <dwrite.h> -#endif - -#if !defined(QT_NO_RAWFONT) - -QT_BEGIN_NAMESPACE - -namespace { - - template<typename T> - struct BigEndian - { - quint8 data[sizeof(T)]; - - operator T() const - { - T littleEndian = 0; - for (int i=0; i<sizeof(T); ++i) { - littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8); - } - - return littleEndian; - } - - BigEndian<T> &operator=(const T &t) - { - for (int i=0; i<sizeof(T); ++i) { - data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff); - } - - return *this; - } - }; - -# pragma pack(1) - - // Common structure for all formats of the "name" table - struct NameTable - { - BigEndian<quint16> format; - BigEndian<quint16> count; - BigEndian<quint16> stringOffset; - }; - - struct NameRecord - { - BigEndian<quint16> platformID; - BigEndian<quint16> encodingID; - BigEndian<quint16> languageID; - BigEndian<quint16> nameID; - BigEndian<quint16> length; - BigEndian<quint16> offset; - }; - - struct OffsetSubTable - { - BigEndian<quint32> scalerType; - BigEndian<quint16> numTables; - BigEndian<quint16> searchRange; - BigEndian<quint16> entrySelector; - BigEndian<quint16> rangeShift; - }; - - struct TableDirectory - { - BigEndian<quint32> identifier; - BigEndian<quint32> checkSum; - BigEndian<quint32> offset; - BigEndian<quint32> length; - }; - - struct OS2Table - { - BigEndian<quint16> version; - BigEndian<qint16> avgCharWidth; - BigEndian<quint16> weightClass; - BigEndian<quint16> widthClass; - BigEndian<quint16> type; - BigEndian<qint16> subscriptXSize; - BigEndian<qint16> subscriptYSize; - BigEndian<qint16> subscriptXOffset; - BigEndian<qint16> subscriptYOffset; - BigEndian<qint16> superscriptXSize; - BigEndian<qint16> superscriptYSize; - BigEndian<qint16> superscriptXOffset; - BigEndian<qint16> superscriptYOffset; - BigEndian<qint16> strikeOutSize; - BigEndian<qint16> strikeOutPosition; - BigEndian<qint16> familyClass; - quint8 panose[10]; - BigEndian<quint32> unicodeRanges[4]; - quint8 vendorID[4]; - BigEndian<quint16> selection; - BigEndian<quint16> firstCharIndex; - BigEndian<quint16> lastCharIndex; - BigEndian<qint16> typoAscender; - BigEndian<qint16> typoDescender; - BigEndian<qint16> typoLineGap; - BigEndian<quint16> winAscent; - BigEndian<quint16> winDescent; - BigEndian<quint32> codepageRanges[2]; - BigEndian<qint16> height; - BigEndian<qint16> capHeight; - BigEndian<quint16> defaultChar; - BigEndian<quint16> breakChar; - BigEndian<quint16> maxContext; - }; - -# pragma pack() - - class EmbeddedFont - { - public: - EmbeddedFont(const QByteArray &fontData); - - QString changeFamilyName(const QString &newFamilyName); - QByteArray data() const { return m_fontData; } - TableDirectory *tableDirectoryEntry(const QByteArray &tagName); - QString familyName(TableDirectory *nameTableDirectory = 0); - - private: - QByteArray m_fontData; - }; - - EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) - { - } - - TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName) - { - Q_ASSERT(tagName.size() == 4); - - const BigEndian<quint32> *tagIdPtr = - reinterpret_cast<const BigEndian<quint32> *>(tagName.constData()); - quint32 tagId = *tagIdPtr; - - OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data()); - TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1); - - TableDirectory *nameTableDirectoryEntry = 0; - for (int i=0; i<offsetSubTable->numTables; ++i, ++tableDirectory) { - if (tableDirectory->identifier == tagId) { - nameTableDirectoryEntry = tableDirectory; - break; - } - } - - return nameTableDirectoryEntry; - } - - QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry) - { - QString name; - - if (nameTableDirectoryEntry == 0) - nameTableDirectoryEntry = tableDirectoryEntry("name"); - - if (nameTableDirectoryEntry != 0) { - NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data() - + nameTableDirectoryEntry->offset); - NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1); - for (int i=0; i<nameTable->count; ++i, ++nameRecord) { - if (nameRecord->nameID == 1 - && nameRecord->platformID == 3 // Windows - && nameRecord->languageID == 0x0409) { // US English - const void *ptr = reinterpret_cast<const quint8 *>(nameTable) - + nameTable->stringOffset - + nameRecord->offset; - - const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr); - for (int j=0; j<nameRecord->length / sizeof(quint16); ++j) - name += QChar(s[j]); - - break; - } - } - } - - return name; - } - - QString EmbeddedFont::changeFamilyName(const QString &newFamilyName) - { - TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name"); - if (nameTableDirectoryEntry == 0) - return QString(); - - QString oldFamilyName = familyName(nameTableDirectoryEntry); - - // Reserve size for name table header, five required name records and string - const int requiredRecordCount = 5; - quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 }; - - int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount; - int newFamilyNameSize = newFamilyName.size() * sizeof(quint16); - - const QString regularString = QString::fromLatin1("Regular"); - int regularStringSize = regularString.size() * sizeof(quint16); - - // Align table size of table to 32 bits (pad with 0) - int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4; - - QByteArray newNameTable(fullSize, char(0)); - - { - NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data()); - nameTable->count = requiredRecordCount; - nameTable->stringOffset = sizeOfHeader; - - NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1); - for (int i=0; i<requiredRecordCount; ++i, nameRecord++) { - nameRecord->nameID = nameIds[i]; - nameRecord->encodingID = 1; - nameRecord->languageID = 0x0409; - nameRecord->platformID = 3; - nameRecord->length = newFamilyNameSize; - - // Special case for sub-family - if (nameIds[i] == 4) { - nameRecord->offset = newFamilyNameSize; - nameRecord->length = regularStringSize; - } - } - - // nameRecord now points to string data - BigEndian<quint16> *stringStorage = reinterpret_cast<BigEndian<quint16> *>(nameRecord); - const quint16 *sourceString = newFamilyName.utf16(); - for (int i=0; i<newFamilyName.size(); ++i) - stringStorage[i] = sourceString[i]; - stringStorage += newFamilyName.size(); - - sourceString = regularString.utf16(); - for (int i=0; i<regularString.size(); ++i) - stringStorage[i] = sourceString[i]; - } - - quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data()); - quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize); - - quint32 checkSum = 0; - while (p < tableEnd) - checkSum += *(p++); - - nameTableDirectoryEntry->checkSum = checkSum; - nameTableDirectoryEntry->offset = m_fontData.size(); - nameTableDirectoryEntry->length = fullSize; - - m_fontData.append(newNameTable); - - return oldFamilyName; - } - -#if !defined(QT_NO_DIRECTWRITE) - - class DirectWriteFontFileStream: public IDWriteFontFileStream - { - public: - DirectWriteFontFileStream(const QByteArray &fontData) - : m_fontData(fontData) - , m_referenceCount(0) - { - } - - ~DirectWriteFontFileStream() - { - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset, - UINT64 fragmentSize, OUT void **fragmentContext); - void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext); - HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize); - HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime); - - private: - QByteArray m_fontData; - ULONG m_referenceCount; - }; - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object) - { - if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { - *object = this; - AddRef(); - return S_OK; - } else { - *object = NULL; - return E_NOINTERFACE; - } - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef() - { - return InterlockedIncrement(&m_referenceCount); - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release() - { - ULONG newCount = InterlockedDecrement(&m_referenceCount); - if (newCount == 0) - delete this; - return newCount; - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment( - const void **fragmentStart, - UINT64 fileOffset, - UINT64 fragmentSize, - OUT void **fragmentContext) - { - *fragmentContext = NULL; - if (fragmentSize + fileOffset <= m_fontData.size()) { - *fragmentStart = m_fontData.data() + fileOffset; - return S_OK; - } else { - *fragmentStart = NULL; - return E_FAIL; - } - } - - void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *) - { - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize) - { - *fileSize = m_fontData.size(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime) - { - *lastWriteTime = 0; - return E_NOTIMPL; - } - - class DirectWriteFontFileLoader: public IDWriteFontFileLoader - { - public: - DirectWriteFontFileLoader() : m_referenceCount(0) {} - - ~DirectWriteFontFileLoader() - { - } - - inline void addKey(const void *key, const QByteArray &fontData) - { - Q_ASSERT(!m_fontDatas.contains(key)); - m_fontDatas.insert(key, fontData); - } - - inline void removeKey(const void *key) - { - m_fontDatas.remove(key); - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey, - UINT32 fontFileReferenceKeySize, - OUT IDWriteFontFileStream **fontFileStream); - - private: - ULONG m_referenceCount; - QHash<const void *, QByteArray> m_fontDatas; - }; - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid, - void **object) - { - if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { - *object = this; - AddRef(); - return S_OK; - } else { - *object = NULL; - return E_NOINTERFACE; - } - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef() - { - return InterlockedIncrement(&m_referenceCount); - } - - ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release() - { - ULONG newCount = InterlockedDecrement(&m_referenceCount); - if (newCount == 0) - delete this; - return newCount; - } - - HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey( - void const *fontFileReferenceKey, - UINT32 fontFileReferenceKeySize, - IDWriteFontFileStream **fontFileStream) - { - Q_UNUSED(fontFileReferenceKeySize); - - if (fontFileReferenceKeySize != sizeof(const void *)) { - qWarning("DirectWriteFontFileLoader::CreateStreamFromKey: Wrong key size"); - return E_FAIL; - } - - const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey); - *fontFileStream = NULL; - if (!m_fontDatas.contains(key)) - return E_FAIL; - - QByteArray fontData = m_fontDatas.value(key); - DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData); - stream->AddRef(); - *fontFileStream = stream; - - return S_OK; - } - - class CustomFontFileLoader - { - public: - CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0) - { - HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast<IUnknown **>(&m_directWriteFactory)); - if (FAILED(hres)) { - qErrnoWarning(hres, "CustomFontFileLoader::CustomFontFileLoader: " - "DWriteCreateFactory failed."); - } else { - m_directWriteFontFileLoader = new DirectWriteFontFileLoader(); - m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader); - } - } - - ~CustomFontFileLoader() - { - if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0) - m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader); - - if (m_directWriteFactory != 0) - m_directWriteFactory->Release(); - } - - void addKey(const void *key, const QByteArray &fontData) - { - if (m_directWriteFontFileLoader != 0) - m_directWriteFontFileLoader->addKey(key, fontData); - } - - void removeKey(const void *key) - { - if (m_directWriteFontFileLoader != 0) - m_directWriteFontFileLoader->removeKey(key); - } - - IDWriteFontFileLoader *loader() const - { - return m_directWriteFontFileLoader; - } - - private: - IDWriteFactory *m_directWriteFactory; - DirectWriteFontFileLoader *m_directWriteFontFileLoader; - }; - -#endif - -} // Anonymous namespace - - -// From qfontdatabase_win.cpp -extern QFontEngine *qt_load_font_engine_win(const QFontDef &request); -// From qfontdatabase.cpp -extern QFont::Weight weightFromInteger(int weight); - -void QRawFontPrivate::platformCleanUp() -{ - if (fontHandle != NULL) { - if (ptrRemoveFontMemResourceEx == NULL) { - void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - ptrRemoveFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func); - } - - if (ptrRemoveFontMemResourceEx == NULL) { - qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32"); - fontHandle = NULL; - } else { - ptrRemoveFontMemResourceEx(fontHandle); - fontHandle = NULL; - } - } -} - -void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, - int pixelSize, - QFont::HintingPreference hintingPreference) -{ - QByteArray fontData(_fontData); - EmbeddedFont font(fontData); - -#if !defined(QT_NO_DIRECTWRITE) - if (hintingPreference == QFont::PreferDefaultHinting - || hintingPreference == QFont::PreferFullHinting) -#endif - { - GUID guid; - CoCreateGuid(&guid); - - QString uniqueFamilyName = QString::fromLatin1("f") - + QString::number(guid.Data1, 36) + QLatin1Char('-') - + QString::number(guid.Data2, 36) + QLatin1Char('-') - + QString::number(guid.Data3, 36) + QLatin1Char('-') - + QString::number(*reinterpret_cast<quint64 *>(guid.Data4), 36); - - QString actualFontName = font.changeFamilyName(uniqueFamilyName); - if (actualFontName.isEmpty()) { - qWarning("QRawFont::platformLoadFromData: Can't change family name of font"); - return; - } - - if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) { - void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - ptrRemoveFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func); - - func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx"); - ptrAddFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrAddFontMemResourceEx>(func); - } - - Q_ASSERT(fontHandle == NULL); - if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) { - DWORD count = 0; - fontData = font.data(); - fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count); - - if (count == 0 && fontHandle != NULL) { - ptrRemoveFontMemResourceEx(fontHandle); - fontHandle = NULL; - } - } - - if (fontHandle == NULL) { - qWarning("QRawFont::platformLoadFromData: AddFontMemResourceEx failed"); - } else { - QFontDef request; - request.family = uniqueFamilyName; - request.pixelSize = pixelSize; - request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch; - request.hintingPreference = hintingPreference; - - fontEngine = qt_load_font_engine_win(request); - if (request.family != fontEngine->fontDef.family) { - qWarning("QRawFont::platformLoadFromData: Failed to load font. " - "Got fallback instead: %s", qPrintable(fontEngine->fontDef.family)); - if (fontEngine->cache_count == 0 && fontEngine->ref == 0) - delete fontEngine; - fontEngine = 0; - } else { - Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0); - - // Override the generated font name - static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName; - fontEngine->fontDef.family = actualFontName; - fontEngine->ref.ref(); - } - } - } -#if !defined(QT_NO_DIRECTWRITE) - else { - CustomFontFileLoader fontFileLoader; - fontFileLoader.addKey(this, fontData); - - IDWriteFactory *factory = NULL; - HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast<IUnknown **>(&factory)); - if (FAILED(hres)) { - qErrnoWarning(hres, "QRawFont::platformLoadFromData: DWriteCreateFactory failed"); - return; - } - - IDWriteFontFile *fontFile = NULL; - void *key = this; - - hres = factory->CreateCustomFontFileReference(&key, sizeof(void *), - fontFileLoader.loader(), &fontFile); - if (FAILED(hres)) { - qErrnoWarning(hres, "QRawFont::platformLoadFromData: " - "CreateCustomFontFileReference failed"); - factory->Release(); - return; - } - - BOOL isSupportedFontType; - DWRITE_FONT_FILE_TYPE fontFileType; - DWRITE_FONT_FACE_TYPE fontFaceType; - UINT32 numberOfFaces; - fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces); - if (!isSupportedFontType) { - fontFile->Release(); - factory->Release(); - return; - } - - IDWriteFontFace *directWriteFontFace = NULL; - hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE, - &directWriteFontFace); - if (FAILED(hres)) { - qErrnoWarning(hres, "QRawFont::platformLoadFromData: CreateFontFace failed"); - fontFile->Release(); - factory->Release(); - return; - } - - fontFile->Release(); - - fontEngine = new QFontEngineDirectWrite(factory, directWriteFontFace, pixelSize); - - // Get font family from font data - fontEngine->fontDef.family = font.familyName(); - fontEngine->ref.ref(); - - directWriteFontFace->Release(); - factory->Release(); - } -#endif - - // Get style and weight info - if (fontEngine != 0) { - TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2"); - if (os2TableEntry != 0) { - const OS2Table *os2Table = - reinterpret_cast<const OS2Table *>(fontData.constData() - + os2TableEntry->offset); - - bool italic = os2Table->selection & 1; - bool oblique = os2Table->selection & 128; - - if (italic) - fontEngine->fontDef.style = QFont::StyleItalic; - else if (oblique) - fontEngine->fontDef.style = QFont::StyleOblique; - else - fontEngine->fontDef.style = QFont::StyleNormal; - - fontEngine->fontDef.weight = weightFromInteger(os2Table->weightClass); - } - } -} - -QT_END_NAMESPACE - -#endif // QT_NO_RAWFONT diff --git a/src/gui/platforms/win/qregion_win.cpp b/src/gui/platforms/win/qregion_win.cpp deleted file mode 100644 index 3466b62cbd..0000000000 --- a/src/gui/platforms/win/qregion_win.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qatomic.h" -#include "qbitmap.h" -#include "qbuffer.h" -#include "qimage.h" -#include "qpolygon.h" -#include "qregion.h" -#include "qt_windows.h" -#include "qpainterpath.h" - -QT_BEGIN_NAMESPACE - -QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0 }; - -HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom) -{ - const int tries = 10; - for (int i = 0; i < tries; ++i) { - HRGN region = 0; - switch (type) { - case QRegion::Rectangle: - region = CreateRectRgn(left, top, right, bottom); - break; - case QRegion::Ellipse: -#ifndef Q_OS_WINCE - region = CreateEllipticRgn(left, top, right, bottom); -#endif - break; - } - if (region) { - if (GetRegionData(region, 0, 0)) - return region; - else - DeleteObject(region); - } - } - return 0; -} - -QRegion qt_region_from_HRGN(HRGN rgn) -{ - int numBytes = GetRegionData(rgn, 0, 0); - if (numBytes == 0) - return QRegion(); - - char *buf = new char[numBytes]; - if (buf == 0) - return QRegion(); - - RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf); - if (GetRegionData(rgn, numBytes, rd) == 0) { - delete [] buf; - return QRegion(); - } - - QRegion region; - RECT *r = reinterpret_cast<RECT*>(rd->Buffer); - for (uint i = 0; i < rd->rdh.nCount; ++i) { - QRect rect; - rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1); - ++r; - region |= rect; - } - - delete [] buf; - - return region; -} - -void qt_win_dispose_rgn(HRGN r) -{ - if (r) - DeleteObject(r); -} - -static void qt_add_rect(HRGN &winRegion, QRect r) -{ - HRGN rgn = CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height()); - if (rgn) { - HRGN dest = CreateRectRgn(0,0,0,0); - int result = CombineRgn(dest, winRegion, rgn, RGN_OR); - if (result) { - DeleteObject(winRegion); - winRegion = dest; - } - DeleteObject(rgn); - } -} - -void QRegion::ensureHandle() const -{ - if (d->rgn) - DeleteObject(d->rgn); - d->rgn = CreateRectRgn(0,0,0,0); - if (d->qt_rgn) { - if (d->qt_rgn->numRects == 1) { - QRect r = d->qt_rgn->extents; - qt_add_rect(d->rgn, r); - return; - } - for (int i = 0;i < d->qt_rgn->numRects;i++) { - QRect r = d->qt_rgn->rects.at(i); - qt_add_rect(d->rgn, r); - } - } -} - - -QT_END_NAMESPACE diff --git a/src/gui/platforms/win/qsound_win.cpp b/src/gui/platforms/win/qsound_win.cpp deleted file mode 100644 index c11482d608..0000000000 --- a/src/gui/platforms/win/qsound_win.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsound.h" - -#ifndef QT_NO_SOUND - -#include "qapplication.h" -#include "qapplication_p.h" -#include <qfile.h> -#include "qpointer.h" -#include "qsound_p.h" - -#include <qt_windows.h> - -QT_BEGIN_NAMESPACE - -class QAuServerWindows : public QAuServer { - Q_OBJECT - -public: - QAuServerWindows(QObject* parent); - ~QAuServerWindows(); - - void playHelper(const QString &filename, int loop, QSound *snd); - void play(const QString& filename, int loop); - void play(QSound*); - - void stop(QSound*); - bool okay(); - - int decLoop(QSound *snd) { return QAuServer::decLoop(snd); } - - HANDLE current; - HANDLE mutex; - HANDLE event; -}; - -QAuServerWindows::QAuServerWindows(QObject* parent) : - QAuServer(parent), current(0) -{ - mutex = CreateMutex(0, 0, 0); - event = CreateEvent(0, FALSE, FALSE, 0); -} - -QAuServerWindows::~QAuServerWindows() -{ - HANDLE mtx = mutex; - WaitForSingleObject(mtx, INFINITE); - mutex = 0; - - ReleaseMutex(mtx); - CloseHandle(mtx); - CloseHandle(event); -} - -struct SoundInfo -{ - SoundInfo(const QString &fn, int lp, QSound *snd, QAuServerWindows *srv) - : sound(snd), server(srv), filename(fn), loops(lp) - { - } - - QSound *sound; - QAuServerWindows *server; - QString filename; - int loops; -}; - -DWORD WINAPI SoundPlayProc(LPVOID param) -{ - SoundInfo *info = (SoundInfo*)param; - - // copy data before waking up GUI thread - QAuServerWindows *server = info->server; - QSound *sound = info->sound; - int loops = info->loops; - QString filename = info->filename; - HANDLE mutex = server->mutex; - HANDLE event = server->event; - info = 0; - - // server must not be destroyed until thread finishes - // and all other sounds have to wait - WaitForSingleObject(mutex, INFINITE); - - if (loops <= 1) { - server->current = 0; - int flags = SND_FILENAME|SND_ASYNC; - if (loops == -1) - flags |= SND_LOOP; - - PlaySound((wchar_t*)filename.utf16(), 0, flags); - if (sound && loops == 1) - server->decLoop(sound); - - // GUI thread continues, but we are done as well. - SetEvent(event); - } else { - // signal GUI thread to continue - sound might be reset! - QPointer<QSound> guarded_sound = sound; - SetEvent(event); - - for (int l = 0; l < loops && server->current; ++l) { - PlaySound((wchar_t*)filename.utf16(), 0, SND_FILENAME | SND_SYNC); - - if (guarded_sound) - server->decLoop(guarded_sound); - } - server->current = 0; - } - ReleaseMutex(mutex); - - return 0; -} - -void QAuServerWindows::playHelper(const QString &filename, int loop, QSound *snd) -{ - if (loop == 0) - return; - // busy? - if (WaitForSingleObject(mutex, 0) == WAIT_TIMEOUT) - return; - ReleaseMutex(mutex); - - DWORD threadid = 0; - SoundInfo info(filename, loop, snd, this); - current = CreateThread(0, 0, SoundPlayProc, &info, 0, &threadid); - CloseHandle(current); - - WaitForSingleObject(event, INFINITE); -} - -void QAuServerWindows::play(const QString& filename, int loop) -{ - playHelper(filename, loop, 0); -} - -void QAuServerWindows::play(QSound* s) -{ - playHelper(s->fileName(), s->loops(), s); -} - -void QAuServerWindows::stop(QSound*) -{ - // stop unlooped sound - if (!current) - PlaySound(0, 0, 0); - // stop after loop is done - current = 0; -} - -bool QAuServerWindows::okay() -{ - return true; -} - -QAuServer* qt_new_audio_server() -{ - return new QAuServerWindows(qApp); -} - -QT_END_NAMESPACE - -#include "qsound_win.moc" - -#endif // QT_NO_SOUND diff --git a/src/gui/platforms/win/qwidget_win.cpp b/src/gui/platforms/win/qwidget_win.cpp deleted file mode 100644 index a02c5ba008..0000000000 --- a/src/gui/platforms/win/qwidget_win.cpp +++ /dev/null @@ -1,2139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qapplication.h" -#include "qapplication_p.h" -#include "qbitmap.h" -#include "qcursor.h" -#include "qdesktopwidget.h" -#include "qevent.h" -#include "qimage.h" -#include "qlayout.h" -#include "qpainter.h" -#include "qstack.h" -#include "qt_windows.h" -#include "qwidget.h" -#include "qwidget_p.h" -#include "private/qbackingstore_p.h" -#include "private/qwindowsurface_raster_p.h" - -#include "qscrollbar.h" -#include "qabstractscrollarea.h" -#include <private/qabstractscrollarea_p.h> - -#include <qdebug.h> - -#include <private/qapplication_p.h> -#include <private/qwininputcontext_p.h> -#include <private/qpaintengine_raster_p.h> -#include <private/qsystemlibrary_p.h> - -#if defined(Q_WS_WINCE) -#include "qguifunctions_wince.h" -QT_USE_NAMESPACE -extern void qt_wince_maximize(QWidget *widget); //defined in qguifunctions_wince.cpp -extern void qt_wince_unmaximize(QWidget *widget); //defined in qguifunctions_wince.cpp -extern void qt_wince_minimize(HWND hwnd); //defined in qguifunctions_wince.cpp -extern void qt_wince_full_screen(HWND hwnd, bool fullScreen, UINT swpf); //defined in qguifunctions_wince.cpp -extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp -#endif - -typedef BOOL (WINAPI *PtrSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); -static PtrSetLayeredWindowAttributes ptrSetLayeredWindowAttributes = 0; - -#ifndef QT_NO_DIRECTDRAW -#include <ddraw.h> -#include <private/qimage_p.h> -static IDirectDraw *qt_ddraw_object; -static IDirectDrawSurface *qt_ddraw_primary; -#endif - - - -#if defined(QT_NON_COMMERCIAL) -#include "qnc_win.h" -#endif - -#if !defined(WS_EX_TOOLWINDOW) -#define WS_EX_TOOLWINDOW 0x00000080 -#endif - -#if !defined(GWLP_WNDPROC) -#define GWLP_WNDPROC GWL_WNDPROC -#endif - -//#define TABLET_DEBUG -#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \ - | PK_ORIENTATION | PK_CURSOR | PK_Z) -#define PACKETMODE 0 -#include <wintab.h> -#include <pktdef.h> - -QT_BEGIN_NAMESPACE - -typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL); -typedef BOOL (API *PtrWTClose)(HCTX); -typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID); -typedef BOOL (API *PtrWTEnable)(HCTX, BOOL); -typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL); -typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID); -typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT); -typedef int (API *PtrWTQueueSizeGet)(HCTX); -typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int); - -static PtrWTOpen ptrWTOpen = 0; -static PtrWTClose ptrWTClose = 0; -static PtrWTInfo ptrWTInfo = 0; -static PtrWTQueueSizeGet ptrWTQueueSizeGet = 0; -static PtrWTQueueSizeSet ptrWTQueueSizeSet = 0; -#ifndef QT_NO_TABLETEVENT -static void init_wintab_functions(); -static void qt_tablet_init(); -static void qt_tablet_cleanup(); -#endif // QT_NO_TABLETEVENT -extern HCTX qt_tablet_context; -extern bool qt_tablet_tilt_support; - -static QWidget *qt_tablet_widget = 0; -QWidget* qt_get_tablet_widget() -{ - return qt_tablet_widget; -} - -extern bool qt_is_gui_used; - -#ifndef QT_NO_TABLETEVENT -static void init_wintab_functions() -{ -#if defined(Q_OS_WINCE) - return; -#else - if (!qt_is_gui_used) - return; - QSystemLibrary library(QLatin1String("wintab32")); - ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenW"); - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); - ptrWTClose = (PtrWTClose)library.resolve("WTClose"); - ptrWTQueueSizeGet = (PtrWTQueueSizeGet)library.resolve("WTQueueSizeGet"); - ptrWTQueueSizeSet = (PtrWTQueueSizeSet)library.resolve("WTQueueSizeSet"); -#endif // Q_OS_WINCE -} - -static void qt_tablet_init() -{ - static bool firstTime = true; - if (!firstTime) - return; - firstTime = false; - qt_tablet_widget = new QWidget(0); - qt_tablet_widget->createWinId(); - qt_tablet_widget->setObjectName(QLatin1String("Qt internal tablet widget")); - // We don't need this internal widget to appear in QApplication::topLevelWidgets() - if (QWidgetPrivate::allWidgets) - QWidgetPrivate::allWidgets->remove(qt_tablet_widget); - LOGCONTEXT lcMine; - qAddPostRoutine(qt_tablet_cleanup); - struct tagAXIS tpOri[3]; - init_wintab_functions(); - if (ptrWTInfo && ptrWTOpen && ptrWTQueueSizeGet && ptrWTQueueSizeSet) { - // make sure we have WinTab - if (!ptrWTInfo(0, 0, NULL)) { -#ifdef TABLET_DEBUG - qWarning("QWidget: Wintab services not available"); -#endif - return; - } - - // some tablets don't support tilt, check if it is possible, - qt_tablet_tilt_support = ptrWTInfo(WTI_DEVICES, DVC_ORIENTATION, &tpOri); - if (qt_tablet_tilt_support) { - // check for azimuth and altitude - qt_tablet_tilt_support = tpOri[0].axResolution && tpOri[1].axResolution; - } - // build our context from the default context - ptrWTInfo(WTI_DEFSYSCTX, 0, &lcMine); - // Go for the raw coordinates, the tablet event will return good stuff - lcMine.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES; - lcMine.lcPktData = PACKETDATA; - lcMine.lcPktMode = PACKETMODE; - lcMine.lcMoveMask = PACKETDATA; - lcMine.lcOutOrgX = 0; - lcMine.lcOutExtX = lcMine.lcInExtX; - lcMine.lcOutOrgY = 0; - lcMine.lcOutExtY = -lcMine.lcInExtY; - qt_tablet_context = ptrWTOpen(qt_tablet_widget->winId(), &lcMine, true); -#ifdef TABLET_DEBUG - qDebug("Tablet is %p", qt_tablet_context); -#endif - if (!qt_tablet_context) { -#ifdef TABLET_DEBUG - qWarning("QWidget: Failed to open the tablet"); -#endif - return; - } - // Set the size of the Packet Queue to the correct size... - int currSize = ptrWTQueueSizeGet(qt_tablet_context); - if (!ptrWTQueueSizeSet(qt_tablet_context, QT_TABLET_NPACKETQSIZE)) { - // Ideally one might want to use a smaller - // multiple, but for now, since we managed to destroy - // the existing Q with the previous call, set it back - // to the other size, which should work. If not, - // there will be trouble. - if (!ptrWTQueueSizeSet(qt_tablet_context, currSize)) { - Q_ASSERT_X(0, "Qt::Internal", "There is no packet queue for" - " the tablet. The tablet will not work"); - } - } - } -} - -static void qt_tablet_cleanup() -{ - if (ptrWTClose) - ptrWTClose(qt_tablet_context); - delete qt_tablet_widget; - qt_tablet_widget = 0; -} -#endif // QT_NO_TABLETEVENT - -const QString qt_reg_winclass(QWidget *w); // defined in qapplication_win.cpp - -#ifndef QT_NO_DRAGANDDROP -void qt_olednd_unregister(QWidget* widget, QOleDropTarget *dst); // dnd_win -QOleDropTarget* qt_olednd_register(QWidget* widget); -#endif - -extern bool qt_nograb(); -extern HRGN qt_win_bitmapToRegion(const QBitmap& bitmap); - -static QWidget *mouseGrb = 0; -static QCursor *mouseGrbCur = 0; -static QWidget *keyboardGrb = 0; -static HHOOK journalRec = 0; - -extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); - -#define XCOORD_MAX 16383 -#define WRECT_MAX 16383 - -/***************************************************************************** - QWidget member functions - *****************************************************************************/ - -#ifndef Q_WS_WINCE -void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) -{ - Q_Q(QWidget); - static int sw = -1, sh = -1; - - Qt::WindowType type = q->windowType(); - Qt::WindowFlags flags = data.window_flags; - - bool topLevel = (flags & Qt::Window); - bool popup = (type == Qt::Popup); - bool dialog = (type == Qt::Dialog - || type == Qt::Sheet - || (flags & Qt::MSWindowsFixedSizeDialogHint)); - bool desktop = (type == Qt::Desktop); - bool tool = (type == Qt::Tool || type == Qt::Drawer); - - HINSTANCE appinst = qWinAppInst(); - HWND parentw, destroyw = 0; - WId id = 0; - - QString windowClassName = qt_reg_winclass(q); - - if (!window) // always initialize - initializeWindow = true; - - if (popup) - flags |= Qt::WindowStaysOnTopHint; // a popup stays on top - - if (sw < 0) { // get the (primary) screen size - sw = GetSystemMetrics(SM_CXSCREEN); - sh = GetSystemMetrics(SM_CYSCREEN); - } - - if (desktop && !q->testAttribute(Qt::WA_DontShowOnScreen)) { // desktop widget - popup = false; // force this flags off - data.crect.setRect(GetSystemMetrics(76 /* SM_XVIRTUALSCREEN */), GetSystemMetrics(77 /* SM_YVIRTUALSCREEN */), - GetSystemMetrics(78 /* SM_CXVIRTUALSCREEN */), GetSystemMetrics(79 /* SM_CYVIRTUALSCREEN */)); - } - - parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0; - - QString title; - int style = WS_CHILD; - int exsty = 0; - - if (window) { - style = GetWindowLong(window, GWL_STYLE); - if (!style) - qErrnoWarning("QWidget::create: GetWindowLong failed"); - topLevel = false; // #### needed for some IE plugins?? - } else if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) { - style = WS_POPUP; - } else if (topLevel && !desktop) { - if (flags & Qt::FramelessWindowHint) - style = WS_POPUP; // no border - else if (flags & Qt::WindowTitleHint) - style = WS_OVERLAPPED; - else - style = 0; - } - if (!desktop) { - // if (!testAttribute(Qt::WA_PaintUnclipped)) - // ### Commented out for now as it causes some problems, but - // this should be correct anyway, so dig some more into this -#ifndef Q_FLATTEN_EXPOSE - style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ; -#endif - if (topLevel) { - if ((type == Qt::Window || dialog || tool)) { - if (!(flags & Qt::FramelessWindowHint)) { - style |= WS_POPUP; - if (!(flags & Qt::MSWindowsFixedSizeDialogHint)) - style |= WS_THICKFRAME; - else - style |= WS_DLGFRAME; - } - if (flags & Qt::WindowTitleHint) - style |= WS_CAPTION; - if (flags & Qt::WindowSystemMenuHint) - style |= WS_SYSMENU; - if (flags & Qt::WindowMinimizeButtonHint) - style |= WS_MINIMIZEBOX; - if (shouldShowMaximizeButton()) - style |= WS_MAXIMIZEBOX; - if (tool) - exsty |= WS_EX_TOOLWINDOW; - if (flags & Qt::WindowContextHelpButtonHint) - exsty |= WS_EX_CONTEXTHELP; - } else { - exsty |= WS_EX_TOOLWINDOW; - } - } - } - - if (flags & Qt::WindowTitleHint) { - title = q->isWindow() ? qAppName() : q->objectName(); - } - - // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in - // qapplication_win.cpp. We switch it off temporarily to avoid move - // and resize events during creationt - q->setAttribute(Qt::WA_WState_Created, false); - - if (window) { // override the old window - if (destroyOldWindow) - destroyw = data.winid; - id = window; - setWinId(window); - LONG res = SetWindowLong(window, GWL_STYLE, style); - if (!res) - qErrnoWarning("QWidget::create: Failed to set window style"); -#ifdef _WIN64 - res = SetWindowLongPtr( window, GWLP_WNDPROC, (LONG_PTR)QtWndProc ); -#else - res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc ); -#endif - if (!res) - qErrnoWarning("QWidget::create: Failed to set window procedure"); - } else if (desktop) { // desktop widget - id = GetDesktopWindow(); -// QWidget *otherDesktop = QWidget::find(id); // is there another desktop? -// if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) { -// otherDesktop->d_func()->setWinId(0); // remove id from widget mapper -// d->setWinId(id); // make sure otherDesktop is -// otherDesktop->d_func()->setWinId(id); // found first -// } else { - setWinId(id); -// } - } else if (topLevel) { // create top-level widget - if (popup) - parentw = 0; - - const bool wasMoved = q->testAttribute(Qt::WA_Moved); - int x = wasMoved ? data.crect.left() : CW_USEDEFAULT; - int y = wasMoved ? data.crect.top() : CW_USEDEFAULT; - int w = CW_USEDEFAULT; - int h = CW_USEDEFAULT; - - // Adjust for framestrut when needed - RECT rect = {0,0,0,0}; - bool isVisibleOnScreen = !q->testAttribute(Qt::WA_DontShowOnScreen); - if (isVisibleOnScreen && AdjustWindowRectEx(&rect, style & ~WS_OVERLAPPED, FALSE, exsty)) { - QTLWExtra *td = maybeTopData(); - if (wasMoved && (td && !td->posFromMove)) { - x = data.crect.x() + rect.left; - y = data.crect.y() + rect.top; - } - - if (q->testAttribute(Qt::WA_Resized)) { - w = data.crect.width() + (rect.right - rect.left); - h = data.crect.height() + (rect.bottom - rect.top); - } - } - //update position & initial size of POPUP window - if (isVisibleOnScreen && topLevel && initializeWindow && (style & WS_POPUP)) { - if (!q->testAttribute(Qt::WA_Resized)) { - w = sw/2; - h = 4*sh/10; - if (extra) { - int dx = rect.right - rect.left; - int dy = rect.bottom - rect.top; - w = qMin(w, extra->maxw + dx); - h = qMin(h, extra->maxh + dy); - w = qMax(w, extra->minw + dx); - h = qMax(h, extra->minh + dy); - } - } - if (!wasMoved) { - x = sw/2 - w/2; - y = sh/2 - h/2; - } - } - - id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()), - reinterpret_cast<const wchar_t *>(title.utf16()), style, - x, y, w, h, - parentw, NULL, appinst, NULL); - if (!id) - qErrnoWarning("QWidget::create: Failed to create window"); - setWinId(id); - if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) { - SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - if (flags & Qt::WindowStaysOnBottomHint) - qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time"; - } else if (flags & Qt::WindowStaysOnBottomHint) - SetWindowPos(id, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - winUpdateIsOpaque(); - } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget - id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()), - reinterpret_cast<const wchar_t *>(title.utf16()), style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), - parentw, NULL, appinst, NULL); - if (!id) - qErrnoWarning("QWidget::create: Failed to create window"); - SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - setWinId(id); - } - - if (desktop) { - q->setAttribute(Qt::WA_WState_Visible); - } else if (topLevel && !q->testAttribute(Qt::WA_DontShowOnScreen)) { - RECT cr; - GetClientRect(id, &cr); - // one cannot trust cr.left and cr.top, use a correction POINT instead - POINT pt; - pt.x = 0; - pt.y = 0; - ClientToScreen(id, &pt); - - if (data.crect.width() == 0 || data.crect.height() == 0) { - data.crect = QRect(pt.x, pt.y, data.crect.width(), data.crect.height()); - } else { - data.crect = QRect(QPoint(pt.x, pt.y), - QPoint(pt.x + cr.right - 1, pt.y + cr.bottom - 1)); - } - - if (data.fstrut_dirty) { - // be nice to activeqt - updateFrameStrut(); - } - } - - if (topLevel) { - if (data.window_flags & Qt::CustomizeWindowHint - && data.window_flags & Qt::WindowTitleHint) { - HMENU systemMenu = GetSystemMenu((HWND)q->internalWinId(), FALSE); - if (data.window_flags & Qt::WindowCloseButtonHint) - EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED); - else - EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED); - } - } - - q->setAttribute(Qt::WA_WState_Created); // accept move/resize events - hd = 0; // no display context - - if (q->testAttribute(Qt::WA_AcceptTouchEvents)) - registerTouchWindow(); - - if (window) { // got window from outside - if (IsWindowVisible(window)) - q->setAttribute(Qt::WA_WState_Visible); - else - q->setAttribute(Qt::WA_WState_Visible, false); - } - - if (extra && !extra->mask.isEmpty()) - setMask_sys(extra->mask); - -#if defined(QT_NON_COMMERCIAL) - QT_NC_WIDGET_CREATE -#endif - - if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) - q->inputContext()->setFocusWidget(q); - - if (destroyw) { - DestroyWindow(destroyw); - } - -#ifndef QT_NO_TABLETEVENT - if (q != qt_tablet_widget && QWidgetPrivate::mapper) - qt_tablet_init(); -#endif // QT_NO_TABLETEVENT - - if (q->testAttribute(Qt::WA_DropSiteRegistered)) - registerDropSite(true); - - if (maybeTopData() && maybeTopData()->opacity != 255) - q->setWindowOpacity(maybeTopData()->opacity/255.); - - if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0)) { - q->setAttribute(Qt::WA_OutsideWSRange, true); - } - - if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) { - Q_ASSERT(q->internalWinId()); - ShowWindow(q->internalWinId(), SW_SHOW); - } -} - -#endif //Q_WS_WINCE - - -void QWidget::destroy(bool destroyWindow, bool destroySubWindows) -{ - Q_D(QWidget); - d->aboutToDestroy(); - if (!isWindow() && parentWidget()) - parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); - d->deactivateWidgetCleanup(); - if (testAttribute(Qt::WA_WState_Created)) { - setAttribute(Qt::WA_WState_Created, false); - for(int i = 0; i < d->children.size(); ++i) { // destroy all widget children - register QObject *obj = d->children.at(i); - if (obj->isWidgetType()) - ((QWidget*)obj)->destroy(destroySubWindows, - destroySubWindows); - } - if (mouseGrb == this) - releaseMouse(); - if (keyboardGrb == this) - releaseKeyboard(); - if (testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal - QApplicationPrivate::leaveModal(this); - else if ((windowType() == Qt::Popup)) - qApp->d_func()->closePopup(this); - if (destroyWindow && !(windowType() == Qt::Desktop) && internalWinId()) { - DestroyWindow(internalWinId()); - } -#ifdef Q_WS_WINCE - if (destroyWindow && (windowType() == Qt::Desktop) && !GetDesktopWindow()) { - DestroyWindow(internalWinId()); - } - -#endif - QT_TRY { - d->setWinId(0); - } QT_CATCH (const std::bad_alloc &) { - // swallow - destructors must not throw - } - } -} - -void QWidgetPrivate::reparentChildren() -{ - Q_Q(QWidget); - QObjectList chlist = q->children(); - for(int i = 0; i < chlist.size(); ++i) { // reparent children - QObject *obj = chlist.at(i); - if (obj->isWidgetType()) { - QWidget *w = (QWidget *)obj; - if ((w->windowType() == Qt::Popup)) { - ; - } else if (w->isWindow()) { - bool showIt = w->isVisible(); - QPoint old_pos = w->pos(); - w->setParent(q, w->windowFlags()); - w->move(old_pos); - if (showIt) - w->show(); - } else { - w->d_func()->invalidateBuffer(w->rect()); - SetParent(w->effectiveWinId(), q->effectiveWinId()); - w->d_func()->reparentChildren(); - } - } - } -} - -void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) -{ - Q_Q(QWidget); - bool wasCreated = q->testAttribute(Qt::WA_WState_Created); - if (q->isVisible() && q->parentWidget() && parent != q->parentWidget()) - q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); - - WId old_winid = data.winid; - // hide and reparent our own window away. Otherwise we might get - // destroyed when emitting the child remove event below. See QWorkspace. - if (q->isVisible() && data.winid) { - ShowWindow(data.winid, SW_HIDE); - SetParent(data.winid, 0); - } - bool dropSiteWasRegistered = false; - if (q->testAttribute(Qt::WA_DropSiteRegistered)) { - dropSiteWasRegistered = true; - q->setAttribute(Qt::WA_DropSiteRegistered, false); // ole dnd unregister (we will register again below) - } - - if ((q->windowType() == Qt::Desktop)) - old_winid = 0; - setWinId(0); - - QObjectPrivate::setParent_helper(parent); - bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide); - - data.window_flags = f; - data.fstrut_dirty = true; - q->setAttribute(Qt::WA_WState_Created, false); - q->setAttribute(Qt::WA_WState_Visible, false); - q->setAttribute(Qt::WA_WState_Hidden, false); - adjustFlags(data.window_flags, q); - // keep compatibility with previous versions, we need to preserve the created state - // (but we recreate the winId for the widget being reparented, again for compatibility) - if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created))) - createWinId(); - if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden) - q->setAttribute(Qt::WA_WState_Hidden); - q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden); - - if (wasCreated) { - reparentChildren(); - } - - if (extra && !extra->mask.isEmpty()) { - QRegion r = extra->mask; - extra->mask = QRegion(); - q->setMask(r); - } - if (extra && extra->topextra && !extra->topextra->caption.isEmpty()) { - setWindowIcon_sys(true); - setWindowTitle_helper(extra->topextra->caption); - } - if (old_winid) - DestroyWindow(old_winid); - - if (q->testAttribute(Qt::WA_AcceptDrops) || dropSiteWasRegistered - || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) - q->setAttribute(Qt::WA_DropSiteRegistered, true); - -#ifdef Q_WS_WINCE - // Show borderless toplevel windows in tasklist & NavBar - if (!parent) { - QString txt = q->windowTitle().isEmpty()?qAppName():q->windowTitle(); - SetWindowText(q->internalWinId(), (wchar_t*)txt.utf16()); - } -#endif - invalidateBuffer(q->rect()); -} - - -QPoint QWidget::mapToGlobal(const QPoint &pos) const -{ - Q_D(const QWidget); - QWidget *parentWindow = window(); - QWExtra *extra = parentWindow->d_func()->extra; - if (!isVisible() || parentWindow->isMinimized() || !testAttribute(Qt::WA_WState_Created) || !internalWinId() - || (extra -#ifndef QT_NO_GRAPHICSVIEW - && extra->proxyWidget -#endif //QT_NO_GRAPHICSVIEW - )) { - if (extra && extra->topextra && extra->topextra->embedded) { - QPoint pt = mapTo(parentWindow, pos); - POINT p = {pt.x(), pt.y()}; - ClientToScreen(parentWindow->effectiveWinId(), &p); - return QPoint(p.x, p.y); - } else { - QPoint toGlobal = mapTo(parentWindow, pos) + parentWindow->pos(); - // Adjust for window decorations - toGlobal += parentWindow->geometry().topLeft() - parentWindow->frameGeometry().topLeft(); - return toGlobal; - } - } - POINT p; - QPoint tmp = d->mapToWS(pos); - p.x = tmp.x(); - p.y = tmp.y(); - ClientToScreen(internalWinId(), &p); - return QPoint(p.x, p.y); -} - -QPoint QWidget::mapFromGlobal(const QPoint &pos) const -{ - Q_D(const QWidget); - QWidget *parentWindow = window(); - QWExtra *extra = parentWindow->d_func()->extra; - if (!isVisible() || parentWindow->isMinimized() || !testAttribute(Qt::WA_WState_Created) || !internalWinId() - || (extra -#ifndef QT_NO_GRAPHICSVIEW - && extra->proxyWidget -#endif //QT_NO_GRAPHICSVIEW - )) { - if (extra && extra->topextra && extra->topextra->embedded) { - POINT p = {pos.x(), pos.y()}; - ScreenToClient(parentWindow->effectiveWinId(), &p); - return mapFrom(parentWindow, QPoint(p.x, p.y)); - } else { - QPoint fromGlobal = mapFrom(parentWindow, pos - parentWindow->pos()); - // Adjust for window decorations - fromGlobal -= parentWindow->geometry().topLeft() - parentWindow->frameGeometry().topLeft(); - return fromGlobal; - } - } - POINT p; - p.x = pos.x(); - p.y = pos.y(); - ScreenToClient(internalWinId(), &p); - return d->mapFromWS(QPoint(p.x, p.y)); -} - -void QWidgetPrivate::updateSystemBackground() {} - -#ifndef QT_NO_CURSOR -void QWidgetPrivate::setCursor_sys(const QCursor &cursor) -{ - Q_UNUSED(cursor); - Q_Q(QWidget); - qt_win_set_cursor(q, false); -} - -void QWidgetPrivate::unsetCursor_sys() -{ - Q_Q(QWidget); - qt_win_set_cursor(q, false); -} -#endif - -void QWidgetPrivate::setWindowTitle_sys(const QString &caption) -{ - Q_Q(QWidget); - if (!q->isWindow()) - return; - - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - SetWindowText(q->internalWinId(), (wchar_t*)caption.utf16()); -} - -HICON qt_createIcon(QIcon icon, int xSize, int ySize, QPixmap **cache) -{ - HICON result = 0; - if (!icon.isNull()) { // valid icon - QSize size = icon.actualSize(QSize(xSize, ySize)); - QPixmap pm = icon.pixmap(size); - if (pm.isNull()) - return 0; - - result = pm.toWinHICON(); - - if (cache) { - delete *cache; - *cache = new QPixmap(pm);; - } - } - return result; -} - -void QWidgetPrivate::setWindowIcon_sys(bool forceReset) -{ - Q_Q(QWidget); - if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow()) - return; - QTLWExtra* x = topData(); - if (x->iconPixmap && !forceReset) - // already been set - return; - - if (x->winIconBig) { - DestroyIcon(x->winIconBig); - x->winIconBig = 0; - } - if (x->winIconSmall) { - DestroyIcon(x->winIconSmall); - x->winIconSmall = 0; - } - - x->winIconSmall = qt_createIcon(q->windowIcon(), - GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), - &(x->iconPixmap)); - x->winIconBig = qt_createIcon(q->windowIcon(), - GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), - &(x->iconPixmap)); - if (x->winIconBig) { - SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); - SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconBig); - } else { - SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); - SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconSmall); - } -} - - -void QWidgetPrivate::setWindowIconText_sys(const QString &iconText) -{ - Q_UNUSED(iconText); -} - - -QCursor *qt_grab_cursor() -{ - return mouseGrbCur; -} - -// The procedure does nothing, but is required for mousegrabbing to work -#ifndef Q_WS_WINCE -LRESULT QT_WIN_CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) -{ - return CallNextHookEx(journalRec, nCode, wParam, lParam); -} -#endif //Q_WS_WINCE - -/* Works only as long as pointer is inside the application's window, - which is good enough for QDockWidget. - - Doesn't call SetWindowsHookEx() - this function causes a system-wide - freeze if any other app on the system installs a hook and fails to - process events. */ -void QWidgetPrivate::grabMouseWhileInWindow() -{ - Q_Q(QWidget); - if (!qt_nograb()) { - if (mouseGrb) - mouseGrb->releaseMouse(); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - SetCapture(q->effectiveWinId()); - mouseGrb = q; -#ifndef QT_NO_CURSOR - mouseGrbCur = new QCursor(mouseGrb->cursor()); -#endif - } -} - -#ifndef Q_WS_WINCE -void QWidget::grabMouse() -{ - if (!qt_nograb()) { - if (mouseGrb) - mouseGrb->releaseMouse(); - journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - SetCapture(effectiveWinId()); - mouseGrb = this; -#ifndef QT_NO_CURSOR - mouseGrbCur = new QCursor(mouseGrb->cursor()); -#endif - } -} - -#ifndef QT_NO_CURSOR -void QWidget::grabMouse(const QCursor &cursor) -{ - if (!qt_nograb()) { - if (mouseGrb) - mouseGrb->releaseMouse(); - journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - SetCapture(effectiveWinId()); - mouseGrbCur = new QCursor(cursor); - SetCursor(mouseGrbCur->handle()); - mouseGrb = this; - } -} -#endif - -void QWidget::releaseMouse() -{ - if (!qt_nograb() && mouseGrb == this) { - ReleaseCapture(); - if (journalRec) { - UnhookWindowsHookEx(journalRec); - journalRec = 0; - } - if (mouseGrbCur) { - delete mouseGrbCur; - mouseGrbCur = 0; - } - mouseGrb = 0; - } -} -#endif - -void QWidget::grabKeyboard() -{ - if (!qt_nograb()) { - if (keyboardGrb) - keyboardGrb->releaseKeyboard(); - keyboardGrb = this; - } -} - -void QWidget::releaseKeyboard() -{ - if (!qt_nograb() && keyboardGrb == this) - keyboardGrb = 0; -} - - -QWidget *QWidget::mouseGrabber() -{ - return mouseGrb; -} - -QWidget *QWidget::keyboardGrabber() -{ - return keyboardGrb; -} - -void QWidget::activateWindow() -{ - window()->createWinId(); - SetForegroundWindow(window()->internalWinId()); -} - -#ifndef Q_WS_WINCE -void QWidget::setWindowState(Qt::WindowStates newstate) -{ - Q_D(QWidget); - Qt::WindowStates oldstate = windowState(); - if (oldstate == newstate) - return; - - int max = SW_MAXIMIZE; - int min = SW_MINIMIZE; - - int normal = SW_SHOWNOACTIVATE; - if (newstate & Qt::WindowActive) { - max = SW_SHOWMAXIMIZED; - min = SW_SHOWMINIMIZED; - normal = SW_SHOWNORMAL; - } - - if (isWindow()) { - createWinId(); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - - // Ensure the initial size is valid, since we store it as normalGeometry below. - if (!testAttribute(Qt::WA_Resized) && !isVisible()) - adjustSize(); - - if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) { - if (newstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen)) - d->topData()->normalGeometry = geometry(); - if (isVisible() && !(newstate & Qt::WindowMinimized)) { - ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal); - if (!(newstate & Qt::WindowFullScreen)) { - QRect r = d->topData()->normalGeometry; - if (!(newstate & Qt::WindowMaximized) && r.width() >= 0) { - if (pos() != r.topLeft() || size() !=r.size()) { - d->topData()->normalGeometry = QRect(0,0,-1,-1); - setGeometry(r); - } - } - } else { - d->updateFrameStrut(); - } - } - } - - if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) { - if (newstate & Qt::WindowFullScreen) { - if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) - d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = Qt::WindowFlags(GetWindowLong(internalWinId(), GWL_STYLE)); -#ifndef Q_FLATTEN_EXPOSE - UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; -#else - UINT style = WS_POPUP; -#endif - if (ulong(d->topData()->savedFlags) & WS_SYSMENU) - style |= WS_SYSMENU; - if (isVisible()) - style |= WS_VISIBLE; - SetWindowLong(internalWinId(), GWL_STYLE, style); - QRect r = QApplication::desktop()->screenGeometry(this); - UINT swpf = SWP_FRAMECHANGED; - if (newstate & Qt::WindowActive) - swpf |= SWP_NOACTIVATE; - - SetWindowPos(internalWinId(), HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf); - d->updateFrameStrut(); - } else { - UINT style = d->topData()->savedFlags; - if (isVisible()) - style |= WS_VISIBLE; - SetWindowLong(internalWinId(), GWL_STYLE, style); - - UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; - if (newstate & Qt::WindowActive) - swpf |= SWP_NOACTIVATE; - SetWindowPos(internalWinId(), 0, 0, 0, 0, 0, swpf); - d->updateFrameStrut(); - - // preserve maximized state - if (isVisible()) - ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal); - - if (!(newstate & Qt::WindowMaximized)) { - QRect r = d->topData()->normalGeometry; - d->topData()->normalGeometry = QRect(0,0,-1,-1); - if (r.isValid()) - setGeometry(r); - } - } - } - - if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) { - if (isVisible()) - ShowWindow(internalWinId(), (newstate & Qt::WindowMinimized) ? min : - (newstate & Qt::WindowMaximized) ? max : normal); - } - } - data->window_state = newstate; - QWindowStateChangeEvent e(oldstate); - QApplication::sendEvent(this, &e); -} -#endif //Q_WS_WINCE - - -/* - \internal - Platform-specific part of QWidget::hide(). -*/ - -void QWidgetPrivate::hide_sys() -{ - Q_Q(QWidget); - deactivateWidgetCleanup(); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); -#ifdef Q_WS_WINCE - if (!qt_wince_is_mobile() && q->isFullScreen()) { - HWND handle = FindWindow(L"HHTaskBar", L""); - if (handle) { - ShowWindow(handle, 1); - EnableWindow(handle, true); - } - } -#endif - if (q->windowFlags() != Qt::Desktop) { - if ((q->windowFlags() & Qt::Popup) && q->internalWinId()) - ShowWindow(q->internalWinId(), SW_HIDE); - else if (q->internalWinId()) - SetWindowPos(q->internalWinId(),0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER); - } - if (q->isWindow()) { - if (QWidgetBackingStore *bs = maybeBackingStore()) - bs->releaseBuffer(); - } else { - invalidateBuffer(q->rect()); - } - q->setAttribute(Qt::WA_Mapped, false); -} - - -/* - \internal - Platform-specific part of QWidget::show(). -*/ -#ifndef Q_WS_WINCE -void QWidgetPrivate::show_sys() -{ - Q_Q(QWidget); -#if defined(QT_NON_COMMERCIAL) - QT_NC_SHOW_WINDOW -#endif - if (q->testAttribute(Qt::WA_OutsideWSRange)) - return; - q->setAttribute(Qt::WA_Mapped); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - - if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - invalidateBuffer(q->rect()); - return; - } - - if (data.window_flags & Qt::Window) { - QTLWExtra *extra = topData(); - if (!extra->hotkeyRegistered) { - // Try to set the hotkey using information from STARTUPINFO - STARTUPINFO startupInfo; - GetStartupInfo(&startupInfo); - // If STARTF_USEHOTKEY is set, hStdInput is the virtual keycode - if (startupInfo.dwFlags & 0x00000200) { - WPARAM hotKey = (WPARAM)startupInfo.hStdInput; - SendMessage(data.winid, WM_SETHOTKEY, hotKey, 0); - } - extra->hotkeyRegistered = 1; - } - } - - int sm = SW_SHOWNORMAL; - bool fakedMaximize = false; - if (q->isWindow()) { - if (q->isMinimized()) { - sm = SW_SHOWMINIMIZED; - if (!IsWindowVisible(q->internalWinId())) - sm = SW_SHOWMINNOACTIVE; - } else if (q->isMaximized()) { - sm = SW_SHOWMAXIMIZED; - // Windows will not behave correctly when we try to maximize a window which does not - // have minimize nor maximize buttons in the window frame. Windows would then ignore - // non-available geometry, and rather maximize the widget to the full screen, minus the - // window frame (caption). So, we do a trick here, by adding a maximize button before - // maximizing the widget, and then remove the maximize button afterwards. - Qt::WindowFlags &flags = data.window_flags; - if (flags & Qt::WindowTitleHint && - !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) { - fakedMaximize = TRUE; - int style = GetWindowLong(q->internalWinId(), GWL_STYLE); - SetWindowLong(q->internalWinId(), GWL_STYLE, style | WS_MAXIMIZEBOX); - } - } - } - if (q->testAttribute(Qt::WA_ShowWithoutActivating) - || (q->windowType() == Qt::Popup) - || (q->windowType() == Qt::ToolTip) - || (q->windowType() == Qt::Tool)) { - sm = SW_SHOWNOACTIVATE; - } - - - if (q->internalWinId()) - ShowWindow(q->internalWinId(), sm); - - if (fakedMaximize) { - int style = GetWindowLong(q->internalWinId(), GWL_STYLE); - SetWindowLong(q->internalWinId(), GWL_STYLE, style & ~WS_MAXIMIZEBOX); - SetWindowPos(q->internalWinId(), 0, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER - | SWP_FRAMECHANGED); - } - - if (q->internalWinId()) { - if (IsIconic(q->internalWinId())) - data.window_state |= Qt::WindowMinimized; - if (IsZoomed(q->internalWinId())) - data.window_state |= Qt::WindowMaximized; - // This is to resolve the problem where popups are opened from the - // system tray and not being implicitly activated - if (q->windowType() == Qt::Popup && - !q->parentWidget() && !qApp->activeWindow()) - q->activateWindow(); - } - - winSetupGestures(); - - invalidateBuffer(q->rect()); -} -#endif //Q_WS_WINCE - -void QWidgetPrivate::setFocus_sys() -{ - Q_Q(QWidget); - if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup) - SetFocus(q->effectiveWinId()); -} - -void QWidgetPrivate::raise_sys() -{ - Q_Q(QWidget); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - if (q->internalWinId()) - SetWindowPos(q->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); -} - -void QWidgetPrivate::lower_sys() -{ - Q_Q(QWidget); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - if (q->internalWinId()) - SetWindowPos(q->internalWinId(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - invalidateBuffer(q->rect()); -} - -void QWidgetPrivate::stackUnder_sys(QWidget* w) -{ - Q_Q(QWidget); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - if (q->internalWinId() && w->internalWinId()) - SetWindowPos(q->internalWinId(), w->internalWinId() , 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - invalidateBuffer(q->rect()); -} - - -/* - Helper function for non-toplevel widgets. Helps to map Qt's 32bit - coordinate system to Windpws's 16bit coordinate system. - - This code is duplicated from the X11 code, so any changes there - should also (most likely) be reflected here. - - (In all comments below: s/X/Windows/g) - */ - -void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) -{ - Q_Q(QWidget); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - - /* - There are up to four different coordinate systems here: - Qt coordinate system for this widget. - X coordinate system for this widget (relative to wrect). - Qt coordinate system for parent - X coordinate system for parent (relative to parent's wrect). - */ - QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX); - QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); - QRect wrect; - //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys) - QRect xrect = data.crect; - - const QWidget *const parent = q->parentWidget(); - QRect parentWRect = parent->data->wrect; - - if (parentWRect.isValid()) { - // parent is clipped, and we have to clip to the same limit as parent - if (!parentWRect.contains(xrect)) { - xrect &= parentWRect; - wrect = xrect; - //translate from parent's to my Qt coord sys - wrect.translate(-data.crect.topLeft()); - } - //translate from parent's Qt coords to parent's X coords - xrect.translate(-parentWRect.topLeft()); - - } else { - // parent is not clipped, we may or may not have to clip - - if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) { - // This is where the main optimization is: we are already - // clipped, and if our clip is still valid, we can just - // move our window, and do not need to move or clip - // children - - QRect vrect = xrect & parent->rect(); - vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords - if (data.wrect.contains(vrect)) { - xrect = data.wrect; - xrect.translate(data.crect.topLeft()); - if (q->internalWinId()) - MoveWindow(q->internalWinId(), xrect.x(), xrect.y(), xrect.width(), xrect.height(), true); - return; - } - } - - if (!validRange.contains(xrect)) { - // we are too big, and must clip - xrect &=wrectRange; - wrect = xrect; - wrect.translate(-data.crect.topLeft()); - //parent's X coord system is equal to parent's Qt coord - //sys, so we don't need to map xrect. - } - - } - - - // unmap if we are outside the valid window system coord system - bool outsideRange = !xrect.isValid(); - bool mapWindow = false; - if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) { - q->setAttribute(Qt::WA_OutsideWSRange, outsideRange); - if (outsideRange) { - if (q->internalWinId()) - ShowWindow(q->internalWinId(), SW_HIDE); - q->setAttribute(Qt::WA_Mapped, false); - } else if (!q->isHidden()) { - mapWindow = true; - } - } - - if (outsideRange) - return; - - bool jump = (data.wrect != wrect); - data.wrect = wrect; - - // and now recursively for all children... - for (int i = 0; i < children.size(); ++i) { - QObject *object = children.at(i); - if (object->isWidgetType()) { - QWidget *w = static_cast<QWidget *>(object); - if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created)) - w->d_func()->setWSGeometry(); - } - } - - // move ourselves to the new position and map (if necessary) after - // the movement. Rationale: moving unmapped windows is much faster - // than moving mapped windows - if (q->internalWinId()) { - if (!parent->internalWinId()) - xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0))); - MoveWindow(q->internalWinId(), xrect.x(), xrect.y(), xrect.width(), xrect.height(), !jump); - } - if (mapWindow && !dontShow) { - q->setAttribute(Qt::WA_Mapped); - if (q->internalWinId()) - ShowWindow(q->internalWinId(), SW_SHOWNOACTIVATE); - } - - if (jump && q->internalWinId()) - InvalidateRect(q->internalWinId(), 0, false); - -} - -// -// The internal qWinRequestConfig, defined in qapplication_win.cpp, stores move, -// resize and setGeometry requests for a widget that is already -// processing a config event. The purpose is to avoid recursion. -// -void qWinRequestConfig(WId, int, int, int, int, int); - -void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) -{ - Q_Q(QWidget); - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - if (extra) { // any size restrictions? - w = qMin(w,extra->maxw); - h = qMin(h,extra->maxh); - w = qMax(w,extra->minw); - h = qMax(h,extra->minh); - } - if (q->isWindow()) - topData()->normalGeometry = QRect(0, 0, -1, -1); - - QSize oldSize(q->size()); - QPoint oldPos(q->pos()); - - if (!q->isWindow()) - isMove = (data.crect.topLeft() != QPoint(x, y)); - bool isResize = w != oldSize.width() || h != oldSize.height(); - - if (!isMove && !isResize) - return; - - if (isResize && !q->testAttribute(Qt::WA_StaticContents) && q->internalWinId()) - ValidateRgn(q->internalWinId(), 0); - -#ifdef Q_WS_WINCE - // On Windows CE we can't just fiddle around with the window state. - // Too much magic in setWindowState. - if (isResize && q->isMaximized()) - q->setWindowState(q->windowState() & ~Qt::WindowMaximized); -#else - if (isResize) - data.window_state &= ~Qt::WindowMaximized; -#endif - - if (data.window_state & Qt::WindowFullScreen) { - QTLWExtra *top = topData(); - - if (q->isWindow()) { - // We need to update these flags when we remove the full screen state - // or the frame will not be updated - UINT style = top->savedFlags; - if (q->isVisible()) - style |= WS_VISIBLE; - SetWindowLong(q->internalWinId(), GWL_STYLE, style); - - UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; - if (data.window_state & Qt::WindowActive) - swpf |= SWP_NOACTIVATE; - SetWindowPos(q->internalWinId(), 0, 0, 0, 0, 0, swpf); - updateFrameStrut(); - } - data.window_state &= ~Qt::WindowFullScreen; - topData()->savedFlags = 0; - } - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false; - const bool isTranslucentWindow = !isOpaque && ptrUpdateLayeredWindowIndirect && (data.window_flags & Qt::FramelessWindowHint) - && GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED; - - if (q->testAttribute(Qt::WA_WState_ConfigPending)) { // processing config event - if (q->internalWinId()) - qWinRequestConfig(q->internalWinId(), isMove ? 2 : 1, x, y, w, h); - } else { - if (!q->testAttribute(Qt::WA_DontShowOnScreen)) - q->setAttribute(Qt::WA_WState_ConfigPending); - if (q->windowType() == Qt::Desktop) { - data.crect.setRect(x, y, w, h); - } else if (q->isWindow()) { - QRect fs(frameStrut()); - if (extra) { - fs.setLeft(x - fs.left()); - fs.setTop(y - fs.top()); - fs.setRight((x + w - 1) + fs.right()); - fs.setBottom((y + h - 1) + fs.bottom()); - } - if (w == 0 || h == 0) { - q->setAttribute(Qt::WA_OutsideWSRange, true); - if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) - hide_sys(); - data.crect = QRect(x, y, w, h); - } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { - q->setAttribute(Qt::WA_OutsideWSRange, false); - - // put the window in its place and show it - MoveWindow(q->internalWinId(), fs.x(), fs.y(), fs.width(), fs.height(), true); - RECT rect; - if (!q->testAttribute(Qt::WA_DontShowOnScreen)) { - GetClientRect(q->internalWinId(), &rect); - data.crect.setRect(x, y, rect.right - rect.left, rect.bottom - rect.top); - } else { - data.crect.setRect(x, y, w, h); - } - - show_sys(); - } else if (!q->testAttribute(Qt::WA_DontShowOnScreen)) { - q->setAttribute(Qt::WA_OutsideWSRange, false); -#ifndef Q_WS_WINCE - // If the window is hidden and in maximized state or minimized, instead of moving the - // window, set the normal position of the window. - WINDOWPLACEMENT wndpl; - GetWindowPlacement(q->internalWinId(), &wndpl); - if ((wndpl.showCmd == SW_MAXIMIZE && !IsWindowVisible(q->internalWinId())) || wndpl.showCmd == SW_SHOWMINIMIZED) { - RECT normal = {fs.x(), fs.y(), fs.x()+fs.width(), fs.y()+fs.height()}; - wndpl.rcNormalPosition = normal; - wndpl.showCmd = wndpl.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE; - SetWindowPlacement(q->internalWinId(), &wndpl); - } else { -#else - if (data.window_state & Qt::WindowMaximized) { - qt_wince_maximize(q); - } else { -#endif - MoveWindow(q->internalWinId(), fs.x(), fs.y(), fs.width(), fs.height(), true); - } - if (!q->isVisible()) - InvalidateRect(q->internalWinId(), 0, FALSE); - RECT rect; - // If the layout has heightForWidth, the MoveWindow() above can - // change the size/position, so refresh them. - - if (isTranslucentWindow) { - data.crect.setRect(x, y, w, h); - } else { - GetClientRect(q->internalWinId(), &rect); - RECT rcNormalPosition ={0}; - // Use (0,0) as window position for embedded ActiveQt controls. - if (!tlwExtra || !tlwExtra->embedded) - GetWindowRect(q->internalWinId(), &rcNormalPosition); - QRect fStrut(frameStrut()); - data.crect.setRect(rcNormalPosition.left + fStrut.left(), - rcNormalPosition.top + fStrut.top(), - rect.right - rect.left, - rect.bottom - rect.top); - isResize = data.crect.size() != oldSize; - } - } else { - q->setAttribute(Qt::WA_OutsideWSRange, false); - data.crect.setRect(x, y, w, h); - } - } else { - QRect oldGeom(data.crect); - data.crect.setRect(x, y, w, h); - if (q->isVisible() && (!inTopLevelResize || q->internalWinId())) { - // Top-level resize optimization does not work for native child widgets; - // disable it for this particular widget. - if (inTopLevelResize) - tlwExtra->inTopLevelResize = false; - - if (!isResize) - moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y()); - else - invalidateBuffer_resizeHelper(oldPos, oldSize); - - if (inTopLevelResize) - tlwExtra->inTopLevelResize = true; - } - if (q->testAttribute(Qt::WA_WState_Created)) - setWSGeometry(); - } - q->setAttribute(Qt::WA_WState_ConfigPending, false); - } - - if (q->isWindow() && q->isVisible() && isResize && !inTopLevelResize) { - invalidateBuffer(q->rect()); //after the resize - } - - // Process events immediately rather than in translateConfigEvent to - // avoid windows message process delay. - if (q->isVisible()) { - if (isMove && q->pos() != oldPos) { - QMoveEvent e(q->pos(), oldPos); - QApplication::sendEvent(q, &e); - } - if (isResize) { - static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt(); - // If we have a backing store with static contents, we have to disable the top-level - // resize optimization in order to get invalidated regions for resized widgets. - // The optimization discards all invalidateBuffer() calls since we're going to - // repaint everything anyways, but that's not the case with static contents. - const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra - && !extra->topextra->inTopLevelResize - && (!extra->topextra->backingStore - || !extra->topextra->backingStore->hasStaticContents()); - if (setTopLevelResize) - extra->topextra->inTopLevelResize = true; - QResizeEvent e(q->size(), oldSize); - QApplication::sendEvent(q, &e); - if (setTopLevelResize) - extra->topextra->inTopLevelResize = false; - } - } else { - if (isMove && q->pos() != oldPos) - q->setAttribute(Qt::WA_PendingMoveEvent, true); - if (isResize) - q->setAttribute(Qt::WA_PendingResizeEvent, true); - } -} - -bool QWidgetPrivate::shouldShowMaximizeButton() -{ - if (data.window_flags & Qt::MSWindowsFixedSizeDialogHint) - return false; - // if the user explicitly asked for the maximize button, we try to add - // it even if the window has fixed size. - if (data.window_flags & Qt::CustomizeWindowHint && - data.window_flags & Qt::WindowMaximizeButtonHint) - return true; - if (extra) { - if ((extra->maxw && extra->maxw != QWIDGETSIZE_MAX && extra->maxw != QLAYOUTSIZE_MAX) - || (extra->maxh && extra->maxh != QWIDGETSIZE_MAX && extra->maxh != QLAYOUTSIZE_MAX)) - return false; - } - return data.window_flags & Qt::WindowMaximizeButtonHint; -} - -void QWidgetPrivate::winUpdateIsOpaque() -{ -#ifndef Q_WS_WINCE - Q_Q(QWidget); - - if (!q->isWindow() || !q->testAttribute(Qt::WA_TranslucentBackground)) - return; - - if ((data.window_flags & Qt::FramelessWindowHint) == 0) - return; - - if (!isOpaque && ptrUpdateLayeredWindowIndirect) { - SetWindowLong(q->internalWinId(), GWL_EXSTYLE, - GetWindowLong(q->internalWinId(), GWL_EXSTYLE) | Q_WS_EX_LAYERED); - } else { - SetWindowLong(q->internalWinId(), GWL_EXSTYLE, - GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & ~Q_WS_EX_LAYERED); - } -#endif -} - -void QWidgetPrivate::setConstraints_sys() -{ -#ifndef Q_WS_WINCE_WM - Q_Q(QWidget); - if (q->isWindow() && q->testAttribute(Qt::WA_WState_Created)) { - int style = GetWindowLong(q->internalWinId(), GWL_STYLE); - if (shouldShowMaximizeButton()) - style |= WS_MAXIMIZEBOX; - else - style &= ~WS_MAXIMIZEBOX; - SetWindowLong(q->internalWinId(), GWL_STYLE, style); - } -#endif -} - -void QWidgetPrivate::scroll_sys(int dx, int dy) -{ - Q_Q(QWidget); - scrollChildren(dx, dy); - - if (!paintOnScreen()) { - scrollRect(q->rect(), dx, dy); - } else { - UINT flags = SW_INVALIDATE; - if (!q->testAttribute(Qt::WA_OpaquePaintEvent)) - flags |= SW_ERASE; - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - ScrollWindowEx(q->internalWinId(), dx, dy, 0, 0, 0, 0, flags); - UpdateWindow(q->internalWinId()); - } -} - -void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) -{ - Q_Q(QWidget); - - if (!paintOnScreen()) { - scrollRect(r, dx, dy); - } else { - RECT wr; - wr.top = r.top(); - wr.left = r.left(); - wr.bottom = r.bottom()+1; - wr.right = r.right()+1; - - UINT flags = SW_INVALIDATE; - if (!q->testAttribute(Qt::WA_OpaquePaintEvent)) - flags |= SW_ERASE; - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - ScrollWindowEx(q->internalWinId(), dx, dy, &wr, &wr, 0, 0, flags); - UpdateWindow(q->internalWinId()); - } -} - -int QWidget::metric(PaintDeviceMetric m) const -{ - Q_D(const QWidget); - int val; - if (m == PdmWidth) { - val = data->crect.width(); - } else if (m == PdmHeight) { - val = data->crect.height(); - } else { - HDC gdc = GetDC(0); - switch (m) { - case PdmDpiX: - case PdmPhysicalDpiX: - if (d->extra && d->extra->customDpiX) - val = d->extra->customDpiX; - else if (d->parent) - val = static_cast<QWidget *>(d->parent)->metric(m); - else - val = GetDeviceCaps(gdc, LOGPIXELSX); - break; - case PdmDpiY: - case PdmPhysicalDpiY: - if (d->extra && d->extra->customDpiY) - val = d->extra->customDpiY; - else if (d->parent) - val = static_cast<QWidget *>(d->parent)->metric(m); - else - val = GetDeviceCaps(gdc, LOGPIXELSY); - break; - case PdmWidthMM: - val = data->crect.width() - * GetDeviceCaps(gdc, HORZSIZE) - / GetDeviceCaps(gdc, HORZRES); - break; - case PdmHeightMM: - val = data->crect.height() - * GetDeviceCaps(gdc, VERTSIZE) - / GetDeviceCaps(gdc, VERTRES); - break; - case PdmNumColors: - if (GetDeviceCaps(gdc, RASTERCAPS) & RC_PALETTE) - val = GetDeviceCaps(gdc, SIZEPALETTE); - else { - HDC hd = d->hd ? HDC(d->hd) : gdc; - int bpp = GetDeviceCaps(hd, BITSPIXEL); - if (bpp == 32) - val = INT_MAX; // ### this is bogus, it should be 2^24 colors for 32 bit as well - else if(bpp<=8) - val = GetDeviceCaps(hd, NUMCOLORS); - else - val = 1 << (bpp * GetDeviceCaps(hd, PLANES)); - } - break; - case PdmDepth: - val = GetDeviceCaps(gdc, BITSPIXEL); - break; - default: - val = 0; - qWarning("QWidget::metric: Invalid metric command"); - } - ReleaseDC(0, gdc); - } - return val; -} - -void QWidgetPrivate::createSysExtra() -{ -#ifndef QT_NO_DRAGANDDROP - extra->dropTarget = 0; -#endif -} - -#ifndef Q_WS_WINCE -void QWidgetPrivate::deleteSysExtra() -{ -} -#endif //Q_WS_WINCE - -void QWidgetPrivate::createTLSysExtra() -{ - extra->topextra->hotkeyRegistered = 0; - extra->topextra->savedFlags = 0; - extra->topextra->winIconBig = 0; - extra->topextra->winIconSmall = 0; -} - -void QWidgetPrivate::deleteTLSysExtra() -{ - if (extra->topextra->winIconSmall) - DestroyIcon(extra->topextra->winIconSmall); - if (extra->topextra->winIconBig) - DestroyIcon(extra->topextra->winIconBig); -} - -void QWidgetPrivate::registerDropSite(bool on) -{ - Q_Q(QWidget); - if (!q->testAttribute(Qt::WA_WState_Created)) - return; - // Enablement is defined by d->extra->dropTarget != 0. - if (on) { - // Turn on. - createExtra(); -#ifndef QT_NO_DRAGANDDROP - if (!q->internalWinId()) - q->nativeParentWidget()->d_func()->createExtra(); - QWExtra *extra = extraData(); - if (!extra->dropTarget) - extra->dropTarget = registerOleDnd(q); -#endif - } else { - // Turn off. - QWExtra *extra = extraData(); -#ifndef QT_NO_DRAGANDDROP - if (extra && extra->dropTarget) { - unregisterOleDnd(q, extra->dropTarget); - extra->dropTarget = 0; - } -#endif - } -} - -#ifndef QT_NO_DRAGANDDROP -QOleDropTarget* QWidgetPrivate::registerOleDnd(QWidget *widget) -{ - QOleDropTarget *dropTarget = new QOleDropTarget(widget); - Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created)); - if (!widget->internalWinId()) { - QWidget *nativeParent = widget->nativeParentWidget(); - Q_ASSERT(nativeParent); - QWExtra *nativeExtra = nativeParent->d_func()->extra; - Q_ASSERT(nativeExtra); - if (!nativeParent->acceptDrops()) - nativeParent->setAcceptDrops(true); - if (!nativeExtra->oleDropWidgets.contains(widget)) - nativeExtra->oleDropWidgets.append(widget); - if (!nativeExtra->dropTarget) { - nativeExtra->dropTarget = registerOleDnd(nativeParent); - Q_ASSERT(nativeExtra->dropTarget); -#ifndef Q_OS_WINCE - CoLockObjectExternal(nativeExtra->dropTarget, false, true); -#endif - RegisterDragDrop(nativeParent->internalWinId(), nativeExtra->dropTarget); - } - } else { - RegisterDragDrop(widget->internalWinId(), dropTarget); -#ifndef Q_OS_WINCE - CoLockObjectExternal(dropTarget, true, true); -#endif - } - return dropTarget; -} - -void QWidgetPrivate::unregisterOleDnd(QWidget *widget, QOleDropTarget *dropTarget) -{ - dropTarget->releaseQt(); - dropTarget->Release(); - Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created)); - if (!widget->internalWinId()) { - QWidget *nativeParent = widget->nativeParentWidget(); - Q_ASSERT(nativeParent); - QWExtra *nativeExtra = nativeParent->d_func()->extra; - Q_ASSERT(nativeExtra); - nativeExtra->oleDropWidgets.removeAll(widget); - nativeExtra->oleDropWidgets.removeAll(static_cast<QWidget *>(0)); - if (nativeExtra->oleDropWidgets.isEmpty() && nativeExtra->dropTarget - && !nativeParent->testAttribute(Qt::WA_DropSiteRegistered)) { -#ifndef Q_OS_WINCE - CoLockObjectExternal(nativeExtra->dropTarget, false, true); -#endif - RevokeDragDrop(nativeParent->internalWinId()); - nativeExtra->dropTarget = 0; - } - } else { -#ifndef Q_OS_WINCE - CoLockObjectExternal(dropTarget, false, true); -#endif - RevokeDragDrop(widget->internalWinId()); - } -} - -#endif //QT_NO_DRAGANDDROP - -// from qregion_win.cpp -extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom); -void QWidgetPrivate::setMask_sys(const QRegion ®ion) -{ - Q_Q(QWidget); - if (!q->internalWinId()) - return; - - if (region.isEmpty()) { - SetWindowRgn(q->internalWinId(), 0, true); - return; - } - - // Since SetWindowRegion takes ownership, and we need to translate, - // we take a copy. - HRGN wr = qt_tryCreateRegion(QRegion::Rectangle, 0,0,0,0); - CombineRgn(wr, region.handle(), 0, RGN_COPY); - - QPoint offset = (q->isWindow() - ? frameStrut().topLeft() - : QPoint(0, 0)); - OffsetRgn(wr, offset.x(), offset.y()); - - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - if (!SetWindowRgn(data.winid, wr, true)) - DeleteObject(wr); -} - -void QWidgetPrivate::updateFrameStrut() -{ - Q_Q(QWidget); - - if (!q->testAttribute(Qt::WA_WState_Created)) - return; - - if (!q->internalWinId()) { - data.fstrut_dirty = false; - return; - } - - RECT rect = {0,0,0,0}; - - QTLWExtra *top = topData(); - uint exstyle = GetWindowLong(q->internalWinId(), GWL_EXSTYLE); - uint style = GetWindowLong(q->internalWinId(), GWL_STYLE); -#ifndef Q_WS_WINCE - if (AdjustWindowRectEx(&rect, style & ~(WS_OVERLAPPED), FALSE, exstyle)) { -#else - if (AdjustWindowRectEx(&rect, style, FALSE, exstyle)) { -#endif - top->frameStrut.setCoords(-rect.left, -rect.top, rect.right, rect.bottom); - data.fstrut_dirty = false; - } -} - -#ifndef Q_WS_WINCE -void QWidgetPrivate::setWindowOpacity_sys(qreal level) -{ - Q_Q(QWidget); - - if (!isOpaque && ptrUpdateLayeredWindow && (data.window_flags & Qt::FramelessWindowHint)) { - if (GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED) { - BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), AC_SRC_ALPHA}; - ptrUpdateLayeredWindow(q->internalWinId(), NULL, NULL, NULL, NULL, NULL, 0, &blend, Q_ULW_ALPHA); - } - return; - } - - static bool function_resolved = false; - if (!function_resolved) { - ptrSetLayeredWindowAttributes = - (PtrSetLayeredWindowAttributes) QSystemLibrary::resolve(QLatin1String("user32"), - "SetLayeredWindowAttributes"); - function_resolved = true; - } - - if (!ptrSetLayeredWindowAttributes) - return; - - int wl = GetWindowLong(q->internalWinId(), GWL_EXSTYLE); - - if (level != 1.0) { - if ((wl&Q_WS_EX_LAYERED) == 0) - SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl | Q_WS_EX_LAYERED); - } else if (wl&Q_WS_EX_LAYERED) { - SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl & ~Q_WS_EX_LAYERED); - } - ptrSetLayeredWindowAttributes(q->internalWinId(), 0, (int)(level * 255), Q_LWA_ALPHA); -} -#endif //Q_WS_WINCE - -// class QGlobalRasterPaintEngine: public QRasterPaintEngine -// { -// public: -// inline QGlobalRasterPaintEngine() : QRasterPaintEngine() { setFlushOnEnd(false); } -// }; -// Q_GLOBAL_STATIC(QGlobalRasterPaintEngine, globalRasterPaintEngine) - - -#ifndef QT_NO_DIRECTDRAW -static uchar *qt_primary_surface_bits; -static int qt_primary_surface_stride; -static QImage::Format qt_primary_surface_format; - -void qt_win_initialize_directdraw() -{ - HRESULT res; - - // Some initialization... - if (!qt_ddraw_object) { - res = DirectDrawCreate(0, &qt_ddraw_object, 0); - - if (res != DD_OK) - qWarning("DirectDrawCreate failed: %d", res); - - qt_ddraw_object->SetCooperativeLevel(0, DDSCL_NORMAL); - - DDSURFACEDESC surfaceDesc; - memset(&surfaceDesc, 0, sizeof(DDSURFACEDESC)); - - surfaceDesc.dwSize = sizeof(DDSURFACEDESC); - surfaceDesc.dwFlags = DDSD_CAPS; - surfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - res = qt_ddraw_object->CreateSurface(&surfaceDesc, &qt_ddraw_primary, 0); - if (res != DD_OK) - qWarning("CreateSurface failed: %d", res); - - memset(&surfaceDesc, 0, sizeof(DDSURFACEDESC)); - surfaceDesc.dwSize = sizeof(DDSURFACEDESC); - res = qt_ddraw_primary->Lock(0, &surfaceDesc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0); - if (res != DD_OK) - qWarning("Locking surface failed: %d", res); - - if (surfaceDesc.ddpfPixelFormat.dwFlags == DDPF_RGB) { - qt_primary_surface_bits = (uchar *) surfaceDesc.lpSurface; - qt_primary_surface_stride = surfaceDesc.lPitch; - qt_primary_surface_format = QImage::Format_RGB32; - } else { - qWarning("QWidget painting: unsupported device depth for onscreen painting...\n"); - } - - qt_ddraw_primary->Unlock(0); - } -} - -class QOnScreenRasterPaintEngine : public QRasterPaintEngine -{ -public: - // The image allocated here leaks... Fix if this code is ifdef'ed - // in - QOnScreenRasterPaintEngine() - : QRasterPaintEngine(new QImage(qt_primary_surface_bits, - QApplication::desktop()->width(), - QApplication::desktop()->height(), - qt_primary_surface_stride, - qt_primary_surface_format)) - { - device = static_cast<QImage *>(d_func()->device); - } - - bool begin(QPaintDevice *) - { - QRegion clip = systemClip(); - originalSystemClip = clip; - clip.translate(widget->mapToGlobal(QPoint(0, 0))); - setSystemClip(clip); - - QRect bounds = clip.boundingRect(); - DDSURFACEDESC surface; - surface.dwSize = sizeof(DDSURFACEDESC); - HRESULT res = qt_ddraw_primary->Lock((RECT *) &bounds, &surface, DDLOCK_WAIT, 0); - if (res != DD_OK) { - qWarning("QWidget painting: locking onscreen bits failed: %d\n", res); - return false; - } - - if (surface.lpSurface == qt_primary_surface_bits) { - qt_primary_surface_bits = (uchar *) surface.lpSurface; - device->data_ptr()->data = qt_primary_surface_bits; - } - - return QRasterPaintEngine::begin(device); - } - - bool end() - { - HRESULT res = qt_ddraw_primary->Unlock(0); - if (res != DD_OK) - qWarning("QWidget::paint, failed to unlock DirectDraw surface: %d", res); - bool ok = QRasterPaintEngine::end(); - setSystemClip(originalSystemClip); - return ok; - } - - QPoint coordinateOffset() const { - return -widget->mapToGlobal(QPoint(0, 0)); - } - - const QWidget *widget; - QImage *device; - QRegion originalSystemClip; -}; -Q_GLOBAL_STATIC(QOnScreenRasterPaintEngine, onScreenPaintEngine) -#else -void qt_win_initialize_directdraw() { } -#endif - -QPaintEngine *QWidget::paintEngine() const -{ -#ifndef QT_NO_DIRECTDRAW - QOnScreenRasterPaintEngine *pe = onScreenPaintEngine(); - pe->widget = this; - return pe; -#endif - - // We set this bit which is checked in setAttribute for - // Qt::WA_PaintOnScreen. We do this to allow these two scenarios: - // - // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to - // windows which would mean suddenly their widgets stop working. - // - // 2. Users set paint on screen and subclass paintEngine() to - // return 0, in which case we have a "hole" in the backingstore - // allowing use of GDI or DirectX directly. - // - // 1 is WRONG, but to minimize silent failures, we have set this - // bit to ignore the setAttribute call. 2. needs to be - // supported because its our only means of embeddeding native - // graphics stuff. - const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1; - - return 0; -} - -QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys() -{ - Q_Q(QWidget); - return new QRasterWindowSurface(q); -} - -void QWidgetPrivate::setModal_sys() -{ -} - -void QWidgetPrivate::registerTouchWindow() -{ - Q_Q(QWidget); - - // enable WM_TOUCH* messages on our window - if (q->testAttribute(Qt::WA_WState_Created) - && QApplicationPrivate::RegisterTouchWindow - && q->windowType() != Qt::Desktop) - QApplicationPrivate::RegisterTouchWindow(q->effectiveWinId(), 0); -} - -void QWidgetPrivate::winSetupGestures() -{ -#if !defined(QT_NO_GESTURES) && !defined(QT_NO_NATIVE_GESTURES) - Q_Q(QWidget); - if (!q || !q->isVisible() || !nativeGesturePanEnabled) - return; - - if (!QApplicationPrivate::HasTouchSupport) - return; - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - if (!qAppPriv->SetGestureConfig) - return; - WId winid = q->internalWinId(); - - bool needh = false; - bool needv = false; - bool singleFingerPanEnabled = false; - -#ifndef QT_NO_SCROLLAREA - if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q->parent())) { - QScrollBar *hbar = asa->horizontalScrollBar(); - QScrollBar *vbar = asa->verticalScrollBar(); - Qt::ScrollBarPolicy hbarpolicy = asa->horizontalScrollBarPolicy(); - Qt::ScrollBarPolicy vbarpolicy = asa->verticalScrollBarPolicy(); - needh = (hbarpolicy == Qt::ScrollBarAlwaysOn || - (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); - needv = (vbarpolicy == Qt::ScrollBarAlwaysOn || - (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); - singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled; - if (!winid) { - winid = q->winId(); // enforces the native winid on the viewport - } - } -#endif //QT_NO_SCROLLAREA - if (winid) { - GESTURECONFIG gc[1]; - memset(gc, 0, sizeof(gc)); - gc[0].dwID = GID_PAN; - if (nativeGesturePanEnabled) { - gc[0].dwWant = GC_PAN; - if (needv && singleFingerPanEnabled) - gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; - else - gc[0].dwBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; - if (needh && singleFingerPanEnabled) - gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; - else - gc[0].dwBlock |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; - } else { - gc[0].dwBlock = GC_PAN; - } - - qAppPriv->SetGestureConfig(winid, 0, sizeof(gc)/sizeof(gc[0]), gc, sizeof(gc[0])); - } -#endif -} - -QT_END_NAMESPACE - -#ifdef Q_WS_WINCE -# include "qwidget_wince.cpp" -#endif diff --git a/src/gui/platforms/win/qwidget_wince.cpp b/src/gui/platforms/win/qwidget_wince.cpp deleted file mode 100644 index 7676182ef0..0000000000 --- a/src/gui/platforms/win/qwidget_wince.cpp +++ /dev/null @@ -1,675 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifdef Q_WS_WINCE - -#include "qguifunctions_wince.h" - -QT_BEGIN_NAMESPACE - -const QString qt_reg_winclass(QWidget *w); // defined in qapplication_win.cpp -extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); - -//#define TABLET_DEBUG -#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \ - | PK_ORIENTATION | PK_CURSOR | PK_Z) -#define PACKETMODE 0 - -typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL); -typedef BOOL (API *PtrWTClose)(HCTX); -typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID); -typedef BOOL (API *PtrWTEnable)(HCTX, BOOL); -typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL); -typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID); -typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT); -typedef int (API *PtrWTQueueSizeGet)(HCTX); -typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int); - -#ifndef QT_NO_TABLETEVENT -static void qt_tablet_init_wce(); -static void qt_tablet_cleanup_wce(); - -static void qt_tablet_init_wce() { - static bool firstTime = true; - if (!firstTime) - return; - firstTime = false; - qt_tablet_widget = new QWidget(0); - qt_tablet_widget->createWinId(); - qt_tablet_widget->setObjectName(QLatin1String("Qt internal tablet widget")); - LOGCONTEXT lcMine; - qAddPostRoutine(qt_tablet_cleanup_wce); - struct tagAXIS tpOri[3]; - if (ptrWTInfo && ptrWTOpen && ptrWTQueueSizeGet && ptrWTQueueSizeSet) { - // make sure we have WinTab - if (!ptrWTInfo(0, 0, NULL)) { -#ifdef TABLET_DEBUG - qWarning("QWidget: Wintab services not available"); -#endif - return; - } - - // some tablets don't support tilt, check if it is possible, - qt_tablet_tilt_support = ptrWTInfo(WTI_DEVICES, DVC_ORIENTATION, &tpOri); - if (qt_tablet_tilt_support) { - // check for azimuth and altitude - qt_tablet_tilt_support = tpOri[0].axResolution && tpOri[1].axResolution; - } - // build our context from the default context - ptrWTInfo(WTI_DEFSYSCTX, 0, &lcMine); - // Go for the raw coordinates, the tablet event will return good stuff - lcMine.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES; - lcMine.lcPktData = PACKETDATA; - lcMine.lcPktMode = PACKETMODE; - lcMine.lcMoveMask = PACKETDATA; - lcMine.lcOutOrgX = 0; - lcMine.lcOutExtX = lcMine.lcInExtX; - lcMine.lcOutOrgY = 0; - lcMine.lcOutExtY = -lcMine.lcInExtY; - qt_tablet_context = ptrWTOpen(qt_tablet_widget->winId(), &lcMine, true); -#ifdef TABLET_DEBUG - qDebug("Tablet is %p", qt_tablet_context); -#endif - if (!qt_tablet_context) { -#ifdef TABLET_DEBUG - qWarning("QWidget: Failed to open the tablet"); -#endif - return; - } - // Set the size of the Packet Queue to the correct size... - int currSize = ptrWTQueueSizeGet(qt_tablet_context); - if (!ptrWTQueueSizeSet(qt_tablet_context, QT_TABLET_NPACKETQSIZE)) { - // Ideally one might want to use a smaller - // multiple, but for now, since we managed to destroy - // the existing Q with the previous call, set it back - // to the other size, which should work. If not, - // there will be trouble. - if (!ptrWTQueueSizeSet(qt_tablet_context, currSize)) { - Q_ASSERT_X(0, "Qt::Internal", "There is no packet queue for" - " the tablet. The tablet will not work"); - } - } - } -} - -static void qt_tablet_cleanup_wce() { - if (ptrWTClose) - ptrWTClose(qt_tablet_context); - delete qt_tablet_widget; - qt_tablet_widget = 0; -} -#endif // QT_NO_TABLETEVENT - - -// The internal qWinRequestConfig, defined in qapplication_win.cpp, stores move, -// resize and setGeometry requests for a widget that is already -// processing a config event. The purpose is to avoid recursion. -// -void qWinRequestConfig(WId, int, int, int, int, int); - -void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) { - Q_Q(QWidget); - static int sw = -1, sh = -1; - - Qt::WindowType type = q->windowType(); - Qt::WindowFlags flags = data.window_flags; - - bool topLevel = (flags & Qt::Window); - bool popup = (type == Qt::Popup); - bool dialog = (type == Qt::Dialog - || type == Qt::Sheet - || (flags & Qt::MSWindowsFixedSizeDialogHint)); - bool desktop = (type == Qt::Desktop); - bool tool = (type == Qt::Tool || type == Qt::Drawer); - - HINSTANCE appinst = qWinAppInst(); - HWND parentw, destroyw = 0; - WId id; - - QString windowClassName = qt_reg_winclass(q); - - if (!window) // always initialize - initializeWindow = true; - - if (popup) - flags |= Qt::WindowStaysOnTopHint; // a popup stays on top - - if (flags & (Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowContextHelpButtonHint)) { - flags |= Qt::WindowSystemMenuHint; - flags |= Qt::WindowTitleHint; - flags &= ~Qt::FramelessWindowHint; - } - - if (sw < 0) { // get the (primary) screen size - sw = GetSystemMetrics(SM_CXSCREEN); - sh = GetSystemMetrics(SM_CYSCREEN); - } - - if (desktop) { // desktop widget - popup = false; // force this flags off - data.crect.setRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); - } - - parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0; - - QString title; - int style = WS_CHILD; - int exsty = WS_EX_NOPARENTNOTIFY; - - if (topLevel) { - if (!(flags & Qt::FramelessWindowHint) && !tool && !q->testAttribute(Qt::WA_DontShowOnScreen)) - style = (WS_OVERLAPPED) | WS_SYSMENU; - else - style = WS_POPUP; - if ((type == Qt::ToolTip) || (type == Qt::SplashScreen)) { - style = WS_POPUP; - exsty |= WS_EX_NOANIMATION; - } else { - if (flags & Qt::WindowTitleHint) - style |= WS_CAPTION; - if (flags & Qt::WindowSystemMenuHint) - style |= WS_SYSMENU; - if (flags & Qt::WindowContextHelpButtonHint) - exsty |= WS_EX_CONTEXTHELP; -#ifndef Q_WS_WINCE_WM - if (flags & Qt::WindowMinimizeButtonHint) - style |= WS_MINIMIZEBOX; - if (shouldShowMaximizeButton()) - style |= WS_MAXIMIZEBOX; -#endif - if (tool) - exsty |= WS_EX_TOOLWINDOW; - } - } - if (dialog) { - style = WS_BORDER | WS_CAPTION; - if (flags & Qt::WindowOkButtonHint) - exsty |= WS_EX_CAPTIONOKBTN; - if (flags & Qt::WindowCancelButtonHint || flags & Qt::WA_DeleteOnClose) - style |= WS_SYSMENU; - if (flags & Qt::WindowContextHelpButtonHint) - exsty |= WS_EX_CONTEXTHELP; - } - if (popup) { - style = WS_POPUP; - exsty |= WS_EX_NOANIMATION; - } - - if (flags & Qt::WindowTitleHint) { - title = q->isWindow() ? qAppName() : q->objectName(); - } - - // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in - // qapplication_win.cpp. We switch it off temporarily to avoid move - // and resize events during creationt - q->setAttribute(Qt::WA_WState_Created, false); - - if (window) { // override the old window - if (destroyOldWindow) - destroyw = data.winid; - id = window; - setWinId(window); - LONG res = SetWindowLong(window, GWL_STYLE, style); - if (!res) - qErrnoWarning("QWidget::create: Failed to set window style"); - - res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc ); - - if (!res) - qErrnoWarning("QWidget::create: Failed to set window procedure"); - } else if (desktop) { // desktop widget - id = GetDesktopWindow(); - if (!id) { //Create a dummy desktop - RECT r; - SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); - id = CreateWindow(reinterpret_cast<const wchar_t *>(windowClassName.utf16()), - reinterpret_cast<const wchar_t *>(title.utf16()), style, - r.left, r.top, r.right - r.left, r.bottom - r.top, - 0, 0, appinst, 0); - } - setWinId(id); - } else if (topLevel) { // create top-level widget - const bool wasMoved = q->testAttribute(Qt::WA_Moved); - - int x, y; - if (qt_wince_is_mobile()) { - x = wasMoved ? data.crect.left() : CW_USEDEFAULT; - y = wasMoved ? data.crect.top() : CW_USEDEFAULT; - } else { - x = wasMoved ? data.crect.left() : 100; - y = wasMoved ? data.crect.top() : 100; - } - - int w = CW_USEDEFAULT; - int h = CW_USEDEFAULT; - - // Adjust for framestrut when needed - RECT rect = {0,0,0,0}; - if (AdjustWindowRectEx(&rect, style, FALSE, exsty)) { - QTLWExtra *td = maybeTopData(); - if (wasMoved && (td && !td->posFromMove)) { - x = data.crect.x() + rect.left; - y = data.crect.y() + rect.top; - } - - if (q->testAttribute(Qt::WA_Resized)) { - w = data.crect.width() + (rect.right - rect.left); - h = data.crect.height() + (rect.bottom - rect.top); - } - } - - id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()), - reinterpret_cast<const wchar_t *>(title.utf16()), style, - x, y, w, h, - 0, 0, appinst, 0); - - if (!id) - qErrnoWarning("QWidget::create: Failed to create window"); - setWinId(id); - if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) - SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget - id = CreateWindowEx(exsty, (wchar_t*)windowClassName.utf16(), (wchar_t*)title.utf16(), style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), - parentw, NULL, appinst, NULL); - if (!id) - qErrnoWarning("QWidget::create: Failed to create window"); - SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - setWinId(id); - } - - if (desktop) { - q->setAttribute(Qt::WA_WState_Visible); - } else if (topLevel && !q->testAttribute(Qt::WA_DontShowOnScreen)) { - RECT cr; - GetClientRect(id, &cr); - // one cannot trust cr.left and cr.top, use a correction POINT instead - POINT pt; - pt.x = 0; - pt.y = 0; - if (!q->testAttribute(Qt::WA_DontShowOnScreen) || q->testAttribute(Qt::WA_Moved)) - ClientToScreen(id, &pt); - data.crect = QRect(QPoint(pt.x, pt.y), - QPoint(pt.x + cr.right - 1, pt.y + cr.bottom - 1)); - - if (data.fstrut_dirty) { - // be nice to activeqt - updateFrameStrut(); - } - } - - q->setAttribute(Qt::WA_WState_Created); // accept move/resize events - hd = 0; // no display context - - if (window) { // got window from outside - if (IsWindowVisible(window)) - q->setAttribute(Qt::WA_WState_Visible); - else - q->setAttribute(Qt::WA_WState_Visible, false); - } - - if (extra && !extra->mask.isEmpty()) - setMask_sys(extra->mask); - -#if defined(QT_NON_COMMERCIAL) - QT_NC_WIDGET_CREATE -#endif - - if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) - q->inputContext()->setFocusWidget(q); - - if (destroyw) { - DestroyWindow(destroyw); - } - -#ifndef QT_NO_TABLETEVENT - if (q != qt_tablet_widget && QWidgetPrivate::mapper) - qt_tablet_init_wce(); -#endif // QT_NO_TABLETEVENT - - if (q->testAttribute(Qt::WA_DropSiteRegistered)) - registerDropSite(true); - - if (maybeTopData() && maybeTopData()->opacity != 255) - q->setWindowOpacity(maybeTopData()->opacity/255.); - - if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) { - Q_ASSERT(q->internalWinId()); - ShowWindow(q->internalWinId(), SW_SHOW); - } -} - -/* - \internal - Platform-specific part of QWidget::show(). -*/ -void QWidgetPrivate::show_sys() { - Q_Q(QWidget); -#if defined(QT_NON_COMMERCIAL) - QT_NC_SHOW_WINDOW -#endif - if (q->testAttribute(Qt::WA_OutsideWSRange)) - return; - - q->setAttribute(Qt::WA_Mapped); - - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - - if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - invalidateBuffer(q->rect()); - return; - } - - - int sm = SW_SHOW; - bool fakedMaximize = false; - if (q->isWindow()) { -#ifndef Q_WS_WINCE_WM - if (q->isMinimized()) { - sm = SW_SHOWMINIMIZED; - } else if (q->isMaximized()) { - sm = SW_SHOWMAXIMIZED; - // Windows will not behave correctly when we try to maximize a window which does not - // have minimize nor maximize buttons in the window frame. Windows would then ignore - // non-available geometry, and rather maximize the widget to the full screen, minus the - // window frame (caption). So, we do a trick here, by adding a maximize button before - // maximizing the widget, and then remove the maximize button afterwards. - Qt::WindowFlags &flags = data.window_flags; - if (flags & Qt::WindowTitleHint && - !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) { - fakedMaximize = TRUE; - int style = GetWindowLong(q->internalWinId(), GWL_STYLE); - SetWindowLong(q->internalWinId(), GWL_STYLE, style | WS_MAXIMIZEBOX); - } - } else -#else - // Imitate minimizing on Windows mobile by hiding the widget. - if (q->isMinimized()) - sm = SW_HIDE; -#endif - if (q->isHidden()) { - sm = SW_HIDE; - } - } - if (q->testAttribute(Qt::WA_ShowWithoutActivating) - || (q->windowType() == Qt::Popup) - || (q->windowType() == Qt::ToolTip) - || (q->windowType() == Qt::Tool)) { - sm = SW_SHOWNOACTIVATE; - } - - ShowWindow(q->internalWinId(), sm); - - if (q->isMaximized() && q->isWindow()) - qt_wince_maximize(q); - -#ifndef Q_WS_WINCE_WM - if (!qt_wince_is_mobile() && q->isFullScreen()) { - HWND handle = FindWindow(L"HHTaskBar", L""); - if (handle) { - ShowWindow(handle, SW_HIDE); - EnableWindow(handle, false); - } - } - - if (fakedMaximize) { - int style = GetWindowLong(q->internalWinId(), GWL_STYLE); - SetWindowLong(q->internalWinId(), GWL_STYLE, style & ~WS_MAXIMIZEBOX); - SetWindowPos(q->internalWinId(), 0, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER - | SWP_FRAMECHANGED); - } -#else - Q_UNUSED(fakedMaximize); -#endif - - if (q->isWindow() && sm == SW_SHOW) - SetForegroundWindow(q->internalWinId()); - - invalidateBuffer(q->rect()); -} - -void QWidget::setWindowState(Qt::WindowStates newstate) -{ - Q_D(QWidget); - Qt::WindowStates oldstate = windowState(); - if (oldstate == newstate) - return; - - int max = SW_SHOWNORMAL; - int normal = SW_SHOWNOACTIVATE; - - if ((oldstate & Qt::WindowMinimized) && !(newstate & Qt::WindowMinimized)) - newstate |= Qt::WindowActive; - if (newstate & Qt::WindowActive) - normal = SW_SHOWNORMAL; - if (isWindow()) { - createWinId(); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - // Ensure the initial size is valid, since we store it as normalGeometry below. - if ((!testAttribute(Qt::WA_Resized) && !isVisible())) - adjustSize(); - if (!d->topData()->normalGeometry.isValid()) { - if (newstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen)) - d->topData()->normalGeometry = geometry(); - if (newstate & Qt::WindowMinimized && !(oldstate & Qt::WindowFullScreen)) - d->topData()->normalGeometry = geometry(); - } - if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) { - if (!(newstate & Qt::WindowMaximized)) { - int style = GetWindowLong(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION; - SetWindowLong(internalWinId(), GWL_STYLE, style); - SetWindowLong(internalWinId(), GWL_EXSTYLE, GetWindowLong (internalWinId(), GWL_EXSTYLE) & ~ WS_EX_NODRAG); - qt_wince_unmaximize(this); - } - if (isVisible() && newstate & Qt::WindowMaximized) - qt_wince_maximize(this); - if (isVisible() && !(newstate & Qt::WindowMinimized)) { - ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal); - if (!(newstate & Qt::WindowFullScreen)) { - QRect r = d->topData()->normalGeometry; - if (!(newstate & Qt::WindowMaximized) && r.width() >= 0) { - if (pos() != r.topLeft() || size() !=r.size()) { - d->topData()->normalGeometry = QRect(0,0,-1,-1); - setGeometry(r); - } - } - } else { - d->updateFrameStrut(); - } - } - } - if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) { - if (newstate & Qt::WindowFullScreen) { - if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) - d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = (Qt::WindowFlags)GetWindowLong(internalWinId(), GWL_STYLE); - UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; - if (isVisible()) - style |= WS_VISIBLE; - SetWindowLong(internalWinId(), GWL_STYLE, style); - QRect r = qApp->desktop()->screenGeometry(this); - UINT swpf = SWP_FRAMECHANGED; - if (newstate & Qt::WindowActive) - swpf |= SWP_NOACTIVATE; - qt_wince_full_screen(internalWinId(), true, swpf); - d->updateFrameStrut(); - } else { - UINT style = d->topData()->savedFlags; - if (isVisible()) - style |= WS_VISIBLE; - SetWindowLong(internalWinId(), GWL_STYLE, style); - UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; - if (newstate & Qt::WindowActive) - swpf |= SWP_NOACTIVATE; - qt_wince_full_screen(internalWinId(), false, swpf); - d->updateFrameStrut(); - - // preserve maximized state - if (isVisible()) { - ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal); - if (newstate & Qt::WindowMaximized) - qt_wince_maximize(this); - } - if (!(newstate & Qt::WindowMaximized)) { - QRect r = d->topData()->normalGeometry; - d->topData()->normalGeometry = QRect(0,0,-1,-1); - if (r.isValid()) - setGeometry(r); - } - } - } - if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) { - if (newstate & Qt::WindowMinimized) - qt_wince_minimize(internalWinId()); - else if (newstate & Qt::WindowMaximized) { - ShowWindow(internalWinId(), max); - qt_wince_maximize(this); - } else { - ShowWindow(internalWinId(), normal); - } - } - } - data->window_state = newstate; - QWindowStateChangeEvent e(oldstate); - QApplication::sendEvent(this, &e); -} - -void QWidgetPrivate::deleteSysExtra() -{ - Q_Q(QWidget); - if (!qt_wince_is_mobile() && q->isFullScreen()) { - HWND handle = FindWindow(L"HHTaskBar", L""); - if (handle) { - ShowWindow(handle, SW_SHOWNORMAL); - EnableWindow(handle, true); - } - } -} - -void QWidgetPrivate::setWindowOpacity_sys(qreal level) { - Q_UNUSED(level); - return; -} - -// The procedure does nothing, but is required for mousegrabbing to work -LRESULT QT_WIN_CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) { - Q_UNUSED(nCode); - Q_UNUSED(wParam); - Q_UNUSED(lParam); - return 0; -} - -void QWidget::grabMouse() { - if (!qt_nograb()) { - if (mouseGrb) - mouseGrb->releaseMouse(); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - SetCapture(internalWinId()); - mouseGrb = this; - } -} - -#ifndef QT_NO_CURSOR -void QWidget::grabMouse(const QCursor &cursor) { - if (!qt_nograb()) { - if (mouseGrb) - mouseGrb->releaseMouse(); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - SetCapture(internalWinId()); - mouseGrbCur = new QCursor(cursor); - SetCursor(mouseGrbCur->handle()); - mouseGrb = this; - } -} -#endif - -void QWidget::releaseMouse() { - if (!qt_nograb() && mouseGrb == this) { - ReleaseCapture(); - if (journalRec) { - journalRec = 0; - } - if (mouseGrbCur) { - delete mouseGrbCur; - mouseGrbCur = 0; - } - mouseGrb = 0; - } -} - -void QWidget::show() -{ - Qt::WindowFlags flags = windowFlags() & 0xff; - int threshold = qApp->autoMaximizeThreshold(); - if ((threshold < 0) || (windowState() & Qt::WindowFullScreen) || (windowState() & Qt::WindowMaximized)) { - setVisible(true); - return; - } - int height = sizeHint().height(); - int screenHeight = (qreal(threshold) / 100.0f * qApp->desktop()->screenGeometry(this).height()); - bool maximize = height > screenHeight; - if (!maximize) { - // If we do not maximize yet we check the widget and its child widgets whether they are - //vertically expanding. If one of the widgets is expanding we maximize. - QList<QWidget *> list = findChildren<QWidget *>(); - bool expandingChild = sizePolicy().verticalPolicy () == QSizePolicy::Expanding; - for (int i = 0; (i < list.size()) && !expandingChild; ++i) { - expandingChild = list.at(i)->sizePolicy().verticalPolicy () == QSizePolicy::Expanding; - } - maximize = expandingChild; - } - if ((minimumSizeHint().height() > qApp->desktop()->screenGeometry(this).height()) || (minimumSizeHint().width() > qApp->desktop()->screenGeometry(this).width())) - maximize = false; - - if ((flags == Qt::Window || flags == Qt::Dialog) && maximize) { - setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) - | Qt::WindowMaximized); - setVisible(true); - } - else { - setVisible(true); - } -} - -QT_END_NAMESPACE - -#endif // Q_WS_WINCE diff --git a/src/gui/platforms/win/qwindowdefs_win.h b/src/gui/platforms/win/qwindowdefs_win.h deleted file mode 100644 index a4dd38410c..0000000000 --- a/src/gui/platforms/win/qwindowdefs_win.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWDEFS_WIN_H -#define QWINDOWDEFS_WIN_H - -#include <QtCore/qglobal.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -QT_END_NAMESPACE - -#if !defined(Q_NOWINSTRICT) -#define Q_WINSTRICT -#endif - -#if defined(Q_WINSTRICT) - -#if !defined(STRICT) -#define STRICT -#endif -#undef NO_STRICT -#define Q_DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name - -#else - -#if !defined(NO_STRICT) -#define NO_STRICT -#endif -#undef STRICT -#define Q_DECLARE_HANDLE(name) typedef HANDLE name - -#endif - -#ifndef HINSTANCE -Q_DECLARE_HANDLE(HINSTANCE); -#endif -#ifndef HDC -Q_DECLARE_HANDLE(HDC); -#endif -#ifndef HWND -Q_DECLARE_HANDLE(HWND); -#endif -#ifndef HFONT -Q_DECLARE_HANDLE(HFONT); -#endif -#ifndef HPEN -Q_DECLARE_HANDLE(HPEN); -#endif -#ifndef HBRUSH -Q_DECLARE_HANDLE(HBRUSH); -#endif -#ifndef HBITMAP -Q_DECLARE_HANDLE(HBITMAP); -#endif -#ifndef HICON -Q_DECLARE_HANDLE(HICON); -#endif -#ifndef HCURSOR -typedef HICON HCURSOR; -#endif -#ifndef HPALETTE -Q_DECLARE_HANDLE(HPALETTE); -#endif -#ifndef HRGN -Q_DECLARE_HANDLE(HRGN); -#endif -#ifndef HMONITOR -Q_DECLARE_HANDLE(HMONITOR); -#endif -#ifndef HRESULT -typedef long HRESULT; -#endif - -typedef struct tagMSG MSG; -typedef HWND WId; - - -QT_BEGIN_NAMESPACE - -Q_CORE_EXPORT HINSTANCE qWinAppInst(); -Q_CORE_EXPORT HINSTANCE qWinAppPrevInst(); -Q_CORE_EXPORT int qWinAppCmdShow(); -Q_GUI_EXPORT HDC qt_win_display_dc(); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QWINDOWDEFS_WIN_H diff --git a/src/gui/platforms/win/qwinnativepangesturerecognizer_win.cpp b/src/gui/platforms/win/qwinnativepangesturerecognizer_win.cpp deleted file mode 100644 index 0d13bafc0c..0000000000 --- a/src/gui/platforms/win/qwinnativepangesturerecognizer_win.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "private/qwinnativepangesturerecognizer_win_p.h" - -#include "qevent.h" -#include "qgraphicsitem.h" -#include "qgesture.h" - -#include "private/qgesture_p.h" -#include "private/qevent_p.h" -#include "private/qapplication_p.h" -#include "private/qwidget_p.h" - -#ifndef QT_NO_GESTURES - -QT_BEGIN_NAMESPACE - -#if !defined(QT_NO_NATIVE_GESTURES) - -QWinNativePanGestureRecognizer::QWinNativePanGestureRecognizer() -{ -} - -QGesture *QWinNativePanGestureRecognizer::create(QObject *target) -{ - if (!target) - return new QPanGesture; // a special case - if (!target->isWidgetType()) - return 0; - if (qobject_cast<QGraphicsObject *>(target)) - return 0; - - QWidget *q = static_cast<QWidget *>(target); - QWidgetPrivate *d = q->d_func(); - d->nativeGesturePanEnabled = true; - d->winSetupGestures(); - - return new QPanGesture; -} - -QGestureRecognizer::Result QWinNativePanGestureRecognizer::recognize(QGesture *state, - QObject *, - QEvent *event) -{ - QPanGesture *q = static_cast<QPanGesture*>(state); - QPanGesturePrivate *d = q->d_func(); - - QGestureRecognizer::Result result = QGestureRecognizer::Ignore; - if (event->type() == QEvent::NativeGesture) { - QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); - switch(ev->gestureType) { - case QNativeGestureEvent::GestureBegin: - break; - case QNativeGestureEvent::Pan: - result = QGestureRecognizer::TriggerGesture; - event->accept(); - break; - case QNativeGestureEvent::GestureEnd: - if (q->state() == Qt::NoGesture) - return QGestureRecognizer::Ignore; // some other gesture has ended - result = QGestureRecognizer::FinishGesture; - break; - default: - return QGestureRecognizer::Ignore; - } - if (q->state() == Qt::NoGesture) { - d->lastOffset = d->offset = QPointF(); - d->startPosition = ev->position; - } else { - d->lastOffset = d->offset; - d->offset = QPointF(ev->position.x() - d->startPosition.x(), - ev->position.y() - d->startPosition.y()); - } - } - return result; -} - -void QWinNativePanGestureRecognizer::reset(QGesture *state) -{ - QPanGesture *pan = static_cast<QPanGesture*>(state); - QPanGesturePrivate *d = pan->d_func(); - - d->lastOffset = d->offset = QPointF(); - d->startPosition = QPoint(); - d->acceleration = 0; - - QGestureRecognizer::reset(state); -} - -#endif // QT_NO_NATIVE_GESTURES - -QT_END_NAMESPACE - -#endif // QT_NO_GESTURES diff --git a/src/gui/platforms/win/qwinnativepangesturerecognizer_win_p.h b/src/gui/platforms/win/qwinnativepangesturerecognizer_win_p.h deleted file mode 100644 index 6d23e41ce3..0000000000 --- a/src/gui/platforms/win/qwinnativepangesturerecognizer_win_p.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H -#define QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QGestureRecognizer> - -#ifndef QT_NO_GESTURES - -QT_BEGIN_NAMESPACE - -#if !defined(QT_NO_NATIVE_GESTURES) - -class QWinNativePanGestureRecognizer : public QGestureRecognizer -{ -public: - QWinNativePanGestureRecognizer(); - - QGesture *create(QObject *target); - QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event); - void reset(QGesture *state); -}; - -#endif // QT_NO_NATIVE_GESTURES - -QT_END_NAMESPACE - -#endif // QT_NO_GESTURES - -#endif // QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H |