summaryrefslogtreecommitdiffstats
path: root/src/widgets/platforms
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@collabora.com>2011-10-27 10:58:57 +0200
committerQt by Nokia <qt-info@nokia.com>2011-10-28 16:29:13 +0200
commita2337f79ffd229aa1e91f6bfec6294570eb3fe44 (patch)
tree48d68ba1c19bb629a096344453cf69cd692affba /src/widgets/platforms
parent1cae2fdb864f2b67333a7c80742b8e493865b3f9 (diff)
Remove Windows and X11 from src/widgets/platforms.
This is dead code, unused with QPA in place, so remove it to avoid confusion caused through grepping for class names existing in both old and new places. Mac code is left in place for now, as some of it is still in use. Change-Id: Ia82cd5bbabe71285ca997f79d8fd9c0504e32c28 Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'src/widgets/platforms')
-rw-r--r--src/widgets/platforms/win/qapplication_win.cpp4239
-rw-r--r--src/widgets/platforms/win/qclipboard_win.cpp398
-rw-r--r--src/widgets/platforms/win/qcolormap_win.cpp201
-rw-r--r--src/widgets/platforms/win/qcursor_win.cpp493
-rw-r--r--src/widgets/platforms/win/qdesktopwidget_win.cpp387
-rw-r--r--src/widgets/platforms/win/qdnd_win.cpp1027
-rw-r--r--src/widgets/platforms/win/qfont_win.cpp166
-rw-r--r--src/widgets/platforms/win/qfontdatabase_win.cpp1348
-rw-r--r--src/widgets/platforms/win/qfontengine_win.cpp1336
-rw-r--r--src/widgets/platforms/win/qfontengine_win_p.h164
-rw-r--r--src/widgets/platforms/win/qguifunctions_wince.cpp408
-rw-r--r--src/widgets/platforms/win/qguifunctions_wince.h151
-rw-r--r--src/widgets/platforms/win/qkeymapper_win.cpp1191
-rw-r--r--src/widgets/platforms/win/qmime_win.cpp1557
-rw-r--r--src/widgets/platforms/win/qole_win.cpp255
-rw-r--r--src/widgets/platforms/win/qpaintdevice_win.cpp62
-rw-r--r--src/widgets/platforms/win/qpixmap_win.cpp477
-rw-r--r--src/widgets/platforms/win/qrawfont_win.cpp709
-rw-r--r--src/widgets/platforms/win/qregion_win.cpp149
-rw-r--r--src/widgets/platforms/win/qsound_win.cpp205
-rw-r--r--src/widgets/platforms/win/qwidget_win.cpp2139
-rw-r--r--src/widgets/platforms/win/qwidget_wince.cpp675
-rw-r--r--src/widgets/platforms/win/qwininputcontext_p.h111
-rw-r--r--src/widgets/platforms/win/qwininputcontext_win.cpp847
-rw-r--r--src/widgets/platforms/win/qwinnativepangesturerecognizer_win.cpp133
-rw-r--r--src/widgets/platforms/win/qwinnativepangesturerecognizer_win_p.h80
-rw-r--r--src/widgets/platforms/x11/qapplication_x11.cpp6223
-rw-r--r--src/widgets/platforms/x11/qclipboard_x11.cpp1539
-rw-r--r--src/widgets/platforms/x11/qcolormap_x11.cpp670
-rw-r--r--src/widgets/platforms/x11/qcursor_x11.cpp640
-rw-r--r--src/widgets/platforms/x11/qdesktopwidget_x11.cpp406
-rw-r--r--src/widgets/platforms/x11/qdnd_x11.cpp2072
-rw-r--r--src/widgets/platforms/x11/qeventdispatcher_x11.cpp191
-rw-r--r--src/widgets/platforms/x11/qeventdispatcher_x11_p.h86
-rw-r--r--src/widgets/platforms/x11/qfont_x11.cpp368
-rw-r--r--src/widgets/platforms/x11/qfontdatabase_x11.cpp2154
-rw-r--r--src/widgets/platforms/x11/qfontengine_x11.cpp1205
-rw-r--r--src/widgets/platforms/x11/qfontengine_x11_p.h180
-rw-r--r--src/widgets/platforms/x11/qkde.cpp176
-rw-r--r--src/widgets/platforms/x11/qkde_p.h81
-rw-r--r--src/widgets/platforms/x11/qkeymapper_x11.cpp1857
-rw-r--r--src/widgets/platforms/x11/qkeymapper_x11_p.cpp489
-rw-r--r--src/widgets/platforms/x11/qmotifdnd_x11.cpp1031
-rw-r--r--src/widgets/platforms/x11/qpaintdevice_x11.cpp84
-rw-r--r--src/widgets/platforms/x11/qpaintengine_x11.cpp2499
-rw-r--r--src/widgets/platforms/x11/qpaintengine_x11_p.h246
-rw-r--r--src/widgets/platforms/x11/qpixmap_x11.cpp2419
-rw-r--r--src/widgets/platforms/x11/qpixmap_x11_p.h156
-rw-r--r--src/widgets/platforms/x11/qregion_x11.cpp92
-rw-r--r--src/widgets/platforms/x11/qsound_x11.cpp296
-rw-r--r--src/widgets/platforms/x11/qt_x11_p.h757
-rw-r--r--src/widgets/platforms/x11/qwidget_x11.cpp3149
-rw-r--r--src/widgets/platforms/x11/qwidgetcreate_x11.cpp79
-rw-r--r--src/widgets/platforms/x11/qx11embed_x11.cpp1810
-rw-r--r--src/widgets/platforms/x11/qx11embed_x11.h132
-rw-r--r--src/widgets/platforms/x11/qx11info_x11.cpp544
-rw-r--r--src/widgets/platforms/x11/qx11info_x11.h123
-rw-r--r--src/widgets/platforms/x11/qximinputcontext_p.h142
-rw-r--r--src/widgets/platforms/x11/qximinputcontext_x11.cpp885
59 files changed, 0 insertions, 51689 deletions
diff --git a/src/widgets/platforms/win/qapplication_win.cpp b/src/widgets/platforms/win/qapplication_win.cpp
deleted file mode 100644
index 725c46d55e..0000000000
--- a/src/widgets/platforms/win/qapplication_win.cpp
+++ /dev/null
@@ -1,4239 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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_WIDGETS_EXPORT qreal qt_fontsmoothing_gamma;
-Q_WIDGETS_EXPORT bool qt_cleartype_enabled;
-Q_WIDGETS_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_WIDGETS_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_WIDGETS_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_WIDGETS_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
- *****************************************************************************/
-
-
-#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:
- {
- /* On Win64, lParam can be 0x00000000fffffffc or 0xfffffffffffffffc (!),
- but MSDN says that lParam should be converted to a DWORD
- before its compared against OBJID_CLIENT
- */
- const DWORD dwObjId = (DWORD)lParam;
- // Ignoring all requests while starting up
- if (QApplication::startingUp() || QApplication::closingDown() || dwObjId != 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/widgets/platforms/win/qclipboard_win.cpp b/src/widgets/platforms/win/qclipboard_win.cpp
deleted file mode 100644
index 841eea1e34..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qcolormap_win.cpp b/src/widgets/platforms/win/qcolormap_win.cpp
deleted file mode 100644
index 4a95977438..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qcursor_win.cpp b/src/widgets/platforms/win/qcursor_win.cpp
deleted file mode 100644
index cef83f5a1b..0000000000
--- a/src/widgets/platforms/win/qcursor_win.cpp
+++ /dev/null
@@ -1,493 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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);
- }
- break;
- 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/widgets/platforms/win/qdesktopwidget_win.cpp b/src/widgets/platforms/win/qdesktopwidget_win.cpp
deleted file mode 100644
index f77cc1f847..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qdnd_win.cpp b/src/widgets/platforms/win/qdnd_win.cpp
deleted file mode 100644
index 073937fc45..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qfont_win.cpp b/src/widgets/platforms/win/qfont_win.cpp
deleted file mode 100644
index 7a0f234ca6..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qfontdatabase_win.cpp b/src/widgets/platforms/win/qfontdatabase_win.cpp
deleted file mode 100644
index 788eb307c3..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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, QString(), 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, QString(), 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, QString(), 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, QString(), 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/widgets/platforms/win/qfontengine_win.cpp b/src/widgets/platforms/win/qfontengine_win.cpp
deleted file mode 100644
index 9d3afb57d9..0000000000
--- a/src/widgets/platforms/win/qfontengine_win.cpp
+++ /dev/null
@@ -1,1336 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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)
-{
- uint ucs4 = str[i].unicode();
- if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
- ++i;
- ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
- }
- return ucs4;
-}
-
-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 || ih <= 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/widgets/platforms/win/qfontengine_win_p.h b/src/widgets/platforms/win/qfontengine_win_p.h
deleted file mode 100644
index ebcafffceb..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qguifunctions_wince.cpp b/src/widgets/platforms/win/qguifunctions_wince.cpp
deleted file mode 100644
index 78dc469b88..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qguifunctions_wince.h b/src/widgets/platforms/win/qguifunctions_wince.h
deleted file mode 100644
index 6384e4ac62..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qkeymapper_win.cpp b/src/widgets/platforms/win/qkeymapper_win.cpp
deleted file mode 100644
index 076b37038d..0000000000
--- a/src/widgets/platforms/win/qkeymapper_win.cpp
+++ /dev/null
@@ -1,1191 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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_WIDGETS_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 *)
-{
- Q_UNUSED(grab);
- Q_UNUSED(count);
- 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/widgets/platforms/win/qmime_win.cpp b/src/widgets/platforms/win/qmime_win.cpp
deleted file mode 100644
index b07214da82..0000000000
--- a/src/widgets/platforms/win/qmime_win.cpp
+++ /dev/null
@@ -1,1557 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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
- \inmodule QtWidgets
-
- 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/widgets/platforms/win/qole_win.cpp b/src/widgets/platforms/win/qole_win.cpp
deleted file mode 100644
index 1e1a672ac5..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qpaintdevice_win.cpp b/src/widgets/platforms/win/qpaintdevice_win.cpp
deleted file mode 100644
index a6d79d8341..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qpixmap_win.cpp b/src/widgets/platforms/win/qpixmap_win.cpp
deleted file mode 100644
index c5adb48f5d..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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() == QPlatformPixmap::RasterClass) {
- QRasterPlatformPixmap* d = static_cast<QRasterPlatformPixmap*>(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 {
- QPlatformPixmap *data = new QRasterPlatformPixmap(depth() == 1 ?
- QPlatformPixmap::BitmapType : QPlatformPixmap::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/widgets/platforms/win/qrawfont_win.cpp b/src/widgets/platforms/win/qrawfont_win.cpp
deleted file mode 100644
index d8aa557975..0000000000
--- a/src/widgets/platforms/win/qrawfont_win.cpp
+++ /dev/null
@@ -1,709 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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) {
- QFunctionPointer 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,
- qreal 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) {
- QFunctionPointer 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/widgets/platforms/win/qregion_win.cpp b/src/widgets/platforms/win/qregion_win.cpp
deleted file mode 100644
index 57fd0858e0..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qsound_win.cpp b/src/widgets/platforms/win/qsound_win.cpp
deleted file mode 100644
index 3c77dacf2a..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qwidget_win.cpp b/src/widgets/platforms/win/qwidget_win.cpp
deleted file mode 100644
index 60446ddb08..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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 &region)
-{
- 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/widgets/platforms/win/qwidget_wince.cpp b/src/widgets/platforms/win/qwidget_wince.cpp
deleted file mode 100644
index b16be300e7..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qwininputcontext_p.h b/src/widgets/platforms/win/qwininputcontext_p.h
deleted file mode 100644
index c0a6ac6b6f..0000000000
--- a/src/widgets/platforms/win/qwininputcontext_p.h
+++ /dev/null
@@ -1,111 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWININPUTCONTEXT_P_H
-#define QWININPUTCONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qinputcontext.cpp. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtWidgets/qinputcontext.h"
-#include "QtCore/qt_windows.h"
-
-#if !defined(IMR_RECONVERTSTRING)
-typedef struct tagRECONVERTSTRING {
- DWORD dwSize;
- DWORD dwVersion;
- DWORD dwStrLen;
- DWORD dwStrOffset;
- DWORD dwCompStrLen;
- DWORD dwCompStrOffset;
- DWORD dwTargetStrLen;
- DWORD dwTargetStrOffset;
-} RECONVERTSTRING, *PRECONVERTSTRING;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QWinInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- explicit QWinInputContext(QObject* parent = 0);
- virtual ~QWinInputContext();
-
- virtual QString identifierName() { return QLatin1String("win"); }
- virtual QString language();
-
- virtual void reset();
- virtual void update();
-
- virtual void mouseHandler(int x, QMouseEvent *event);
- virtual bool isComposing() const;
-
- virtual void setFocusWidget(QWidget *w);
-
- bool startComposition();
- bool endComposition();
- bool composition(LPARAM lparam);
- int reconvertString(RECONVERTSTRING *reconv);
-
- static void TranslateMessage(const MSG *msg);
- static LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
- static void updateImeStatus(QWidget *w, bool hasFocus);
- static void enablePopupChild(QWidget *w, bool e);
- static void enable(QWidget *w, bool e);
-
-private:
- void init();
- bool recursionGuard;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWININPUTCONTEXT_P_H
diff --git a/src/widgets/platforms/win/qwininputcontext_win.cpp b/src/widgets/platforms/win/qwininputcontext_win.cpp
deleted file mode 100644
index 9ec9942af8..0000000000
--- a/src/widgets/platforms/win/qwininputcontext_win.cpp
+++ /dev/null
@@ -1,847 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwininputcontext_p.h"
-#include "qinputcontext_p.h"
-
-#include "qfont.h"
-#include "qwidget.h"
-#include "qapplication.h"
-#include "qevent.h"
-#include "qtextformat.h"
-#include "qtextboundaryfinder.h"
-
-//#define Q_IME_DEBUG
-
-#ifdef Q_IME_DEBUG
-#include "qdebug.h"
-#endif
-
-#if defined(Q_WS_WINCE)
-extern void qt_wince_show_SIP(bool show); // defined in qguifunctions_wince.cpp
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
-
-
-DEFINE_GUID(IID_IActiveIMMApp,
-0x08c0e040, 0x62d1, 0x11d1, 0x93, 0x26, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e);
-
-
-
-DEFINE_GUID(CLSID_CActiveIMM,
-0x4955DD33, 0xB159, 0x11d0, 0x8F, 0xCF, 0x0, 0xAA, 0x00, 0x6B, 0xCC, 0x59);
-
-
-
-DEFINE_GUID(IID_IActiveIMMMessagePumpOwner,
-0xb5cf2cfa, 0x8aeb, 0x11d1, 0x93, 0x64, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e);
-
-
-
-interface IEnumRegisterWordW;
-interface IEnumInputContext;
-
-
-bool qt_sendSpontaneousEvent(QObject*, QEvent*);
-
-
-#define IFMETHOD HRESULT STDMETHODCALLTYPE
-
-interface IActiveIMMApp : public IUnknown
-{
-public:
- virtual IFMETHOD AssociateContext(HWND hWnd, HIMC hIME, HIMC __RPC_FAR *phPrev) = 0;
- virtual IFMETHOD dummy_ConfigureIMEA() = 0;
- virtual IFMETHOD ConfigureIMEW(HKL hKL, HWND hWnd, DWORD dwMode, REGISTERWORDW __RPC_FAR *pData) = 0;
- virtual IFMETHOD CreateContext(HIMC __RPC_FAR *phIMC) = 0;
- virtual IFMETHOD DestroyContext(HIMC hIME) = 0;
- virtual IFMETHOD dummy_EnumRegisterWordA() = 0;
- virtual IFMETHOD EnumRegisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister, LPVOID pData,
- IEnumRegisterWordW __RPC_FAR *__RPC_FAR *pEnum) = 0;
- virtual IFMETHOD dummy_EscapeA() = 0;
- virtual IFMETHOD EscapeW(HKL hKL, HIMC hIMC, UINT uEscape, LPVOID pData, LRESULT __RPC_FAR *plResult) = 0;
- virtual IFMETHOD dummy_GetCandidateListA() = 0;
- virtual IFMETHOD GetCandidateListW(HIMC hIMC, DWORD dwIndex, UINT uBufLen, CANDIDATELIST __RPC_FAR *pCandList,
- UINT __RPC_FAR *puCopied) = 0;
- virtual IFMETHOD dummy_GetCandidateListCountA() = 0;
- virtual IFMETHOD GetCandidateListCountW(HIMC hIMC, DWORD __RPC_FAR *pdwListSize, DWORD __RPC_FAR *pdwBufLen) = 0;
- virtual IFMETHOD GetCandidateWindow(HIMC hIMC, DWORD dwIndex, CANDIDATEFORM __RPC_FAR *pCandidate) = 0;
- virtual IFMETHOD dummy_GetCompositionFontA() = 0;
- virtual IFMETHOD GetCompositionFontW(HIMC hIMC, LOGFONTW __RPC_FAR *plf) = 0;
- virtual IFMETHOD dummy_GetCompositionStringA() = 0;
- virtual IFMETHOD GetCompositionStringW(HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LONG __RPC_FAR *plCopied, LPVOID pBuf) = 0;
- virtual IFMETHOD GetCompositionWindow(HIMC hIMC, COMPOSITIONFORM __RPC_FAR *pCompForm) = 0;
- virtual IFMETHOD GetContext(HWND hWnd, HIMC __RPC_FAR *phIMC) = 0;
- virtual IFMETHOD dummy_GetConversionListA() = 0;
- virtual IFMETHOD GetConversionListW(HKL hKL, HIMC hIMC, LPWSTR pSrc, UINT uBufLen, UINT uFlag,
- CANDIDATELIST __RPC_FAR *pDst, UINT __RPC_FAR *puCopied) = 0;
- virtual IFMETHOD GetConversionStatus(HIMC hIMC, DWORD __RPC_FAR *pfdwConversion, DWORD __RPC_FAR *pfdwSentence) = 0;
- virtual IFMETHOD GetDefaultIMEWnd(HWND hWnd, HWND __RPC_FAR *phDefWnd) = 0;
- virtual IFMETHOD dummy_GetDescriptionA() = 0;
- virtual IFMETHOD GetDescriptionW(HKL hKL, UINT uBufLen, LPWSTR szDescription, UINT __RPC_FAR *puCopied) = 0;
- virtual IFMETHOD dummy_GetGuideLineA() = 0;
- virtual IFMETHOD GetGuideLineW(HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LPWSTR pBuf, DWORD __RPC_FAR *pdwResult) = 0;
- virtual IFMETHOD dummy_GetIMEFileNameA() = 0;
- virtual IFMETHOD GetIMEFileNameW(HKL hKL, UINT uBufLen, LPWSTR szFileName, UINT __RPC_FAR *puCopied) = 0;
- virtual IFMETHOD GetOpenStatus(HIMC hIMC) = 0;
- virtual IFMETHOD GetProperty(HKL hKL, DWORD fdwIndex, DWORD __RPC_FAR *pdwProperty) = 0;
- virtual IFMETHOD dummy_GetRegisterWordStyleA() = 0;
- virtual IFMETHOD GetRegisterWordStyleW(HKL hKL, UINT nItem, STYLEBUFW __RPC_FAR *pStyleBuf, UINT __RPC_FAR *puCopied) = 0;
- virtual IFMETHOD GetStatusWindowPos(HIMC hIMC, POINT __RPC_FAR *pptPos) = 0;
- virtual IFMETHOD GetVirtualKey(HWND hWnd, UINT __RPC_FAR *puVirtualKey) = 0;
- virtual IFMETHOD dummy_InstallIMEA() = 0;
- virtual IFMETHOD InstallIMEW(LPWSTR szIMEFileName, LPWSTR szLayoutText, HKL __RPC_FAR *phKL) = 0;
- virtual IFMETHOD IsIME(HKL hKL) = 0;
- virtual IFMETHOD dummy_IsUIMessageA() = 0;
- virtual IFMETHOD IsUIMessageW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam) = 0;
- virtual IFMETHOD NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) = 0;
- virtual IFMETHOD dummy_RegisterWordA() = 0;
- virtual IFMETHOD RegisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister) = 0;
- virtual IFMETHOD ReleaseContext(HWND hWnd, HIMC hIMC) = 0;
- virtual IFMETHOD SetCandidateWindow(HIMC hIMC, CANDIDATEFORM __RPC_FAR *pCandidate) = 0;
- virtual IFMETHOD SetCompositionFontA(HIMC hIMC, LOGFONTA __RPC_FAR *plf) = 0;
- virtual IFMETHOD SetCompositionFontW(HIMC hIMC, LOGFONTW __RPC_FAR *plf) = 0;
- virtual IFMETHOD dummy_SetCompositionStringA() = 0;
- virtual IFMETHOD SetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen,
- LPVOID pRead, DWORD dwReadLen) = 0;
- virtual IFMETHOD SetCompositionWindow(HIMC hIMC, COMPOSITIONFORM __RPC_FAR *pCompForm) = 0;
- virtual IFMETHOD SetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence) = 0;
- virtual IFMETHOD SetOpenStatus(HIMC hIMC, BOOL fOpen) = 0;
- virtual IFMETHOD SetStatusWindowPos(HIMC hIMC, POINT __RPC_FAR *pptPos) = 0;
- virtual IFMETHOD SimulateHotKey(HWND hWnd, DWORD dwHotKeyID) = 0;
- virtual IFMETHOD dummy_UnregisterWordA() = 0;
- virtual IFMETHOD UnregisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szUnregister) = 0;
- virtual IFMETHOD Activate(BOOL fRestoreLayout) = 0;
- virtual IFMETHOD Deactivate(void) = 0;
- virtual IFMETHOD OnDefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT __RPC_FAR *plResult) = 0;
- virtual IFMETHOD FilterClientWindows(ATOM __RPC_FAR *aaClassList, UINT uSize) = 0;
- virtual IFMETHOD dummy_GetCodePageA() = 0;
- virtual IFMETHOD GetLangId(HKL hKL, LANGID __RPC_FAR *plid) = 0;
- virtual IFMETHOD AssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) = 0;
- virtual IFMETHOD DisableIME(DWORD idThread) = 0;
- virtual IFMETHOD dummy_GetImeMenuItemsA() = 0;
- virtual IFMETHOD GetImeMenuItemsW(HIMC hIMC, DWORD dwFlags, DWORD dwType, /*IMEMENUITEMINFOW*/ void __RPC_FAR *pImeParentMenu,
- /*IMEMENUITEMINFOW*/ void __RPC_FAR *pImeMenu, DWORD dwSize, DWORD __RPC_FAR *pdwResult) = 0;
- virtual IFMETHOD EnumInputContext(DWORD idThread, IEnumInputContext __RPC_FAR *__RPC_FAR *ppEnum) = 0;
-};
-
-interface IActiveIMMMessagePumpOwner : public IUnknown
-{
-public:
- virtual IFMETHOD Start(void) = 0;
- virtual IFMETHOD End(void) = 0;
- virtual IFMETHOD OnTranslateMessage(const MSG __RPC_FAR *pMsg) = 0;
- virtual IFMETHOD Pause(DWORD __RPC_FAR *pdwCookie) = 0;
- virtual IFMETHOD Resume(DWORD dwCookie) = 0;
-};
-
-
-static IActiveIMMApp *aimm = 0;
-static IActiveIMMMessagePumpOwner *aimmpump = 0;
-static QString *imeComposition = 0;
-static int imePosition = -1;
-bool qt_use_rtl_extensions = false;
-static bool haveCaret = false;
-
-#ifndef LGRPID_INSTALLED
-#define LGRPID_INSTALLED 0x00000001 // installed language group ids
-#define LGRPID_SUPPORTED 0x00000002 // supported language group ids
-#endif
-
-#ifndef LGRPID_ARABIC
-#define LGRPID_WESTERN_EUROPE 0x0001 // Western Europe & U.S.
-#define LGRPID_CENTRAL_EUROPE 0x0002 // Central Europe
-#define LGRPID_BALTIC 0x0003 // Baltic
-#define LGRPID_GREEK 0x0004 // Greek
-#define LGRPID_CYRILLIC 0x0005 // Cyrillic
-#define LGRPID_TURKISH 0x0006 // Turkish
-#define LGRPID_JAPANESE 0x0007 // Japanese
-#define LGRPID_KOREAN 0x0008 // Korean
-#define LGRPID_TRADITIONAL_CHINESE 0x0009 // Traditional Chinese
-#define LGRPID_SIMPLIFIED_CHINESE 0x000a // Simplified Chinese
-#define LGRPID_THAI 0x000b // Thai
-#define LGRPID_HEBREW 0x000c // Hebrew
-#define LGRPID_ARABIC 0x000d // Arabic
-#define LGRPID_VIETNAMESE 0x000e // Vietnamese
-#define LGRPID_INDIC 0x000f // Indic
-#define LGRPID_GEORGIAN 0x0010 // Georgian
-#define LGRPID_ARMENIAN 0x0011 // Armenian
-#endif
-
-static DWORD WM_MSIME_MOUSE = 0;
-
-QWinInputContext::QWinInputContext(QObject *parent)
- : QInputContext(parent), recursionGuard(false)
-{
-#ifndef Q_WS_WINCE
- QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
- if (ver & QSysInfo::WV_NT_based && ver >= QSysInfo::WV_VISTA) {
- // Since the IsValidLanguageGroup/IsValidLocale functions always return true on
- // Vista, check the Keyboard Layouts for enabling RTL.
- UINT nLayouts = GetKeyboardLayoutList(0, 0);
- if (nLayouts) {
- HKL *lpList = new HKL[nLayouts];
- GetKeyboardLayoutList(nLayouts, lpList);
- for (int i = 0; i<(int)nLayouts; i++) {
- WORD plangid = PRIMARYLANGID((quintptr)lpList[i]);
- if (plangid == LANG_ARABIC
- || plangid == LANG_HEBREW
- || plangid == LANG_FARSI
-#ifdef LANG_SYRIAC
- || plangid == LANG_SYRIAC
-#endif
- ) {
- qt_use_rtl_extensions = true;
- break;
- }
- }
- delete []lpList;
- }
- } else {
- // figure out whether a RTL language is installed
- qt_use_rtl_extensions = IsValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED)
- || IsValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED)
- || IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
- || IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
-#ifdef LANG_SYRIAC
- || IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
-#endif
- || IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED);
- }
-#else
- qt_use_rtl_extensions = false;
-#endif
-
- WM_MSIME_MOUSE = RegisterWindowMessage(L"MSIMEMouseOperation");
-}
-
-QWinInputContext::~QWinInputContext()
-{
- // release active input method if we have one
- if (aimm) {
- aimmpump->End();
- aimmpump->Release();
- aimm->Deactivate();
- aimm->Release();
- aimm = 0;
- aimmpump = 0;
- }
- delete imeComposition;
- imeComposition = 0;
-}
-
-static HWND getDefaultIMEWnd(HWND wnd)
-{
- HWND ime_wnd;
- if(aimm)
- aimm->GetDefaultIMEWnd(wnd, &ime_wnd);
- else
- ime_wnd = ImmGetDefaultIMEWnd(wnd);
- return ime_wnd;
-}
-
-static HIMC getContext(HWND wnd)
-{
- HIMC imc;
- if (aimm)
- aimm->GetContext(wnd, &imc);
- else
- imc = ImmGetContext(wnd);
-
- return imc;
-}
-
-static void releaseContext(HWND wnd, HIMC imc)
-{
- if (aimm)
- aimm->ReleaseContext(wnd, imc);
- else
- ImmReleaseContext(wnd, imc);
-}
-
-static void notifyIME(HIMC imc, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
-{
- if (!imc)
- return;
- if (aimm)
- aimm->NotifyIME(imc, dwAction, dwIndex, dwValue);
- else
- ImmNotifyIME(imc, dwAction, dwIndex, dwValue);
-}
-
-static LONG getCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpbuf, DWORD dBufLen)
-{
- LONG len = 0;
- if (aimm)
- aimm->GetCompositionStringW(himc, dwIndex, dBufLen, &len, lpbuf);
- else
- len = ImmGetCompositionString(himc, dwIndex, lpbuf, dBufLen);
- return len;
-}
-
-static int getCursorPosition(HIMC himc)
-{
- return getCompositionString(himc, GCS_CURSORPOS, 0, 0);
-}
-
-static QString getString(HIMC himc, DWORD dwindex, int *selStart = 0, int *selLength = 0)
-{
- const int bufferSize = 256;
- wchar_t buffer[bufferSize];
- int len = getCompositionString(himc, dwindex, buffer, bufferSize * sizeof(wchar_t));
-
- if (selStart) {
- char attrbuffer[bufferSize];
- int attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, bufferSize);
- *selStart = attrlen+1;
- *selLength = -1;
- for (int i = 0; i < attrlen; i++) {
- if (attrbuffer[i] & ATTR_TARGET_CONVERTED) {
- *selStart = qMin(*selStart, i);
- *selLength = qMax(*selLength, i);
- }
- }
- *selLength = qMax(0, *selLength - *selStart + 1);
- }
-
- if (len <= 0)
- return QString();
-
- return QString((QChar*)buffer, len / sizeof(QChar));
-}
-
-void QWinInputContext::TranslateMessage(const MSG *msg)
-{
- if (!aimmpump || aimmpump->OnTranslateMessage(msg) != S_OK)
- ::TranslateMessage(msg);
-}
-
-LRESULT QWinInputContext::DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- LRESULT retval;
- if (!aimm || aimm->OnDefWindowProc(hwnd, msg, wParam, lParam, &retval) != S_OK)
- {
- retval = ::DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return retval;
-}
-
-
-void QWinInputContext::update()
-{
- QWidget *w = focusWidget();
- if(!w)
- return;
-
- Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
- HIMC imc = getContext(w->effectiveWinId());
-
- if (!imc)
- return;
-
- QFont f = qvariant_cast<QFont>(w->inputMethodQuery(Qt::ImFont));
- HFONT hf;
- hf = f.handle();
-
- LOGFONT lf;
- if (GetObject(hf, sizeof(lf), &lf)) {
- if (aimm)
- aimm->SetCompositionFontW(imc, &lf);
- else
- ImmSetCompositionFont(imc, &lf);
- }
-
- QRect r = w->inputMethodQuery(Qt::ImMicroFocus).toRect();
-
- // The ime window positions are based on the WinId with active focus.
- QWidget *imeWnd = QWidget::find(::GetFocus());
- if (imeWnd && !aimm) {
- QPoint pt (r.topLeft());
- pt = w->mapToGlobal(pt);
- pt = imeWnd->mapFromGlobal(pt);
- r.moveTo(pt);
- }
-
- COMPOSITIONFORM cf;
- // ### need X-like inputStyle config settings
- cf.dwStyle = CFS_FORCE_POSITION;
- cf.ptCurrentPos.x = r.x();
- cf.ptCurrentPos.y = r.y();
-
- CANDIDATEFORM candf;
- candf.dwIndex = 0;
- candf.dwStyle = CFS_EXCLUDE;
- candf.ptCurrentPos.x = r.x();
- candf.ptCurrentPos.y = r.y() + r.height();
- candf.rcArea.left = r.x();
- candf.rcArea.top = r.y();
- candf.rcArea.right = r.x() + r.width();
- candf.rcArea.bottom = r.y() + r.height();
-
- if(haveCaret)
- SetCaretPos(r.x(), r.y());
-
- if (aimm) {
- aimm->SetCompositionWindow(imc, &cf);
- aimm->SetCandidateWindow(imc, &candf);
- } else {
- ImmSetCompositionWindow(imc, &cf);
- ImmSetCandidateWindow(imc, &candf);
- }
-
- releaseContext(w->effectiveWinId(), imc);
-}
-
-
-bool QWinInputContext::endComposition()
-{
- QWidget *fw = focusWidget();
-#ifdef Q_IME_DEBUG
- qDebug("endComposition! fw = %s", fw ? fw->className() : "(null)");
-#endif
- bool result = true;
- if(imePosition == -1 || recursionGuard)
- return result;
-
- // Googles Pinyin Input Method likes to call endComposition again
- // when we call notifyIME with CPS_CANCEL, so protect ourselves
- // against that.
- recursionGuard = true;
-
- if (fw) {
- Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created));
- HIMC imc = getContext(fw->effectiveWinId());
- notifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
- releaseContext(fw->effectiveWinId(), imc);
- if(haveCaret) {
- DestroyCaret();
- haveCaret = false;
- }
- }
-
- if (!fw)
- fw = QApplication::focusWidget();
-
- if (fw) {
- QInputMethodEvent e;
- result = qt_sendSpontaneousEvent(fw, &e);
- }
-
- if (imeComposition)
- imeComposition->clear();
- imePosition = -1;
-
- recursionGuard = false;
-
- return result;
-}
-
-void QWinInputContext::reset()
-{
- QWidget *fw = focusWidget();
-
-#ifdef Q_IME_DEBUG
- qDebug("sending accept to focus widget %s", fw ? fw->className() : "(null)");
-#endif
-
- if (fw && imePosition != -1) {
- QInputMethodEvent e;
- if (imeComposition)
- e.setCommitString(*imeComposition);
- imePosition = -1;
- qt_sendSpontaneousEvent(fw, &e);
- }
-
- if (imeComposition)
- imeComposition->clear();
- imePosition = -1;
-
- if (fw) {
- Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created));
- HIMC imc = getContext(fw->effectiveWinId());
- notifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
- releaseContext(fw->effectiveWinId(), imc);
- }
-
-}
-
-
-bool QWinInputContext::startComposition()
-{
-#ifdef Q_IME_DEBUG
- qDebug("startComposition");
-#endif
-
- if (!imeComposition)
- imeComposition = new QString();
-
- QWidget *fw = focusWidget();
- if (fw) {
- Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created));
- imePosition = 0;
- haveCaret = CreateCaret(fw->effectiveWinId(), 0, 1, 1);
- HideCaret(fw->effectiveWinId());
- update();
- }
- return fw != 0;
-}
-
-enum StandardFormat {
- PreeditFormat,
- SelectionFormat
-};
-
-bool QWinInputContext::composition(LPARAM lParam)
-{
-#ifdef Q_IME_DEBUG
- QString str;
- if (lParam & GCS_RESULTSTR)
- str += "RESULTSTR ";
- if (lParam & GCS_COMPSTR)
- str += "COMPSTR ";
- if (lParam & GCS_COMPATTR)
- str += "COMPATTR ";
- if (lParam & GCS_CURSORPOS)
- str += "CURSORPOS ";
- if (lParam & GCS_COMPCLAUSE)
- str += "COMPCLAUSE ";
- if (lParam & CS_INSERTCHAR)
- str += "INSERTCHAR ";
- if (lParam & CS_NOMOVECARET)
- str += "NOMOVECARET ";
- qDebug("composition, lParam=(%x) %s imePosition=%d", lParam, str.latin1(), imePosition);
-#endif
-
- bool result = true;
-
- if(!lParam)
- // bogus event
- return true;
-
- QWidget *fw = QApplication::focusWidget();
- if (fw) {
- Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created));
- HIMC imc = getContext(fw->effectiveWinId());
- QInputMethodEvent e;
- if (lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS)) {
- if (imePosition == -1)
- // need to send a start event
- startComposition();
-
- // some intermediate composition result
- int selStart, selLength;
- *imeComposition = getString(imc, GCS_COMPSTR, &selStart, &selLength);
- imePosition = getCursorPosition(imc);
- if (lParam & CS_INSERTCHAR && lParam & CS_NOMOVECARET) {
- // make korean work correctly. Hope this is correct for all IMEs
- selStart = 0;
- selLength = imeComposition->length();
- }
- if(selLength == 0)
- selStart = 0;
-
- QList<QInputMethodEvent::Attribute> attrs;
- if (selStart > 0)
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selStart,
- standardFormat(PreeditFormat));
- if (selLength)
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart, selLength,
- standardFormat(SelectionFormat));
- if (selStart + selLength < imeComposition->length())
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart + selLength,
- imeComposition->length() - selStart - selLength,
- standardFormat(PreeditFormat));
- if(imePosition >= 0)
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, imePosition, selLength ? 0 : 1, QVariant());
-
- e = QInputMethodEvent(*imeComposition, attrs);
- }
- if (lParam & GCS_RESULTSTR) {
- if(imePosition == -1)
- startComposition();
- // a fixed result, return the converted string
- *imeComposition = getString(imc, GCS_RESULTSTR);
- imePosition = -1;
- e.setCommitString(*imeComposition);
- imeComposition->clear();
- }
- result = qt_sendSpontaneousEvent(fw, &e);
- update();
- releaseContext(fw->effectiveWinId(), imc);
- }
-#ifdef Q_IME_DEBUG
- qDebug("imecomposition: cursor pos at %d, str=%x", imePosition, str[0].unicode());
-#endif
- return result;
-}
-
-static HIMC defaultContext = 0;
-
-// checks whether widget is a popup
-inline bool isPopup(QWidget *w)
-{
- if (w && (w->windowFlags() & Qt::Popup) == Qt::Popup)
- return true;
- else
- return false;
-}
-// checks whether widget is in a popup
-inline bool isInPopup(QWidget *w)
-{
- if (w && (isPopup(w) || isPopup(w->window())))
- return true;
- else
- return false;
-}
-
-// find the parent widget, which is a non popup toplevel
-// this is valid only if the widget is/in a popup
-inline QWidget *findParentforPopup(QWidget *w)
-{
- QWidget *e = QWidget::find(w->effectiveWinId());
- // check if this or its parent is a popup
- while (isInPopup(e)) {
- e = e->window()->parentWidget();
- if (!e)
- break;
- e = QWidget::find(e->effectiveWinId());
- }
- if (e)
- return e->window();
- else
- return 0;
-}
-
-// enables or disables the ime
-inline void enableIme(QWidget *w, bool value)
-{
- if (value) {
- // enable ime
- if (defaultContext)
- ImmAssociateContext(w->effectiveWinId(), defaultContext);
-#ifdef Q_WS_WINCE
- if (qApp->autoSipEnabled())
- qt_wince_show_SIP(true);
-#endif
- } else {
- // disable ime
- HIMC oldimc = ImmAssociateContext(w->effectiveWinId(), 0);
- if (!defaultContext)
- defaultContext = oldimc;
-#ifdef Q_WS_WINCE
- if (qApp->autoSipEnabled())
- qt_wince_show_SIP(false);
-#endif
- }
-}
-
-
-void QWinInputContext::updateImeStatus(QWidget *w, bool hasFocus)
-{
- if (!w)
- return;
- // It's always the proxy that carries the hints.
- QWidget *focusProxyWidget = w->focusProxy();
- if (!focusProxyWidget)
- focusProxyWidget = w;
- bool e = w->testAttribute(Qt::WA_InputMethodEnabled) && w->isEnabled()
- && !(focusProxyWidget->inputMethodHints() & (Qt::ImhExclusiveInputMask | Qt::ImhHiddenText));
- bool hasIme = e && hasFocus;
-#ifdef Q_IME_DEBUG
- qDebug("%s HasFocus = %d hasIme = %d e = %d ", w->className(), hasFocus, hasIme, e);
-#endif
- if (hasFocus || e) {
- if (isInPopup(w))
- QWinInputContext::enablePopupChild(w, hasIme);
- else
- QWinInputContext::enable(w, hasIme);
- }
-}
-
-void QWinInputContext::enablePopupChild(QWidget *w, bool e)
-{
- if (aimm) {
- enable(w, e);
- return;
- }
-
- if (!w || !isInPopup(w))
- return;
-#ifdef Q_IME_DEBUG
- qDebug("enablePopupChild: w=%s, enable = %s", w ? w->className() : "(null)" , e ? "true" : "false");
-#endif
- QWidget *parent = findParentforPopup(w);
- if (parent) {
- // update ime status of the normal toplevel parent of the popup
- enableIme(parent, e);
- }
- QWidget *toplevel = w->window();
- if (toplevel) {
- // update ime status of the toplevel popup
- enableIme(toplevel, e);
- }
-}
-
-void QWinInputContext::enable(QWidget *w, bool e)
-{
- if(w) {
-#ifdef Q_IME_DEBUG
- qDebug("enable: w=%s, enable = %s", w ? w->className() : "(null)" , e ? "true" : "false");
-#endif
- if (!w->testAttribute(Qt::WA_WState_Created))
- return;
- if(aimm) {
- HIMC oldimc;
- if (!e) {
- aimm->AssociateContext(w->effectiveWinId(), 0, &oldimc);
- if (!defaultContext)
- defaultContext = oldimc;
- } else if (defaultContext) {
- aimm->AssociateContext(w->effectiveWinId(), defaultContext, &oldimc);
- }
- } else {
- // update ime status on the widget
- QWidget *p = QWidget::find(w->effectiveWinId());
- if (p)
- enableIme(p, e);
- }
- }
-}
-
-void QWinInputContext::setFocusWidget(QWidget *w)
-{
- QWidget *oldFocus = focusWidget();
- if (oldFocus == w)
- return;
- if (w) {
- QWinInputContext::updateImeStatus(w, true);
- } else {
- if (oldFocus)
- QWinInputContext::updateImeStatus(oldFocus , false);
- }
- QInputContext::setFocusWidget(w);
- update();
-}
-
-bool QWinInputContext::isComposing() const
-{
- return imeComposition && !imeComposition->isEmpty();
-}
-
-void QWinInputContext::mouseHandler(int pos, QMouseEvent *e)
-{
- if(e->type() != QEvent::MouseButtonPress)
- return;
-
- if (pos < 0 || pos > imeComposition->length())
- reset();
-
- // Probably should pass the correct button, but it seems to work fine like this.
- DWORD button = MK_LBUTTON;
-
- QWidget *fw = focusWidget();
- if (fw) {
- Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created));
- HIMC himc = getContext(fw->effectiveWinId());
- HWND ime_wnd = getDefaultIMEWnd(fw->effectiveWinId());
- SendMessage(ime_wnd, WM_MSIME_MOUSE, MAKELONG(MAKEWORD(button, pos == 0 ? 2 : 1), pos), (LPARAM)himc);
- releaseContext(fw->effectiveWinId(), himc);
- }
- //qDebug("mouseHandler: got value %d pos=%d", ret,pos);
-}
-
-QString QWinInputContext::language()
-{
- return QString();
-}
-
-int QWinInputContext::reconvertString(RECONVERTSTRING *reconv)
-{
- QWidget *w = focusWidget();
- if(!w)
- return -1;
-
- Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
- QString surroundingText = qvariant_cast<QString>(w->inputMethodQuery(Qt::ImSurroundingText));
- int memSize = sizeof(RECONVERTSTRING)+(surroundingText.length()+1)*sizeof(ushort);
- // If memory is not allocated, return the required size.
- if (!reconv) {
- if (surroundingText.isEmpty())
- return -1;
- else
- return memSize;
- }
- int pos = qvariant_cast<int>(w->inputMethodQuery(Qt::ImCursorPosition));
- // find the word in the surrounding text.
- QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText);
- bounds.setPosition(pos);
- if (bounds.isAtBoundary()) {
- if (QTextBoundaryFinder::EndWord == bounds.boundaryReasons())
- bounds.toPreviousBoundary();
- } else {
- bounds.toPreviousBoundary();
- }
- int startPos = bounds.position();
- bounds.toNextBoundary();
- int endPos = bounds.position();
- // select the text, this will be overwritten by following ime events.
- QList<QInputMethodEvent::Attribute> attrs;
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant());
- QInputMethodEvent e(QString(), attrs);
- qt_sendSpontaneousEvent(w, &e);
-
- reconv->dwSize = memSize;
- reconv->dwVersion = 0;
-
- reconv->dwStrLen = surroundingText.length();
- reconv->dwStrOffset = sizeof(RECONVERTSTRING);
- reconv->dwCompStrLen = endPos-startPos;
- reconv->dwCompStrOffset = startPos*sizeof(ushort);
- reconv->dwTargetStrLen = reconv->dwCompStrLen;
- reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
- memcpy((char*)(reconv+1), surroundingText.utf16(), surroundingText.length()*sizeof(ushort));
- return memSize;
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/win/qwinnativepangesturerecognizer_win.cpp b/src/widgets/platforms/win/qwinnativepangesturerecognizer_win.cpp
deleted file mode 100644
index 85ef0a949f..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/widgets/platforms/win/qwinnativepangesturerecognizer_win_p.h b/src/widgets/platforms/win/qwinnativepangesturerecognizer_win_p.h
deleted file mode 100644
index 4f15a82b7e..0000000000
--- a/src/widgets/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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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
diff --git a/src/widgets/platforms/x11/qapplication_x11.cpp b/src/widgets/platforms/x11/qapplication_x11.cpp
deleted file mode 100644
index 1827423f7d..0000000000
--- a/src/widgets/platforms/x11/qapplication_x11.cpp
+++ /dev/null
@@ -1,6223 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// ### 4.0: examine Q_EXPORT's below. The respective symbols had all
-// been in use (e.g. in the KDE wm) before the introduction of a version
-// map. One might want to turn some of them into proper public API and
-// provide a proper alternative for others. See also the exports in
-// qapplication_win.cpp, which suggest a unification.
-
-#include "qplatformdefs.h"
-
-#include "qcolormap.h"
-#include "qdesktopwidget.h"
-#include "qapplication.h"
-#include "qapplication_p.h"
-#include "qcursor.h"
-#include "qwidget.h"
-#include "qbitarray.h"
-#include "qpainter.h"
-#include "qfile.h"
-#include "qpixmapcache.h"
-#include "qdatetime.h"
-#include "qtextcodec.h"
-#include "qdatastream.h"
-#include "qbuffer.h"
-#include "qsocketnotifier.h"
-#include "qsessionmanager.h"
-#include "qclipboard.h"
-#include "qwhatsthis.h"
-#include "qsettings.h"
-#include "qstylefactory.h"
-#include "qfileinfo.h"
-#include "qdir.h"
-#include "qhash.h"
-#include "qevent.h"
-#include "qevent_p.h"
-#include "qvarlengtharray.h"
-#include "qdebug.h"
-#include <private/qcrashhandler_p.h>
-#include <private/qcolor_p.h>
-#include <private/qcursor_p.h>
-#include <private/qiconloader_p.h>
-#include <qgtkstyle.h>
-#include "qstyle.h"
-#include "qmetaobject.h"
-#include "qtimer.h"
-#include "qlibrary.h"
-#include <private/qgraphicssystemfactory_p.h>
-#include "qguiplatformplugin_p.h"
-#include "qkde_p.h"
-
-#if !defined (QT_NO_TABLET)
-extern "C" {
-# define class c_class //XIproto.h has a name member named 'class' which the c++ compiler doesn't like
-# include <wacomcfg.h>
-# undef class
-}
-#endif
-
-#ifndef QT_GUI_DOUBLE_CLICK_RADIUS
-#define QT_GUI_DOUBLE_CLICK_RADIUS 5
-#endif
-
-
-//#define ALIEN_DEBUG
-
-#if !defined(QT_NO_GLIB)
-# include "qguieventdispatcher_glib_p.h"
-#endif
-#include "qeventdispatcher_x11_p.h"
-#include <private/qpaintengine_x11_p.h>
-
-#include <private/qkeymapper_p.h>
-
-// Input method stuff
-#ifndef QT_NO_IM
-#include "qinputcontext.h"
-#include "qinputcontextfactory.h"
-#endif // QT_NO_IM
-
-#ifndef QT_NO_XFIXES
-#include <X11/extensions/Xfixes.h>
-#endif // QT_NO_XFIXES
-
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-
-#define XK_MISCELLANY
-#include <X11/keysymdef.h>
-#if !defined(QT_NO_XINPUT)
-#include <X11/extensions/XI.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <locale.h>
-
-#include "qwidget_p.h"
-
-#include <private/qbackingstore_p.h>
-
-#ifdef QT_RX71_MULTITOUCH
-# include <qsocketnotifier.h>
-# include <linux/input.h>
-# include <errno.h>
-#endif
-
-#if _POSIX_VERSION+0 < 200112L && !defined(Q_OS_BSD4)
-# define QT_NO_UNSETENV
-#endif
-
-QT_BEGIN_NAMESPACE
-
-//#define X_NOT_BROKEN
-#ifdef X_NOT_BROKEN
-// Some X libraries are built with setlocale #defined to _Xsetlocale,
-// even though library users are then built WITHOUT such a definition.
-// This creates a problem - Qt might setlocale() one value, but then
-// X looks and doesn't see the value Qt set. The solution here is to
-// implement _Xsetlocale just in case X calls it - redirecting it to
-// the real libC version.
-//
-# ifndef setlocale
-extern "C" char *_Xsetlocale(int category, const char *locale);
-char *_Xsetlocale(int category, const char *locale)
-{
- //qDebug("_Xsetlocale(%d,%s),category,locale");
- return setlocale(category,locale);
-}
-# endif // setlocale
-#endif // X_NOT_BROKEN
-
-/* Warning: if you modify this string, modify the list of atoms in qt_x11_p.h as well! */
-static const char * x11_atomnames = {
- // window-manager <-> client protocols
- "WM_PROTOCOLS\0"
- "WM_DELETE_WINDOW\0"
- "WM_TAKE_FOCUS\0"
- "_NET_WM_PING\0"
- "_NET_WM_CONTEXT_HELP\0"
- "_NET_WM_SYNC_REQUEST\0"
- "_NET_WM_SYNC_REQUEST_COUNTER\0"
-
- // ICCCM window state
- "WM_STATE\0"
- "WM_CHANGE_STATE\0"
-
- // Session management
- "WM_CLIENT_LEADER\0"
- "WM_WINDOW_ROLE\0"
- "SM_CLIENT_ID\0"
-
- // Clipboard
- "CLIPBOARD\0"
- "INCR\0"
- "TARGETS\0"
- "MULTIPLE\0"
- "TIMESTAMP\0"
- "SAVE_TARGETS\0"
- "CLIP_TEMPORARY\0"
- "_QT_SELECTION\0"
- "_QT_CLIPBOARD_SENTINEL\0"
- "_QT_SELECTION_SENTINEL\0"
- "CLIPBOARD_MANAGER\0"
-
- "RESOURCE_MANAGER\0"
-
- "_XSETROOT_ID\0"
-
- "_QT_SCROLL_DONE\0"
- "_QT_INPUT_ENCODING\0"
-
- "_MOTIF_WM_HINTS\0"
-
- "DTWM_IS_RUNNING\0"
- "ENLIGHTENMENT_DESKTOP\0"
- "_DT_SAVE_MODE\0"
- "_SGI_DESKS_MANAGER\0"
-
- // EWMH (aka NETWM)
- "_NET_SUPPORTED\0"
- "_NET_VIRTUAL_ROOTS\0"
- "_NET_WORKAREA\0"
-
- "_NET_MOVERESIZE_WINDOW\0"
- "_NET_WM_MOVERESIZE\0"
-
- "_NET_WM_NAME\0"
- "_NET_WM_ICON_NAME\0"
- "_NET_WM_ICON\0"
-
- "_NET_WM_PID\0"
-
- "_NET_WM_WINDOW_OPACITY\0"
-
- "_NET_WM_STATE\0"
- "_NET_WM_STATE_ABOVE\0"
- "_NET_WM_STATE_BELOW\0"
- "_NET_WM_STATE_FULLSCREEN\0"
- "_NET_WM_STATE_MAXIMIZED_HORZ\0"
- "_NET_WM_STATE_MAXIMIZED_VERT\0"
- "_NET_WM_STATE_MODAL\0"
- "_NET_WM_STATE_STAYS_ON_TOP\0"
- "_NET_WM_STATE_DEMANDS_ATTENTION\0"
-
- "_NET_WM_USER_TIME\0"
- "_NET_WM_USER_TIME_WINDOW\0"
- "_NET_WM_FULL_PLACEMENT\0"
-
- "_NET_WM_WINDOW_TYPE\0"
- "_NET_WM_WINDOW_TYPE_DESKTOP\0"
- "_NET_WM_WINDOW_TYPE_DOCK\0"
- "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
- "_NET_WM_WINDOW_TYPE_MENU\0"
- "_NET_WM_WINDOW_TYPE_UTILITY\0"
- "_NET_WM_WINDOW_TYPE_SPLASH\0"
- "_NET_WM_WINDOW_TYPE_DIALOG\0"
- "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
- "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
- "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
- "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
- "_NET_WM_WINDOW_TYPE_COMBO\0"
- "_NET_WM_WINDOW_TYPE_DND\0"
- "_NET_WM_WINDOW_TYPE_NORMAL\0"
- "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
-
- "_KDE_NET_WM_FRAME_STRUT\0"
-
- "_NET_STARTUP_INFO\0"
- "_NET_STARTUP_INFO_BEGIN\0"
-
- "_NET_SUPPORTING_WM_CHECK\0"
-
- "_NET_WM_CM_S0\0"
-
- "_NET_SYSTEM_TRAY_VISUAL\0"
-
- "_NET_ACTIVE_WINDOW\0"
-
- // Property formats
- "COMPOUND_TEXT\0"
- "TEXT\0"
- "UTF8_STRING\0"
-
- // xdnd
- "XdndEnter\0"
- "XdndPosition\0"
- "XdndStatus\0"
- "XdndLeave\0"
- "XdndDrop\0"
- "XdndFinished\0"
- "XdndTypeList\0"
- "XdndActionList\0"
-
- "XdndSelection\0"
-
- "XdndAware\0"
- "XdndProxy\0"
-
- "XdndActionCopy\0"
- "XdndActionLink\0"
- "XdndActionMove\0"
- "XdndActionPrivate\0"
-
- // Motif DND
- "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
- "_MOTIF_DRAG_INITIATOR_INFO\0"
- "_MOTIF_DRAG_RECEIVER_INFO\0"
- "_MOTIF_DRAG_WINDOW\0"
- "_MOTIF_DRAG_TARGETS\0"
-
- "XmTRANSFER_SUCCESS\0"
- "XmTRANSFER_FAILURE\0"
-
- // Xkb
- "_XKB_RULES_NAMES\0"
-
- // XEMBED
- "_XEMBED\0"
- "_XEMBED_INFO\0"
-
- // Wacom old. (before version 0.10)
- "Wacom Stylus\0"
- "Wacom Cursor\0"
- "Wacom Eraser\0"
-
- // Tablet
- "STYLUS\0"
- "ERASER\0"
-};
-
-Q_WIDGETS_EXPORT QX11Data *qt_x11Data = 0;
-
-/*****************************************************************************
- Internal variables and functions
- *****************************************************************************/
-static const char *appName = 0; // application name
-static const char *appClass = 0; // application class
-static const char *appFont = 0; // application font
-static const char *appBGCol = 0; // application bg color
-static const char *appFGCol = 0; // application fg color
-static const char *appBTNCol = 0; // application btn color
-static const char *mwGeometry = 0; // main widget geometry
-static const char *mwTitle = 0; // main widget title
-char *qt_ximServer = 0; // XIM Server will connect to
-static bool appSync = false; // X11 synchronization
-#if defined(QT_DEBUG)
-static bool appNoGrab = false; // X11 grabbing enabled
-static bool appDoGrab = false; // X11 grabbing override (gdb)
-#endif
-static bool app_save_rootinfo = false; // save root info
-static bool app_do_modal = false; // modal mode
-static Window curWin = 0; // current window
-
-
-// function to update the workarea of the screen - in qdesktopwidget_x11.cpp
-extern void qt_desktopwidget_update_workarea();
-
-// Function to change the window manager state (from qwidget_x11.cpp)
-extern void qt_change_net_wm_state(const QWidget *w, bool set, Atom one, Atom two = 0);
-
-// modifier masks for alt, meta, super, hyper, and mode_switch - detected when the application starts
-// and/or keyboard layout changes
-uchar qt_alt_mask = 0;
-uchar qt_meta_mask = 0;
-uchar qt_super_mask = 0;
-uchar qt_hyper_mask = 0;
-uchar qt_mode_switch_mask = 0;
-
-// flags for extensions for special Languages, currently only for RTL languages
-bool qt_use_rtl_extensions = false;
-
-static Window mouseActWindow = 0; // window where mouse is
-static Qt::MouseButton mouseButtonPressed = Qt::NoButton; // last mouse button pressed
-static Qt::MouseButtons mouseButtonState = Qt::NoButton; // mouse button state
-static Time mouseButtonPressTime = 0; // when was a button pressed
-static short mouseXPos, mouseYPos; // mouse pres position in act window
-static short mouseGlobalXPos, mouseGlobalYPos; // global mouse press position
-
-extern QWidgetList *qt_modal_stack; // stack of modal widgets
-
-// window where mouse buttons have been pressed
-static Window pressed_window = XNone;
-
-// popup control
-static bool replayPopupMouseEvent = false;
-static bool popupGrabOk;
-
-bool qt_sm_blockUserInput = false; // session management
-
-Q_WIDGETS_EXPORT int qt_xfocusout_grab_counter = 0;
-
-#if !defined (QT_NO_TABLET)
-Q_GLOBAL_STATIC(QTabletDeviceDataList, tablet_devices)
-QTabletDeviceDataList *qt_tablet_devices()
-{
- return tablet_devices();
-}
-
-extern bool qt_tabletChokeMouse;
-#endif
-
-typedef bool(*QX11FilterFunction)(XEvent *event);
-
-Q_GLOBAL_STATIC(QList<QX11FilterFunction>, x11Filters)
-
-Q_WIDGETS_EXPORT void qt_installX11EventFilter(QX11FilterFunction func)
-{
- Q_ASSERT(func);
-
- if (QList<QX11FilterFunction> *list = x11Filters())
- list->append(func);
-}
-
-Q_WIDGETS_EXPORT void qt_removeX11EventFilter(QX11FilterFunction func)
-{
- Q_ASSERT(func);
-
- if (QList<QX11FilterFunction> *list = x11Filters())
- list->removeOne(func);
-}
-
-
-static bool qt_x11EventFilter(XEvent* ev)
-{
- long unused;
- if (qApp->filterEvent(ev, &unused))
- return true;
- if (const QList<QX11FilterFunction> *list = x11Filters()) {
- for (QList<QX11FilterFunction>::const_iterator it = list->constBegin(); it != list->constEnd(); ++it) {
- if ((*it)(ev))
- return true;
- }
- }
-
- return qApp->x11EventFilter(ev);
-}
-
-#if !defined(QT_NO_XIM)
-XIMStyle qt_xim_preferred_style = 0;
-#endif
-int qt_ximComposingKeycode=0;
-QTextCodec * qt_input_mapper = 0;
-
-extern bool qt_check_clipboard_sentinel(); //def in qclipboard_x11.cpp
-extern bool qt_check_selection_sentinel(); //def in qclipboard_x11.cpp
-extern bool qt_xfixes_clipboard_changed(Window clipboardOwner, Time timestamp); //def in qclipboard_x11.cpp
-extern bool qt_xfixes_selection_changed(Window selectionOwner, Time timestamp); //def in qclipboard_x11.cpp
-
-static void qt_save_rootinfo();
-Q_WIDGETS_EXPORT bool qt_try_modal(QWidget *, XEvent *);
-
-QWidget *qt_button_down = 0; // last widget to be pressed with the mouse
-QPointer<QWidget> qt_last_mouse_receiver = 0;
-static QWidget *qt_popup_down = 0; // popup that contains the pressed widget
-
-extern bool qt_xdnd_dragging;
-
-// gui or non-gui from qapplication.cpp
-extern bool qt_is_gui_used;
-
-/*!
- \internal
- Try to resolve a \a symbol from \a library with the version specified
- by \a vernum.
-
- Note that, in the case of the Xfixes library, \a vernum is not the same as
- \c XFIXES_MAJOR - it is a part of soname and may differ from the Xfixes
- version.
-*/
-static void* qt_load_library_runtime(const char *library, int vernum,
- int highestVernum, const char *symbol)
-{
- QList<int> versions;
- // we try to load in the following order:
- // explicit version -> the default one -> (from the highest (highestVernum) to the lowest (vernum) )
- if (vernum != -1)
- versions << vernum;
- versions << -1;
- if (vernum != -1) {
- for(int i = highestVernum; i > vernum; --i)
- versions << i;
- }
- Q_FOREACH(int version, versions) {
- QLatin1String libName(library);
- QLibrary xfixesLib(libName, version);
- void *ptr = xfixesLib.resolve(symbol);
- if (ptr)
- return ptr;
- }
- return 0;
-}
-
-#ifndef QT_NO_XINPUT
-# ifdef QT_RUNTIME_XINPUT
-# define XINPUT_LOAD_RUNTIME(vernum, symbol, symbol_type) \
- (symbol_type)qt_load_library_runtime("libXi", vernum, 6, #symbol);
-# define XINPUT_LOAD(symbol) \
- XINPUT_LOAD_RUNTIME(1, symbol, Ptr##symbol)
-# else // not runtime XInput
-# define XINPUT_LOAD(symbol) symbol
-# endif // QT_RUNTIME_XINPUT
-#else // not using Xinput at all
-# define XINPUT_LOAD(symbol) 0
-#endif // QT_NO_XINPUT
-
-#ifndef QT_NO_XFIXES
-# ifdef QT_RUNTIME_XFIXES
-# define XFIXES_LOAD_RUNTIME(vernum, symbol, symbol_type) \
- (symbol_type)qt_load_library_runtime("libXfixes", vernum, 4, #symbol);
-# define XFIXES_LOAD_V1(symbol) \
- XFIXES_LOAD_RUNTIME(1, symbol, Ptr##symbol)
-# define XFIXES_LOAD_V2(symbol) \
- XFIXES_LOAD_RUNTIME(2, symbol, Ptr##symbol)
-
-# else // not runtime Xfixes
-
-# if XFIXES_MAJOR >= 2
-# define XFIXES_LOAD_V1(symbol) symbol
-# define XFIXES_LOAD_V2(symbol) symbol
-# elif XFIXES_MAJOR >= 1
-# define XFIXES_LOAD_V1(symbol) symbol
-# define XFIXES_LOAD_V2(symbol) 0
-# else
-# error Unsupported version of Xfixes
-# endif
-# endif // QT_RUNTIME_XFIXES
-#else // not using Xfixes at all
-# define XFIXES_LOAD_V1(symbol) 0
-# define XFIXES_LOAD_V2(symbol) 0
-#endif // QT_NO_XFIXES
-
-#ifndef QT_NO_XFIXES
-
-struct qt_xfixes_selection_event_data
-{
- // which selection to filter out.
- Atom selection;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool qt_xfixes_scanner(Display*, XEvent *event, XPointer arg)
-{
- qt_xfixes_selection_event_data *data =
- reinterpret_cast<qt_xfixes_selection_event_data*>(arg);
- if (event->type == X11->xfixes_eventbase + XFixesSelectionNotify) {
- XFixesSelectionNotifyEvent *xfixes_event = reinterpret_cast<XFixesSelectionNotifyEvent*>(event);
- if (xfixes_event->selection == data->selection)
- return true;
- }
- return false;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-#endif // QT_NO_XFIXES
-
-class QETWidget : public QWidget // event translator widget
-{
-public:
- QWidgetPrivate* d_func() { return QWidget::d_func(); }
- bool translateMouseEvent(const XEvent *);
- void translatePaintEvent(const XEvent *);
- bool translateConfigEvent(const XEvent *);
- bool translateCloseEvent(const XEvent *);
- bool translateScrollDoneEvent(const XEvent *);
- bool translateWheelEvent(int global_x, int global_y, int delta, Qt::MouseButtons buttons,
- Qt::KeyboardModifiers modifiers, Qt::Orientation orient);
-#if !defined (QT_NO_TABLET)
- bool translateXinputEvent(const XEvent*, QTabletDeviceData *tablet);
-#endif
- bool translatePropertyEvent(const XEvent *);
-
- void doDeferredMap()
- {
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- if (!testAttribute(Qt::WA_Resized)) {
- adjustSize();
- setAttribute(Qt::WA_Resized, false);
- }
-
- /*
- workaround for WM's that throw away ConfigureRequests from the following:
-
- window->hide();
- window->move(x, y); // could also be resize(), move()+resize(), or setGeometry()
- window->show();
- */
- QRect r = geometry();
-
- XMoveResizeWindow(X11->display,
- internalWinId(),
- r.x(),
- r.y(),
- r.width(),
- r.height());
-
- // static gravity!
- XSizeHints sh;
- long unused;
- XGetWMNormalHints(X11->display, internalWinId(), &sh, &unused);
- sh.flags |= USPosition | PPosition | USSize | PSize | PWinGravity;
- sh.x = r.x();
- sh.y = r.y();
- sh.width = r.width();
- sh.height = r.height();
- sh.win_gravity = StaticGravity;
- XSetWMNormalHints(X11->display, internalWinId(), &sh);
-
- setAttribute(Qt::WA_Mapped);
- if (testAttribute(Qt::WA_DontShowOnScreen))
- return;
- d_func()->topData()->waitingForMapNotify = 1;
- XMapWindow(X11->display, internalWinId());
- }
-};
-
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
-#if !defined(QT_NO_GLIB)
- if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
- eventDispatcher = (q->type() != QApplication::Tty
- ? new QGuiEventDispatcherGlib(q)
- : new QEventDispatcherGlib(q));
- else
-#endif
- eventDispatcher = (q->type() != QApplication::Tty
- ? new QEventDispatcherX11(q)
- : new QEventDispatcherUNIX(q));
-}
-
-/*****************************************************************************
- Default X error handlers
- *****************************************************************************/
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static int (*original_x_errhandler)(Display *dpy, XErrorEvent *);
-static int (*original_xio_errhandler)(Display *dpy);
-
-static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
-{
- if (X11->display != dpy) {
- // only handle X errors for our display
- return 0;
- }
-
- switch (err->error_code) {
- case BadAtom:
- if (err->request_code == 20 /* X_GetProperty */
- && (err->resourceid == XA_RESOURCE_MANAGER
- || err->resourceid == XA_RGB_DEFAULT_MAP
- || err->resourceid == ATOM(_NET_SUPPORTED)
- || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK)
- || err->resourceid == ATOM(XdndProxy)
- || err->resourceid == ATOM(XdndAware))) {
- // Perhaps we're running under SECURITY reduction? :/
- return 0;
- }
- break;
-
- case BadWindow:
- if (err->request_code == 2 /* X_ChangeWindowAttributes */
- || err->request_code == 38 /* X_QueryPointer */) {
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (err->resourceid == RootWindow(dpy, i)) {
- // Perhaps we're running under SECURITY reduction? :/
- return 0;
- }
- }
- }
- X11->seen_badwindow = true;
- if (err->request_code == 25 /* X_SendEvent */) {
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (err->resourceid == RootWindow(dpy, i)) {
- // Perhaps we're running under SECURITY reduction? :/
- return 0;
- }
- }
- if (X11->xdndHandleBadwindow()) {
- qDebug("xdndHandleBadwindow returned true");
- return 0;
- }
- }
- if (X11->ignore_badwindow)
- return 0;
- break;
-
- default:
-#if !defined(QT_NO_XINPUT)
- if (err->request_code == X11->xinput_major
- && err->error_code == (X11->xinput_errorbase + XI_BadDevice)
- && err->minor_code == 3 /* X_OpenDevice */) {
- return 0;
- }
-#endif
- break;
- }
-
- char errstr[256];
- XGetErrorText( dpy, err->error_code, errstr, 256 );
- char buffer[256];
- char request_str[256];
- qsnprintf(buffer, 256, "%d", err->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", buffer, "", request_str, 256);
- if (err->request_code < 128) {
- // X error for a normal protocol request
- qWarning( "X Error: %s %d\n"
- " Major opcode: %d (%s)\n"
- " Resource id: 0x%lx",
- errstr, err->error_code,
- err->request_code,
- request_str,
- err->resourceid );
- } else {
- // X error for an extension request
- const char *extensionName = 0;
- if (err->request_code == X11->xrender_major)
- extensionName = "RENDER";
- else if (err->request_code == X11->xrandr_major)
- extensionName = "RANDR";
- else if (err->request_code == X11->xinput_major)
- extensionName = "XInputExtension";
- else if (err->request_code == X11->mitshm_major)
- extensionName = "MIT-SHM";
-#ifndef QT_NO_XKB
- else if(err->request_code == X11->xkb_major)
- extensionName = "XKEYBOARD";
-#endif
-
- char minor_str[256];
- if (extensionName) {
- qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code);
- XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256);
- } else {
- extensionName = "Uknown extension";
- qsnprintf(minor_str, 256, "Unknown request");
- }
- qWarning( "X Error: %s %d\n"
- " Extension: %d (%s)\n"
- " Minor opcode: %d (%s)\n"
- " Resource id: 0x%lx",
- errstr, err->error_code,
- err->request_code,
- extensionName,
- err->minor_code,
- minor_str,
- err->resourceid );
- }
-
- // ### we really should distinguish between severe, non-severe and
- // ### application specific errors
-
- return 0;
-}
-
-
-static int qt_xio_errhandler(Display *)
-{
- qWarning("%s: Fatal IO error: client killed", appName);
- QApplicationPrivate::reset_instance_pointer();
- exit(1);
- //### give the application a chance for a proper shutdown instead,
- //### exit(1) doesn't help.
- return 0;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-#ifndef QT_NO_XSYNC
-struct qt_sync_request_event_data
-{
- WId window;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg)
-{
- qt_sync_request_event_data *data =
- reinterpret_cast<qt_sync_request_event_data*>(arg);
- if (event->type == ClientMessage &&
- event->xany.window == data->window &&
- event->xclient.message_type == ATOM(WM_PROTOCOLS) &&
- (Atom)event->xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST)) {
- QWidget *w = QWidget::find(event->xany.window);
- if (QTLWExtra *tlw = ((QETWidget*)w)->d_func()->maybeTopData()) {
- const ulong timestamp = (const ulong) event->xclient.data.l[1];
- if (timestamp > X11->time)
- X11->time = timestamp;
- if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
- tlw->syncRequestTimestamp = timestamp;
- tlw->newCounterValueLo = event->xclient.data.l[2];
- tlw->newCounterValueHi = event->xclient.data.l[3];
- }
- }
- return true;
- }
- return false;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-#endif // QT_NO_XSYNC
-
-static void qt_x11_create_intern_atoms()
-{
- const char *names[QX11Data::NAtoms];
- const char *ptr = x11_atomnames;
-
- int i = 0;
- while (*ptr) {
- names[i++] = ptr;
- while (*ptr)
- ++ptr;
- ++ptr;
- }
-
- Q_ASSERT(i == QX11Data::NPredefinedAtoms);
-
- QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
- settings_atom_name += XDisplayName(X11->displayName);
- names[i++] = settings_atom_name;
-
- Q_ASSERT(i == QX11Data::NAtoms);
-#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
- XInternAtoms(X11->display, (char **)names, i, False, X11->atoms);
-#else
- for (i = 0; i < QX11Data::NAtoms; ++i)
- X11->atoms[i] = XInternAtom(X11->display, (char *)names[i], False);
-#endif
-}
-
-Q_WIDGETS_EXPORT void qt_x11_apply_settings_in_all_apps()
-{
- QByteArray stamp;
- QDataStream s(&stamp, QIODevice::WriteOnly);
- s << QDateTime::currentDateTime();
-
- XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
- ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
- PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
-}
-
-/*! \internal
- apply the settings to the application
-*/
-bool QApplicationPrivate::x11_apply_settings()
-{
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
-
- settings.beginGroup(QLatin1String("Qt"));
-
- /*
- Qt settings. This is now they are written into the datastream.
-
- Palette / * - QPalette
- font - QFont
- libraryPath - QStringList
- style - QString
- doubleClickInterval - int
- keyboardInputInterval - int
- cursorFlashTime - int
- wheelScrollLines - int
- colorSpec - QString
- defaultCodec - QString
- globalStrut/width - int
- globalStrut/height - int
- GUIEffects - QStringList
- Font Substitutions/ * - QStringList
- Font Substitutions/... - QStringList
- */
-
- QStringList strlist;
- int i;
- QPalette pal(Qt::black);
- int groupCount = 0;
- strlist = settings.value(QLatin1String("Palette/active")).toStringList();
- if (!strlist.isEmpty()) {
- ++groupCount;
- for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
- pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
- if (!strlist.isEmpty()) {
- ++groupCount;
- for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
- pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
- if (!strlist.isEmpty()) {
- ++groupCount;
- for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
- pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
-
- // ### Fix properly for 4.6
- bool usingGtkSettings = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
- if (!usingGtkSettings) {
- if (groupCount == QPalette::NColorGroups)
- QApplicationPrivate::setSystemPalette(pal);
- }
-
- if (!appFont) {
- // ### Fix properly for 4.6
- if (!usingGtkSettings) {
- QFont font(QApplication::font());
- QString fontDescription;
- // Override Qt font if KDE4 settings can be used
- if (X11->desktopVersion == 4) {
- QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
- fontDescription = kdeSettings.value(QLatin1String("font")).toString();
- if (fontDescription.isEmpty()) {
- // KDE stores fonts without quotes
- fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(","));
- }
- }
- if (fontDescription.isEmpty())
- fontDescription = settings.value(QLatin1String("font")).toString();
- if (!fontDescription .isEmpty()) {
- font.fromString(fontDescription );
- QApplicationPrivate::setSystemFont(font);
- }
- }
- }
-
- // read library (ie. plugin) path list
- QString libpathkey =
- QString::fromLatin1("%1.%2/libraryPath")
- .arg(QT_VERSION >> 16)
- .arg((QT_VERSION & 0xff00) >> 8);
- QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
- if (! pathlist.isEmpty()) {
- QStringList::ConstIterator it = pathlist.constBegin();
- while (it != pathlist.constEnd())
- QApplication::addLibraryPath(*it++);
- }
-
- // read new QStyle
- QString stylename = settings.value(QLatin1String("style")).toString();
-
- if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) {
- stylename = qt_guiPlatformPlugin()->styleName();
- }
-
- static QString currentStyleName = stylename;
- if (QCoreApplication::startingUp()) {
- if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
- QApplicationPrivate::styleOverride = stylename;
- } else {
- if (currentStyleName != stylename) {
- currentStyleName = stylename;
- QApplication::setStyle(stylename);
- }
- }
-
- int num =
- settings.value(QLatin1String("doubleClickInterval"),
- QApplication::doubleClickInterval()).toInt();
- QApplication::setDoubleClickInterval(num);
-
- num =
- settings.value(QLatin1String("cursorFlashTime"),
- QApplication::cursorFlashTime()).toInt();
- QApplication::setCursorFlashTime(num);
-
-#ifndef QT_NO_WHEELEVENT
- num =
- settings.value(QLatin1String("wheelScrollLines"),
- QApplication::wheelScrollLines()).toInt();
- QApplication::setWheelScrollLines(num);
-#endif
-
- QString colorspec = settings.value(QLatin1String("colorSpec"),
- QVariant(QLatin1String("default"))).toString();
- if (colorspec == QLatin1String("normal"))
- QApplication::setColorSpec(QApplication::NormalColor);
- else if (colorspec == QLatin1String("custom"))
- QApplication::setColorSpec(QApplication::CustomColor);
- else if (colorspec == QLatin1String("many"))
- QApplication::setColorSpec(QApplication::ManyColor);
- else if (colorspec != QLatin1String("default"))
- colorspec = QLatin1String("default");
-
- QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
- QVariant(QLatin1String("none"))).toString();
- if (defaultcodec != QLatin1String("none")) {
- QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
- if (codec)
- QTextCodec::setCodecForTr(codec);
- }
-
- int w = settings.value(QLatin1String("globalStrut/width")).toInt();
- int h = settings.value(QLatin1String("globalStrut/height")).toInt();
- QSize strut(w, h);
- if (strut.isValid())
- QApplication::setGlobalStrut(strut);
-
- QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
- QApplication::setEffectEnabled(Qt::UI_General,
- effects.contains(QLatin1String("general")));
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
- effects.contains(QLatin1String("animatemenu")));
- QApplication::setEffectEnabled(Qt::UI_FadeMenu,
- effects.contains(QLatin1String("fademenu")));
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
- effects.contains(QLatin1String("animatecombo")));
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
- effects.contains(QLatin1String("animatetooltip")));
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
- effects.contains(QLatin1String("fadetooltip")));
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
- effects.contains(QLatin1String("animatetoolbox")));
-
- if (!X11->has_fontconfig) {
- settings.beginGroup(QLatin1String("Font Substitutions"));
- QStringList fontsubs = settings.childKeys();
- if (!fontsubs.isEmpty()) {
- QStringList::Iterator it = fontsubs.begin();
- for (; it != fontsubs.end(); ++it) {
- QString fam = *it;
- QStringList subs = settings.value(fam).toStringList();
- QFont::insertSubstitutions(fam, subs);
- }
- }
- settings.endGroup();
- }
-
- qt_use_rtl_extensions =
- settings.value(QLatin1String("useRtlExtensions"), false).toBool();
-
-#ifndef QT_NO_XIM
- if (qt_xim_preferred_style == 0) {
- QString ximInputStyle = settings.value(QLatin1String("XIMInputStyle"),
- QVariant(QLatin1String("on the spot"))).toString().toLower();
- if (ximInputStyle == QLatin1String("on the spot"))
- qt_xim_preferred_style = XIMPreeditCallbacks | XIMStatusNothing;
- else if (ximInputStyle == QLatin1String("over the spot"))
- qt_xim_preferred_style = XIMPreeditPosition | XIMStatusNothing;
- else if (ximInputStyle == QLatin1String("off the spot"))
- qt_xim_preferred_style = XIMPreeditArea | XIMStatusArea;
- else if (ximInputStyle == QLatin1String("root"))
- qt_xim_preferred_style = XIMPreeditNothing | XIMStatusNothing;
- }
-#endif
- QStringList inputMethods = QInputContextFactory::keys();
- if (inputMethods.size() > 2 && inputMethods.contains(QLatin1String("imsw-multi"))) {
- X11->default_im = QLatin1String("imsw-multi");
- } else {
- X11->default_im = settings.value(QLatin1String("DefaultInputMethod"),
- QLatin1String("xim")).toString();
- }
-
- settings.endGroup(); // Qt
-
- return true;
-}
-
-
-/*! \internal
- Resets the QApplication::instance() pointer to zero
-*/
-void QApplicationPrivate::reset_instance_pointer()
-{ QApplication::self = 0; }
-
-
-// read the _QT_INPUT_ENCODING property and apply the settings to
-// the application
-static void qt_set_input_encoding()
-{
- Atom type;
- int format;
- ulong nitems, after = 1;
- unsigned char *data = 0;
-
- int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_QT_INPUT_ENCODING), 0, 1024,
- False, XA_STRING, &type, &format, &nitems,
- &after, &data);
- if (e != Success || !nitems || type == XNone) {
- // Always use the locale codec, since we have no examples of non-local
- // XIMs, and since we cannot get a sensible answer about the encoding
- // from the XIM.
- qt_input_mapper = QTextCodec::codecForLocale();
-
- } else {
- if (!qstricmp((char *)data, "locale"))
- qt_input_mapper = QTextCodec::codecForLocale();
- else
- qt_input_mapper = QTextCodec::codecForName((char *)data);
- // make sure we have an input codec
- if(!qt_input_mapper)
- qt_input_mapper = QTextCodec::codecForName("ISO 8859-1");
- }
- if (qt_input_mapper && qt_input_mapper->mibEnum() == 11) // 8859-8
- qt_input_mapper = QTextCodec::codecForName("ISO 8859-8-I");
- if(data)
- XFree((char *)data);
-}
-
-// set font, foreground and background from x11 resources. The
-// arguments may override the resource settings.
-static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
- const char* bg = 0, const char* button = 0)
-{
-
- QString resFont, resFG, resBG, resButton, resEF, sysFont, selectBackground, selectForeground;
-
- QApplication::setEffectEnabled(Qt::UI_General, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu, false);
- QApplication::setEffectEnabled(Qt::UI_FadeMenu, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, false);
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, false);
-
- bool paletteAlreadySet = false;
- if (QApplication::desktopSettingsAware()) {
- // first, read from settings
- QApplicationPrivate::x11_apply_settings();
- // the call to QApplication::style() below creates the system
- // palette, which breaks the logic after the RESOURCE_MANAGER
- // loop... so I have to save this value to be able to use it later
- paletteAlreadySet = (QApplicationPrivate::sys_pal != 0);
-
- // second, parse the RESOURCE_MANAGER property
- int format;
- ulong nitems, after = 1;
- QString res;
- long offset = 0;
- Atom type = XNone;
-
- while (after > 0) {
- uchar *data = 0;
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(0),
- ATOM(RESOURCE_MANAGER),
- offset, 8192, False, AnyPropertyType,
- &type, &format, &nitems, &after,
- &data) != Success) {
- res = QString();
- break;
- }
- if (type == XA_STRING)
- res += QString::fromLatin1((char*)data);
- else
- res += QString::fromLocal8Bit((char*)data);
- offset += 2048; // offset is in 32bit quantities... 8192/4 == 2048
- if (data)
- XFree((char *)data);
- }
-
- QString key, value;
- int l = 0, r;
- QString apn = QString::fromLocal8Bit(appName);
- QString apc = QString::fromLocal8Bit(appClass);
- int apnl = apn.length();
- int apcl = apc.length();
- int resl = res.length();
-
- while (l < resl) {
- r = res.indexOf(QLatin1Char('\n'), l);
- if (r < 0)
- r = resl;
- while (res.at(l).isSpace())
- l++;
- bool mine = false;
- QChar sc = res.at(l + 1);
- if (res.at(l) == QLatin1Char('*') &&
- (sc == QLatin1Char('f') || sc == QLatin1Char('b') || sc == QLatin1Char('g') ||
- sc == QLatin1Char('F') || sc == QLatin1Char('B') || sc == QLatin1Char('G') ||
- sc == QLatin1Char('s') || sc == QLatin1Char('S')
- // capital T only, since we're looking for "Text.selectSomething"
- || sc == QLatin1Char('T'))) {
- // OPTIMIZED, since we only want "*[fbgsT].."
- QString item = res.mid(l, r - l).simplified();
- int i = item.indexOf(QLatin1Char(':'));
- key = item.left(i).trimmed().mid(1).toLower();
- value = item.right(item.length() - i - 1).trimmed();
- mine = true;
- } else if ((apnl && res.at(l) == apn.at(0)) || (appClass && apcl && res.at(l) == apc.at(0))) {
- if (res.mid(l,apnl) == apn && (res.at(l+apnl) == QLatin1Char('.')
- || res.at(l+apnl) == QLatin1Char('*'))) {
- QString item = res.mid(l, r - l).simplified();
- int i = item.indexOf(QLatin1Char(':'));
- key = item.left(i).trimmed().mid(apnl+1).toLower();
- value = item.right(item.length() - i - 1).trimmed();
- mine = true;
- } else if (res.mid(l,apcl) == apc && (res.at(l+apcl) == QLatin1Char('.')
- || res.at(l+apcl) == QLatin1Char('*'))) {
- QString item = res.mid(l, r - l).simplified();
- int i = item.indexOf(QLatin1Char(':'));
- key = item.left(i).trimmed().mid(apcl+1).toLower();
- value = item.right(item.length() - i - 1).trimmed();
- mine = true;
- }
- }
-
- if (mine) {
- if (!font && key == QLatin1String("systemfont"))
- sysFont = value.left(value.lastIndexOf(QLatin1Char(':')));
- if (!font && key == QLatin1String("font"))
- resFont = value;
- else if (!fg && !paletteAlreadySet) {
- if (key == QLatin1String("foreground"))
- resFG = value;
- else if (!bg && key == QLatin1String("background"))
- resBG = value;
- else if (!bg && !button && key == QLatin1String("button.background"))
- resButton = value;
- else if (key == QLatin1String("text.selectbackground")) {
- selectBackground = value;
- } else if (key == QLatin1String("text.selectforeground")) {
- selectForeground = value;
- }
- } else if (key == QLatin1String("guieffects"))
- resEF = value;
- // NOTE: if you add more, change the [fbg] stuff above
- }
-
- l = r + 1;
- }
- }
- if (!sysFont.isEmpty())
- resFont = sysFont;
- if (resFont.isEmpty())
- resFont = QString::fromLocal8Bit(font);
- if (resFG.isEmpty())
- resFG = QString::fromLocal8Bit(fg);
- if (resBG.isEmpty())
- resBG = QString::fromLocal8Bit(bg);
- if (resButton.isEmpty())
- resButton = QString::fromLocal8Bit(button);
- if (!resFont.isEmpty()
- && !X11->has_fontconfig
- && !QApplicationPrivate::sys_font) {
- // set application font
- QFont fnt;
- fnt.setRawName(resFont);
-
- // the font we get may actually be an alias for another font,
- // so we reset the application font to the real font info.
- if (! fnt.exactMatch()) {
- QFontInfo fontinfo(fnt);
- fnt.setFamily(fontinfo.family());
- fnt.setRawMode(fontinfo.rawMode());
-
- if (! fnt.rawMode()) {
- fnt.setItalic(fontinfo.italic());
- fnt.setWeight(fontinfo.weight());
- fnt.setUnderline(fontinfo.underline());
- fnt.setStrikeOut(fontinfo.strikeOut());
- fnt.setStyleHint(fontinfo.styleHint());
-
- if (fnt.pointSize() <= 0 && fnt.pixelSize() <= 0) {
- // size is all wrong... fix it
- qreal pointSize = fontinfo.pixelSize() * 72. / (float) QX11Info::appDpiY();
- if (pointSize <= 0)
- pointSize = 12;
- fnt.setPointSize(qRound(pointSize));
- }
- }
- }
-
- QApplicationPrivate::setSystemFont(fnt);
- }
- // QGtkStyle sets it's own system palette
- bool gtkStyle = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
- bool kdeColors = (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE);
- if (!gtkStyle && (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty()))) {// set app colors
- bool allowX11ColorNames = QColor::allowX11ColorNames();
- QColor::setAllowX11ColorNames(true);
-
- (void) QApplication::style(); // trigger creation of application style and system palettes
- QColor btn;
- QColor bg;
- QColor fg;
- QColor bfg;
- QColor wfg;
- if (!resBG.isEmpty())
- bg = QColor(resBG);
- if (!bg.isValid())
- bg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Window);
-
- if (!resFG.isEmpty())
- fg = QColor(resFG);
- if (!fg.isValid())
- fg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::WindowText);
-
- if (!resButton.isEmpty())
- btn = QColor(resButton);
- else if (!resBG.isEmpty())
- btn = bg;
- if (!btn.isValid())
- btn = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Button);
-
- int h,s,v;
- fg.getHsv(&h,&s,&v);
- QColor base = Qt::white;
- bool bright_mode = false;
- if (v >= 255 - 50) {
- base = btn.darker(150);
- bright_mode = true;
- }
-
- QPalette pal(fg, btn, btn.lighter(125), btn.darker(130), btn.darker(120), wfg.isValid() ? wfg : fg, Qt::white, base, bg);
- QColor disabled((fg.red() + btn.red()) / 2,
- (fg.green() + btn.green())/ 2,
- (fg.blue() + btn.blue()) / 2);
- pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
- btn.darker(130), btn.darker(150), disabled, Qt::white, Qt::white, bg);
-
- QColor highlight, highlightText;
- if (!selectBackground.isEmpty() && !selectForeground.isEmpty()) {
- highlight = QColor(selectBackground);
- highlightText = QColor(selectForeground);
- }
-
- if (highlight.isValid() && highlightText.isValid()) {
- pal.setColor(QPalette::Highlight, highlight);
- pal.setColor(QPalette::HighlightedText, highlightText);
-
- // calculate disabled colors by removing saturation
- highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
- highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
- pal.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
- } else if (bright_mode) {
- pal.setColor(QPalette::HighlightedText, base);
- pal.setColor(QPalette::Highlight, Qt::white);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
- pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
- } else {
- pal.setColor(QPalette::HighlightedText, Qt::white);
- pal.setColor(QPalette::Highlight, Qt::darkBlue);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
- pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
- }
-
- pal = qt_guiPlatformPlugin()->palette().resolve(pal);
- QApplicationPrivate::setSystemPalette(pal);
- QColor::setAllowX11ColorNames(allowX11ColorNames);
- }
-
- if (!resEF.isEmpty()) {
- QStringList effects = resEF.split(QLatin1Char(' '));
- QApplication::setEffectEnabled(Qt::UI_General, effects.contains(QLatin1String("general")));
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
- effects.contains(QLatin1String("animatemenu")));
- QApplication::setEffectEnabled(Qt::UI_FadeMenu,
- effects.contains(QLatin1String("fademenu")));
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
- effects.contains(QLatin1String("animatecombo")));
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
- effects.contains(QLatin1String("animatetooltip")));
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
- effects.contains(QLatin1String("fadetooltip")));
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
- effects.contains(QLatin1String("animatetoolbox")));
- }
-
- QIconLoader::instance()->updateSystemTheme();
-}
-
-
-// update the supported array
-static void qt_get_net_supported()
-{
- Atom type;
- int format;
- long offset = 0;
- unsigned long nitems, after;
- unsigned char *data = 0;
-
- int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_SUPPORTED), 0, 0,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
- if (data)
- XFree(data);
-
- if (X11->net_supported_list)
- delete [] X11->net_supported_list;
- X11->net_supported_list = 0;
-
- if (e == Success && type == XA_ATOM && format == 32) {
- QBuffer ts;
- ts.open(QIODevice::WriteOnly);
-
- while (after > 0) {
- XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_SUPPORTED), offset, 1024,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
-
- if (type == XA_ATOM && format == 32) {
- ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long));
- offset += nitems;
- } else
- after = 0;
- if (data)
- XFree(data);
- }
-
- // compute nitems
- QByteArray buffer(ts.buffer());
- nitems = buffer.size() / sizeof(Atom);
- X11->net_supported_list = new Atom[nitems + 1];
- Atom *a = (Atom *) buffer.data();
- uint i;
- for (i = 0; i < nitems; i++)
- X11->net_supported_list[i] = a[i];
- X11->net_supported_list[nitems] = 0;
- }
-}
-
-
-bool QX11Data::isSupportedByWM(Atom atom)
-{
- if (!X11->net_supported_list)
- return false;
-
- bool supported = false;
- int i = 0;
- while (X11->net_supported_list[i] != 0) {
- if (X11->net_supported_list[i++] == atom) {
- supported = true;
- break;
- }
- }
-
- return supported;
-}
-
-
-// update the virtual roots array
-static void qt_get_net_virtual_roots()
-{
- if (X11->net_virtual_root_list)
- delete [] X11->net_virtual_root_list;
- X11->net_virtual_root_list = 0;
-
- if (!X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)))
- return;
-
- Atom type;
- int format;
- long offset = 0;
- unsigned long nitems, after;
- unsigned char *data;
-
- int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_VIRTUAL_ROOTS), 0, 0,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
- if (data)
- XFree(data);
-
- if (e == Success && type == XA_ATOM && format == 32) {
- QBuffer ts;
- ts.open(QIODevice::WriteOnly);
-
- while (after > 0) {
- XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_VIRTUAL_ROOTS), offset, 1024,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
-
- if (type == XA_ATOM && format == 32) {
- ts.write(reinterpret_cast<char *>(data), nitems * 4);
- offset += nitems;
- } else
- after = 0;
- if (data)
- XFree(data);
- }
-
- // compute nitems
- QByteArray buffer(ts.buffer());
- nitems = buffer.size() / sizeof(Window);
- X11->net_virtual_root_list = new Window[nitems + 1];
- Window *a = (Window *) buffer.data();
- uint i;
- for (i = 0; i < nitems; i++)
- X11->net_virtual_root_list[i] = a[i];
- X11->net_virtual_root_list[nitems] = 0;
- }
-}
-
-void qt_net_remove_user_time(QWidget *tlw)
-{
- Q_ASSERT(tlw);
- QTLWExtra *extra = tlw->d_func()->maybeTopData();
- if (extra && extra->userTimeWindow) {
- Q_ASSERT(tlw->internalWinId());
- XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW));
- XDestroyWindow(X11->display, extra->userTimeWindow);
- extra->userTimeWindow = 0;
- }
-}
-
-void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp)
-{
- Q_ASSERT(tlw);
- Q_ASSERT(tlw->isWindow());
- Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
- QTLWExtra *extra = tlw->d_func()->topData();
- WId wid = tlw->internalWinId();
- const bool isSupportedByWM = X11->isSupportedByWM(ATOM(_NET_WM_USER_TIME_WINDOW));
- if (extra->userTimeWindow || isSupportedByWM) {
- if (!extra->userTimeWindow) {
- extra->userTimeWindow = XCreateSimpleWindow(X11->display,
- tlw->internalWinId(),
- -1, -1, 1, 1, 0, 0, 0);
- wid = extra->userTimeWindow;
- XChangeProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW),
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&wid, 1);
- XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME));
- } else if (!isSupportedByWM) {
- // WM no longer supports it, then we should remove the
- // _NET_WM_USER_TIME_WINDOW atom.
- qt_net_remove_user_time(tlw);
- } else {
- wid = extra->userTimeWindow;
- }
- }
- XChangeProperty(X11->display, wid, ATOM(_NET_WM_USER_TIME),
- XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &timestamp, 1);
-}
-
-static void qt_check_focus_model()
-{
- Window fw = XNone;
- int unused;
- XGetInputFocus(X11->display, &fw, &unused);
- if (fw == PointerRoot)
- X11->focus_model = QX11Data::FM_PointerRoot;
- else
- X11->focus_model = QX11Data::FM_Other;
-}
-
-#ifndef QT_NO_TABLET
-
-#if !defined (Q_OS_IRIX)
-// from include/Xwacom.h
-# define XWACOM_PARAM_TOOLID 322
-# define XWACOM_PARAM_TOOLSERIAL 323
-
-typedef WACOMCONFIG * (*PtrWacomConfigInit) (Display*, WACOMERRORFUNC);
-typedef WACOMDEVICE * (*PtrWacomConfigOpenDevice) (WACOMCONFIG*, const char*);
-typedef int *(*PtrWacomConfigGetRawParam) (WACOMDEVICE*, int, int*, int, unsigned*);
-typedef int (*PtrWacomConfigCloseDevice) (WACOMDEVICE *);
-typedef void (*PtrWacomConfigTerm) (WACOMCONFIG *);
-
-static PtrWacomConfigInit ptrWacomConfigInit = 0;
-static PtrWacomConfigOpenDevice ptrWacomConfigOpenDevice = 0;
-static PtrWacomConfigGetRawParam ptrWacomConfigGetRawParam = 0;
-static PtrWacomConfigCloseDevice ptrWacomConfigCloseDevice = 0;
-static PtrWacomConfigTerm ptrWacomConfigTerm = 0;
-Q_GLOBAL_STATIC(QByteArray, wacomDeviceName)
-#endif
-
-#endif
-
-/*****************************************************************************
- qt_init() - initializes Qt for X11
- *****************************************************************************/
-
-#if !defined(QT_NO_FONTCONFIG)
-static void getXDefault(const char *group, const char *key, int *val)
-{
- char *str = XGetDefault(X11->display, group, key);
- if (str) {
- char *end = 0;
- int v = strtol(str, &end, 0);
- if (str != end)
- *val = v;
- // otherwise use fontconfig to convert the string to integer
- else
- FcNameConstant((FcChar8 *) str, val);
- }
-}
-
-static void getXDefault(const char *group, const char *key, double *val)
-{
- char *str = XGetDefault(X11->display, group, key);
- if (str) {
- bool ok;
- double v = QByteArray(str).toDouble(&ok);
- if (ok)
- *val = v;
- }
-}
-
-static void getXDefault(const char *group, const char *key, bool *val)
-{
- char *str = XGetDefault(X11->display, group, key);
- if (str) {
- char c = str[0];
- if (isupper((int)c))
- c = tolower(c);
- if (c == 't' || c == 'y' || c == '1')
- *val = true;
- else if (c == 'f' || c == 'n' || c == '0')
- *val = false;
- if (c == 'o') {
- c = str[1];
- if (isupper((int)c))
- c = tolower(c);
- if (c == 'n')
- *val = true;
- if (c == 'f')
- *val = false;
- }
- }
-}
-#endif
-
-// ### This should be static but it isn't because of the friend declaration
-// ### in qpaintdevice.h which then should have a static too but can't have
-// ### it because "storage class specifiers invalid in friend function
-// ### declarations" :-) Ideas anyone?
-void qt_init(QApplicationPrivate *priv, int,
- Display *display, Qt::HANDLE visual, Qt::HANDLE colormap)
-{
- X11 = new QX11Data;
- X11->display = display;
- X11->displayName = 0;
- X11->foreignDisplay = (display != 0);
- X11->focus_model = -1;
-
- // RANDR
- X11->use_xrandr = false;
- X11->xrandr_major = 0;
- X11->xrandr_eventbase = 0;
- X11->xrandr_errorbase = 0;
-
- // RENDER
- X11->use_xrender = false;
- X11->xrender_major = 0;
- X11->xrender_version = 0;
-
- // XFIXES
- X11->use_xfixes = false;
- X11->xfixes_major = 0;
- X11->xfixes_eventbase = 0;
- X11->xfixes_errorbase = 0;
-
- // XInputExtension
- X11->use_xinput = false;
- X11->xinput_major = 0;
- X11->xinput_eventbase = 0;
- X11->xinput_errorbase = 0;
-
- X11->use_xkb = false;
- X11->xkb_major = 0;
- X11->xkb_eventbase = 0;
- X11->xkb_errorbase = 0;
-
- // MIT-SHM
- X11->use_mitshm = false;
- X11->use_mitshm_pixmaps = false;
- X11->mitshm_major = 0;
-
- X11->sip_serial = 0;
- X11->net_supported_list = 0;
- X11->net_virtual_root_list = 0;
- X11->wm_client_leader = 0;
- X11->screens = 0;
- X11->argbVisuals = 0;
- X11->argbColormaps = 0;
- X11->screenCount = 0;
- X11->time = CurrentTime;
- X11->userTime = CurrentTime;
- X11->ignore_badwindow = false;
- X11->seen_badwindow = false;
-
- X11->motifdnd_active = false;
-
- X11->default_im = QLatin1String("imsw-multi");
- priv->inputContext = 0;
-
- // colormap control
- X11->visual_class = -1;
- X11->visual_id = -1;
- X11->color_count = 0;
- X11->custom_cmap = false;
-
- // outside visual/colormap
- X11->visual = reinterpret_cast<Visual *>(visual);
- X11->colormap = colormap;
-
- // Fontconfig
- X11->has_fontconfig = false;
-#if !defined(QT_NO_FONTCONFIG)
- if (qgetenv("QT_X11_NO_FONTCONFIG").isNull())
- X11->has_fontconfig = FcInit();
- X11->fc_antialias = true;
-#endif
-
-#ifndef QT_NO_XRENDER
- memset(X11->solid_fills, 0, sizeof(X11->solid_fills));
- for (int i = 0; i < X11->solid_fill_count; ++i)
- X11->solid_fills[i].screen = -1;
- memset(X11->pattern_fills, 0, sizeof(X11->pattern_fills));
- for (int i = 0; i < X11->pattern_fill_count; ++i)
- X11->pattern_fills[i].screen = -1;
-#endif
-
- X11->startupId = 0;
-
- int argc = priv->argc;
- char **argv = priv->argv;
-
- if (X11->display) {
- // Qt part of other application
-
- // Set application name and class
- appName = qstrdup("Qt-subapplication");
- char *app_class = 0;
- if (argv) {
- const char* p = strrchr(argv[0], '/');
- app_class = qstrdup(p ? p + 1 : argv[0]);
- if (app_class[0])
- app_class[0] = toupper(app_class[0]);
- }
- appClass = app_class;
- } else {
- // Qt controls everything (default)
-
- // With the threaded QML renderer, we always need this.
- XInitThreads();
-
- // Set application name and class
- char *app_class = 0;
- if (argv && argv[0]) {
- const char *p = strrchr(argv[0], '/');
- appName = p ? p + 1 : argv[0];
- app_class = qstrdup(appName);
- if (app_class[0])
- app_class[0] = toupper(app_class[0]);
- }
- appClass = app_class;
- }
-
- // Install default error handlers
- original_x_errhandler = XSetErrorHandler(qt_x_errhandler);
- original_xio_errhandler = XSetIOErrorHandler(qt_xio_errhandler);
-
- // Get command line params
- int j = argc ? 1 : 0;
- for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
- QByteArray arg(argv[i]);
- if (arg == "-display") {
- if (++i < argc && !X11->display)
- X11->displayName = argv[i];
- } else if (arg == "-fn" || arg == "-font") {
- if (++i < argc)
- appFont = argv[i];
- } else if (arg == "-bg" || arg == "-background") {
- if (++i < argc)
- appBGCol = argv[i];
- } else if (arg == "-btn" || arg == "-button") {
- if (++i < argc)
- appBTNCol = argv[i];
- } else if (arg == "-fg" || arg == "-foreground") {
- if (++i < argc)
- appFGCol = argv[i];
- } else if (arg == "-name") {
- if (++i < argc)
- appName = argv[i];
- } else if (arg == "-title") {
- if (++i < argc)
- mwTitle = argv[i];
- } else if (arg == "-geometry") {
- if (++i < argc)
- mwGeometry = argv[i];
- } else if (arg == "-im") {
- if (++i < argc)
- qt_ximServer = argv[i];
- } else if (arg == "-ncols") { // xv and netscape use this name
- if (++i < argc)
- X11->color_count = qMax(0,atoi(argv[i]));
- } else if (arg == "-visual") { // xv and netscape use this name
- if (++i < argc && !X11->visual) {
- QString s = QString::fromLocal8Bit(argv[i]).toLower();
- if (s == QLatin1String("staticgray"))
- X11->visual_class = StaticGray;
- else if (s == QLatin1String("grayscale"))
- X11->visual_class = XGrayScale;
- else if (s == QLatin1String("staticcolor"))
- X11->visual_class = StaticColor;
- else if (s == QLatin1String("pseudocolor"))
- X11->visual_class = PseudoColor;
- else if (s == QLatin1String("truecolor"))
- X11->visual_class = TrueColor;
- else if (s == QLatin1String("directcolor"))
- X11->visual_class = DirectColor;
- else
- X11->visual_id = static_cast<int>(strtol(argv[i], 0, 0));
- }
-#ifndef QT_NO_XIM
- } else if (arg == "-inputstyle") {
- if (++i < argc) {
- QString s = QString::fromLocal8Bit(argv[i]).toLower();
- if (s == QLatin1String("onthespot"))
- qt_xim_preferred_style = XIMPreeditCallbacks |
- XIMStatusNothing;
- else if (s == QLatin1String("overthespot"))
- qt_xim_preferred_style = XIMPreeditPosition |
- XIMStatusNothing;
- else if (s == QLatin1String("offthespot"))
- qt_xim_preferred_style = XIMPreeditArea |
- XIMStatusArea;
- else if (s == QLatin1String("root"))
- qt_xim_preferred_style = XIMPreeditNothing |
- XIMStatusNothing;
- }
-#endif
- } else if (arg == "-cmap") { // xv uses this name
- if (!X11->colormap)
- X11->custom_cmap = true;
- }
- else if (arg == "-sync")
- appSync = !appSync;
-#if defined(QT_DEBUG)
- else if (arg == "-nograb")
- appNoGrab = !appNoGrab;
- else if (arg == "-dograb")
- appDoGrab = !appDoGrab;
-#endif
- else
- argv[j++] = argv[i];
- }
-
- priv->argc = j;
-
-#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
- if (!appNoGrab && !appDoGrab) {
- QString s;
- s.sprintf("/proc/%d/cmdline", getppid());
- QFile f(s);
- if (f.open(QIODevice::ReadOnly)) {
- s.clear();
- char c;
- while (f.getChar(&c) && c) {
- if (c == '/')
- s.clear();
- else
- s += QLatin1Char(c);
- }
- if (s == QLatin1String("gdb")) {
- appNoGrab = true;
- qDebug("Qt: gdb: -nograb added to command-line options.\n"
- "\t Use the -dograb option to enforce grabbing.");
- }
- f.close();
- }
- }
-#endif
-
- // Connect to X server
- if (qt_is_gui_used && !X11->display) {
- if ((X11->display = XOpenDisplay(X11->displayName)) == 0) {
- qWarning("%s: cannot connect to X server %s", appName,
- XDisplayName(X11->displayName));
- QApplicationPrivate::reset_instance_pointer();
- exit(1);
- }
-
- if (appSync) // if "-sync" argument
- XSynchronize(X11->display, true);
- }
-
- // Common code, regardless of whether display is foreign.
-
- // Get X parameters
-
- if (qt_is_gui_used) {
- X11->defaultScreen = DefaultScreen(X11->display);
- X11->screenCount = ScreenCount(X11->display);
-
- X11->screens = new QX11InfoData[X11->screenCount];
- X11->argbVisuals = new Visual *[X11->screenCount];
- X11->argbColormaps = new Colormap[X11->screenCount];
-
- for (int s = 0; s < X11->screenCount; s++) {
- QX11InfoData *screen = X11->screens + s;
- screen->ref = 1; // ensures it doesn't get deleted
- screen->screen = s;
-
- int widthMM = DisplayWidthMM(X11->display, s);
- if (widthMM != 0) {
- screen->dpiX = (DisplayWidth(X11->display, s) * 254 + widthMM * 5) / (widthMM * 10);
- } else {
- screen->dpiX = 72;
- }
-
- int heightMM = DisplayHeightMM(X11->display, s);
- if (heightMM != 0) {
- screen->dpiY = (DisplayHeight(X11->display, s) * 254 + heightMM * 5) / (heightMM * 10);
- } else {
- screen->dpiY = 72;
- }
-
- X11->argbVisuals[s] = 0;
- X11->argbColormaps[s] = 0;
- }
-
-
-#ifndef QT_NO_XRENDER
- int xrender_eventbase, xrender_errorbase;
- // See if XRender is supported on the connected display
- if (XQueryExtension(X11->display, "RENDER", &X11->xrender_major,
- &xrender_eventbase, &xrender_errorbase)
- && XRenderQueryExtension(X11->display, &xrender_eventbase,
- &xrender_errorbase)) {
- // Check the version as well - we need v0.4 or higher
- int major = 0;
- int minor = 0;
- XRenderQueryVersion(X11->display, &major, &minor);
- if (qgetenv("QT_X11_NO_XRENDER").isNull()) {
- X11->use_xrender = (major >= 0 && minor >= 5);
- X11->xrender_version = major*100+minor;
- // workaround for broken XServer on Ubuntu Breezy (6.8 compiled with 7.0
- // protocol headers)
- if (X11->xrender_version == 10
- && VendorRelease(X11->display) < 60900000
- && QByteArray(ServerVendor(X11->display)).contains("X.Org"))
- X11->xrender_version = 9;
- }
- }
-#endif // QT_NO_XRENDER
-
-#ifndef QT_NO_MITSHM
- int mitshm_minor;
- int mitshm_major;
- int mitshm_eventbase;
- int mitshm_errorbase;
- int mitshm_pixmaps;
- if (XQueryExtension(X11->display, "MIT-SHM", &X11->mitshm_major,
- &mitshm_eventbase, &mitshm_errorbase)
- && XShmQueryVersion(X11->display, &mitshm_major, &mitshm_minor,
- &mitshm_pixmaps))
- {
- QString displayName = QLatin1String(XDisplayName(NULL));
-
- // MITSHM only works for local displays, so do a quick check here
- // to determine whether the display is local or not (not 100 % accurate).
- // BGR server layouts are not supported either, since it requires the raster
- // engine to work on a QImage with BGR layout.
- bool local = displayName.isEmpty() || displayName.lastIndexOf(QLatin1Char(':')) == 0;
- if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0)) {
- Visual *defaultVisual = DefaultVisual(X11->display, DefaultScreen(X11->display));
- X11->use_mitshm = ((defaultVisual->red_mask == 0xff0000
- || defaultVisual->red_mask == 0xf800)
- && (defaultVisual->green_mask == 0xff00
- || defaultVisual->green_mask == 0x7e0)
- && (defaultVisual->blue_mask == 0xff
- || defaultVisual->blue_mask == 0x1f));
- X11->use_mitshm_pixmaps = X11->use_mitshm && mitshm_pixmaps;
- }
- }
-#endif // QT_NO_MITSHM
-
- // initialize the graphics system - order is imporant here - it must be done before
- // the QColormap::initialize() call
- QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name);
- QColormap::initialize();
-
- // Support protocols
- X11->xdndSetup();
-
- // Finally create all atoms
- qt_x11_create_intern_atoms();
-
- // initialize NET lists
- qt_get_net_supported();
- qt_get_net_virtual_roots();
-
-#ifndef QT_NO_XRANDR
- // See if XRandR is supported on the connected display
- if (XQueryExtension(X11->display, "RANDR", &X11->xrandr_major,
- &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
-
-# ifdef QT_RUNTIME_XRANDR
- X11->ptrXRRSelectInput = 0;
- X11->ptrXRRUpdateConfiguration = 0;
- X11->ptrXRRRootToScreen = 0;
- X11->ptrXRRQueryExtension = 0;
- QLibrary xrandrLib(QLatin1String("Xrandr"), 2);
- if (!xrandrLib.load()) { // try without the version number
- xrandrLib.setFileName(QLatin1String("Xrandr"));
- xrandrLib.load();
- }
- if (xrandrLib.isLoaded()) {
- X11->ptrXRRSelectInput =
- (PtrXRRSelectInput) xrandrLib.resolve("XRRSelectInput");
- X11->ptrXRRUpdateConfiguration =
- (PtrXRRUpdateConfiguration) xrandrLib.resolve("XRRUpdateConfiguration");
- X11->ptrXRRRootToScreen =
- (PtrXRRRootToScreen) xrandrLib.resolve("XRRRootToScreen");
- X11->ptrXRRQueryExtension =
- (PtrXRRQueryExtension) xrandrLib.resolve("XRRQueryExtension");
- X11->ptrXRRSizes =
- (PtrXRRSizes) xrandrLib.resolve("XRRSizes");
- }
-# else
- X11->ptrXRRSelectInput = XRRSelectInput;
- X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration;
- X11->ptrXRRRootToScreen = XRRRootToScreen;
- X11->ptrXRRQueryExtension = XRRQueryExtension;
- X11->ptrXRRSizes = XRRSizes;
-# endif
-
- if (X11->ptrXRRQueryExtension
- && X11->ptrXRRQueryExtension(X11->display, &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
- // XRandR is supported
- X11->use_xrandr = true;
- }
- }
-#endif // QT_NO_XRANDR
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- // XRender is supported, let's see if we have a PictFormat for the
- // default visual
- XRenderPictFormat *format =
- XRenderFindVisualFormat(X11->display,
- (Visual *) QX11Info::appVisual(X11->defaultScreen));
-
- if (!format) {
- X11->use_xrender = false;
- }
- }
-#endif // QT_NO_XRENDER
-
-#ifndef QT_NO_XFIXES
- // See if Xfixes is supported on the connected display
- if (XQueryExtension(X11->display, "XFIXES", &X11->xfixes_major,
- &X11->xfixes_eventbase, &X11->xfixes_errorbase)) {
- X11->ptrXFixesQueryExtension = XFIXES_LOAD_V1(XFixesQueryExtension);
- X11->ptrXFixesQueryVersion = XFIXES_LOAD_V1(XFixesQueryVersion);
- X11->ptrXFixesSetCursorName = XFIXES_LOAD_V2(XFixesSetCursorName);
- X11->ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput);
-
- if(X11->ptrXFixesQueryExtension && X11->ptrXFixesQueryVersion
- && X11->ptrXFixesQueryExtension(X11->display, &X11->xfixes_eventbase,
- &X11->xfixes_errorbase)) {
- // Xfixes is supported.
- // Note: the XFixes protocol version is negotiated using QueryVersion.
- // We supply the highest version we support, the X server replies with
- // the highest version it supports, but no higher than the version we
- // asked for. The version sent back is the protocol version the X server
- // will use to talk us. If this call is removed, the behavior of the
- // X server when it receives an XFixes request is undefined.
- int major = 3;
- int minor = 0;
- X11->ptrXFixesQueryVersion(X11->display, &major, &minor);
- X11->use_xfixes = (major >= 1);
- X11->xfixes_major = major;
- }
- }
-#endif // QT_NO_XFIXES
-
-#ifndef QT_NO_XCURSOR
-#ifdef QT_RUNTIME_XCURSOR
- X11->ptrXcursorLibraryLoadCursor = 0;
- QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
- bool xcursorFound = xcursorLib.load();
- if (!xcursorFound) { //try without the version number
- xcursorLib.setFileName(QLatin1String("Xcursor"));
- xcursorFound = xcursorLib.load();
- }
- if (xcursorFound) {
- X11->ptrXcursorLibraryLoadCursor =
- (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
- }
-#else
- X11->ptrXcursorLibraryLoadCursor = XcursorLibraryLoadCursor;
-#endif // QT_RUNTIME_XCURSOR
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XSYNC
- int xsync_evbase, xsync_errbase;
- int major, minor;
- if (XSyncQueryExtension(X11->display, &xsync_evbase, &xsync_errbase))
- XSyncInitialize(X11->display, &major, &minor);
-#endif // QT_NO_XSYNC
-
-#ifndef QT_NO_XINERAMA
-#ifdef QT_RUNTIME_XINERAMA
- X11->ptrXineramaQueryExtension = 0;
- X11->ptrXineramaIsActive = 0;
- X11->ptrXineramaQueryScreens = 0;
- QLibrary xineramaLib(QLatin1String("Xinerama"), 1);
- bool xineramaFound = xineramaLib.load();
- if (!xineramaFound) { //try without the version number
- xineramaLib.setFileName(QLatin1String("Xinerama"));
- xineramaFound = xineramaLib.load();
- }
- if (xineramaFound) {
- X11->ptrXineramaQueryExtension =
- (PtrXineramaQueryExtension) xineramaLib.resolve("XineramaQueryExtension");
- X11->ptrXineramaIsActive =
- (PtrXineramaIsActive) xineramaLib.resolve("XineramaIsActive");
- X11->ptrXineramaQueryScreens =
- (PtrXineramaQueryScreens) xineramaLib.resolve("XineramaQueryScreens");
- }
-#else
- X11->ptrXineramaQueryScreens = XineramaQueryScreens;
- X11->ptrXineramaIsActive = XineramaIsActive;
- X11->ptrXineramaQueryExtension = XineramaQueryExtension;
-#endif // QT_RUNTIME_XINERAMA
-#endif // QT_NO_XINERAMA
-
-#ifndef QT_NO_XINPUT
- // See if Xinput is supported on the connected display
- X11->ptrXCloseDevice = 0;
- X11->ptrXListInputDevices = 0;
- X11->ptrXOpenDevice = 0;
- X11->ptrXFreeDeviceList = 0;
- X11->ptrXSelectExtensionEvent = 0;
- X11->use_xinput = XQueryExtension(X11->display, "XInputExtension", &X11->xinput_major,
- &X11->xinput_eventbase, &X11->xinput_errorbase);
- if (X11->use_xinput) {
- X11->ptrXCloseDevice = XINPUT_LOAD(XCloseDevice);
- X11->ptrXListInputDevices = XINPUT_LOAD(XListInputDevices);
- X11->ptrXOpenDevice = XINPUT_LOAD(XOpenDevice);
- X11->ptrXFreeDeviceList = XINPUT_LOAD(XFreeDeviceList);
- X11->ptrXSelectExtensionEvent = XINPUT_LOAD(XSelectExtensionEvent);
- }
-#endif // QT_NO_XINPUT
-
-#ifndef QT_NO_XKB
- int xkblibMajor = XkbMajorVersion;
- int xkblibMinor = XkbMinorVersion;
- X11->use_xkb = XkbQueryExtension(X11->display,
- &X11->xkb_major,
- &X11->xkb_eventbase,
- &X11->xkb_errorbase,
- &xkblibMajor,
- &xkblibMinor);
- if (X11->use_xkb) {
- // If XKB is detected, set the GrabsUseXKBState option so input method
- // compositions continue to work (ie. deadkeys)
- unsigned int state = XkbPCF_GrabsUseXKBStateMask;
- (void) XkbSetPerClientControls(X11->display, state, &state);
-
- // select for group change events
- XkbSelectEventDetails(X11->display,
- XkbUseCoreKbd,
- XkbStateNotify,
- XkbAllStateComponentsMask,
- XkbGroupStateMask);
-
- // current group state is queried when creating the keymapper, no need to do it here
- }
-#endif
-
-
-#if !defined(QT_NO_FONTCONFIG)
- int dpi = 0;
- getXDefault("Xft", FC_DPI, &dpi);
- if (dpi) {
- for (int s = 0; s < ScreenCount(X11->display); ++s) {
- QX11Info::setAppDpiX(s, dpi);
- QX11Info::setAppDpiY(s, dpi);
- }
- }
- double fc_scale = 1.;
- getXDefault("Xft", FC_SCALE, &fc_scale);
- X11->fc_scale = fc_scale;
- for (int s = 0; s < ScreenCount(X11->display); ++s) {
- int subpixel = FC_RGBA_UNKNOWN;
-#if !defined(QT_NO_XRENDER) && (RENDER_MAJOR > 0 || RENDER_MINOR >= 6)
- if (X11->use_xrender) {
- int rsp = XRenderQuerySubpixelOrder(X11->display, s);
- switch (rsp) {
- default:
- case SubPixelUnknown:
- subpixel = FC_RGBA_UNKNOWN;
- break;
- case SubPixelHorizontalRGB:
- subpixel = FC_RGBA_RGB;
- break;
- case SubPixelHorizontalBGR:
- subpixel = FC_RGBA_BGR;
- break;
- case SubPixelVerticalRGB:
- subpixel = FC_RGBA_VRGB;
- break;
- case SubPixelVerticalBGR:
- subpixel = FC_RGBA_VBGR;
- break;
- case SubPixelNone:
- subpixel = FC_RGBA_NONE;
- break;
- }
- }
-#endif
-
- char *rgba = XGetDefault(X11->display, "Xft", FC_RGBA);
- if (rgba) {
- char *end = 0;
- int v = strtol(rgba, &end, 0);
- if (rgba != end) {
- subpixel = v;
- } else if (qstrncmp(rgba, "unknown", 7) == 0) {
- subpixel = FC_RGBA_UNKNOWN;
- } else if (qstrncmp(rgba, "rgb", 3) == 0) {
- subpixel = FC_RGBA_RGB;
- } else if (qstrncmp(rgba, "bgr", 3) == 0) {
- subpixel = FC_RGBA_BGR;
- } else if (qstrncmp(rgba, "vrgb", 4) == 0) {
- subpixel = FC_RGBA_VRGB;
- } else if (qstrncmp(rgba, "vbgr", 4) == 0) {
- subpixel = FC_RGBA_VBGR;
- } else if (qstrncmp(rgba, "none", 4) == 0) {
- subpixel = FC_RGBA_NONE;
- }
- }
- X11->screens[s].subpixel = subpixel;
- }
- getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias);
-#ifdef FC_HINT_STYLE
- X11->fc_hint_style = -1;
- getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style);
-#endif
-#if 0
- // ###### these are implemented by Xft, not sure we need them
- getXDefault("Xft", FC_AUTOHINT, &X11->fc_autohint);
- getXDefault("Xft", FC_HINTING, &X11->fc_autohint);
- getXDefault("Xft", FC_MINSPACE, &X11->fc_autohint);
-#endif
-#endif // QT_NO_XRENDER
-
- // initialize key mapper
- QKeyMapper::changeKeyboard();
-
- // Misc. initialization
-#if 0 //disabled for now..
- QSegfaultHandler::initialize(priv->argv, priv->argc);
-#endif
- QCursorData::initialize();
- }
- QFont::initialize();
-
- if(qt_is_gui_used) {
- qApp->setObjectName(QString::fromLocal8Bit(appName));
-
- int screen;
- for (screen = 0; screen < X11->screenCount; ++screen) {
- XSelectInput(X11->display, QX11Info::appRootWindow(screen),
- KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask);
-
-#ifndef QT_NO_XRANDR
- if (X11->use_xrandr)
- X11->ptrXRRSelectInput(X11->display, QX11Info::appRootWindow(screen), True);
-#endif // QT_NO_XRANDR
- }
- }
-
- if (qt_is_gui_used) {
- // Attempt to determine the current running X11 Desktop Enviornment
- // Use dbus if/when we can, but fall back to using windowManagerName() for now
-
-#ifndef QT_NO_XFIXES
- if (X11->ptrXFixesSelectSelectionInput)
- X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(), ATOM(_NET_WM_CM_S0),
- XFixesSetSelectionOwnerNotifyMask
- | XFixesSelectionWindowDestroyNotifyMask
- | XFixesSelectionClientCloseNotifyMask);
-#endif // QT_NO_XFIXES
- X11->compositingManagerRunning = XGetSelectionOwner(X11->display,
- ATOM(_NET_WM_CM_S0));
- X11->desktopEnvironment = DE_UNKNOWN;
- X11->desktopVersion = 0;
-
- Atom type;
- int format;
- unsigned long length, after;
- uchar *data = 0;
- int rc;
-
- do {
- if (!qgetenv("KDE_FULL_SESSION").isEmpty()) {
- X11->desktopEnvironment = DE_KDE;
- X11->desktopVersion = qgetenv("KDE_SESSION_VERSION").toInt();
- break;
- }
-
- if (qgetenv("DESKTOP_SESSION") == "gnome") {
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
- if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE),
- 0, 2, False, XA_STRING, &type, &format, &length,
- &after, &data);
- if (rc == Success && length) {
- if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) {
- // Pretend that xfce4 is gnome, as it uses the same libraries.
- // The detection above is stolen from xdg-open.
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- // We got the property but it wasn't xfce4. Free data before it gets overwritten.
- XFree(data);
- data = 0;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
- 0, 1, False, AnyPropertyType, &type, &format, &length,
- &after, &data);
- if (rc == Success && length) {
- // DTWM is running, meaning most likely CDE is running...
- X11->desktopEnvironment = DE_CDE;
- break;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_SGI_DESKS_MANAGER), 0, 1, False, XA_WINDOW,
- &type, &format, &length, &after, &data);
- if (rc == Success && length) {
- X11->desktopEnvironment = DE_4DWM;
- break;
- }
-
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_SUPPORTING_WM_CHECK),
- 0, 1024, False, XA_WINDOW, &type,
- &format, &length, &after, &data) == Success) {
- if (type == XA_WINDOW && format == 32) {
- Window windowManagerWindow = *((Window*) data);
- XFree(data);
- data = 0;
-
- if (windowManagerWindow != XNone) {
- Atom utf8atom = ATOM(UTF8_STRING);
- if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
- 0, 1024, False, utf8atom, &type,
- &format, &length, &after, &data) == Success) {
- if (type == utf8atom && format == 8) {
- if (qstrcmp((const char *)data, "MCompositor") == 0)
- X11->desktopEnvironment = DE_MEEGO_COMPOSITOR;
- }
- }
- }
- }
- }
-
- } while(0);
-
- if (data)
- XFree((char *)data);
-
-#if !defined(QT_NO_STYLE_GTK)
- if (X11->desktopEnvironment == DE_GNOME) {
- static bool menusHaveIcons = QGtkStyle::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true);
- QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons);
- }
-#endif
- qt_set_input_encoding();
-
- qt_set_x11_resources(appFont, appFGCol, appBGCol, appBTNCol);
-
- // be smart about the size of the default font. most X servers have helvetica
- // 12 point available at 2 resolutions:
- // 75dpi (12 pixels) and 100dpi (17 pixels).
- // At 95 DPI, a 12 point font should be 16 pixels tall - in which case a 17
- // pixel font is a closer match than a 12 pixel font
- int ptsz = (X11->use_xrender
- ? 9
- : (int) (((QX11Info::appDpiY() >= 95 ? 17. : 12.) *
- 72. / (float) QX11Info::appDpiY()) + 0.5));
-
- if (!QApplicationPrivate::sys_font) {
- // no font from settings or RESOURCE_MANAGER, provide a fallback
- QFont f(X11->has_fontconfig ? QLatin1String("Sans Serif") : QLatin1String("Helvetica"),
- ptsz);
- QApplicationPrivate::setSystemFont(f);
- }
-
-#if !defined (QT_NO_TABLET)
- if (X11->use_xinput) {
- int ndev,
- i,
- j;
- bool gotStylus,
- gotEraser;
- XDeviceInfo *devices = 0, *devs;
- XInputClassInfo *ip;
- XAnyClassPtr any;
- XValuatorInfoPtr v;
- XAxisInfoPtr a;
- XDevice *dev = 0;
-
- if (X11->ptrXListInputDevices) {
- devices = X11->ptrXListInputDevices(X11->display, &ndev);
- if (!devices)
- qWarning("QApplication: Failed to get list of tablet devices");
- }
- if (!devices)
- ndev = -1;
- QTabletEvent::TabletDevice deviceType;
- for (devs = devices, i = 0; i < ndev && devs; i++, devs++) {
- dev = 0;
- deviceType = QTabletEvent::NoDevice;
- gotStylus = false;
- gotEraser = false;
-
-#if defined(Q_OS_IRIX)
- QString devName = QString::fromLocal8Bit(devs->name).toLower();
- if (devName == QLatin1String(WACOM_NAME)) {
- deviceType = QTabletEvent::Stylus;
- gotStylus = true;
- }
-#else
- if (devs->type == ATOM(XWacomStylus) || devs->type == ATOM(XTabletStylus)) {
- deviceType = QTabletEvent::Stylus;
- if (wacomDeviceName()->isEmpty())
- wacomDeviceName()->append(devs->name);
- gotStylus = true;
- } else if (devs->type == ATOM(XWacomEraser) || devs->type == ATOM(XTabletEraser)) {
- deviceType = QTabletEvent::XFreeEraser;
- gotEraser = true;
- }
-#endif
- if (deviceType == QTabletEvent::NoDevice)
- continue;
-
- if (gotStylus || gotEraser) {
- if (X11->ptrXOpenDevice)
- dev = X11->ptrXOpenDevice(X11->display, devs->id);
-
- if (!dev)
- continue;
-
- QTabletDeviceData device_data;
- device_data.deviceType = deviceType;
- device_data.eventCount = 0;
- device_data.device = dev;
- device_data.xinput_motion = -1;
- device_data.xinput_key_press = -1;
- device_data.xinput_key_release = -1;
- device_data.xinput_button_press = -1;
- device_data.xinput_button_release = -1;
- device_data.xinput_proximity_in = -1;
- device_data.xinput_proximity_out = -1;
- device_data.widgetToGetPress = 0;
-
- if (dev->num_classes > 0) {
- for (ip = dev->classes, j = 0; j < dev->num_classes;
- ip++, j++) {
- switch (ip->input_class) {
- case KeyClass:
- DeviceKeyPress(dev, device_data.xinput_key_press,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- DeviceKeyRelease(dev, device_data.xinput_key_release,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- break;
- case ButtonClass:
- DeviceButtonPress(dev, device_data.xinput_button_press,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- DeviceButtonRelease(dev, device_data.xinput_button_release,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- break;
- case ValuatorClass:
- // I'm only going to be interested in motion when the
- // stylus is already down anyway!
- DeviceMotionNotify(dev, device_data.xinput_motion,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- ProximityIn(dev, device_data.xinput_proximity_in, device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- ProximityOut(dev, device_data.xinput_proximity_out, device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- default:
- break;
- }
- }
- }
-
- // get the min/max value for pressure!
- any = (XAnyClassPtr) (devs->inputclassinfo);
- for (j = 0; j < devs->num_classes; j++) {
- if (any->c_class == ValuatorClass) {
- v = (XValuatorInfoPtr) any;
- a = (XAxisInfoPtr) ((char *) v +
- sizeof (XValuatorInfo));
-#if defined (Q_OS_IRIX)
- // I'm not exaclty wild about this, but the
- // dimensions of the tablet are more relevant here
- // than the min and max values from the axis
- // (actually it seems to be 2/3 or what is in the
- // axis. So we'll try to parse it from this
- // string. --tws
- char returnString[SGIDeviceRtrnLen];
- int tmp;
- if (XSGIMiscQueryExtension(X11->display, &tmp, &tmp)
- && XSGIDeviceQuery(X11->display, devs->id,
- "dimensions", returnString)) {
- QString str = QLatin1String(returnString);
- int comma = str.indexOf(',');
- device_data.minX = 0;
- device_data.minY = 0;
- device_data.maxX = str.left(comma).toInt();
- device_data.maxY = str.mid(comma + 1).toInt();
- } else {
- device_data.minX = a[WAC_XCOORD_I].min_value;
- device_data.maxX = a[WAC_XCOORD_I].max_value;
- device_data.minY = a[WAC_YCOORD_I].min_value;
- device_data.maxY = a[WAC_YCOORD_I].max_value;
- }
- device_data.minPressure = a[WAC_PRESSURE_I].min_value;
- device_data.maxPressure = a[WAC_PRESSURE_I].max_value;
- device_data.minTanPressure = a[WAC_TAN_PRESSURE_I].min_value;
- device_data.maxTanPressure = a[WAC_TAN_PRESSURE_I].max_value;
- device_data.minZ = a[WAC_ZCOORD_I].min_value;
- device_data.maxZ = a[WAC_ZCOORD_I].max_value;
-#else
- device_data.minX = a[0].min_value;
- device_data.maxX = a[0].max_value;
- device_data.minY = a[1].min_value;
- device_data.maxY = a[1].max_value;
- device_data.minPressure = a[2].min_value;
- device_data.maxPressure = a[2].max_value;
- device_data.minTanPressure = 0;
- device_data.maxTanPressure = 0;
- device_data.minZ = 0;
- device_data.maxZ = 0;
-#endif
-
- // got the max pressure no need to go further...
- break;
- }
- any = (XAnyClassPtr) ((char *) any + any->length);
- } // end of for loop
-
- tablet_devices()->append(device_data);
- } // if (gotStylus || gotEraser)
- }
- if (X11->ptrXFreeDeviceList)
- X11->ptrXFreeDeviceList(devices);
- }
-#endif // QT_NO_TABLET
-
- X11->startupId = getenv("DESKTOP_STARTUP_ID");
- if (X11->startupId) {
-#ifndef QT_NO_UNSETENV
- unsetenv("DESKTOP_STARTUP_ID");
-#else
- // it's a small memory leak, however we won't crash if Qt is
- // unloaded and someones tries to use the envoriment.
- putenv(strdup("DESKTOP_STARTUP_ID="));
-#endif
- }
- } else {
- // read some non-GUI settings when not using the X server...
-
- if (QApplication::desktopSettingsAware()) {
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
-
- // read library (ie. plugin) path list
- QString libpathkey = QString::fromLatin1("%1.%2/libraryPath")
- .arg(QT_VERSION >> 16)
- .arg((QT_VERSION & 0xff00) >> 8);
- QStringList pathlist =
- settings.value(libpathkey).toString().split(QLatin1Char(':'));
- if (! pathlist.isEmpty()) {
- QStringList::ConstIterator it = pathlist.constBegin();
- while (it != pathlist.constEnd())
- QApplication::addLibraryPath(*it++);
- }
-
- QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
- QVariant(QLatin1String("none"))).toString();
- if (defaultcodec != QLatin1String("none")) {
- QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
- if (codec)
- QTextCodec::setCodecForTr(codec);
- }
-
- settings.endGroup(); // Qt
- }
- }
-
-#if !defined (Q_OS_IRIX) && !defined (QT_NO_TABLET)
- QLibrary wacom(QString::fromLatin1("wacomcfg"), 0); // version 0 is the latest release at time of writing this.
- // NOTE: C casts instead of reinterpret_cast for GCC 3.3.x
- ptrWacomConfigInit = (PtrWacomConfigInit)wacom.resolve("WacomConfigInit");
- ptrWacomConfigOpenDevice = (PtrWacomConfigOpenDevice)wacom.resolve("WacomConfigOpenDevice");
- ptrWacomConfigGetRawParam = (PtrWacomConfigGetRawParam)wacom.resolve("WacomConfigGetRawParam");
- ptrWacomConfigCloseDevice = (PtrWacomConfigCloseDevice)wacom.resolve("WacomConfigCloseDevice");
- ptrWacomConfigTerm = (PtrWacomConfigTerm)wacom.resolve("WacomConfigTerm");
-
- if (ptrWacomConfigInit == 0 || ptrWacomConfigOpenDevice == 0 || ptrWacomConfigGetRawParam == 0
- || ptrWacomConfigCloseDevice == 0 || ptrWacomConfigTerm == 0) { // either we have all, or we have none.
- ptrWacomConfigInit = 0;
- ptrWacomConfigOpenDevice = 0;
- ptrWacomConfigGetRawParam = 0;
- ptrWacomConfigCloseDevice = 0;
- ptrWacomConfigTerm = 0;
- }
-#endif
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
-}
-
-/*****************************************************************************
- qt_cleanup() - cleans up when the application is finished
- *****************************************************************************/
-
-void qt_cleanup()
-{
- if (app_save_rootinfo) // root window must keep state
- qt_save_rootinfo();
-
- if (qt_is_gui_used) {
- QPixmapCache::clear();
- QCursorData::cleanup();
- QFont::cleanup();
- QColormap::cleanup();
-
-#if !defined (QT_NO_TABLET)
- QTabletDeviceDataList *devices = qt_tablet_devices();
- if (X11->ptrXCloseDevice)
- for (int i = 0; i < devices->size(); ++i)
- X11->ptrXCloseDevice(X11->display, (XDevice*)devices->at(i).device);
- devices->clear();
-#endif
- }
-
-#ifndef QT_NO_XRENDER
- for (int i = 0; i < X11->solid_fill_count; ++i) {
- if (X11->solid_fills[i].picture)
- XRenderFreePicture(X11->display, X11->solid_fills[i].picture);
- }
- for (int i = 0; i < X11->pattern_fill_count; ++i) {
- if (X11->pattern_fills[i].picture)
- XRenderFreePicture(X11->display, X11->pattern_fills[i].picture);
- }
-#endif
-
-#if !defined(QT_NO_IM)
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = 0;
-#endif
-
- // Reset the error handlers
- if (qt_is_gui_used)
- XSync(X11->display, False); // sync first to process all possible errors
- XSetErrorHandler(original_x_errhandler);
- XSetIOErrorHandler(original_xio_errhandler);
-
- if (X11->argbColormaps) {
- for (int s = 0; s < X11->screenCount; s++) {
- if (X11->argbColormaps[s])
- XFreeColormap(X11->display, X11->argbColormaps[s]);
- }
- }
-
- if (qt_is_gui_used && !X11->foreignDisplay)
- XCloseDisplay(X11->display); // close X display
- X11->display = 0;
-
- delete [] X11->screens;
- delete [] X11->argbVisuals;
- delete [] X11->argbColormaps;
-
- if (X11->foreignDisplay) {
- delete [] (char *)appName;
- appName = 0;
- }
-
- delete [] (char *)appClass;
- appClass = 0;
-
- if (X11->net_supported_list)
- delete [] X11->net_supported_list;
- X11->net_supported_list = 0;
-
- if (X11->net_virtual_root_list)
- delete [] X11->net_virtual_root_list;
- X11->net_virtual_root_list = 0;
-
- delete X11;
- X11 = 0;
-}
-
-
-/*****************************************************************************
- Platform specific global and internal functions
- *****************************************************************************/
-
-void qt_save_rootinfo() // save new root info
-{
- Atom type;
- int format;
- unsigned long length, after;
- uchar *data = 0;
-
- if (ATOM(_XSETROOT_ID)) { // kill old pixmap
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_XSETROOT_ID), 0, 1,
- True, AnyPropertyType, &type, &format,
- &length, &after, &data) == Success) {
- if (type == XA_PIXMAP && format == 32 && length == 1 &&
- after == 0 && data) {
- XKillClient(X11->display, *((Pixmap*)data));
- }
- Pixmap dummy = XCreatePixmap(X11->display, QX11Info::appRootWindow(),
- 1, 1, 1);
- XChangeProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_XSETROOT_ID), XA_PIXMAP, 32,
- PropModeReplace, (uchar *)&dummy, 1);
- XSetCloseDownMode(X11->display, RetainPermanent);
- }
- }
- if (data)
- XFree((char *)data);
-}
-
-void qt_updated_rootinfo()
-{
- app_save_rootinfo = true;
-}
-
-// ### Cleanup, this function is not in use!
-bool qt_wstate_iconified(WId winid)
-{
- Atom type;
- int format;
- unsigned long length, after;
- uchar *data = 0;
- int r = XGetWindowProperty(X11->display, winid, ATOM(WM_STATE), 0, 2,
- False, AnyPropertyType, &type, &format,
- &length, &after, &data);
- bool iconic = false;
- if (r == Success && data && format == 32) {
- // quint32 *wstate = (quint32*)data;
- unsigned long *wstate = (unsigned long *) data;
- iconic = (*wstate == IconicState);
- XFree((char *)data);
- }
- return iconic;
-}
-
-QString QApplicationPrivate::appName() const
-{
- return QString::fromLocal8Bit(QT_PREPEND_NAMESPACE(appName));
-}
-
-const char *QX11Info::appClass() // get application class
-{
- return QT_PREPEND_NAMESPACE(appClass);
-}
-
-bool qt_nograb() // application no-grab option
-{
-#if defined(QT_DEBUG)
- return appNoGrab;
-#else
- return false;
-#endif
-}
-
-
-/*****************************************************************************
- Platform specific QApplication members
- *****************************************************************************/
-
-
-void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_widget)
-{
- static bool beenHereDoneThat = false;
- if (beenHereDoneThat)
- return;
- beenHereDoneThat = true;
- Q_ASSERT(main_widget->testAttribute(Qt::WA_WState_Created));
- if (mwTitle) {
- XStoreName(X11->display, main_widget->effectiveWinId(), (char*)mwTitle);
- QByteArray net_wm_name = QString::fromLocal8Bit(mwTitle).toUtf8();
- XChangeProperty(X11->display, main_widget->effectiveWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
- PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
- }
- if (mwGeometry) { // parse geometry
- int x, y;
- int w, h;
- int m = XParseGeometry((char*)mwGeometry, &x, &y, (uint*)&w, (uint*)&h);
- QSize minSize = main_widget->minimumSize();
- QSize maxSize = main_widget->maximumSize();
- if ((m & XValue) == 0)
- x = main_widget->geometry().x();
- if ((m & YValue) == 0)
- y = main_widget->geometry().y();
- if ((m & WidthValue) == 0)
- w = main_widget->width();
- if ((m & HeightValue) == 0)
- h = main_widget->height();
- w = qMin(w,maxSize.width());
- h = qMin(h,maxSize.height());
- w = qMax(w,minSize.width());
- h = qMax(h,minSize.height());
- if ((m & XNegative)) {
- x = QApplication::desktop()->width() + x - w;
- }
- if ((m & YNegative)) {
- y = QApplication::desktop()->height() + y - h;
- }
- main_widget->setGeometry(x, y, w, h);
- }
-}
-
-#ifndef QT_NO_CURSOR
-
-/*****************************************************************************
- QApplication cursor stack
- *****************************************************************************/
-
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
-
- QWidgetList all = allWidgets();
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- register QWidget *w = *it;
- if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
- qt_x11_enforce_cursor(w);
- }
- XFlush(X11->display); // make X execute it NOW
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
-
- if (QWidgetPrivate::mapper != 0 && !closingDown()) {
- QWidgetList all = allWidgets();
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- register QWidget *w = *it;
- if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
- qt_x11_enforce_cursor(w);
- }
- XFlush(X11->display);
- }
-}
-
-#endif
-
-
-/*****************************************************************************
- Routines to find a Qt widget from a screen position
- *****************************************************************************/
-
-Window QX11Data::findClientWindow(Window win, Atom property, bool leaf)
-{
- Atom type = XNone;
- int format, i;
- ulong nitems, after;
- uchar *data = 0;
- Window root, parent, target=0, *children=0;
- uint nchildren;
- if (XGetWindowProperty(X11->display, win, property, 0, 0, false, AnyPropertyType,
- &type, &format, &nitems, &after, &data) == Success) {
- if (data)
- XFree((char *)data);
- if (type)
- return win;
- }
- if (!XQueryTree(X11->display,win,&root,&parent,&children,&nchildren)) {
- if (children)
- XFree((char *)children);
- return 0;
- }
- for (i=nchildren-1; !target && i >= 0; i--)
- target = X11->findClientWindow(children[i], property, leaf);
- if (children)
- XFree((char *)children);
- return target;
-}
-
-QWidget *QApplication::topLevelAt(const QPoint &p)
-{
-#ifdef QT_NO_CURSOR
- Q_UNUSED(p);
- return 0;
-#else
- int screen = QCursor::x11Screen();
- int unused;
-
- int x = p.x();
- int y = p.y();
- Window target;
- if (!XTranslateCoordinates(X11->display,
- QX11Info::appRootWindow(screen),
- QX11Info::appRootWindow(screen),
- x, y, &unused, &unused, &target)) {
- return 0;
- }
- if (!target || target == QX11Info::appRootWindow(screen))
- return 0;
- QWidget *w;
- w = QWidget::find((WId)target);
-
- if (!w) {
- X11->ignoreBadwindow();
- target = X11->findClientWindow(target, ATOM(WM_STATE), true);
- if (X11->badwindow())
- return 0;
- w = QWidget::find((WId)target);
- if (!w) {
- // Perhaps the widget at (x,y) is inside a foreign application?
- // Search all toplevel widgets to see if one is within target
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; i < list.count(); ++i) {
- QWidget *widget = list.at(i);
- Window ctarget = target;
- if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- Window wid = widget->internalWinId();
- while (ctarget && !w) {
- X11->ignoreBadwindow();
- if (!XTranslateCoordinates(X11->display,
- QX11Info::appRootWindow(screen),
- ctarget, x, y, &unused, &unused, &ctarget)
- || X11->badwindow())
- break;
- if (ctarget == wid) {
- // Found!
- w = widget;
- break;
- }
- }
- }
- if (w)
- break;
- }
- }
- }
- return w ? w->window() : 0;
-#endif
-}
-
-void QApplication::syncX()
-{
- if (X11->display)
- XSync(X11->display, False); // don't discard events
-}
-
-
-void QApplication::beep()
-{
- if (X11->display)
- XBell(X11->display, 0);
- else
- printf("\7");
-}
-
-void QApplication::alert(QWidget *widget, int msec)
-{
- if (!QApplicationPrivate::checkInstance("alert"))
- return;
-
- QWidgetList windowsToMark;
- if (!widget) {
- windowsToMark += topLevelWidgets();
- } else {
- windowsToMark.append(widget->window());
- }
-
- for (int i = 0; i < windowsToMark.size(); ++i) {
- QWidget *window = windowsToMark.at(i);
- if (!window->isActiveWindow()) {
- qt_change_net_wm_state(window, true, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
- if (msec != 0) {
- QTimer *timer = new QTimer(qApp);
- timer->setSingleShot(true);
- connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
- if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(window)) {
- qApp->d_func()->alertTimerHash.remove(window);
- delete oldTimer;
- }
- qApp->d_func()->alertTimerHash.insert(window, timer);
- timer->start(msec);
- }
- }
- }
-}
-
-void QApplicationPrivate::_q_alertTimeOut()
-{
- if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
- QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
- while (it != alertTimerHash.end()) {
- if (it.value() == timer) {
- QWidget *window = it.key();
- qt_change_net_wm_state(window, false, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
- alertTimerHash.erase(it);
- timer->deleteLater();
- break;
- }
- ++it;
- }
- }
-}
-
-/*****************************************************************************
- Special lookup functions for windows that have been reparented recently
- *****************************************************************************/
-
-static QWidgetMapper *wPRmapper = 0; // alternative widget mapper
-
-void qPRCreate(const QWidget *widget, Window oldwin)
-{ // QWidget::reparent mechanism
- if (!wPRmapper)
- wPRmapper = new QWidgetMapper;
-
- QETWidget *w = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
- wPRmapper->insert((int)oldwin, w); // add old window to mapper
- w->setAttribute(Qt::WA_WState_Reparented); // set reparented flag
-}
-
-void qPRCleanup(QWidget *widget)
-{
- QETWidget *etw = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
- if (!(wPRmapper && widget->testAttribute(Qt::WA_WState_Reparented)))
- return; // not a reparented widget
- QWidgetMapper::Iterator it = wPRmapper->begin();
- while (it != wPRmapper->constEnd()) {
- QWidget *w = *it;
- if (w == etw) { // found widget
- etw->setAttribute(Qt::WA_WState_Reparented, false); // clear flag
- it = wPRmapper->erase(it);// old window no longer needed
- } else {
- ++it;
- }
- }
- if (wPRmapper->size() == 0) { // became empty
- delete wPRmapper; // then reset alt mapper
- wPRmapper = 0;
- }
-}
-
-static QETWidget *qPRFindWidget(Window oldwin)
-{
- return wPRmapper ? (QETWidget*)wPRmapper->value((int)oldwin, 0) : 0;
-}
-
-int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
-{
- if (w && !w->internalWinId())
- return 0;
- QETWidget *widget = (QETWidget*)w;
- if (event->xclient.format == 32 && event->xclient.message_type) {
- if (event->xclient.message_type == ATOM(WM_PROTOCOLS)) {
- Atom a = event->xclient.data.l[0];
- if (a == ATOM(WM_DELETE_WINDOW)) {
- if (passive_only) return 0;
- widget->translateCloseEvent(event);
- }
- else if (a == ATOM(WM_TAKE_FOCUS)) {
- if ((ulong) event->xclient.data.l[1] > X11->time)
- X11->time = event->xclient.data.l[1];
- QWidget *amw = activeModalWidget();
- if (amw && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus))
- amw = 0;
- if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) {
- QWidget *p = amw->parentWidget();
- while (p && p != widget)
- p = p->parentWidget();
- if (!p || !X11->net_supported_list)
- amw->raise(); // help broken window managers
- amw->activateWindow();
- }
-#ifndef QT_NO_WHATSTHIS
- } else if (a == ATOM(_NET_WM_CONTEXT_HELP)) {
- QWhatsThis::enterWhatsThisMode();
-#endif // QT_NO_WHATSTHIS
- } else if (a == ATOM(_NET_WM_PING)) {
- // avoid send/reply loops
- Window root = RootWindow(X11->display, w->x11Info().screen());
- if (event->xclient.window != root) {
- event->xclient.window = root;
- XSendEvent(event->xclient.display, event->xclient.window,
- False, SubstructureNotifyMask|SubstructureRedirectMask, event);
- }
-#ifndef QT_NO_XSYNC
- } else if (a == ATOM(_NET_WM_SYNC_REQUEST)) {
- const ulong timestamp = (const ulong) event->xclient.data.l[1];
- if (timestamp > X11->time)
- X11->time = timestamp;
- if (QTLWExtra *tlw = w->d_func()->maybeTopData()) {
- if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
- tlw->syncRequestTimestamp = timestamp;
- tlw->newCounterValueLo = event->xclient.data.l[2];
- tlw->newCounterValueHi = event->xclient.data.l[3];
- }
- }
-#endif
- }
- } else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
- widget->translateScrollDoneEvent(event);
- } else if (event->xclient.message_type == ATOM(XdndPosition)) {
- X11->xdndHandlePosition(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndEnter)) {
- X11->xdndHandleEnter(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndStatus)) {
- X11->xdndHandleStatus(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndLeave)) {
- X11->xdndHandleLeave(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndDrop)) {
- X11->xdndHandleDrop(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndFinished)) {
- X11->xdndHandleFinished(widget, event, passive_only);
- } else {
- if (passive_only) return 0;
- // All other are interactions
- }
- } else {
- X11->motifdndHandle(widget, event, passive_only);
- }
-
- return 0;
-}
-
-int QApplication::x11ProcessEvent(XEvent* event)
-{
- Q_D(QApplication);
- QScopedLoopLevelCounter loopLevelCounter(d->threadData);
-
-#ifdef ALIEN_DEBUG
- //qDebug() << "QApplication::x11ProcessEvent:" << event->type;
-#endif
- switch (event->type) {
- case ButtonPress:
- pressed_window = event->xbutton.window;
- X11->userTime = event->xbutton.time;
- // fallthrough intended
- case ButtonRelease:
- X11->time = event->xbutton.time;
- break;
- case MotionNotify:
- X11->time = event->xmotion.time;
- break;
- case XKeyPress:
- X11->userTime = event->xkey.time;
- // fallthrough intended
- case XKeyRelease:
- X11->time = event->xkey.time;
- break;
- case PropertyNotify:
- X11->time = event->xproperty.time;
- break;
- case EnterNotify:
- case LeaveNotify:
- X11->time = event->xcrossing.time;
- break;
- case SelectionClear:
- X11->time = event->xselectionclear.time;
- break;
- default:
- break;
- }
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
- XFixesSelectionNotifyEvent *req =
- reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
- X11->time = req->selection_timestamp;
- if (req->selection == ATOM(_NET_WM_CM_S0))
- X11->compositingManagerRunning = req->owner;
- }
-#endif
-
- QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window);
-
- if (wPRmapper) { // just did a widget reparent?
- if (widget == 0) { // not in std widget mapper
- switch (event->type) { // only for mouse/key events
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case XKeyPress:
- case XKeyRelease:
- widget = qPRFindWidget(event->xany.window);
- break;
- }
- }
- else if (widget->testAttribute(Qt::WA_WState_Reparented))
- qPRCleanup(widget); // remove from alt mapper
- }
-
- QETWidget *keywidget=0;
- bool grabbed=false;
- if (event->type==XKeyPress || event->type==XKeyRelease) {
- keywidget = (QETWidget*)QWidget::keyboardGrabber();
- if (keywidget) {
- grabbed = true;
- } else if (!keywidget) {
- if (d->inPopupMode()) // no focus widget, see if we have a popup
- keywidget = (QETWidget*) (activePopupWidget()->focusWidget() ? activePopupWidget()->focusWidget() : activePopupWidget());
- else if (QApplicationPrivate::focus_widget)
- keywidget = (QETWidget*)QApplicationPrivate::focus_widget;
- else if (widget)
- keywidget = (QETWidget*)widget->window();
- }
- }
-
-#ifndef QT_NO_IM
- // Filtering input events by the input context. It has to be taken
- // place before any other key event consumers such as eventfilters
- // and accelerators because some input methods require quite
- // various key combination and sequences. It often conflicts with
- // accelerators and so on, so we must give the input context the
- // filtering opportunity first to ensure all input methods work
- // properly regardless of application design.
-
- if(keywidget && keywidget->isEnabled() && keywidget->testAttribute(Qt::WA_InputMethodEnabled)) {
- // block user interaction during session management
- if((event->type==XKeyPress || event->type==XKeyRelease) && qt_sm_blockUserInput)
- return true;
-
- // for XIM handling
- QInputContext *qic = keywidget->inputContext();
- if(qic && qic->x11FilterEvent(keywidget, event))
- return true;
-
- // filterEvent() accepts QEvent *event rather than preexpanded
- // key event attribute values. This is intended to pass other
- // QInputEvent in future. Other non IM-related events should
- // not be forwarded to input contexts to prevent weird event
- // handling.
- if ((event->type == XKeyPress || event->type == XKeyRelease)) {
- int code = -1;
- int count = 0;
- Qt::KeyboardModifiers modifiers;
- QEvent::Type type;
- QString text;
- KeySym keySym;
-
- qt_keymapper_private()->translateKeyEventInternal(keywidget, event, keySym, count,
- text, modifiers, code, type, false);
-
- // both key press/release is required for some complex
- // input methods. don't eliminate anything.
- QKeyEventEx keyevent(type, code, modifiers, text, false, qMax(qMax(count, 1), text.length()),
- event->xkey.keycode, keySym, event->xkey.state);
- if(qic && qic->filterEvent(&keyevent))
- return true;
- }
- } else
-#endif // QT_NO_IM
- {
- if (XFilterEvent(event, XNone))
- return true;
- }
-
- if (qt_x11EventFilter(event)) // send through app filter
- return 1;
-
- if (event->type == MappingNotify) {
- // keyboard mapping changed
- XRefreshKeyboardMapping(&event->xmapping);
-
- QKeyMapper::changeKeyboard();
- return 0;
- }
-#ifndef QT_NO_XKB
- else if (X11->use_xkb && event->type == X11->xkb_eventbase) {
- XkbAnyEvent *xkbevent = (XkbAnyEvent *) event;
- switch (xkbevent->xkb_type) {
- case XkbStateNotify:
- {
- XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent;
- if ((xkbstateevent->changed & XkbGroupStateMask) != 0) {
- qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group;
- QKeyMapper::changeKeyboard();
- }
- break;
- }
- default:
- break;
- }
- }
-#endif
-
- if (!widget) { // don't know this windows
- QWidget* popup = QApplication::activePopupWidget();
- if (popup) {
-
- /*
- That is more than suboptimal. The real solution should
- do some keyevent and buttonevent translation, so that
- the popup still continues to work as the user expects.
- Unfortunately this translation is currently only
- possible with a known widget. I'll change that soon
- (Matthias).
- */
-
- // Danger - make sure we don't lock the server
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- case XKeyPress:
- case XKeyRelease:
- do {
- popup->close();
- } while ((popup = qApp->activePopupWidget()));
- return 1;
- }
- }
- return -1;
- }
-
- if (event->type == XKeyPress || event->type == XKeyRelease)
- widget = keywidget; // send XKeyEvents through keywidget->x11Event()
-
- if (app_do_modal) // modal event handling
- if (!qt_try_modal(widget, event)) {
- if (event->type == ClientMessage && !widget->x11Event(event))
- x11ClientMessage(widget, event, true);
- return 1;
- }
-
-
- if (widget->x11Event(event)) // send through widget filter
- return 1;
-#if !defined (QT_NO_TABLET)
- if (!qt_xdnd_dragging) {
- QTabletDeviceDataList *tablets = qt_tablet_devices();
- for (int i = 0; i < tablets->size(); ++i) {
- QTabletDeviceData &tab = tablets->operator [](i);
- if (event->type == tab.xinput_motion
- || event->type == tab.xinput_button_release
- || event->type == tab.xinput_button_press
- || event->type == tab.xinput_proximity_in
- || event->type == tab.xinput_proximity_out) {
- widget->translateXinputEvent(event, &tab);
- return 0;
- }
- }
- }
-#endif
-
-#ifndef QT_NO_XRANDR
- if (X11->use_xrandr && event->type == (X11->xrandr_eventbase + RRScreenChangeNotify)) {
- // update Xlib internals with the latest screen configuration
- X11->ptrXRRUpdateConfiguration(event);
-
- // update the size for desktop widget
- int scr = X11->ptrXRRRootToScreen(X11->display, event->xany.window);
- QDesktopWidget *desktop = QApplication::desktop();
- QWidget *w = desktop->screen(scr);
- QSize oldSize(w->size());
- w->data->crect.setWidth(DisplayWidth(X11->display, scr));
- w->data->crect.setHeight(DisplayHeight(X11->display, scr));
- QResizeEvent e(w->size(), oldSize);
- QApplication::sendEvent(w, &e);
- if (w != desktop)
- QApplication::sendEvent(desktop, &e);
- }
-#endif // QT_NO_XRANDR
-
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
- XFixesSelectionNotifyEvent *req = reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
-
- // compress all XFixes events related to this selection
- // we don't want to handle old SelectionNotify events.
- qt_xfixes_selection_event_data xfixes_event;
- xfixes_event.selection = req->selection;
- for (XEvent ev;;) {
- if (!XCheckIfEvent(X11->display, &ev, &qt_xfixes_scanner, (XPointer)&xfixes_event))
- break;
- }
-
- if (req->selection == ATOM(CLIPBOARD)) {
- if (qt_xfixes_clipboard_changed(req->owner, req->selection_timestamp)) {
- emit clipboard()->changed(QClipboard::Clipboard);
- emit clipboard()->dataChanged();
- }
- } else if (req->selection == XA_PRIMARY) {
- if (qt_xfixes_selection_changed(req->owner, req->selection_timestamp)) {
- emit clipboard()->changed(QClipboard::Selection);
- emit clipboard()->selectionChanged();
- }
- }
- }
-#endif // QT_NO_XFIXES
-
- switch (event->type) {
-
- case ButtonRelease: // mouse event
- if (!d->inPopupMode() && !QWidget::mouseGrabber() && pressed_window != widget->internalWinId()
- && (widget = (QETWidget*) QWidget::find((WId)pressed_window)) == 0)
- break;
- // fall through intended
- case ButtonPress:
- if (event->xbutton.root != RootWindow(X11->display, widget->x11Info().screen())
- && ! qt_xdnd_dragging) {
- while (activePopupWidget())
- activePopupWidget()->close();
- return 1;
- }
- if (event->type == ButtonPress)
- qt_net_update_user_time(widget->window(), X11->userTime);
- // fall through intended
- case MotionNotify:
-#if !defined(QT_NO_TABLET)
- if (!qt_tabletChokeMouse) {
-#endif
- if (widget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
- QPoint pos(event->xbutton.x, event->xbutton.y);
- pos = widget->d_func()->mapFromWS(pos);
- QWidget *window = widget->window();
- pos = widget->mapTo(window, pos);
- if (QWidget *child = window->childAt(pos)) {
- widget = static_cast<QETWidget *>(child);
- pos = child->mapFrom(window, pos);
- event->xbutton.x = pos.x();
- event->xbutton.y = pos.y();
- }
- }
- widget->translateMouseEvent(event);
-#if !defined(QT_NO_TABLET)
- } else {
- qt_tabletChokeMouse = false;
- }
-#endif
- break;
-
- case XKeyPress: // keyboard event
- qt_net_update_user_time(widget->window(), X11->userTime);
- // fallthrough intended
- case XKeyRelease:
- {
- if (keywidget && keywidget->isEnabled()) { // should always exist
- // qDebug("sending key event");
- qt_keymapper_private()->translateKeyEvent(keywidget, event, grabbed);
- }
- break;
- }
-
- case GraphicsExpose:
- case Expose: // paint event
- widget->translatePaintEvent(event);
- break;
-
- case ConfigureNotify: // window move/resize event
- if (event->xconfigure.event == event->xconfigure.window)
- widget->translateConfigEvent(event);
- break;
-
- case XFocusIn: { // got focus
- if ((widget->windowType() == Qt::Desktop))
- break;
- if (d->inPopupMode()) // some delayed focus event to ignore
- break;
- if (!widget->isWindow())
- break;
- if (event->xfocus.detail != NotifyAncestor &&
- event->xfocus.detail != NotifyInferior &&
- event->xfocus.detail != NotifyNonlinear)
- break;
- setActiveWindow(widget);
- if (X11->focus_model == QX11Data::FM_PointerRoot) {
- // We got real input focus from somewhere, but we were in PointerRoot
- // mode, so we don't trust this event. Check the focus model to make
- // sure we know what focus mode we are using...
- qt_check_focus_model();
- }
- }
- break;
-
- case XFocusOut: // lost focus
- if ((widget->windowType() == Qt::Desktop))
- break;
- if (!widget->isWindow())
- break;
- if (event->xfocus.mode == NotifyGrab) {
- qt_xfocusout_grab_counter++;
- break;
- }
- if (event->xfocus.detail != NotifyAncestor &&
- event->xfocus.detail != NotifyNonlinearVirtual &&
- event->xfocus.detail != NotifyNonlinear)
- break;
- if (!d->inPopupMode() && widget == QApplicationPrivate::active_window) {
- XEvent ev;
- bool focus_will_change = false;
- if (XCheckTypedEvent(X11->display, XFocusIn, &ev)) {
- // we're about to get an XFocusIn, if we know we will
- // get a new active window, we don't want to set the
- // active window to 0 now
- QWidget *w2 = QWidget::find(ev.xany.window);
- if (w2
- && w2->windowType() != Qt::Desktop
- && !d->inPopupMode() // some delayed focus event to ignore
- && w2->isWindow()
- && (ev.xfocus.detail == NotifyAncestor
- || ev.xfocus.detail == NotifyInferior
- || ev.xfocus.detail == NotifyNonlinear))
- focus_will_change = true;
-
- XPutBackEvent(X11->display, &ev);
- }
- if (!focus_will_change)
- setActiveWindow(0);
- }
- break;
-
- case EnterNotify: { // enter window
- if (QWidget::mouseGrabber() && (!d->inPopupMode() || widget->window() != activePopupWidget()))
- break;
- if ((event->xcrossing.mode != NotifyNormal
- && event->xcrossing.mode != NotifyUngrab)
- || event->xcrossing.detail == NotifyVirtual
- || event->xcrossing.detail == NotifyNonlinearVirtual)
- break;
- if (event->xcrossing.focus &&
- !(widget->windowType() == Qt::Desktop) && !widget->isActiveWindow()) {
- if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
- qt_check_focus_model();
- if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
- setActiveWindow(widget);
- }
-
- if (qt_button_down && !d->inPopupMode())
- break;
-
- QWidget *alien = widget->childAt(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
- event->xcrossing.y)));
- QWidget *enter = alien ? alien : widget;
- QWidget *leave = 0;
- if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
- leave = qt_last_mouse_receiver;
- else
- leave = QWidget::find(curWin);
-
- // ### Alien: enter/leave might be wrong here with overlapping siblings
- // if the enter widget is native and stacked under a non-native widget.
- QApplicationPrivate::dispatchEnterLeave(enter, leave);
- curWin = widget->internalWinId();
- qt_last_mouse_receiver = enter;
- if (!d->inPopupMode() || widget->window() == activePopupWidget())
- widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
- }
- break;
- case LeaveNotify: { // leave window
- QWidget *mouseGrabber = QWidget::mouseGrabber();
- if (mouseGrabber && !d->inPopupMode())
- break;
- if (curWin && widget->internalWinId() != curWin)
- break;
- if ((event->xcrossing.mode != NotifyNormal
- && event->xcrossing.mode != NotifyUngrab)
- || event->xcrossing.detail == NotifyInferior)
- break;
- if (!(widget->windowType() == Qt::Desktop))
- widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
-
- QWidget* enter = 0;
- QPoint enterPoint;
- XEvent ev;
- while (XCheckMaskEvent(X11->display, EnterWindowMask | LeaveWindowMask , &ev)
- && !qt_x11EventFilter(&ev)) {
- QWidget* event_widget = QWidget::find(ev.xcrossing.window);
- if(event_widget && event_widget->x11Event(&ev))
- break;
- if (ev.type == LeaveNotify
- || (ev.xcrossing.mode != NotifyNormal
- && ev.xcrossing.mode != NotifyUngrab)
- || ev.xcrossing.detail == NotifyVirtual
- || ev.xcrossing.detail == NotifyNonlinearVirtual)
- continue;
- enter = event_widget;
- if (enter)
- enterPoint = enter->d_func()->mapFromWS(QPoint(ev.xcrossing.x, ev.xcrossing.y));
- if (ev.xcrossing.focus &&
- enter && !(enter->windowType() == Qt::Desktop) && !enter->isActiveWindow()) {
- if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
- qt_check_focus_model();
- if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
- setActiveWindow(enter);
- }
- break;
- }
-
- if ((! enter || (enter->windowType() == Qt::Desktop)) &&
- event->xcrossing.focus && widget == QApplicationPrivate::active_window &&
- X11->focus_model == QX11Data::FM_PointerRoot // PointerRoot mode
- ) {
- setActiveWindow(0);
- }
-
- if (qt_button_down && !d->inPopupMode())
- break;
-
- if (!curWin)
- QApplicationPrivate::dispatchEnterLeave(widget, 0);
-
- if (enter) {
- QWidget *alienEnter = enter->childAt(enterPoint);
- if (alienEnter)
- enter = alienEnter;
- }
-
- QWidget *leave = qt_last_mouse_receiver ? qt_last_mouse_receiver : widget;
- QWidget *activePopupWidget = qApp->activePopupWidget();
-
- if (mouseGrabber && activePopupWidget && leave == activePopupWidget)
- enter = mouseGrabber;
- else if (enter != widget && mouseGrabber) {
- if (!widget->rect().contains(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
- event->xcrossing.y))))
- break;
- }
-
- QApplicationPrivate::dispatchEnterLeave(enter, leave);
- qt_last_mouse_receiver = enter;
-
- if (enter && QApplicationPrivate::tryModalHelper(enter, 0)) {
- QWidget *nativeEnter = enter->internalWinId() ? enter : enter->nativeParentWidget();
- curWin = nativeEnter->internalWinId();
- static_cast<QETWidget *>(nativeEnter)->translateMouseEvent(&ev); //we don't get MotionNotify, emulate it
- } else {
- curWin = 0;
- qt_last_mouse_receiver = 0;
- }
- }
- break;
-
- case UnmapNotify: // window hidden
- if (widget->isWindow()) {
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- widget->d_func()->topData()->waitingForMapNotify = 0;
-
- if (widget->windowType() != Qt::Popup && !widget->testAttribute(Qt::WA_DontShowOnScreen)) {
- widget->setAttribute(Qt::WA_Mapped, false);
- if (widget->isVisible()) {
- widget->d_func()->topData()->spont_unmapped = 1;
- QHideEvent e;
- QApplication::sendSpontaneousEvent(widget, &e);
- widget->d_func()->hideChildren(true);
- }
- }
-
- if (!widget->d_func()->topData()->validWMState && X11->deferred_map.removeAll(widget))
- widget->doDeferredMap();
- }
- break;
-
- case MapNotify: // window shown
- if (widget->isWindow()) {
- // if we got a MapNotify when we were not waiting for it, it most
- // likely means the user has already asked to hide the window before
- // it ever being shown, so we try to withdraw a window after sending
- // the QShowEvent.
- bool pendingHide = widget->testAttribute(Qt::WA_WState_ExplicitShowHide) && widget->testAttribute(Qt::WA_WState_Hidden);
- widget->d_func()->topData()->waitingForMapNotify = 0;
-
- if (widget->windowType() != Qt::Popup) {
- widget->setAttribute(Qt::WA_Mapped);
- if (widget->d_func()->topData()->spont_unmapped) {
- widget->d_func()->topData()->spont_unmapped = 0;
- widget->d_func()->showChildren(true);
- QShowEvent e;
- QApplication::sendSpontaneousEvent(widget, &e);
-
- // show() must have been called on this widget in
- // order to reach this point, but we could have
- // cleared these 2 attributes in case something
- // previously forced us into WithdrawnState
- // (e.g. kdocker)
- widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
- widget->setAttribute(Qt::WA_WState_Visible, true);
- }
- }
- if (pendingHide) // hide the window
- XWithdrawWindow(X11->display, widget->internalWinId(), widget->x11Info().screen());
- }
- break;
-
- case ClientMessage: // client message
- return x11ClientMessage(widget,event,False);
-
- case ReparentNotify: { // window manager reparents
- // compress old reparent events to self
- XEvent ev;
- while (XCheckTypedWindowEvent(X11->display,
- widget->effectiveWinId(),
- ReparentNotify,
- &ev)) {
- if (ev.xreparent.window != ev.xreparent.event) {
- XPutBackEvent(X11->display, &ev);
- break;
- }
- }
- if (widget->isWindow()) {
- QTLWExtra *topData = widget->d_func()->topData();
-
- // store the parent. Useful for many things, embedding for instance.
- topData->parentWinId = event->xreparent.parent;
-
- // the widget frame strut should also be invalidated
- widget->data->fstrut_dirty = 1;
-
- // work around broken window managers... if we get a
- // ReparentNotify before the MapNotify, we assume that
- // we're being managed by a reparenting window
- // manager.
- //
- // however, the WM_STATE property may not have been set
- // yet, but we are going to assume that it will
- // be... otherwise we could try to map again after getting
- // an UnmapNotify... which could then, in turn, trigger a
- // race in the window manager which causes the window to
- // disappear when it really should be hidden.
- if (topData->waitingForMapNotify && !topData->validWMState) {
- topData->waitingForMapNotify = 0;
- topData->validWMState = 1;
- }
-
- if (X11->focus_model != QX11Data::FM_Unknown) {
- // toplevel reparented...
- QWidget *newparent = QWidget::find(event->xreparent.parent);
- if (! newparent || (newparent->windowType() == Qt::Desktop)) {
- // we don't know about the new parent (or we've been
- // reparented to root), perhaps a window manager
- // has been (re)started? reset the focus model to unknown
- X11->focus_model = QX11Data::FM_Unknown;
- }
- }
- }
- break;
- }
- case SelectionRequest: {
- XSelectionRequestEvent *req = &event->xselectionrequest;
- if (! req)
- break;
-
- if (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)) {
- X11->xdndHandleSelectionRequest(req);
-
- } else if (qt_clipboard) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
- QApplication::sendSpontaneousEvent(qt_clipboard, &e);
- }
- break;
- }
- case SelectionClear: {
- XSelectionClearEvent *req = &event->xselectionclear;
- // don't deliver dnd events to the clipboard, it gets confused
- if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
- break;
-
- if (qt_clipboard && !X11->use_xfixes) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
- QApplication::sendSpontaneousEvent(qt_clipboard, &e);
- }
- break;
- }
-
- case SelectionNotify: {
- XSelectionEvent *req = &event->xselection;
- // don't deliver dnd events to the clipboard, it gets confused
- if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
- break;
-
- if (qt_clipboard) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
- QApplication::sendSpontaneousEvent(qt_clipboard, &e);
- }
- break;
- }
- case PropertyNotify:
- // some properties changed
- if (event->xproperty.window == QX11Info::appRootWindow(0)) {
- // root properties for the first screen
- if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_CLIPBOARD_SENTINEL)) {
- if (qt_check_clipboard_sentinel()) {
- emit clipboard()->changed(QClipboard::Clipboard);
- emit clipboard()->dataChanged();
- }
- } else if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_SELECTION_SENTINEL)) {
- if (qt_check_selection_sentinel()) {
- emit clipboard()->changed(QClipboard::Selection);
- emit clipboard()->selectionChanged();
- }
- } else if (QApplicationPrivate::obey_desktop_settings) {
- if (event->xproperty.atom == ATOM(RESOURCE_MANAGER))
- qt_set_x11_resources();
- else if (event->xproperty.atom == ATOM(_QT_SETTINGS_TIMESTAMP))
- qt_set_x11_resources();
- }
- }
- if (event->xproperty.window == QX11Info::appRootWindow()) {
- // root properties for the default screen
- if (event->xproperty.atom == ATOM(_QT_INPUT_ENCODING)) {
- qt_set_input_encoding();
- } else if (event->xproperty.atom == ATOM(_NET_SUPPORTED)) {
- qt_get_net_supported();
- } else if (event->xproperty.atom == ATOM(_NET_VIRTUAL_ROOTS)) {
- qt_get_net_virtual_roots();
- } else if (event->xproperty.atom == ATOM(_NET_WORKAREA)) {
- qt_desktopwidget_update_workarea();
-
- // emit the workAreaResized() signal
- QDesktopWidget *desktop = QApplication::desktop();
- int numScreens = desktop->numScreens();
- for (int i = 0; i < numScreens; ++i)
- emit desktop->workAreaResized(i);
- }
- } else if (widget) {
- widget->translatePropertyEvent(event);
- } else {
- return -1; // don't know this window
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-bool QApplication::x11EventFilter(XEvent *)
-{
- return false;
-}
-
-
-
-/*****************************************************************************
- Modal widgets; Since Xlib has little support for this we roll our own
- modal widget mechanism.
- 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;
-
- 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;
-}
-
-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());
- 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;
- }
- }
- app_do_modal = qt_modal_stack != 0;
-}
-
-bool qt_try_modal(QWidget *widget, XEvent *event)
-{
- if (qt_xdnd_dragging) {
- // allow mouse events while DnD is active
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- return true;
- default:
- break;
- }
- }
-
- // allow mouse release events to be sent to widgets that have been pressed
- if (event->type == ButtonRelease) {
- QWidget *alienWidget = widget->childAt(widget->mapFromGlobal(QPoint(event->xbutton.x_root,
- event->xbutton.y_root)));
- if (widget == qt_button_down || (alienWidget && alienWidget == qt_button_down))
- return true;
- }
-
- if (QApplicationPrivate::tryModalHelper(widget))
- return true;
-
- // disallow mouse/key events
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case XKeyPress:
- case XKeyRelease:
- case EnterNotify:
- case LeaveNotify:
- case ClientMessage:
- return false;
- default:
- break;
- }
-
- return true;
-}
-
-
-/*****************************************************************************
- 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
- *****************************************************************************/
-
-
-static int openPopupCount = 0;
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- Q_Q(QApplication);
- openPopupCount++;
- if (!QApplicationPrivate::popupWidgets) { // create list
- QApplicationPrivate::popupWidgets = new QWidgetList;
- }
- QApplicationPrivate::popupWidgets->append(popup); // add to end of list
- Display *dpy = X11->display;
- if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- int r = XGrabKeyboard(dpy, popup->effectiveWinId(), false,
- GrabModeAsync, GrabModeAsync, X11->time);
- if ((popupGrabOk = (r == GrabSuccess))) {
- r = XGrabPointer(dpy, popup->effectiveWinId(), true,
- (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
- GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
- if (!(popupGrabOk = (r == GrabSuccess))) {
- // transfer grab back to the keyboard grabber if any
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
- else
- XUngrabKeyboard(dpy, X11->time);
- }
- }
- }
-
- // 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);
- q->sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- Q_Q(QApplication);
- if (!QApplicationPrivate::popupWidgets)
- return;
- QApplicationPrivate::popupWidgets->removeAll(popup);
- if (popup == qt_popup_down) {
- qt_button_down = 0;
- qt_popup_down = 0;
- }
- if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
- if (!qt_nograb() && popupGrabOk) { // grabbing not disabled
- Display *dpy = X11->display;
- if (popup->geometry().contains(QPoint(mouseGlobalXPos, mouseGlobalYPos))
- || popup->testAttribute(Qt::WA_NoMouseReplay)) {
- // mouse release event or inside
- replayPopupMouseEvent = false;
- } else { // mouse press event
- mouseButtonPressTime -= 10000; // avoid double click
- replayPopupMouseEvent = true;
- }
- // transfer grab back to mouse grabber if any, otherwise release the grab
- if (QWidgetPrivate::mouseGrabber != 0)
- QWidgetPrivate::mouseGrabber->grabMouse();
- else
- XUngrabPointer(dpy, X11->time);
-
- // transfer grab back to keyboard grabber if any, otherwise release the grab
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
- else
- XUngrabKeyboard(dpy, X11->time);
-
- XFlush(dpy);
- }
- if (QApplicationPrivate::active_window) {
- if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
- if (fw != QApplication::focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- q->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 (QWidget *fw = aw->focusWidget())
- fw->setFocus(Qt::PopupFocusReason);
-
- // regrab the keyboard and mouse in case 'popup' lost the grab
- if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
- Display *dpy = X11->display;
- Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
- int r = XGrabKeyboard(dpy, aw->effectiveWinId(), false,
- GrabModeAsync, GrabModeAsync, X11->time);
- if ((popupGrabOk = (r == GrabSuccess))) {
- r = XGrabPointer(dpy, aw->effectiveWinId(), true,
- (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
- GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
- if (!(popupGrabOk = (r == GrabSuccess))) {
- // transfer grab back to keyboard grabber
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
- else
- XUngrabKeyboard(dpy, X11->time);
- }
- }
- }
- }
-}
-
-/*****************************************************************************
- Event translation; translates X11 events to Qt events
- *****************************************************************************/
-
-//
-// Mouse event translation
-//
-// Xlib doesn't give mouse double click events, so we generate them by
-// comparing window, time and position between two mouse press events.
-//
-
-static Qt::MouseButtons translateMouseButtons(int s)
-{
- Qt::MouseButtons ret = 0;
- if (s & Button1Mask)
- ret |= Qt::LeftButton;
- if (s & Button2Mask)
- ret |= Qt::MidButton;
- if (s & Button3Mask)
- ret |= Qt::RightButton;
- return ret;
-}
-
-Qt::KeyboardModifiers QX11Data::translateModifiers(int s)
-{
- Qt::KeyboardModifiers ret = 0;
- if (s & ShiftMask)
- ret |= Qt::ShiftModifier;
- if (s & ControlMask)
- ret |= Qt::ControlModifier;
- if (s & qt_alt_mask)
- ret |= Qt::AltModifier;
- if (s & qt_meta_mask)
- ret |= Qt::MetaModifier;
- if (s & qt_mode_switch_mask)
- ret |= Qt::GroupSwitchModifier;
- return ret;
-}
-
-bool QETWidget::translateMouseEvent(const XEvent *event)
-{
- if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
- Q_ASSERT(internalWinId());
-
- Q_D(QWidget);
- QEvent::Type type; // event parameters
- QPoint pos;
- QPoint globalPos;
- Qt::MouseButton button = Qt::NoButton;
- Qt::MouseButtons buttons;
- Qt::KeyboardModifiers modifiers;
- XEvent nextEvent;
-
- if (qt_sm_blockUserInput) // block user interaction during session management
- return true;
-
- if (event->type == MotionNotify) { // mouse move
- if (event->xmotion.root != RootWindow(X11->display, x11Info().screen()) &&
- ! qt_xdnd_dragging)
- return false;
-
- XMotionEvent lastMotion = event->xmotion;
- while(XPending(X11->display)) { // compress mouse moves
- XNextEvent(X11->display, &nextEvent);
- if (nextEvent.type == ConfigureNotify
- || nextEvent.type == PropertyNotify
- || nextEvent.type == Expose
- || nextEvent.type == GraphicsExpose
- || nextEvent.type == NoExpose
- || nextEvent.type == KeymapNotify
- || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify)
- && qt_button_down == this)
- || (nextEvent.type == ClientMessage
- && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) ||
- (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) &&
- (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) {
- qApp->x11ProcessEvent(&nextEvent);
- continue;
- } else if (nextEvent.type != MotionNotify ||
- nextEvent.xmotion.window != event->xmotion.window ||
- nextEvent.xmotion.state != event->xmotion.state) {
- XPutBackEvent(X11->display, &nextEvent);
- break;
- }
- if (!qt_x11EventFilter(&nextEvent)
- && !x11Event(&nextEvent)) // send event through filter
- lastMotion = nextEvent.xmotion;
- else
- break;
- }
- type = QEvent::MouseMove;
- pos.rx() = lastMotion.x;
- pos.ry() = lastMotion.y;
- pos = d->mapFromWS(pos);
- globalPos.rx() = lastMotion.x_root;
- globalPos.ry() = lastMotion.y_root;
- buttons = translateMouseButtons(lastMotion.state);
- modifiers = X11->translateModifiers(lastMotion.state);
- if (qt_button_down && !buttons)
- qt_button_down = 0;
- } else if (event->type == EnterNotify || event->type == LeaveNotify) {
- XEvent *xevent = (XEvent *)event;
- //unsigned int xstate = event->xcrossing.state;
- type = QEvent::MouseMove;
- pos.rx() = xevent->xcrossing.x;
- pos.ry() = xevent->xcrossing.y;
- pos = d->mapFromWS(pos);
- globalPos.rx() = xevent->xcrossing.x_root;
- globalPos.ry() = xevent->xcrossing.y_root;
- buttons = translateMouseButtons(xevent->xcrossing.state);
- modifiers = X11->translateModifiers(xevent->xcrossing.state);
- if (qt_button_down && !buttons)
- qt_button_down = 0;
- if (qt_button_down)
- return true;
- } else { // button press or release
- pos.rx() = event->xbutton.x;
- pos.ry() = event->xbutton.y;
- pos = d->mapFromWS(pos);
- globalPos.rx() = event->xbutton.x_root;
- globalPos.ry() = event->xbutton.y_root;
- buttons = translateMouseButtons(event->xbutton.state);
- modifiers = X11->translateModifiers(event->xbutton.state);
- switch (event->xbutton.button) {
- case Button1: button = Qt::LeftButton; break;
- case Button2: button = Qt::MidButton; break;
- case Button3: button = Qt::RightButton; break;
- case Button4:
- case Button5:
- case 6:
- case 7:
- // the fancy mouse wheel.
-
- // We are only interested in ButtonPress.
- if (event->type == ButtonPress){
- // compress wheel events (the X Server will simply
- // send a button press for each single notch,
- // regardless whether the application can catch up
- // or not)
- int delta = 1;
- XEvent xevent;
- while (XCheckTypedWindowEvent(X11->display, effectiveWinId(), ButtonPress, &xevent)){
- if (xevent.xbutton.button != event->xbutton.button){
- XPutBackEvent(X11->display, &xevent);
- break;
- }
- delta++;
- }
-
- // the delta is defined as multiples of
- // WHEEL_DELTA, which is set to 120. Future wheels
- // may offer a finer-resolution. A positive delta
- // indicates forward rotation, a negative one
- // backward rotation respectively.
- int btn = event->xbutton.button;
- delta *= 120 * ((btn == Button4 || btn == 6) ? 1 : -1);
- bool hor = (((btn == Button4 || btn == Button5) && (modifiers & Qt::AltModifier)) ||
- (btn == 6 || btn == 7));
- translateWheelEvent(globalPos.x(), globalPos.y(), delta, buttons,
- modifiers, (hor) ? Qt::Horizontal: Qt::Vertical);
- }
- return true;
- case 8: button = Qt::XButton1; break;
- case 9: button = Qt::XButton2; break;
- }
- if (event->type == ButtonPress) { // mouse button pressed
- buttons |= button;
-#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
- QTabletDeviceDataList *tablets = qt_tablet_devices();
- for (int i = 0; i < tablets->size(); ++i) {
- QTabletDeviceData &tab = tablets->operator[](i);
- XEvent myEv;
- if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
- if (translateXinputEvent(&myEv, &tab)) {
- //Spontaneous event sent. Check if we need to continue.
- if (qt_tabletChokeMouse) {
- qt_tabletChokeMouse = false;
- return false;
- }
- }
- }
- }
-#endif
- if (!qt_button_down) {
- qt_button_down = childAt(pos); //magic for masked widgets
- if (!qt_button_down)
- qt_button_down = this;
- }
- if (mouseActWindow == event->xbutton.window &&
- mouseButtonPressed == button &&
- (long)event->xbutton.time -(long)mouseButtonPressTime
- < QApplication::doubleClickInterval() &&
- qAbs(event->xbutton.x - mouseXPos) < QT_GUI_DOUBLE_CLICK_RADIUS &&
- qAbs(event->xbutton.y - mouseYPos) < QT_GUI_DOUBLE_CLICK_RADIUS) {
- type = QEvent::MouseButtonDblClick;
- mouseButtonPressTime -= 2000; // no double-click next time
- } else {
- type = QEvent::MouseButtonPress;
- mouseButtonPressTime = event->xbutton.time;
- }
- mouseButtonPressed = button; // save event params for
- mouseXPos = event->xbutton.x; // future double click tests
- mouseYPos = event->xbutton.y;
- mouseGlobalXPos = globalPos.x();
- mouseGlobalYPos = globalPos.y();
- } else { // mouse button released
- buttons &= ~button;
-#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
- QTabletDeviceDataList *tablets = qt_tablet_devices();
- for (int i = 0; i < tablets->size(); ++i) {
- QTabletDeviceData &tab = tablets->operator[](i);
- XEvent myEv;
- if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
- if (translateXinputEvent(&myEv, &tab)) {
- //Spontaneous event sent. Check if we need to continue.
- if (qt_tabletChokeMouse) {
- qt_tabletChokeMouse = false;
- return false;
- }
- }
- }
- }
-#endif
- type = QEvent::MouseButtonRelease;
- }
- }
- mouseActWindow = effectiveWinId(); // save some event params
- mouseButtonState = buttons;
- if (type == 0) // don't send event
- return false;
-
- if (qApp->d_func()->inPopupMode()) { // in popup mode
- QWidget *activePopupWidget = qApp->activePopupWidget();
- QWidget *popup = qApp->activePopupWidget();
- if (popup != this) {
- if (event->type == LeaveNotify)
- return false;
- if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
- popup = this;
- else // send to last popup
- pos = popup->mapFromGlobal(globalPos);
- }
- bool releaseAfter = false;
- QWidget *popupChild = popup->childAt(pos);
-
- if (popup != qt_popup_down){
- qt_button_down = 0;
- qt_popup_down = 0;
- }
-
- switch (type) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- qt_button_down = popupChild;
- qt_popup_down = popup;
- break;
- case QEvent::MouseButtonRelease:
- releaseAfter = true;
- break;
- default:
- break; // nothing for mouse move
- }
-
- int oldOpenPopupCount = openPopupCount;
-
- if (popup->isEnabled()) {
- // deliver event
- replayPopupMouseEvent = false;
- QWidget *receiver = popup;
- QPoint widgetPos = pos;
- if (qt_button_down)
- receiver = qt_button_down;
- else if (popupChild)
- receiver = popupChild;
- if (receiver != popup)
- widgetPos = receiver->mapFromGlobal(globalPos);
- QWidget *alien = childAt(mapFromGlobal(globalPos));
- QMouseEvent e(type, widgetPos, globalPos, button, buttons, modifiers);
- QApplicationPrivate::sendMouseEvent(receiver, &e, alien, this, &qt_button_down, qt_last_mouse_receiver);
- } else {
- // close disabled popups when a mouse button is pressed or released
- switch (type) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonRelease:
- popup->close();
- break;
- default:
- break;
- }
- }
-
- if (qApp->activePopupWidget() != activePopupWidget
- && replayPopupMouseEvent) {
- // the active popup was closed, replay the mouse event
- if (!(windowType() == Qt::Popup)) {
-#if 1
- qt_button_down = 0;
-#else
- if (buttons == button)
- qt_button_down = this;
- QMouseEvent e(type, mapFromGlobal(globalPos), globalPos, button,
- buttons, modifiers);
- QApplication::sendSpontaneousEvent(this, &e);
-
- if (type == QEvent::MouseButtonPress
- && button == Qt::RightButton
- && (openPopupCount == oldOpenPopupCount)) {
- QContextMenuEvent e(QContextMenuEvent::Mouse, mapFromGlobal(globalPos),
- globalPos, modifiers);
- QApplication::sendSpontaneousEvent(this, &e);
- }
-#endif
- }
- replayPopupMouseEvent = false;
- } else if (type == QEvent::MouseButtonPress
- && button == Qt::RightButton
- && (openPopupCount == oldOpenPopupCount)) {
- QWidget *popupEvent = popup;
- if (qt_button_down)
- popupEvent = qt_button_down;
- else if(popupChild)
- popupEvent = popupChild;
- QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
- QApplication::sendSpontaneousEvent(popupEvent, &e);
- }
-
- if (releaseAfter) {
- qt_button_down = 0;
- qt_popup_down = 0;
- }
- } else {
- QWidget *alienWidget = childAt(pos);
- QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type, buttons,
- qt_button_down, alienWidget);
- if (!widget) {
- if (type == QEvent::MouseButtonRelease)
- QApplicationPrivate::mouse_buttons &= ~button;
- return false; // don't send event
- }
-
- int oldOpenPopupCount = openPopupCount;
- QMouseEvent e(type, pos, globalPos, button, buttons, modifiers);
- QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
- qt_last_mouse_receiver);
- if (type == QEvent::MouseButtonPress
- && button == Qt::RightButton
- && (openPopupCount == oldOpenPopupCount)) {
- QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
- QApplication::sendSpontaneousEvent(widget, &e);
- }
- }
- return true;
-}
-
-
-//
-// Wheel event translation
-//
-bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta,
- Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
- Qt::Orientation orient)
-{
- const QPoint globalPos = QPoint(global_x, global_y);
- QPoint pos = mapFromGlobal(globalPos);
- QWidget *widget = childAt(pos);
- if (!widget)
- widget = this;
- else if (!widget->internalWinId())
- pos = widget->mapFromGlobal(globalPos);
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QETWidget::translateWheelEvent: receiver:" << widget << "pos:" << pos;
-#endif
-
- // send the event to the widget or its ancestors
- {
- QWidget* popup = qApp->activePopupWidget();
- if (popup && window() != popup)
- popup->close();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
- if (QApplication::sendSpontaneousEvent(widget, &e))
-#endif
- return true;
- }
-
- // send the event to the widget that has the focus or its ancestors, if different
- if (widget != qApp->focusWidget() && (widget = qApp->focusWidget())) {
- if (widget && !widget->internalWinId())
- pos = widget->mapFromGlobal(globalPos);
- QWidget* popup = qApp->activePopupWidget();
- if (popup && widget != popup)
- popup->hide();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
- if (QApplication::sendSpontaneousEvent(widget, &e))
-#endif
- return true;
- }
- return false;
-}
-
-
-//
-// XInput Translation Event
-//
-#if !defined (QT_NO_TABLET)
-
-#if !defined (Q_OS_IRIX)
-void fetchWacomToolId(int &deviceType, qint64 &serialId)
-{
- if (ptrWacomConfigInit == 0) // we actually have the lib
- return;
- WACOMCONFIG *config = ptrWacomConfigInit(X11->display, 0);
- if (config == 0)
- return;
- WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, wacomDeviceName()->constData());
- if (device == 0)
- return;
- unsigned keys[1];
- int serialInt;
- ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLSERIAL, &serialInt, 1, keys);
- serialId = serialInt;
- int toolId;
- ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLID, &toolId, 1, keys);
- switch(toolId) {
- case 0x007: /* Mouse 4D and 2D */
- case 0x017: /* Intuos3 2D Mouse */
- case 0x094:
- case 0x09c:
- deviceType = QTabletEvent::FourDMouse;
- break;
- case 0x096: /* Lens cursor */
- case 0x097: /* Intuos3 Lens cursor */
- deviceType = QTabletEvent::Puck;
- break;
- case 0x0fa:
- case 0x81b: /* Intuos3 Classic Pen Eraser */
- case 0x82a: /* Eraser */
- case 0x82b: /* Intuos3 Grip Pen Eraser */
- case 0x85a:
- case 0x91a:
- case 0x91b: /* Intuos3 Airbrush Eraser */
- case 0xd1a:
- deviceType = QTabletEvent::XFreeEraser;
- break;
- case 0x112:
- case 0x912:
- case 0x913: /* Intuos3 Airbrush */
- case 0xd12:
- deviceType = QTabletEvent::Airbrush;
- break;
- case 0x012:
- case 0x022:
- case 0x032:
- case 0x801: /* Intuos3 Inking pen */
- case 0x812: /* Inking pen */
- case 0x813: /* Intuos3 Classic Pen */
- case 0x822: /* Pen */
- case 0x823: /* Intuos3 Grip Pen */
- case 0x832: /* Stroke pen */
- case 0x842:
- case 0x852:
- case 0x885: /* Intuos3 Marker Pen */
- default: /* Unknown tool */
- deviceType = QTabletEvent::Stylus;
- }
-
- /* Close device and return */
- ptrWacomConfigCloseDevice (device);
- ptrWacomConfigTerm(config);
-}
-#endif
-
-struct qt_tablet_motion_data
-{
- bool filterByWidget;
- const QWidget *widget;
- const QWidget *etWidget;
- int tabletMotionType;
- bool error; // found a reason to stop searching
-};
-
-static Bool qt_mouseMotion_scanner(Display *, XEvent *event, XPointer arg)
-{
- qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
- if (data->error)
- return false;
-
- if (event->type == MotionNotify)
- return true;
-
- data->error = event->type != data->tabletMotionType; // we stop compression when another event gets in between.
- return false;
-}
-
-static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg)
-{
- qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
- if (data->error)
- return false;
- if (event->type == data->tabletMotionType) {
- const XDeviceMotionEvent *const motion = reinterpret_cast<const XDeviceMotionEvent*>(event);
- if (data->filterByWidget) {
- const QPoint curr(motion->x, motion->y);
- const QWidget *w = data->etWidget;
- const QWidget *const child = w->childAt(curr);
- if (child) {
- w = child;
- }
- if (w == data->widget)
- return true;
- } else {
- return true;
- }
- }
-
- data->error = event->type != MotionNotify; // we stop compression when another event gets in between.
- return false;
-}
-
-bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet)
-{
-#if defined (Q_OS_IRIX)
- // Wacom has put defines in their wacom.h file so it would be quite wise
- // to use them, need to think of a decent way of not using
- // it when it doesn't exist...
- XDeviceState *s;
- XInputClass *iClass;
- XValuatorState *vs;
- int j;
-#endif
-
- Q_ASSERT(tablet != 0);
-
- QWidget *w = this;
- QPoint global,
- curr;
- QPointF hiRes;
- qreal pressure = 0;
- int xTilt = 0,
- yTilt = 0,
- z = 0;
- qreal tangentialPressure = 0;
- qreal rotation = 0;
- int deviceType = QTabletEvent::NoDevice;
- int pointerType = QTabletEvent::UnknownPointer;
- const XDeviceMotionEvent *motion = 0;
- XDeviceButtonEvent *button = 0;
- const XProximityNotifyEvent *proximity = 0;
- QEvent::Type t;
- Qt::KeyboardModifiers modifiers = 0;
-#if !defined (Q_OS_IRIX)
- XID device_id;
-#endif
-
- if (ev->type == tablet->xinput_motion) {
- motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
- t = QEvent::TabletMove;
- global = QPoint(motion->x_root, motion->y_root);
- curr = QPoint(motion->x, motion->y);
-#if !defined (Q_OS_IRIX)
- device_id = motion->deviceid;
-#endif
- } else if (ev->type == tablet->xinput_button_press || ev->type == tablet->xinput_button_release) {
- if (ev->type == tablet->xinput_button_press) {
- t = QEvent::TabletPress;
- } else {
- t = QEvent::TabletRelease;
- }
- button = (XDeviceButtonEvent*)ev;
-
- global = QPoint(button->x_root, button->y_root);
- curr = QPoint(button->x, button->y);
-#if !defined (Q_OS_IRIX)
- device_id = button->deviceid;
-#endif
- } else { // Proximity
- if (ev->type == tablet->xinput_proximity_in)
- t = QEvent::TabletEnterProximity;
- else
- t = QEvent::TabletLeaveProximity;
- proximity = (const XProximityNotifyEvent*)ev;
-#if !defined (Q_OS_IRIX)
- device_id = proximity->deviceid;
-#endif
- }
-
- qint64 uid = 0;
-#if defined (Q_OS_IRIX)
- QRect screenArea = qApp->desktop()->screenGeometry(this);
- s = XQueryDeviceState(X11->display, static_cast<XDevice *>(tablet->device));
- if (!s)
- return false;
- iClass = s->data;
- for (j = 0; j < s->num_classes; j++) {
- if (iClass->c_class == ValuatorClass) {
- vs = reinterpret_cast<XValuatorState *>(iClass);
- // figure out what device we have, based on bitmasking...
- if (vs->valuators[WAC_TRANSDUCER_I]
- & WAC_TRANSDUCER_PROX_MSK) {
- switch (vs->valuators[WAC_TRANSDUCER_I]
- & WAC_TRANSDUCER_MSK) {
- case WAC_PUCK_ID:
- pointerType = QTabletEvent::Puck;
- break;
- case WAC_STYLUS_ID:
- pointerType = QTabletEvent::Pen;
- break;
- case WAC_ERASER_ID:
- pointerType = QTabletEvent::Eraser;
- break;
- }
- // Get a Unique Id for the device, Wacom gives us this ability
- uid = vs->valuators[WAC_TRANSDUCER_I] & WAC_TRANSDUCER_ID_MSK;
- uid = (uid << 24) | vs->valuators[WAC_SERIAL_NUM_I];
- switch (WAC_TRANSDUCER_I & 0x0F0600) {
- case 0x080200:
- deviceType = QTabletEvent::Stylus;
- break;
- case 0x090200:
- deviceType = QTabletEvent::Airbrush;
- break;
- case 0x000400:
- deviceType = QTabletEvent::FourDMouse;
- break;
- case 0x000600:
- deviceType = QTabletEvent::Puck;
- break;
- case 0x080400:
- deviceType = QTabletEvent::RotationStylus;
- break;
- }
- } else {
- pointerType = QTabletEvent::UnknownPointer;
- deviceType = QTabletEvent::NoDevice;
- uid = 0;
- }
-
- if (!proximity) {
- // apparently Wacom needs a cast for the +/- values to make sense
- xTilt = short(vs->valuators[WAC_XTILT_I]);
- yTilt = short(vs->valuators[WAC_YTILT_I]);
- pressure = vs->valuators[WAC_PRESSURE_I];
- if (deviceType == QTabletEvent::FourDMouse
- || deviceType == QTabletEvent::RotationStylus) {
- rotation = vs->valuators[WAC_ROTATION_I] / 64.0;
- if (deviceType == QTabletEvent::FourDMouse)
- z = vs->valuators[WAC_ZCOORD_I];
- } else if (deviceType == QTabletEvent::Airbrush) {
- tangentialPressure = vs->valuators[WAC_TAN_PRESSURE_I]
- / qreal(tablet->maxTanPressure - tablet->minTanPressure);
- }
-
- hiRes = tablet->scaleCoord(vs->valuators[WAC_XCOORD_I], vs->valuators[WAC_YCOORD_I],
- screenArea.x(), screenArea.width(),
- screenArea.y(), screenArea.height());
- }
- break;
- }
- iClass = reinterpret_cast<XInputClass*>(reinterpret_cast<char*>(iClass) + iClass->length);
- }
- XFreeDeviceState(s);
-#else
- QTabletDeviceDataList *tablet_list = qt_tablet_devices();
- for (int i = 0; i < tablet_list->size(); ++i) {
- const QTabletDeviceData &t = tablet_list->at(i);
- if (device_id == static_cast<XDevice *>(t.device)->device_id) {
- deviceType = t.deviceType;
- if (t.deviceType == QTabletEvent::XFreeEraser) {
- deviceType = QTabletEvent::Stylus;
- pointerType = QTabletEvent::Eraser;
- } else if (t.deviceType == QTabletEvent::Stylus) {
- pointerType = QTabletEvent::Pen;
- }
- break;
- }
- }
-
- fetchWacomToolId(deviceType, uid);
-
- QRect screenArea = qApp->desktop()->rect();
- if (motion) {
- xTilt = (short) motion->axis_data[3];
- yTilt = (short) motion->axis_data[4];
- rotation = ((short) motion->axis_data[5]) / 64.0;
- pressure = (short) motion->axis_data[2];
- modifiers = X11->translateModifiers(motion->state);
- hiRes = tablet->scaleCoord(motion->axis_data[0], motion->axis_data[1],
- screenArea.x(), screenArea.width(),
- screenArea.y(), screenArea.height());
- } else if (button) {
- xTilt = (short) button->axis_data[3];
- yTilt = (short) button->axis_data[4];
- rotation = ((short) button->axis_data[5]) / 64.0;
- pressure = (short) button->axis_data[2];
- modifiers = X11->translateModifiers(button->state);
- hiRes = tablet->scaleCoord(button->axis_data[0], button->axis_data[1],
- screenArea.x(), screenArea.width(),
- screenArea.y(), screenArea.height());
- } else if (proximity) {
- pressure = 0;
- modifiers = 0;
- }
- if (deviceType == QTabletEvent::Airbrush) {
- tangentialPressure = rotation;
- rotation = 0.;
- }
-#endif
-
- if (tablet->widgetToGetPress) {
- w = tablet->widgetToGetPress;
- } else {
- QWidget *child = w->childAt(curr);
- if (child)
- w = child;
- }
- curr = w->mapFromGlobal(global);
-
- if (t == QEvent::TabletPress) {
- tablet->widgetToGetPress = w;
- } else if (t == QEvent::TabletRelease && tablet->widgetToGetPress) {
- w = tablet->widgetToGetPress;
- curr = w->mapFromGlobal(global);
- tablet->widgetToGetPress = 0;
- }
-
- QTabletEvent e(t, curr, global, hiRes,
- deviceType, pointerType,
- qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
- xTilt, yTilt, tangentialPressure, rotation, z, modifiers, uid);
- if (proximity) {
- QApplication::sendSpontaneousEvent(qApp, &e);
- } else {
- QApplication::sendSpontaneousEvent(w, &e);
- const bool accepted = e.isAccepted();
- if (!accepted && ev->type == tablet->xinput_motion) {
- // If the widget does not accept tablet events, we drop the next ones from the event queue
- // for this widget so it is not overloaded with the numerous tablet events.
- qt_tablet_motion_data tabletMotionData;
- tabletMotionData.tabletMotionType = tablet->xinput_motion;
- tabletMotionData.widget = w;
- tabletMotionData.etWidget = this;
- // if nothing is pressed, the events are filtered by position
- tabletMotionData.filterByWidget = (tablet->widgetToGetPress == 0);
-
- bool reinsertMouseEvent = false;
- XEvent mouseMotionEvent;
- while (true) {
- // Find first mouse event since we expect them in pairs inside Qt
- tabletMotionData.error =false;
- if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
- reinsertMouseEvent = true;
- } else {
- break;
- }
-
- // Now discard any duplicate tablet events.
- tabletMotionData.error = false;
- XEvent dummy;
- while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
- // just discard the event
- }
- }
-
- if (reinsertMouseEvent) {
- XPutBackEvent(X11->display, &mouseMotionEvent);
- }
- }
- }
- return true;
-}
-#endif
-
-bool QETWidget::translatePropertyEvent(const XEvent *event)
-{
- Q_D(QWidget);
- if (!isWindow()) return true;
-
- Atom ret;
- int format, e;
- unsigned char *data = 0;
- unsigned long nitems, after;
-
- if (event->xproperty.atom == ATOM(_KDE_NET_WM_FRAME_STRUT)) {
- this->data->fstrut_dirty = 1;
-
- if (event->xproperty.state == PropertyNewValue) {
- e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_KDE_NET_WM_FRAME_STRUT),
- 0, 4, // struts are 4 longs
- False, XA_CARDINAL, &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == XA_CARDINAL &&
- format == 32 && nitems == 4) {
- long *strut = (long *) data;
- d->topData()->frameStrut.setCoords(strut[0], strut[2], strut[1], strut[3]);
- this->data->fstrut_dirty = 0;
- }
- }
- } else if (event->xproperty.atom == ATOM(_NET_WM_STATE)) {
- bool max = false;
- bool full = false;
- Qt::WindowStates oldState = Qt::WindowStates(this->data->window_state);
-
- if (event->xproperty.state == PropertyNewValue) {
- // using length of 1024 should be safe for all current and
- // possible NET states...
- e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_NET_WM_STATE), 0, 1024,
- False, XA_ATOM, &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == XA_ATOM && format == 32 && nitems > 0) {
- Atom *states = (Atom *) data;
-
- unsigned long i;
- uint maximized = 0;
- for (i = 0; i < nitems; i++) {
- if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- maximized |= 1;
- else if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
- maximized |= 2;
- else if (states[i] == ATOM(_NET_WM_STATE_FULLSCREEN))
- full = true;
- }
- if (maximized == 3) {
- // only set maximized if both horizontal and vertical properties are set
- max = true;
- }
- }
- }
-
- bool send_event = false;
-
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))) {
- if (max && !isMaximized()) {
- this->data->window_state = this->data->window_state | Qt::WindowMaximized;
- send_event = true;
- } else if (!max && isMaximized()) {
- this->data->window_state &= ~Qt::WindowMaximized;
- send_event = true;
- }
- }
-
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
- if (full && !isFullScreen()) {
- this->data->window_state = this->data->window_state | Qt::WindowFullScreen;
- send_event = true;
- } else if (!full && isFullScreen()) {
- this->data->window_state &= ~Qt::WindowFullScreen;
- send_event = true;
- }
- }
-
- if (send_event) {
- QWindowStateChangeEvent e(oldState);
- QApplication::sendSpontaneousEvent(this, &e);
- }
- } else if (event->xproperty.atom == ATOM(WM_STATE)) {
- // the widget frame strut should also be invalidated
- this->data->fstrut_dirty = 1;
-
- if (event->xproperty.state == PropertyDelete) {
- // the window manager has removed the WM State property,
- // so it is now in the withdrawn state (ICCCM 4.1.3.1) and
- // we are free to reuse this window
- d->topData()->parentWinId = 0;
- d->topData()->validWMState = 0;
- // map the window if we were waiting for a transition to
- // withdrawn
- if (X11->deferred_map.removeAll(this)) {
- doDeferredMap();
- } else if (isVisible()
- && !testAttribute(Qt::WA_Mapped)
- && !testAttribute(Qt::WA_OutsideWSRange)) {
- // so that show() will work again. As stated in the
- // ICCCM section 4.1.4: "Only the client can effect a
- // transition into or out of the Withdrawn state.",
- // but apparently this particular window manager
- // doesn't seem to care
- setAttribute(Qt::WA_WState_ExplicitShowHide, false);
- setAttribute(Qt::WA_WState_Visible, false);
- }
- } else {
- // the window manager has changed the WM State property...
- // we are wanting to see if we are withdrawn so that we
- // can reuse this window...
- e = XGetWindowProperty(X11->display, internalWinId(), ATOM(WM_STATE), 0, 2, False,
- ATOM(WM_STATE), &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == ATOM(WM_STATE) && format == 32 && nitems > 0) {
- long *state = (long *) data;
- switch (state[0]) {
- case WithdrawnState:
- // if we are in the withdrawn state, we are free
- // to reuse this window provided we remove the
- // WM_STATE property (ICCCM 4.1.3.1)
- XDeleteProperty(X11->display, internalWinId(), ATOM(WM_STATE));
-
- // set the parent id to zero, so that show() will
- // work again
- d->topData()->parentWinId = 0;
- d->topData()->validWMState = 0;
- // map the window if we were waiting for a
- // transition to withdrawn
- if (X11->deferred_map.removeAll(this)) {
- doDeferredMap();
- } else if (isVisible()
- && !testAttribute(Qt::WA_Mapped)
- && !testAttribute(Qt::WA_OutsideWSRange)) {
- // so that show() will work again. As stated
- // in the ICCCM section 4.1.4: "Only the
- // client can effect a transition into or out
- // of the Withdrawn state.", but apparently
- // this particular window manager doesn't seem
- // to care
- setAttribute(Qt::WA_WState_ExplicitShowHide, false);
- setAttribute(Qt::WA_WState_Visible, false);
- }
- break;
-
- case IconicState:
- d->topData()->validWMState = 1;
- if (!isMinimized()) {
- // window was minimized
- this->data->window_state = this->data->window_state | Qt::WindowMinimized;
- QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state & ~Qt::WindowMinimized));
- QApplication::sendSpontaneousEvent(this, &e);
- }
- break;
-
- default:
- d->topData()->validWMState = 1;
- if (isMinimized()) {
- // window was un-minimized
- this->data->window_state &= ~Qt::WindowMinimized;
- QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state | Qt::WindowMinimized));
- QApplication::sendSpontaneousEvent(this, &e);
- }
- break;
- }
- }
- }
- } else if (event->xproperty.atom == ATOM(_NET_WM_WINDOW_OPACITY)) {
- // the window opacity was changed
- if (event->xproperty.state == PropertyNewValue) {
- e = XGetWindowProperty(event->xclient.display,
- event->xclient.window,
- ATOM(_NET_WM_WINDOW_OPACITY),
- 0, 1, False, XA_CARDINAL,
- &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 1
- && after == 0 && data) {
- ulong value = *(ulong*)(data);
- d->topData()->opacity = uint(value >> 24);
- }
- } else
- d->topData()->opacity = 255;
- }
-
- if (data)
- XFree(data);
-
- return true;
-}
-
-
-//
-// Paint event translation
-//
-// When receiving many expose events, we compress them (union of all expose
-// rectangles) into one event which is sent to the widget.
-
-struct PaintEventInfo {
- Window window;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool isPaintOrScrollDoneEvent(Display *, XEvent *ev, XPointer a)
-{
- PaintEventInfo *info = (PaintEventInfo *)a;
- if (ev->type == Expose || ev->type == GraphicsExpose
- || (ev->type == ClientMessage && ev->xclient.message_type == ATOM(_QT_SCROLL_DONE)))
- {
- if (ev->xexpose.window == info->window)
- return True;
- }
- return False;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-
-
-static
-bool translateBySips(QWidget* that, QRect& paintRect)
-{
- int dx=0, dy=0;
- int sips=0;
- for (int i = 0; i < X11->sip_list.size(); ++i) {
- const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
- if (sip.scrolled_widget == that) {
- if (sips) {
- dx += sip.dx;
- dy += sip.dy;
- }
- sips++;
- }
- }
- if (sips > 1) {
- paintRect.translate(dx, dy);
- return true;
- }
- return false;
-}
-
-void QETWidget::translatePaintEvent(const XEvent *event)
-{
- if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
- Q_ASSERT(internalWinId());
-
- Q_D(QWidget);
- QRect paintRect(event->xexpose.x, event->xexpose.y,
- event->xexpose.width, event->xexpose.height);
- XEvent xevent;
- PaintEventInfo info;
- info.window = internalWinId();
- translateBySips(this, paintRect);
- paintRect = d->mapFromWS(paintRect);
-
- QRegion paintRegion = paintRect;
-
- // WARNING: this is O(number_of_events * number_of_matching_events)
- while (XCheckIfEvent(X11->display,&xevent,isPaintOrScrollDoneEvent,
- (XPointer)&info) &&
- !qt_x11EventFilter(&xevent) &&
- !x11Event(&xevent)) // send event through filter
- {
- if (xevent.type == Expose || xevent.type == GraphicsExpose) {
- QRect exposure(xevent.xexpose.x,
- xevent.xexpose.y,
- xevent.xexpose.width,
- xevent.xexpose.height);
- translateBySips(this, exposure);
- exposure = d->mapFromWS(exposure);
- paintRegion |= exposure;
- } else {
- translateScrollDoneEvent(&xevent);
- }
- }
-
- if (!paintRegion.isEmpty() && !testAttribute(Qt::WA_WState_ConfigPending))
- d->syncBackingStore(paintRegion);
-}
-
-//
-// Scroll-done event translation.
-//
-
-bool QETWidget::translateScrollDoneEvent(const XEvent *event)
-{
- long id = event->xclient.data.l[0];
-
- // Remove any scroll-in-progress record for the given id.
- for (int i = 0; i < X11->sip_list.size(); ++i) {
- const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
- if (sip.id == id) {
- X11->sip_list.removeAt(i);
- return true;
- }
- }
-
- return false;
-}
-
-//
-// ConfigureNotify (window move and resize) event translation
-
-bool QETWidget::translateConfigEvent(const XEvent *event)
-{
- Q_ASSERT((!isWindow() && !testAttribute(Qt::WA_NativeWindow)) ? internalWinId() : true);
-
- Q_D(QWidget);
- bool wasResize = testAttribute(Qt::WA_WState_ConfigPending); // set in QWidget::setGeometry_sys()
- setAttribute(Qt::WA_WState_ConfigPending, false);
-
- if (testAttribute(Qt::WA_OutsideWSRange)) {
- // discard events for windows that have a geometry X can't handle
- XEvent xevent;
- while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
- !qt_x11EventFilter(&xevent) &&
- !x11Event(&xevent)) // send event through filter
- ;
- return true;
- }
-
- const QSize oldSize = size();
-
- if (isWindow()) {
- QPoint newCPos(geometry().topLeft());
- QSize newSize(event->xconfigure.width, event->xconfigure.height);
-
- bool trust = isVisible()
- && (d->topData()->parentWinId == XNone ||
- d->topData()->parentWinId == QX11Info::appRootWindow());
- bool isCPos = false;
-
- if (event->xconfigure.send_event || trust) {
- // if a ConfigureNotify comes from a real sendevent request, we can
- // trust its values.
- newCPos.rx() = event->xconfigure.x + event->xconfigure.border_width;
- newCPos.ry() = event->xconfigure.y + event->xconfigure.border_width;
- isCPos = true;
- }
- if (isVisible())
- QApplication::syncX();
-
- if (d->extra->compress_events) {
- // ConfigureNotify compression for faster opaque resizing
- XEvent otherEvent;
- while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify,
- &otherEvent)) {
- if (qt_x11EventFilter(&otherEvent))
- continue;
-
- if (x11Event(&otherEvent))
- continue;
-
- if (otherEvent.xconfigure.event != otherEvent.xconfigure.window)
- continue;
-
- newSize.setWidth(otherEvent.xconfigure.width);
- newSize.setHeight(otherEvent.xconfigure.height);
-
- if (otherEvent.xconfigure.send_event || trust) {
- newCPos.rx() = otherEvent.xconfigure.x +
- otherEvent.xconfigure.border_width;
- newCPos.ry() = otherEvent.xconfigure.y +
- otherEvent.xconfigure.border_width;
- isCPos = true;
- }
- }
-#ifndef QT_NO_XSYNC
- qt_sync_request_event_data sync_event;
- sync_event.window = internalWinId();
- for (XEvent ev;;) {
- if (!XCheckIfEvent(X11->display, &ev, &qt_sync_request_scanner, (XPointer)&sync_event))
- break;
- }
-#endif // QT_NO_XSYNC
- }
-
- if (!isCPos) {
- // we didn't get an updated position of the toplevel.
- // either we haven't moved or there is a bug in the window manager.
- // anyway, let's query the position to be certain.
- int x, y;
- Window child;
- XTranslateCoordinates(X11->display, internalWinId(),
- QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
- 0, 0, &x, &y, &child);
- newCPos.rx() = x;
- newCPos.ry() = y;
- }
-
- QRect cr (geometry());
- if (newCPos != cr.topLeft()) { // compare with cpos (exluding frame)
- QPoint oldPos = geometry().topLeft();
- cr.moveTopLeft(newCPos);
- data->crect = cr;
- if (isVisible()) {
- QMoveEvent e(newCPos, oldPos); // pos (including frame), not cpos
- QApplication::sendSpontaneousEvent(this, &e);
- } else {
- setAttribute(Qt::WA_PendingMoveEvent, true);
- }
- }
- if (newSize != cr.size()) { // size changed
- cr.setSize(newSize);
- data->crect = cr;
-
- uint old_state = data->window_state;
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
- data->window_state &= ~Qt::WindowMaximized;
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
- data->window_state &= ~Qt::WindowFullScreen;
-
- if (old_state != data->window_state) {
- QWindowStateChangeEvent e((Qt::WindowStates) old_state);
- QApplication::sendEvent(this, &e);
- }
-
- if (!isVisible())
- setAttribute(Qt::WA_PendingResizeEvent, true);
- wasResize = true;
- }
-
- } else {
- XEvent xevent;
- while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
- !qt_x11EventFilter(&xevent) &&
- !x11Event(&xevent)) // send event through filter
- ;
- }
-
- if (wasResize) {
- if (isVisible() && data->crect.size() != oldSize) {
- Q_ASSERT(d->extra->topextra);
- QWidgetBackingStore *bs = d->extra->topextra->backingStore.data();
- const bool hasStaticContents = bs && bs->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 (!hasStaticContents)
- d->extra->topextra->inTopLevelResize = true;
- QResizeEvent e(data->crect.size(), oldSize);
- QApplication::sendSpontaneousEvent(this, &e);
- }
-
- const bool waitingForMapNotify = d->extra->topextra && d->extra->topextra->waitingForMapNotify;
- if (!waitingForMapNotify) {
- if (d->paintOnScreen()) {
- QRegion updateRegion(rect());
- if (testAttribute(Qt::WA_StaticContents))
- updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
- d->syncBackingStore(updateRegion);
- } else {
- d->syncBackingStore();
- }
- }
-
- if (d->extra && d->extra->topextra)
- d->extra->topextra->inTopLevelResize = false;
- }
-#ifndef QT_NO_XSYNC
- if (QTLWExtra *tlwExtra = d->maybeTopData()) {
- if (tlwExtra->newCounterValueLo != 0 || tlwExtra->newCounterValueHi != 0) {
- XSyncValue value;
- XSyncIntsToValue(&value,
- tlwExtra->newCounterValueLo,
- tlwExtra->newCounterValueHi);
-
- XSyncSetCounter(X11->display, tlwExtra->syncUpdateCounter, value);
- tlwExtra->newCounterValueHi = 0;
- tlwExtra->newCounterValueLo = 0;
- }
- }
-#endif
- return true;
-}
-
-//
-// Close window event translation.
-//
-bool QETWidget::translateCloseEvent(const XEvent *)
-{
- Q_D(QWidget);
- return d->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
-}
-
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-int QApplication::cursorFlashTime()
-{
- return QApplicationPrivate::cursor_flash_time;
-}
-
-void QApplication::setDoubleClickInterval(int ms)
-{
- QApplicationPrivate::mouse_double_click_time = ms;
-}
-
-int QApplication::doubleClickInterval()
-{
- return QApplicationPrivate::mouse_double_click_time;
-}
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::keyboardInputInterval()
-{
- return QApplicationPrivate::keyboard_input_time;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int n)
-{
- QApplicationPrivate::wheel_scroll_lines = n;
-}
-
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-#endif
-
-void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-{
- switch (effect) {
- case Qt::UI_AnimateMenu:
- if (enable) QApplicationPrivate::fade_menu = false;
- QApplicationPrivate::animate_menu = enable;
- break;
- case Qt::UI_FadeMenu:
- if (enable)
- QApplicationPrivate::animate_menu = true;
- QApplicationPrivate::fade_menu = enable;
- break;
- case Qt::UI_AnimateCombo:
- QApplicationPrivate::animate_combo = enable;
- break;
- case Qt::UI_AnimateTooltip:
- if (enable) QApplicationPrivate::fade_tooltip = false;
- QApplicationPrivate::animate_tooltip = enable;
- break;
- case Qt::UI_FadeTooltip:
- if (enable)
- QApplicationPrivate::animate_tooltip = true;
- 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 || !QApplicationPrivate::animate_ui)
- return false;
-
- 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;
- }
-}
-
-/*****************************************************************************
- Session management support
- *****************************************************************************/
-
-#ifndef QT_NO_SESSIONMANAGER
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <X11/SM/SMlib.h>
-QT_END_INCLUDE_NAMESPACE
-
-class QSessionManagerPrivate : public QObjectPrivate
-{
-public:
- QSessionManagerPrivate(QSessionManager* mgr, QString& id, QString& key)
- : QObjectPrivate(), sm(mgr), sessionId(id), sessionKey(key),
- restartHint(QSessionManager::RestartIfRunning), eventLoop(0) {}
- QSessionManager* sm;
- QStringList restartCommand;
- QStringList discardCommand;
- QString& sessionId;
- QString& sessionKey;
- QSessionManager::RestartHint restartHint;
- QEventLoop *eventLoop;
-};
-
-class QSmSocketReceiver : public QObject
-{
- Q_OBJECT
-public:
- QSmSocketReceiver(int socket)
- {
- QSocketNotifier* sn = new QSocketNotifier(socket, QSocketNotifier::Read, this);
- connect(sn, SIGNAL(activated(int)), this, SLOT(socketActivated(int)));
- }
-
-public slots:
- void socketActivated(int);
-};
-
-
-static SmcConn smcConnection = 0;
-static bool sm_interactionActive;
-static bool sm_smActive;
-static int sm_interactStyle;
-static int sm_saveType;
-static bool sm_cancel;
-// static bool sm_waitingForPhase2; ### never used?!?
-static bool sm_waitingForInteraction;
-static bool sm_isshutdown;
-// static bool sm_shouldbefast; ### never used?!?
-static bool sm_phase2;
-static bool sm_in_phase2;
-
-static QSmSocketReceiver* sm_receiver = 0;
-
-static void resetSmState();
-static void sm_setProperty(const char* name, const char* type,
- int num_vals, SmPropValue* vals);
-static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
- int saveType, Bool shutdown , int interactStyle, Bool fast);
-static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData) ;
-static void sm_dieCallback(SmcConn smcConn, SmPointer clientData) ;
-static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData);
-static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer clientData);
-static void sm_interactCallback(SmcConn smcConn, SmPointer clientData);
-static void sm_performSaveYourself(QSessionManagerPrivate*);
-
-static void resetSmState()
-{
-// sm_waitingForPhase2 = false; ### never used?!?
- sm_waitingForInteraction = false;
- sm_interactionActive = false;
- sm_interactStyle = SmInteractStyleNone;
- sm_smActive = false;
- qt_sm_blockUserInput = false;
- sm_isshutdown = false;
-// sm_shouldbefast = false; ### never used?!?
- sm_phase2 = false;
- sm_in_phase2 = false;
-}
-
-
-// theoretically it's possible to set several properties at once. For
-// simplicity, however, we do just one property at a time
-static void sm_setProperty(const char* name, const char* type,
- int num_vals, SmPropValue* vals)
-{
- if (num_vals) {
- SmProp prop;
- prop.name = (char*)name;
- prop.type = (char*)type;
- prop.num_vals = num_vals;
- prop.vals = vals;
-
- SmProp* props[1];
- props[0] = &prop;
- SmcSetProperties(smcConnection, 1, props);
- }
- else {
- char* names[1];
- names[0] = (char*) name;
- SmcDeleteProperties(smcConnection, 1, names);
- }
-}
-
-static void sm_setProperty(const QString& name, const QString& value)
-{
- QByteArray v = value.toUtf8();
- SmPropValue prop;
- prop.length = v.length();
- prop.value = (SmPointer) v.constData();
- sm_setProperty(name.toLatin1().data(), SmARRAY8, 1, &prop);
-}
-
-static void sm_setProperty(const QString& name, const QStringList& value)
-{
- SmPropValue *prop = new SmPropValue[value.count()];
- int count = 0;
- QList<QByteArray> vl;
- for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
- prop[count].length = (*it).length();
- vl.append((*it).toUtf8());
- prop[count].value = (char*)vl.last().data();
- ++count;
- }
- sm_setProperty(name.toLatin1().data(), SmLISTofARRAY8, count, prop);
- delete [] prop;
-}
-
-
-// workaround for broken libsm, see below
-struct QT_smcConn {
- unsigned int save_yourself_in_progress : 1;
- unsigned int shutdown_in_progress : 1;
-};
-
-static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
- int saveType, Bool shutdown , int interactStyle, Bool /*fast*/)
-{
- if (smcConn != smcConnection)
- return;
- sm_cancel = false;
- sm_smActive = true;
- sm_isshutdown = shutdown;
- sm_saveType = saveType;
- sm_interactStyle = interactStyle;
-// sm_shouldbefast = fast; ### never used?!?
-
- // ugly workaround for broken libSM. libSM should do that _before_
- // actually invoking the callback in sm_process.c
- ((QT_smcConn*)smcConn)->save_yourself_in_progress = true;
- if (sm_isshutdown)
- ((QT_smcConn*)smcConn)->shutdown_in_progress = true;
-
- sm_performSaveYourself((QSessionManagerPrivate*) clientData);
- if (!sm_isshutdown) // we cannot expect a confirmation message in that case
- resetSmState();
-}
-
-static void sm_performSaveYourself(QSessionManagerPrivate* smd)
-{
- if (sm_isshutdown)
- qt_sm_blockUserInput = true;
-
- QSessionManager* sm = smd->sm;
-
- // generate a new session key
- timeval tv;
- gettimeofday(&tv, 0);
- smd->sessionKey = QString::number(qulonglong(tv.tv_sec)) + QLatin1Char('_') + QString::number(qulonglong(tv.tv_usec));
-
- QStringList arguments = qApp->arguments();
- QString argument0 = arguments.isEmpty() ? qApp->applicationFilePath() : arguments.at(0);
-
- // tell the session manager about our program in best POSIX style
- sm_setProperty(QString::fromLatin1(SmProgram), argument0);
- // tell the session manager about our user as well.
- struct passwd *entryPtr = 0;
-#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
- QVarLengthArray<char, 1024> buf(qMax<long>(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L));
- struct passwd entry;
- while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) {
- if (buf.size() >= 32768) {
- // too big already, fail
- static char badusername[] = "";
- entryPtr = &entry;
- entry.pw_name = badusername;
- break;
- }
-
- // retry with a bigger buffer
- buf.resize(buf.size() * 2);
- }
-#else
- entryPtr = getpwuid(geteuid());
-#endif
- if (entryPtr)
- sm_setProperty(QString::fromLatin1(SmUserID), QString::fromLatin1(entryPtr->pw_name));
-
- // generate a restart and discard command that makes sense
- QStringList restart;
- restart << argument0 << QLatin1String("-session")
- << smd->sessionId + QLatin1Char('_') + smd->sessionKey;
- if (qstricmp(appName, QX11Info::appClass()) != 0)
- restart << QLatin1String("-name") << qAppName();
- sm->setRestartCommand(restart);
- QStringList discard;
- sm->setDiscardCommand(discard);
-
- switch (sm_saveType) {
- case SmSaveBoth:
- qApp->commitData(*sm);
- if (sm_isshutdown && sm_cancel)
- break; // we cancelled the shutdown, no need to save state
- // fall through
- case SmSaveLocal:
- qApp->saveState(*sm);
- break;
- case SmSaveGlobal:
- qApp->commitData(*sm);
- break;
- default:
- break;
- }
-
- if (sm_phase2 && !sm_in_phase2) {
- SmcRequestSaveYourselfPhase2(smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) smd);
- qt_sm_blockUserInput = false;
- }
- else {
- // close eventual interaction monitors and cancel the
- // shutdown, if required. Note that we can only cancel when
- // performing a shutdown, it does not work for checkpoints
- if (sm_interactionActive) {
- SmcInteractDone(smcConnection, sm_isshutdown && sm_cancel);
- sm_interactionActive = false;
- }
- else if (sm_cancel && sm_isshutdown) {
- if (sm->allowsErrorInteraction()) {
- SmcInteractDone(smcConnection, True);
- sm_interactionActive = false;
- }
- }
-
- // set restart and discard command in session manager
- sm_setProperty(QString::fromLatin1(SmRestartCommand), sm->restartCommand());
- sm_setProperty(QString::fromLatin1(SmDiscardCommand), sm->discardCommand());
-
- // set the restart hint
- SmPropValue prop;
- prop.length = sizeof(int);
- int value = sm->restartHint();
- prop.value = (SmPointer) &value;
- sm_setProperty(SmRestartStyleHint, SmCARD8, 1, &prop);
-
- // we are done
- SmcSaveYourselfDone(smcConnection, !sm_cancel);
- }
-}
-
-static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */)
-{
- if (smcConn != smcConnection)
- return;
- resetSmState();
- QEvent quitEvent(QEvent::Quit);
- QApplication::sendEvent(qApp, &quitEvent);
-}
-
-static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData)
-{
- if (smcConn != smcConnection)
- return;
- if (sm_waitingForInteraction)
- ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
- resetSmState();
-}
-
-static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer /*clientData */)
-{
- if (smcConn != smcConnection)
- return;
- resetSmState();
-}
-
-static void sm_interactCallback(SmcConn smcConn, SmPointer clientData)
-{
- if (smcConn != smcConnection)
- return;
- if (sm_waitingForInteraction)
- ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
-}
-
-static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData)
-{
- if (smcConn != smcConnection)
- return;
- sm_in_phase2 = true;
- sm_performSaveYourself((QSessionManagerPrivate*) clientData);
-}
-
-
-void QSmSocketReceiver::socketActivated(int)
-{
- IceProcessMessages(SmcGetIceConnection(smcConnection), 0, 0);
-}
-
-
-#undef Bool
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qapplication_x11.moc"
-QT_END_INCLUDE_NAMESPACE
-
-QSessionManager::QSessionManager(QApplication * app, QString &id, QString& key)
- : QObject(*new QSessionManagerPrivate(this, id, key), app)
-{
- Q_D(QSessionManager);
- d->restartHint = RestartIfRunning;
-
- resetSmState();
- char cerror[256];
- char* myId = 0;
- QByteArray b_id = id.toLatin1();
- char* prevId = b_id.data();
-
- SmcCallbacks cb;
- cb.save_yourself.callback = sm_saveYourselfCallback;
- cb.save_yourself.client_data = (SmPointer) d;
- cb.die.callback = sm_dieCallback;
- cb.die.client_data = (SmPointer) d;
- cb.save_complete.callback = sm_saveCompleteCallback;
- cb.save_complete.client_data = (SmPointer) d;
- cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
- cb.shutdown_cancelled.client_data = (SmPointer) d;
-
- // avoid showing a warning message below
- if (qgetenv("SESSION_MANAGER").isEmpty())
- return;
-
- smcConnection = SmcOpenConnection(0, 0, 1, 0,
- SmcSaveYourselfProcMask |
- SmcDieProcMask |
- SmcSaveCompleteProcMask |
- SmcShutdownCancelledProcMask,
- &cb,
- prevId,
- &myId,
- 256, cerror);
-
- id = QString::fromLatin1(myId);
- ::free(myId); // it was allocated by C
-
- QString error = QString::fromLocal8Bit(cerror);
- if (!smcConnection) {
- qWarning("Qt: Session management error: %s", qPrintable(error));
- }
- else {
- sm_receiver = new QSmSocketReceiver(IceConnectionNumber(SmcGetIceConnection(smcConnection)));
- }
-}
-
-QSessionManager::~QSessionManager()
-{
- if (smcConnection)
- SmcCloseConnection(smcConnection, 0, 0);
- smcConnection = 0;
- delete sm_receiver;
-}
-
-QString QSessionManager::sessionId() const
-{
- Q_D(const QSessionManager);
- return d->sessionId;
-}
-
-QString QSessionManager::sessionKey() const
-{
- Q_D(const QSessionManager);
- return d->sessionKey;
-}
-
-
-void* QSessionManager::handle() const
-{
- return (void*) smcConnection;
-}
-
-
-bool QSessionManager::allowsInteraction()
-{
- Q_D(QSessionManager);
- if (sm_interactionActive)
- return true;
-
- if (sm_waitingForInteraction)
- return false;
-
- if (sm_interactStyle == SmInteractStyleAny) {
- sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogNormal,
- sm_interactCallback, (SmPointer*) d);
- }
- if (sm_waitingForInteraction) {
- QEventLoop eventLoop;
- d->eventLoop = &eventLoop;
- (void) eventLoop.exec();
- d->eventLoop = 0;
-
- sm_waitingForInteraction = false;
- if (sm_smActive) { // not cancelled
- sm_interactionActive = true;
- qt_sm_blockUserInput = false;
- return true;
- }
- }
- return false;
-}
-
-bool QSessionManager::allowsErrorInteraction()
-{
- Q_D(QSessionManager);
- if (sm_interactionActive)
- return true;
-
- if (sm_waitingForInteraction)
- return false;
-
- if (sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors) {
- sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogError,
- sm_interactCallback, (SmPointer*) d);
- }
- if (sm_waitingForInteraction) {
- QEventLoop eventLoop;
- d->eventLoop = &eventLoop;
- (void) eventLoop.exec();
- d->eventLoop = 0;
-
- sm_waitingForInteraction = false;
- if (sm_smActive) { // not cancelled
- sm_interactionActive = true;
- qt_sm_blockUserInput = false;
- return true;
- }
- }
- return false;
-}
-
-void QSessionManager::release()
-{
- if (sm_interactionActive) {
- SmcInteractDone(smcConnection, False);
- sm_interactionActive = false;
- if (sm_smActive && sm_isshutdown)
- qt_sm_blockUserInput = true;
- }
-}
-
-void QSessionManager::cancel()
-{
- sm_cancel = true;
-}
-
-void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
-{
- Q_D(QSessionManager);
- d->restartHint = hint;
-}
-
-QSessionManager::RestartHint QSessionManager::restartHint() const
-{
- Q_D(const QSessionManager);
- return d->restartHint;
-}
-
-void QSessionManager::setRestartCommand(const QStringList& command)
-{
- Q_D(QSessionManager);
- d->restartCommand = command;
-}
-
-QStringList QSessionManager::restartCommand() const
-{
- Q_D(const QSessionManager);
- return d->restartCommand;
-}
-
-void QSessionManager::setDiscardCommand(const QStringList& command)
-{
- Q_D(QSessionManager);
- d->discardCommand = command;
-}
-
-QStringList QSessionManager::discardCommand() const
-{
- Q_D(const QSessionManager);
- return d->discardCommand;
-}
-
-void QSessionManager::setManagerProperty(const QString& name, const QString& value)
-{
- sm_setProperty(name, value);
-}
-
-void QSessionManager::setManagerProperty(const QString& name, const QStringList& value)
-{
- sm_setProperty(name, value);
-}
-
-bool QSessionManager::isPhase2() const
-{
- return sm_in_phase2;
-}
-
-void QSessionManager::requestPhase2()
-{
- sm_phase2 = true;
-}
-
-#endif // QT_NO_SESSIONMANAGER
-
-#if defined(QT_RX71_MULTITOUCH)
-
-static inline int testBit(const char *array, int bit)
-{
- return (array[bit/8] & (1<<(bit%8)));
-}
-
-static int openRX71Device(const QByteArray &deviceName)
-{
- int fd = open(deviceName, O_RDONLY | O_NONBLOCK);
- if (fd == -1) {
- fd = -errno;
- return fd;
- }
-
- // fetch the event type mask and check that the device reports absolute coordinates
- char eventTypeMask[(EV_MAX + sizeof(char) - 1) * sizeof(char) + 1];
- memset(eventTypeMask, 0, sizeof(eventTypeMask));
- if (ioctl(fd, EVIOCGBIT(0, sizeof(eventTypeMask)), eventTypeMask) < 0) {
- close(fd);
- return -1;
- }
- if (!testBit(eventTypeMask, EV_ABS)) {
- close(fd);
- return -1;
- }
-
- // make sure that we can get the absolute X and Y positions from the device
- char absMask[(ABS_MAX + sizeof(char) - 1) * sizeof(char) + 1];
- memset(absMask, 0, sizeof(absMask));
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absMask)), absMask) < 0) {
- close(fd);
- return -1;
- }
- if (!testBit(absMask, ABS_X) || !testBit(absMask, ABS_Y)) {
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{
- Q_Q(QApplication);
-
- QByteArray deviceName = QByteArray("/dev/input/event");
- int currentDeviceNumber = 0;
- for (;;) {
- int fd = openRX71Device(QByteArray(deviceName + QByteArray::number(currentDeviceNumber++)));
- if (fd == -ENOENT) {
- // no more devices
- break;
- }
- if (fd < 0) {
- // not a touch device
- continue;
- }
-
- struct input_absinfo abs_x, abs_y, abs_z;
- ioctl(fd, EVIOCGABS(ABS_X), &abs_x);
- ioctl(fd, EVIOCGABS(ABS_Y), &abs_y);
- ioctl(fd, EVIOCGABS(ABS_Z), &abs_z);
-
- int deviceNumber = allRX71TouchPoints.count();
-
- QSocketNotifier *socketNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
- QObject::connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(_q_readRX71MultiTouchEvents()));
-
- RX71TouchPointState touchPointState = {
- socketNotifier,
- QTouchEvent::TouchPoint(deviceNumber),
-
- abs_x.minimum, abs_x.maximum, q->desktop()->screenGeometry().width(),
- abs_y.minimum, abs_y.maximum, q->desktop()->screenGeometry().height(),
- abs_z.minimum, abs_z.maximum
- };
- allRX71TouchPoints.append(touchPointState);
- }
-
- hasRX71MultiTouch = allRX71TouchPoints.count() > 1;
- if (!hasRX71MultiTouch) {
- for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
- QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
- close(socketNotifier->socket());
- delete socketNotifier;
- }
- allRX71TouchPoints.clear();
- }
-}
-
-void QApplicationPrivate::cleanupMultitouch_sys()
-{
- hasRX71MultiTouch = false;
- for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
- QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
- close(socketNotifier->socket());
- delete socketNotifier;
- }
- allRX71TouchPoints.clear();
-}
-
-bool QApplicationPrivate::readRX71MultiTouchEvents(int deviceNumber)
-{
- RX71TouchPointState &touchPointState = allRX71TouchPoints[deviceNumber];
- QSocketNotifier *socketNotifier = touchPointState.socketNotifier;
- int fd = socketNotifier->socket();
-
- QTouchEvent::TouchPoint &touchPoint = touchPointState.touchPoint;
-
- bool down = touchPoint.state() != Qt::TouchPointReleased;
- if (down)
- touchPoint.setState(Qt::TouchPointStationary);
-
- bool changed = false;
- for (;;) {
- struct input_event inputEvent;
- int bytesRead = read(fd, &inputEvent, sizeof(inputEvent));
- if (bytesRead <= 0)
- break;
- if (bytesRead != sizeof(inputEvent)) {
- qWarning("Qt: INTERNAL ERROR: short read in readRX71MultiTouchEvents()");
- return false;
- }
-
- switch (inputEvent.type) {
- case EV_SYN:
- changed = true;
- switch (touchPoint.state()) {
- case Qt::TouchPointPressed:
- case Qt::TouchPointReleased:
- // make sure we don't compress pressed and releases with any other events
- return changed;
- default:
- break;
- }
- continue;
- case EV_KEY:
- case EV_ABS:
- break;
- default:
- qWarning("Qt: WARNING: unknown event type %d on multitouch device", inputEvent.type);
- continue;
- }
-
- QPointF screenPos = touchPoint.screenPos();
- switch (inputEvent.code) {
- case BTN_TOUCH:
- if (!down && inputEvent.value != 0)
- touchPoint.setState(Qt::TouchPointPressed);
- else if (down && inputEvent.value == 0)
- touchPoint.setState(Qt::TouchPointReleased);
- break;
- case ABS_TOOL_WIDTH:
- case ABS_VOLUME:
- case ABS_PRESSURE:
- // ignore for now
- break;
- case ABS_X:
- {
- qreal newValue = ((qreal(inputEvent.value - touchPointState.minX)
- / qreal(touchPointState.maxX - touchPointState.minX))
- * touchPointState.scaleX);
- screenPos.rx() = newValue;
- touchPoint.setScreenPos(screenPos);
- break;
- }
- case ABS_Y:
- {
- qreal newValue = ((qreal(inputEvent.value - touchPointState.minY)
- / qreal(touchPointState.maxY - touchPointState.minY))
- * touchPointState.scaleY);
- screenPos.ry() = newValue;
- touchPoint.setScreenPos(screenPos);
- break;
- }
- case ABS_Z:
- {
- // map Z (signal strength) to pressure for now
- qreal newValue = (qreal(inputEvent.value - touchPointState.minZ)
- / qreal(touchPointState.maxZ - touchPointState.minZ));
- touchPoint.setPressure(newValue);
- break;
- }
- default:
- qWarning("Qt: WARNING: unknown event code %d on multitouch device", inputEvent.code);
- continue;
- }
- }
-
- if (down && touchPoint.state() != Qt::TouchPointReleased)
- touchPoint.setState(changed ? Qt::TouchPointMoved : Qt::TouchPointStationary);
-
- return changed;
-}
-
-void QApplicationPrivate::_q_readRX71MultiTouchEvents()
-{
- // read touch events from all devices
- bool changed = false;
- for (int i = 0; i < allRX71TouchPoints.count(); ++i)
- changed = readRX71MultiTouchEvents(i) || changed;
- if (!changed)
- return;
-
- QList<QTouchEvent::TouchPoint> touchPoints;
- for (int i = 0; i < allRX71TouchPoints.count(); ++i)
- touchPoints.append(allRX71TouchPoints.at(i).touchPoint);
-
- translateRawTouchEvent(0, QTouchEvent::TouchScreen, touchPoints);
-}
-
-#else // !QT_RX71_MULTITOUCH
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{ }
-void QApplicationPrivate::cleanupMultitouch_sys()
-{ }
-
-#endif // QT_RX71_MULTITOUCH
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qclipboard_x11.cpp b/src/widgets/platforms/x11/qclipboard_x11.cpp
deleted file mode 100644
index 97e076cbc2..0000000000
--- a/src/widgets/platforms/x11/qclipboard_x11.cpp
+++ /dev/null
@@ -1,1539 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// #define QCLIPBOARD_DEBUG
-// #define QCLIPBOARD_DEBUG_VERBOSE
-
-#ifdef QCLIPBOARD_DEBUG
-# define DEBUG qDebug
-#else
-# define DEBUG if (false) qDebug
-#endif
-
-#ifdef QCLIPBOARD_DEBUG_VERBOSE
-# define VDEBUG qDebug
-#else
-# define VDEBUG if (false) qDebug
-#endif
-
-#include "qplatformdefs.h"
-
-#include "qclipboard.h"
-#include "qclipboard_p.h"
-
-#ifndef QT_NO_CLIPBOARD
-
-#include "qabstracteventdispatcher.h"
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#include "qbitmap.h"
-#include "qiodevice.h"
-#include "qbuffer.h"
-#include "qtextcodec.h"
-#include "qlist.h"
-#include "qmap.h"
-#include "qapplication_p.h"
-#include "qevent.h"
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-#include "qimagewriter.h"
-#include "qelapsedtimer.h"
-#include "qvariant.h"
-#include "qdnd_p.h"
-#include <private/qwidget_p.h>
-
-#ifndef QT_NO_XFIXES
-#include <X11/extensions/Xfixes.h>
-#endif // QT_NO_XFIXES
-
-QT_BEGIN_NAMESPACE
-
-/*****************************************************************************
- Internal QClipboard functions for X11.
- *****************************************************************************/
-
-static int clipboard_timeout = 5000; // 5s timeout on clipboard operations
-
-static QWidget * owner = 0;
-static QWidget *requestor = 0;
-static bool timer_event_clear = false;
-static int timer_id = 0;
-
-static int pending_timer_id = 0;
-static bool pending_clipboard_changed = false;
-static bool pending_selection_changed = false;
-
-
-// event capture mechanism for qt_xclb_wait_for_event
-static bool waiting_for_data = false;
-static bool has_captured_event = false;
-static Window capture_event_win = XNone;
-static int capture_event_type = -1;
-static XEvent captured_event;
-
-class QClipboardWatcher; // forward decl
-static QClipboardWatcher *selection_watcher = 0;
-static QClipboardWatcher *clipboard_watcher = 0;
-
-static void cleanup()
-{
- delete owner;
- delete requestor;
- owner = 0;
- requestor = 0;
-}
-
-static
-void setupOwner()
-{
- if (owner)
- return;
- owner = new QWidget(0);
- owner->setObjectName(QLatin1String("internal clipboard owner"));
- owner->createWinId();
- requestor = new QWidget(0);
- requestor->createWinId();
- requestor->setObjectName(QLatin1String("internal clipboard requestor"));
- // We don't need this internal widgets to appear in QApplication::topLevelWidgets()
- if (QWidgetPrivate::allWidgets) {
- QWidgetPrivate::allWidgets->remove(owner);
- QWidgetPrivate::allWidgets->remove(requestor);
- }
- qAddPostRoutine(cleanup);
-}
-
-
-class QClipboardWatcher : public QInternalMimeData {
-public:
- QClipboardWatcher(QClipboard::Mode mode);
- ~QClipboardWatcher();
- bool empty() const;
- virtual bool hasFormat_sys(const QString &mimetype) const;
- virtual QStringList formats_sys() const;
-
- QVariant retrieveData_sys(const QString &mimetype, QVariant::Type type) const;
- QByteArray getDataInFormat(Atom fmtatom) const;
-
- Atom atom;
- mutable QStringList formatList;
- mutable QByteArray format_atoms;
-};
-
-class QClipboardData
-{
-private:
- QMimeData *&mimeDataRef() const
- {
- if(mode == QClipboard::Selection)
- return selectionData;
- return clipboardData;
- }
-
-public:
- QClipboardData(QClipboard::Mode mode);
- ~QClipboardData();
-
- void setSource(QMimeData* s)
- {
- if ((mode == QClipboard::Selection && selectionData == s)
- || clipboardData == s) {
- return;
- }
-
- if (selectionData != clipboardData) {
- delete mimeDataRef();
- }
-
- mimeDataRef() = s;
- }
-
- QMimeData *source() const
- {
- return mimeDataRef();
- }
-
- void clear()
- {
- timestamp = CurrentTime;
- if (selectionData == clipboardData) {
- mimeDataRef() = 0;
- } else {
- QMimeData *&src = mimeDataRef();
- delete src;
- src = 0;
- }
- }
-
- static QMimeData *selectionData;
- static QMimeData *clipboardData;
- Time timestamp;
- QClipboard::Mode mode;
-};
-
-QMimeData *QClipboardData::selectionData = 0;
-QMimeData *QClipboardData::clipboardData = 0;
-
-QClipboardData::QClipboardData(QClipboard::Mode clipboardMode)
-{
- timestamp = CurrentTime;
- mode = clipboardMode;
-}
-
-QClipboardData::~QClipboardData()
-{ clear(); }
-
-
-static QClipboardData *internalCbData = 0;
-static QClipboardData *internalSelData = 0;
-
-static void cleanupClipboardData()
-{
- delete internalCbData;
- internalCbData = 0;
-}
-
-static QClipboardData *clipboardData()
-{
- if (internalCbData == 0) {
- internalCbData = new QClipboardData(QClipboard::Clipboard);
- qAddPostRoutine(cleanupClipboardData);
- }
- return internalCbData;
-}
-
-static void cleanupSelectionData()
-{
- delete internalSelData;
- internalSelData = 0;
-}
-
-static QClipboardData *selectionData()
-{
- if (internalSelData == 0) {
- internalSelData = new QClipboardData(QClipboard::Selection);
- qAddPostRoutine(cleanupSelectionData);
- }
- return internalSelData;
-}
-
-class QClipboardINCRTransaction
-{
-public:
- QClipboardINCRTransaction(Window w, Atom p, Atom t, int f, QByteArray d, unsigned int i);
- ~QClipboardINCRTransaction(void);
-
- int x11Event(XEvent *event);
-
- Window window;
- Atom property, target;
- int format;
- QByteArray data;
- unsigned int increment;
- unsigned int offset;
-};
-
-typedef QMap<Window,QClipboardINCRTransaction*> TransactionMap;
-static TransactionMap *transactions = 0;
-static QApplication::EventFilter prev_event_filter = 0;
-static int incr_timer_id = 0;
-
-static bool qt_x11_incr_event_filter(void *message, long *result)
-{
- XEvent *event = reinterpret_cast<XEvent *>(message);
- TransactionMap::Iterator it = transactions->find(event->xany.window);
- if (it != transactions->end()) {
- if ((*it)->x11Event(event) != 0)
- return true;
- }
- if (prev_event_filter)
- return prev_event_filter(event, result);
- return false;
-}
-
-/*
- called when no INCR activity has happened for 'clipboard_timeout'
- milliseconds... we assume that all unfinished transactions have
- timed out and remove everything from the transaction map
-*/
-static void qt_xclb_incr_timeout(void)
-{
- qWarning("QClipboard: Timed out while sending data");
-
- while (transactions)
- delete *transactions->begin();
-}
-
-QClipboardINCRTransaction::QClipboardINCRTransaction(Window w, Atom p, Atom t, int f,
- QByteArray d, unsigned int i)
- : window(w), property(p), target(t), format(f), data(d), increment(i), offset(0u)
-{
- DEBUG("QClipboard: sending %d bytes (INCR transaction %p)", d.size(), this);
-
- XSelectInput(X11->display, window, PropertyChangeMask);
-
- if (! transactions) {
- VDEBUG("QClipboard: created INCR transaction map");
- transactions = new TransactionMap;
- prev_event_filter = qApp->setEventFilter(qt_x11_incr_event_filter);
- incr_timer_id = QApplication::clipboard()->startTimer(clipboard_timeout);
- }
- transactions->insert(window, this);
-}
-
-QClipboardINCRTransaction::~QClipboardINCRTransaction(void)
-{
- VDEBUG("QClipboard: destroyed INCR transacton %p", this);
-
- XSelectInput(X11->display, window, NoEventMask);
-
- transactions->remove(window);
- if (transactions->isEmpty()) {
- VDEBUG("QClipboard: no more INCR transactions");
- delete transactions;
- transactions = 0;
-
- (void)qApp->setEventFilter(prev_event_filter);
-
- if (incr_timer_id != 0) {
- QApplication::clipboard()->killTimer(incr_timer_id);
- incr_timer_id = 0;
- }
- }
-}
-
-int QClipboardINCRTransaction::x11Event(XEvent *event)
-{
- if (event->type != PropertyNotify
- || (event->xproperty.state != PropertyDelete
- || event->xproperty.atom != property))
- return 0;
-
- // restart the INCR timer
- if (incr_timer_id) QApplication::clipboard()->killTimer(incr_timer_id);
- incr_timer_id = QApplication::clipboard()->startTimer(clipboard_timeout);
-
- unsigned int bytes_left = data.size() - offset;
- if (bytes_left > 0) {
- unsigned int xfer = qMin(increment, bytes_left);
- VDEBUG("QClipboard: sending %d bytes, %d remaining (INCR transaction %p)",
- xfer, bytes_left - xfer, this);
-
- XChangeProperty(X11->display, window, property, target, format,
- PropModeReplace, (uchar *) data.data() + offset, xfer);
- offset += xfer;
- } else {
- // INCR transaction finished...
- XChangeProperty(X11->display, window, property, target, format,
- PropModeReplace, (uchar *) data.data(), 0);
- delete this;
- }
-
- return 1;
-}
-
-
-/*****************************************************************************
- QClipboard member functions for X11.
- *****************************************************************************/
-
-struct qt_init_timestamp_data
-{
- Time timestamp;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool qt_init_timestamp_scanner(Display*, XEvent *event, XPointer arg)
-{
- qt_init_timestamp_data *data =
- reinterpret_cast<qt_init_timestamp_data*>(arg);
- switch(event->type)
- {
- case ButtonPress:
- case ButtonRelease:
- data->timestamp = event->xbutton.time;
- break;
- case MotionNotify:
- data->timestamp = event->xmotion.time;
- break;
- case XKeyPress:
- case XKeyRelease:
- data->timestamp = event->xkey.time;
- break;
- case PropertyNotify:
- data->timestamp = event->xproperty.time;
- break;
- case EnterNotify:
- case LeaveNotify:
- data->timestamp = event->xcrossing.time;
- break;
- case SelectionClear:
- data->timestamp = event->xselectionclear.time;
- break;
- default:
- break;
- }
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
- XFixesSelectionNotifyEvent *req =
- reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
- data->timestamp = req->selection_timestamp;
- }
-#endif
- return false;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-QClipboard::QClipboard(QObject *parent)
- : QObject(*new QClipboardPrivate, parent)
-{
- // create desktop widget since we need it to get PropertyNotify or
- // XFixesSelectionNotify events when someone changes the
- // clipboard.
- (void)QApplication::desktop();
-
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && X11->ptrXFixesSelectSelectionInput) {
- const unsigned long eventMask =
- XFixesSetSelectionOwnerNotifyMask | XFixesSelectionWindowDestroyNotifyMask | XFixesSelectionClientCloseNotifyMask;
- for (int i = 0; i < X11->screenCount; ++i) {
- X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(i),
- XA_PRIMARY, eventMask);
- X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(i),
- ATOM(CLIPBOARD), eventMask);
- }
- }
-#endif // QT_NO_XFIXES
-
- if (X11->time == CurrentTime) {
- // send a dummy event to myself to get the timestamp from X11.
- qt_init_timestamp_data data;
- data.timestamp = CurrentTime;
- XEvent ev;
- XCheckIfEvent(X11->display, &ev, &qt_init_timestamp_scanner, (XPointer)&data);
- if (data.timestamp == CurrentTime) {
- setupOwner();
- // We need this value just for completeness, we don't use it.
- long dummy = 0;
- Window ownerId = owner->internalWinId();
- XChangeProperty(X11->display, ownerId,
- ATOM(CLIP_TEMPORARY), XA_INTEGER, 32,
- PropModeReplace, (uchar*)&dummy, 1);
- XWindowEvent(X11->display, ownerId, PropertyChangeMask, &ev);
- data.timestamp = ev.xproperty.time;
- XDeleteProperty(X11->display, ownerId, ATOM(CLIP_TEMPORARY));
- }
- X11->time = data.timestamp;
- }
-}
-
-void QClipboard::clear(Mode mode)
-{
- setMimeData(0, mode);
-}
-
-
-bool QClipboard::supportsMode(Mode mode) const
-{
- return (mode == Clipboard || mode == Selection);
-}
-
-bool QClipboard::ownsMode(Mode mode) const
-{
- if (mode == Clipboard)
- return clipboardData()->timestamp != CurrentTime;
- else if(mode == Selection)
- return selectionData()->timestamp != CurrentTime;
- else
- return false;
-}
-
-
-// event filter function... captures interesting events while
-// qt_xclb_wait_for_event is running the event loop
-static bool qt_x11_clipboard_event_filter(void *message, long *)
-{
- XEvent *event = reinterpret_cast<XEvent *>(message);
- if (event->xany.type == capture_event_type &&
- event->xany.window == capture_event_win) {
- VDEBUG("QClipboard: event_filter(): caught event type %d", event->type);
- has_captured_event = true;
- captured_event = *event;
- return true;
- }
- return false;
-}
-
-static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer)
-{
- return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY
- || e->xselectionrequest.selection == ATOM(CLIPBOARD)))
- || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY
- || e->xselectionclear.selection == ATOM(CLIPBOARD))));
-}
-
-bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout)
-{
- QElapsedTimer started;
- started.start();
- QElapsedTimer now = started;
-
- if (QAbstractEventDispatcher::instance()->inherits("QtMotif")
- || QApplication::clipboard()->property("useEventLoopWhenWaiting").toBool()) {
- if (waiting_for_data) {
- Q_ASSERT(!"QClipboard: internal error, qt_xclb_wait_for_event recursed");
- return false;
- }
- waiting_for_data = true;
-
-
- has_captured_event = false;
- capture_event_win = win;
- capture_event_type = type;
-
- QApplication::EventFilter old_event_filter =
- qApp->setEventFilter(qt_x11_clipboard_event_filter);
-
- do {
- if (XCheckTypedWindowEvent(display, win, type, event)) {
- waiting_for_data = false;
- qApp->setEventFilter(old_event_filter);
- return true;
- }
-
- XSync(X11->display, false);
- usleep(50000);
-
- now.start();
-
- QEventLoop::ProcessEventsFlags flags(QEventLoop::ExcludeUserInputEvents
- | QEventLoop::ExcludeSocketNotifiers
- | QEventLoop::WaitForMoreEvents
- | QEventLoop::X11ExcludeTimers);
- QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
- eventDispatcher->processEvents(flags);
-
- if (has_captured_event) {
- waiting_for_data = false;
- *event = captured_event;
- qApp->setEventFilter(old_event_filter);
- return true;
- }
- } while (started.msecsTo(now) < timeout);
-
- waiting_for_data = false;
- qApp->setEventFilter(old_event_filter);
- } else {
- do {
- if (XCheckTypedWindowEvent(X11->display,win,type,event))
- return true;
-
- // process other clipboard events, since someone is probably requesting data from us
- XEvent e;
- if (XCheckIfEvent(X11->display, &e, checkForClipboardEvents, 0))
- qApp->x11ProcessEvent(&e);
-
- now.start();
-
- XFlush(X11->display);
-
- // sleep 50 ms, so we don't use up CPU cycles all the time.
- struct timeval usleep_tv;
- usleep_tv.tv_sec = 0;
- usleep_tv.tv_usec = 50000;
- select(0, 0, 0, 0, &usleep_tv);
- } while (started.msecsTo(now) < timeout);
- }
- return false;
-}
-
-
-static inline int maxSelectionIncr(Display *dpy)
-{ return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; }
-
-bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deleteProperty,
- QByteArray *buffer, int *size, Atom *type, int *format)
-{
- int maxsize = maxSelectionIncr(display);
- ulong bytes_left; // bytes_after
- ulong length; // nitems
- uchar *data;
- Atom dummy_type;
- int dummy_format;
- int r;
-
- if (!type) // allow null args
- type = &dummy_type;
- if (!format)
- format = &dummy_format;
-
- // Don't read anything, just get the size of the property data
- r = XGetWindowProperty(display, win, property, 0, 0, False,
- AnyPropertyType, type, format,
- &length, &bytes_left, &data);
- if (r != Success || (type && *type == XNone)) {
- buffer->resize(0);
- return false;
- }
- XFree((char*)data);
-
- int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;
-
- VDEBUG("QClipboard: read_property(): initial property length: %d", proplen);
-
- switch (*format) {
- case 8:
- default:
- format_inc = sizeof(char) / 1;
- break;
-
- case 16:
- format_inc = sizeof(short) / 2;
- proplen *= sizeof(short) / 2;
- break;
-
- case 32:
- format_inc = sizeof(long) / 4;
- proplen *= sizeof(long) / 4;
- break;
- }
-
- int newSize = proplen;
- buffer->resize(newSize);
-
- bool ok = (buffer->size() == newSize);
- VDEBUG("QClipboard: read_property(): buffer resized to %d", buffer->size());
-
- if (ok && newSize) {
- // could allocate buffer
-
- while (bytes_left) {
- // more to read...
-
- r = XGetWindowProperty(display, win, property, offset, maxsize/4,
- False, AnyPropertyType, type, format,
- &length, &bytes_left, &data);
- if (r != Success || (type && *type == XNone))
- break;
-
- offset += length / (32 / *format);
- length *= format_inc * (*format) / 8;
-
- // Here we check if we get a buffer overflow and tries to
- // recover -- this shouldn't normally happen, but it doesn't
- // hurt to be defensive
- if ((int)(buffer_offset + length) > buffer->size()) {
- length = buffer->size() - buffer_offset;
-
- // escape loop
- bytes_left = 0;
- }
-
- memcpy(buffer->data() + buffer_offset, data, length);
- buffer_offset += length;
-
- XFree((char*)data);
- }
-
- if (*format == 8 && *type == ATOM(COMPOUND_TEXT)) {
- // convert COMPOUND_TEXT to a multibyte string
- XTextProperty textprop;
- textprop.encoding = *type;
- textprop.format = *format;
- textprop.nitems = buffer_offset;
- textprop.value = (unsigned char *) buffer->data();
-
- char **list_ret = 0;
- int count;
- if (XmbTextPropertyToTextList(display, &textprop, &list_ret,
- &count) == Success && count && list_ret) {
- offset = buffer_offset = strlen(list_ret[0]);
- buffer->resize(offset);
- memcpy(buffer->data(), list_ret[0], offset);
- }
- if (list_ret) XFreeStringList(list_ret);
- }
- }
-
- // correct size, not 0-term.
- if (size)
- *size = buffer_offset;
-
- VDEBUG("QClipboard: read_property(): buffer size %d, buffer offset %d, offset %d",
- buffer->size(), buffer_offset, offset);
-
- if (deleteProperty)
- XDeleteProperty(display, win, property);
-
- XFlush(display);
-
- return ok;
-}
-
-QByteArray QX11Data::clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm)
-{
- XEvent event;
-
- QByteArray buf;
- QByteArray tmp_buf;
- bool alloc_error = false;
- int length;
- int offset = 0;
-
- if (nbytes > 0) {
- // Reserve buffer + zero-terminator (for text data)
- // We want to complete the INCR transfer even if we cannot
- // allocate more memory
- buf.resize(nbytes+1);
- alloc_error = buf.size() != nbytes+1;
- }
-
- for (;;) {
- XFlush(display);
- if (!clipboardWaitForEvent(win,PropertyNotify,&event,clipboard_timeout))
- break;
- if (event.xproperty.atom != property ||
- event.xproperty.state != PropertyNewValue)
- continue;
- if (X11->clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) {
- if (length == 0) { // no more data, we're done
- if (nullterm) {
- buf.resize(offset+1);
- buf[offset] = '\0';
- } else {
- buf.resize(offset);
- }
- return buf;
- } else if (!alloc_error) {
- if (offset+length > (int)buf.size()) {
- buf.resize(offset+length+65535);
- if (buf.size() != offset+length+65535) {
- alloc_error = true;
- length = buf.size() - offset;
- }
- }
- memcpy(buf.data()+offset, tmp_buf.constData(), length);
- tmp_buf.resize(0);
- offset += length;
- }
- } else {
- break;
- }
- }
-
- // timed out ... create a new requestor window, otherwise the requestor
- // could consider next request to be still part of this timed out request
- delete requestor;
- requestor = new QWidget(0);
- requestor->setObjectName(QLatin1String("internal clipboard requestor"));
- // We don't need this internal widget to appear in QApplication::topLevelWidgets()
- if (QWidgetPrivate::allWidgets)
- QWidgetPrivate::allWidgets->remove(requestor);
-
- return QByteArray();
-}
-
-static Atom send_targets_selection(QClipboardData *d, Window window, Atom property)
-{
- QVector<Atom> types;
- QStringList formats = QInternalMimeData::formatsHelper(d->source());
- for (int i = 0; i < formats.size(); ++i) {
- QList<Atom> atoms = X11->xdndMimeAtomsForFormat(formats.at(i));
- for (int j = 0; j < atoms.size(); ++j) {
- if (!types.contains(atoms.at(j)))
- types.append(atoms.at(j));
- }
- }
- types.append(ATOM(TARGETS));
- types.append(ATOM(MULTIPLE));
- types.append(ATOM(TIMESTAMP));
- types.append(ATOM(SAVE_TARGETS));
-
- XChangeProperty(X11->display, window, property, XA_ATOM, 32,
- PropModeReplace, (uchar *) types.data(), types.size());
- return property;
-}
-
-static Atom send_selection(QClipboardData *d, Atom target, Window window, Atom property)
-{
- Atom atomFormat = target;
- int dataFormat = 0;
- QByteArray data;
-
- QByteArray fmt = X11->xdndAtomToString(target);
- if (fmt.isEmpty()) { // Not a MIME type we have
- DEBUG("QClipboard: send_selection(): converting to type '%s' is not supported", fmt.data());
- return XNone;
- }
- DEBUG("QClipboard: send_selection(): converting to type '%s'", fmt.data());
-
- if (X11->xdndMimeDataForAtom(target, d->source(), &data, &atomFormat, &dataFormat)) {
-
- VDEBUG("QClipboard: send_selection():\n"
- " property type %lx\n"
- " property name '%s'\n"
- " format %d\n"
- " %d bytes\n",
- target, X11->xdndMimeAtomToString(atomFormat).toLatin1().data(), dataFormat, data.size());
-
- // don't allow INCR transfers when using MULTIPLE or to
- // Motif clients (since Motif doesn't support INCR)
- static Atom motif_clip_temporary = ATOM(CLIP_TEMPORARY);
- bool allow_incr = property != motif_clip_temporary;
-
- // X_ChangeProperty protocol request is 24 bytes
- const int increment = (XMaxRequestSize(X11->display) * 4) - 24;
- if (data.size() > increment && allow_incr) {
- long bytes = data.size();
- XChangeProperty(X11->display, window, property,
- ATOM(INCR), 32, PropModeReplace, (uchar *) &bytes, 1);
-
- (void)new QClipboardINCRTransaction(window, property, atomFormat, dataFormat, data, increment);
- return property;
- }
-
- // make sure we can perform the XChangeProperty in a single request
- if (data.size() > increment)
- return XNone; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
- int dataSize = data.size() / (dataFormat / 8);
- // use a single request to transfer data
- XChangeProperty(X11->display, window, property, atomFormat,
- dataFormat, PropModeReplace, (uchar *) data.data(),
- dataSize);
- }
- return property;
-}
-
-/*! \internal
- Internal cleanup for Windows.
-*/
-void QClipboard::ownerDestroyed()
-{ }
-
-
-/*! \internal
- Internal optimization for Windows.
-*/
-void QClipboard::connectNotify(const char *)
-{ }
-
-
-bool QClipboard::event(QEvent *e)
-{
- if (e->type() == QEvent::Timer) {
- QTimerEvent *te = (QTimerEvent *) e;
-
- if (waiting_for_data) // should never happen
- return false;
-
- if (te->timerId() == timer_id) {
- killTimer(timer_id);
- timer_id = 0;
-
- timer_event_clear = true;
- if (selection_watcher) // clear selection
- selectionData()->clear();
- if (clipboard_watcher) // clear clipboard
- clipboardData()->clear();
- timer_event_clear = false;
-
- return true;
- } else if (te->timerId() == pending_timer_id) {
- // I hate klipper
- killTimer(pending_timer_id);
- pending_timer_id = 0;
-
- if (pending_clipboard_changed) {
- pending_clipboard_changed = false;
- clipboardData()->clear();
- emitChanged(QClipboard::Clipboard);
- }
- if (pending_selection_changed) {
- pending_selection_changed = false;
- selectionData()->clear();
- emitChanged(QClipboard::Selection);
- }
-
- return true;
- } else if (te->timerId() == incr_timer_id) {
- killTimer(incr_timer_id);
- incr_timer_id = 0;
-
- qt_xclb_incr_timeout();
-
- return true;
- } else {
- return QObject::event(e);
- }
- } else if (e->type() != QEvent::Clipboard) {
- return QObject::event(e);
- }
-
- XEvent *xevent = (XEvent *)(((QClipboardEvent *)e)->data());
- Display *dpy = X11->display;
-
- if (!xevent) {
- // That means application exits and we need to give clipboard
- // content to the clipboard manager.
- // First we check if there is a clipboard manager.
- if (XGetSelectionOwner(X11->display, ATOM(CLIPBOARD_MANAGER)) == XNone
- || !owner)
- return true;
-
- Window ownerId = owner->internalWinId();
- Q_ASSERT(ownerId);
- // we delete the property so the manager saves all TARGETS.
- XDeleteProperty(X11->display, ownerId, ATOM(_QT_SELECTION));
- XConvertSelection(X11->display, ATOM(CLIPBOARD_MANAGER), ATOM(SAVE_TARGETS),
- ATOM(_QT_SELECTION), ownerId, X11->time);
- XSync(dpy, false);
-
- XEvent event;
- // waiting until the clipboard manager fetches the content.
- if (!X11->clipboardWaitForEvent(ownerId, SelectionNotify, &event, 10000)) {
- qWarning("QClipboard: Unable to receive an event from the "
- "clipboard manager in a reasonable time");
- }
-
- return true;
- }
-
- switch (xevent->type) {
-
- case SelectionClear:
- // new selection owner
- if (xevent->xselectionclear.selection == XA_PRIMARY) {
- QClipboardData *d = selectionData();
-
- // ignore the event if it was generated before we gained selection ownership
- if (d->timestamp != CurrentTime && xevent->xselectionclear.time <= d->timestamp)
- break;
-
- DEBUG("QClipboard: new selection owner 0x%lx at time %lx (ours %lx)",
- XGetSelectionOwner(dpy, XA_PRIMARY),
- xevent->xselectionclear.time, d->timestamp);
-
- if (! waiting_for_data) {
- d->clear();
- emitChanged(QClipboard::Selection);
- } else {
- pending_selection_changed = true;
- if (! pending_timer_id)
- pending_timer_id = QApplication::clipboard()->startTimer(0);
- }
- } else if (xevent->xselectionclear.selection == ATOM(CLIPBOARD)) {
- QClipboardData *d = clipboardData();
-
- // ignore the event if it was generated before we gained selection ownership
- if (d->timestamp != CurrentTime && xevent->xselectionclear.time <= d->timestamp)
- break;
-
- DEBUG("QClipboard: new clipboard owner 0x%lx at time %lx (%lx)",
- XGetSelectionOwner(dpy, ATOM(CLIPBOARD)),
- xevent->xselectionclear.time, d->timestamp);
-
- if (! waiting_for_data) {
- d->clear();
- emitChanged(QClipboard::Clipboard);
- } else {
- pending_clipboard_changed = true;
- if (! pending_timer_id)
- pending_timer_id = QApplication::clipboard()->startTimer(0);
- }
- } else {
- qWarning("QClipboard: Unknown SelectionClear event received");
- return false;
- }
- break;
-
- case SelectionNotify:
- /*
- Something has delivered data to us, but this was not caught
- by QClipboardWatcher::getDataInFormat()
-
- Just skip the event to prevent Bad Things (tm) from
- happening later on...
- */
- break;
-
- case SelectionRequest:
- {
- // someone wants our data
- XSelectionRequestEvent *req = &xevent->xselectionrequest;
-
- if (requestor && req->requestor == requestor->internalWinId())
- break;
-
- XEvent event;
- event.xselection.type = SelectionNotify;
- event.xselection.display = req->display;
- event.xselection.requestor = req->requestor;
- event.xselection.selection = req->selection;
- event.xselection.target = req->target;
- event.xselection.property = XNone;
- event.xselection.time = req->time;
-
- DEBUG("QClipboard: SelectionRequest from %lx\n"
- " selection 0x%lx (%s) target 0x%lx (%s)",
- req->requestor,
- req->selection,
- X11->xdndAtomToString(req->selection).data(),
- req->target,
- X11->xdndAtomToString(req->target).data());
-
- QClipboardData *d;
- if (req->selection == XA_PRIMARY) {
- d = selectionData();
- } else if (req->selection == ATOM(CLIPBOARD)) {
- d = clipboardData();
- } else {
- qWarning("QClipboard: Unknown selection '%lx'", req->selection);
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
- break;
- }
-
- if (! d->source()) {
- qWarning("QClipboard: Cannot transfer data, no data available");
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
- break;
- }
-
- DEBUG("QClipboard: SelectionRequest at time %lx (ours %lx)",
- req->time, d->timestamp);
-
- if (d->timestamp == CurrentTime // we don't own the selection anymore
- || (req->time != CurrentTime && req->time < d->timestamp)) {
- DEBUG("QClipboard: SelectionRequest too old");
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
- break;
- }
-
- Atom xa_targets = ATOM(TARGETS);
- Atom xa_multiple = ATOM(MULTIPLE);
- Atom xa_timestamp = ATOM(TIMESTAMP);
-
- struct AtomPair { Atom target; Atom property; } *multi = 0;
- Atom multi_type = XNone;
- int multi_format = 0;
- int nmulti = 0;
- int imulti = -1;
- bool multi_writeback = false;
-
- if (req->target == xa_multiple) {
- QByteArray multi_data;
- if (req->property == XNone
- || !X11->clipboardReadProperty(req->requestor, req->property, false, &multi_data,
- 0, &multi_type, &multi_format)
- || multi_format != 32) {
- // MULTIPLE property not formatted correctly
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
- break;
- }
- nmulti = multi_data.size()/sizeof(*multi);
- multi = new AtomPair[nmulti];
- memcpy(multi,multi_data.data(),multi_data.size());
- imulti = 0;
- }
-
- for (; imulti < nmulti; ++imulti) {
- Atom target;
- Atom property;
-
- if (multi) {
- target = multi[imulti].target;
- property = multi[imulti].property;
- } else {
- target = req->target;
- property = req->property;
- if (property == XNone) // obsolete client
- property = target;
- }
-
- Atom ret = XNone;
- if (target == XNone || property == XNone) {
- ;
- } else if (target == xa_timestamp) {
- if (d->timestamp != CurrentTime) {
- XChangeProperty(dpy, req->requestor, property, XA_INTEGER, 32,
- PropModeReplace, (uchar *) &d->timestamp, 1);
- ret = property;
- } else {
- qWarning("QClipboard: Invalid data timestamp");
- }
- } else if (target == xa_targets) {
- ret = send_targets_selection(d, req->requestor, property);
- } else {
- ret = send_selection(d, target, req->requestor, property);
- }
-
- if (nmulti > 0) {
- if (ret == XNone) {
- multi[imulti].property = XNone;
- multi_writeback = true;
- }
- } else {
- event.xselection.property = ret;
- break;
- }
- }
-
- if (nmulti > 0) {
- if (multi_writeback) {
- // according to ICCCM 2.6.2 says to put None back
- // into the original property on the requestor window
- XChangeProperty(dpy, req->requestor, req->property, multi_type, 32,
- PropModeReplace, (uchar *) multi, nmulti * 2);
- }
-
- delete [] multi;
- event.xselection.property = req->property;
- }
-
- // send selection notify to requestor
- XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
-
- DEBUG("QClipboard: SelectionNotify to 0x%lx\n"
- " property 0x%lx (%s)",
- req->requestor, event.xselection.property,
- X11->xdndAtomToString(event.xselection.property).data());
- }
- break;
- }
-
- return true;
-}
-
-
-
-
-
-
-QClipboardWatcher::QClipboardWatcher(QClipboard::Mode mode)
- : QInternalMimeData()
-{
- switch (mode) {
- case QClipboard::Selection:
- atom = XA_PRIMARY;
- break;
-
- case QClipboard::Clipboard:
- atom = ATOM(CLIPBOARD);
- break;
-
- default:
- qWarning("QClipboardWatcher: Internal error: Unsupported clipboard mode");
- break;
- }
-
- setupOwner();
-}
-
-QClipboardWatcher::~QClipboardWatcher()
-{
- if(selection_watcher == this)
- selection_watcher = 0;
- if(clipboard_watcher == this)
- clipboard_watcher = 0;
-}
-
-bool QClipboardWatcher::empty() const
-{
- Display *dpy = X11->display;
- Window win = XGetSelectionOwner(dpy, atom);
-
- if(win == requestor->internalWinId()) {
- qWarning("QClipboardWatcher::empty: Internal error: Application owns the selection");
- return true;
- }
-
- return win == XNone;
-}
-
-QStringList QClipboardWatcher::formats_sys() const
-{
- if (empty())
- return QStringList();
-
- if (!formatList.count()) {
- // get the list of targets from the current clipboard owner - we do this
- // once so that multiple calls to this function don't require multiple
- // server round trips...
-
- format_atoms = getDataInFormat(ATOM(TARGETS));
-
- if (format_atoms.size() > 0) {
- Atom *targets = (Atom *) format_atoms.data();
- int size = format_atoms.size() / sizeof(Atom);
-
- for (int i = 0; i < size; ++i) {
- if (targets[i] == 0)
- continue;
-
- QStringList formatsForAtom = X11->xdndMimeFormatsForAtom(targets[i]);
- for (int j = 0; j < formatsForAtom.size(); ++j) {
- if (!formatList.contains(formatsForAtom.at(j)))
- formatList.append(formatsForAtom.at(j));
- }
- VDEBUG(" format: %s", X11->xdndAtomToString(targets[i]).data());
- VDEBUG(" data:\n%s\n", getDataInFormat(targets[i]).data());
- }
- DEBUG("QClipboardWatcher::format: %d formats available", formatList.count());
- }
- }
-
- return formatList;
-}
-
-bool QClipboardWatcher::hasFormat_sys(const QString &format) const
-{
- QStringList list = formats();
- return list.contains(format);
-}
-
-QVariant QClipboardWatcher::retrieveData_sys(const QString &fmt, QVariant::Type requestedType) const
-{
- if (fmt.isEmpty() || empty())
- return QByteArray();
-
- (void)formats(); // trigger update of format list
- DEBUG("QClipboardWatcher::data: fetching format '%s'", fmt.toLatin1().data());
-
- QList<Atom> atoms;
- Atom *targets = (Atom *) format_atoms.data();
- int size = format_atoms.size() / sizeof(Atom);
- for (int i = 0; i < size; ++i)
- atoms.append(targets[i]);
-
- QByteArray encoding;
- Atom fmtatom = X11->xdndMimeAtomForFormat(fmt, requestedType, atoms, &encoding);
-
- if (fmtatom == 0)
- return QVariant();
-
- return X11->xdndMimeConvertToFormat(fmtatom, getDataInFormat(fmtatom), fmt, requestedType, encoding);
-}
-
-QByteArray QClipboardWatcher::getDataInFormat(Atom fmtatom) const
-{
- QByteArray buf;
-
- Display *dpy = X11->display;
- requestor->createWinId();
- Window win = requestor->internalWinId();
- Q_ASSERT(requestor->testAttribute(Qt::WA_WState_Created));
-
- DEBUG("QClipboardWatcher::getDataInFormat: selection '%s' format '%s'",
- X11->xdndAtomToString(atom).data(), X11->xdndAtomToString(fmtatom).data());
-
- XSelectInput(dpy, win, NoEventMask); // don't listen for any events
-
- XDeleteProperty(dpy, win, ATOM(_QT_SELECTION));
- XConvertSelection(dpy, atom, fmtatom, ATOM(_QT_SELECTION), win, X11->time);
- XSync(dpy, false);
-
- VDEBUG("QClipboardWatcher::getDataInFormat: waiting for SelectionNotify event");
-
- XEvent xevent;
- if (!X11->clipboardWaitForEvent(win,SelectionNotify,&xevent,clipboard_timeout) ||
- xevent.xselection.property == XNone) {
- DEBUG("QClipboardWatcher::getDataInFormat: format not available");
- return buf;
- }
-
- VDEBUG("QClipboardWatcher::getDataInFormat: fetching data...");
-
- Atom type;
- XSelectInput(dpy, win, PropertyChangeMask);
-
- if (X11->clipboardReadProperty(win, ATOM(_QT_SELECTION), true, &buf, 0, &type, 0)) {
- if (type == ATOM(INCR)) {
- int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
- buf = X11->clipboardReadIncrementalProperty(win, ATOM(_QT_SELECTION), nbytes, false);
- }
- }
-
- XSelectInput(dpy, win, NoEventMask);
-
- DEBUG("QClipboardWatcher::getDataInFormat: %d bytes received", buf.size());
-
- return buf;
-}
-
-
-const QMimeData* QClipboard::mimeData(Mode mode) const
-{
- QClipboardData *d = 0;
- switch (mode) {
- case Selection:
- d = selectionData();
- break;
- case Clipboard:
- d = clipboardData();
- break;
- default:
- qWarning("QClipboard::mimeData: unsupported mode '%d'", mode);
- return 0;
- }
-
- if (! d->source() && ! timer_event_clear) {
- if (mode == Selection) {
- if (! selection_watcher)
- selection_watcher = new QClipboardWatcher(mode);
- d->setSource(selection_watcher);
- } else {
- if (! clipboard_watcher)
- clipboard_watcher = new QClipboardWatcher(mode);
- d->setSource(clipboard_watcher);
- }
-
- if (! timer_id) {
- // start a zero timer - we will clear cached data when the timer
- // times out, which will be the next time we hit the event loop...
- // that way, the data is cached long enough for calls within a single
- // loop/function, but the data doesn't linger around in case the selection
- // changes
- QClipboard *that = ((QClipboard *) this);
- timer_id = that->startTimer(0);
- }
- }
-
- return d->source();
-}
-
-
-void QClipboard::setMimeData(QMimeData* src, Mode mode)
-{
- Atom atom, sentinel_atom;
- QClipboardData *d;
- switch (mode) {
- case Selection:
- atom = XA_PRIMARY;
- sentinel_atom = ATOM(_QT_SELECTION_SENTINEL);
- d = selectionData();
- break;
-
- case Clipboard:
- atom = ATOM(CLIPBOARD);
- sentinel_atom = ATOM(_QT_CLIPBOARD_SENTINEL);
- d = clipboardData();
- break;
-
- default:
- qWarning("QClipboard::setMimeData: unsupported mode '%d'", mode);
- return;
- }
-
- Display *dpy = X11->display;
- Window newOwner;
-
- if (! src) { // no data, clear clipboard contents
- newOwner = XNone;
- d->clear();
- } else {
- setupOwner();
-
- newOwner = owner->internalWinId();
-
- d->setSource(src);
- d->timestamp = X11->time;
- }
-
- Window prevOwner = XGetSelectionOwner(dpy, atom);
- // use X11->time, since d->timestamp == CurrentTime when clearing
- XSetSelectionOwner(dpy, atom, newOwner, X11->time);
-
- if (mode == Selection)
- emitChanged(QClipboard::Selection);
- else
- emitChanged(QClipboard::Clipboard);
-
- if (XGetSelectionOwner(dpy, atom) != newOwner) {
- qWarning("QClipboard::setData: Cannot set X11 selection owner for %s",
- X11->xdndAtomToString(atom).data());
- d->clear();
- return;
- }
-
- // Signal to other Qt processes that the selection has changed
- Window owners[2];
- owners[0] = newOwner;
- owners[1] = prevOwner;
- XChangeProperty(dpy, QApplication::desktop()->screen(0)->internalWinId(),
- sentinel_atom, XA_WINDOW, 32, PropModeReplace,
- (unsigned char*)&owners, 2);
-}
-
-
-/*
- Called by the main event loop in qapplication_x11.cpp when either
- the _QT_SELECTION_SENTINEL property has been changed (i.e. when some
- Qt process has performed QClipboard::setData()) or when Xfixes told
- us that an other application changed the selection. If it returns
- true, the QClipBoard dataChanged() signal should be emitted.
-*/
-
-bool qt_check_selection_sentinel()
-{
- bool doIt = true;
- if (owner && !X11->use_xfixes) {
- /*
- Since the X selection mechanism cannot give any signal when
- the selection has changed, we emulate it (for Qt processes) here.
- The notification should be ignored in case of either
- a) This is the process that did setData (because setData()
- then has already emitted dataChanged())
- b) This is the process that owned the selection when dataChanged()
- was called (because we have then received a SelectionClear event,
- and have already emitted dataChanged() as a result of that)
- */
-
- unsigned char *retval;
- Atom actualType;
- int actualFormat;
- ulong nitems;
- ulong bytesLeft;
-
- if (XGetWindowProperty(X11->display,
- QApplication::desktop()->screen(0)->internalWinId(),
- ATOM(_QT_SELECTION_SENTINEL), 0, 2, False, XA_WINDOW,
- &actualType, &actualFormat, &nitems,
- &bytesLeft, &retval) == Success) {
- Window *owners = (Window *)retval;
- if (actualType == XA_WINDOW && actualFormat == 32 && nitems == 2) {
- Window win = owner->internalWinId();
- if (owners[0] == win || owners[1] == win)
- doIt = false;
- }
-
- XFree(owners);
- }
- }
-
- if (doIt) {
- if (waiting_for_data) {
- pending_selection_changed = true;
- if (! pending_timer_id)
- pending_timer_id = QApplication::clipboard()->startTimer(0);
- doIt = false;
- } else {
- selectionData()->clear();
- }
- }
-
- return doIt;
-}
-
-
-bool qt_check_clipboard_sentinel()
-{
- bool doIt = true;
- if (owner && !X11->use_xfixes) {
- unsigned char *retval;
- Atom actualType;
- int actualFormat;
- unsigned long nitems, bytesLeft;
-
- if (XGetWindowProperty(X11->display,
- QApplication::desktop()->screen(0)->internalWinId(),
- ATOM(_QT_CLIPBOARD_SENTINEL), 0, 2, False, XA_WINDOW,
- &actualType, &actualFormat, &nitems, &bytesLeft,
- &retval) == Success) {
- Window *owners = (Window *)retval;
- if (actualType == XA_WINDOW && actualFormat == 32 && nitems == 2) {
- Window win = owner->internalWinId();
- if (owners[0] == win || owners[1] == win)
- doIt = false;
- }
-
- XFree(owners);
- }
- }
-
- if (doIt) {
- if (waiting_for_data) {
- pending_clipboard_changed = true;
- if (! pending_timer_id)
- pending_timer_id = QApplication::clipboard()->startTimer(0);
- doIt = false;
- } else {
- clipboardData()->clear();
- }
- }
-
- return doIt;
-}
-
-bool qt_xfixes_selection_changed(Window selectionOwner, Time timestamp)
-{
- QClipboardData *d = selectionData();
-#ifdef QCLIPBOARD_DEBUG
- DEBUG("qt_xfixes_selection_changed: owner = %u; selectionOwner = %u; internal timestamp = %u; external timestamp = %u",
- (unsigned int)(owner ? (int)owner->internalWinId() : 0), (unsigned int)selectionOwner,
- (unsigned int)(d ? d->timestamp : 0), (unsigned int)timestamp);
-#endif
- if (!owner || (selectionOwner && selectionOwner != owner->internalWinId()) ||
- (!selectionOwner && (d->timestamp == CurrentTime || d->timestamp < timestamp)))
- return qt_check_selection_sentinel();
- return false;
-}
-
-bool qt_xfixes_clipboard_changed(Window clipboardOwner, Time timestamp)
-{
- QClipboardData *d = clipboardData();
-#ifdef QCLIPBOARD_DEBUG
- DEBUG("qt_xfixes_clipboard_changed: owner = %u; clipboardOwner = %u; internal timestamp = %u; external timestamp = %u",
- (unsigned int)(owner ? (int)owner->internalWinId() : 0), (unsigned int)clipboardOwner,
- (unsigned int)(d ? d->timestamp : 0), (unsigned int)timestamp);
-#endif
- if (!owner || (clipboardOwner && clipboardOwner != owner->internalWinId()) ||
- (!clipboardOwner && (d->timestamp == CurrentTime || d->timestamp < timestamp)))
- return qt_check_clipboard_sentinel();
- return false;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_CLIPBOARD
diff --git a/src/widgets/platforms/x11/qcolormap_x11.cpp b/src/widgets/platforms/x11/qcolormap_x11.cpp
deleted file mode 100644
index 1d6d7b8adb..0000000000
--- a/src/widgets/platforms/x11/qcolormap_x11.cpp
+++ /dev/null
@@ -1,670 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcolormap.h"
-
-#include "qapplication.h"
-#include "qdebug.h"
-#include "qdesktopwidget.h"
-#include "qvarlengtharray.h"
-
-#include "qx11info_x11.h"
-#include <private/qt_x11_p.h>
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-class QColormapPrivate
-{
-public:
- QColormapPrivate()
- : ref(1), mode(QColormap::Direct), depth(0),
- colormap(0), defaultColormap(true),
- visual(0), defaultVisual(true),
- r_max(0), g_max(0), b_max(0),
- r_shift(0), g_shift(0), b_shift(0)
- {}
-
- QAtomicInt ref;
-
- QColormap::Mode mode;
- int depth;
-
- Colormap colormap;
- bool defaultColormap;
-
- Visual *visual;
- bool defaultVisual;
-
- int r_max;
- int g_max;
- int b_max;
-
- uint r_shift;
- uint g_shift;
- uint b_shift;
-
- QVector<QColor> colors;
- QVector<int> pixels;
-};
-
-
-static uint right_align(uint v)
-{
- while (!(v & 0x1))
- v >>= 1;
- return v;
-}
-
-static int lowest_bit(uint v)
-{
- int i;
- uint b = 1u;
- for (i = 0; ((v & b) == 0u) && i < 32; ++i)
- b <<= 1u;
- return i == 32 ? -1 : i;
-}
-
-static int cube_root(int v)
-{
- if (v == 1)
- return 1;
- // brute force algorithm
- int i = 1;
- for (;;) {
- const int b = i * i * i;
- if (b <= v) {
- ++i;
- } else {
- --i;
- break;
- }
- }
- return i;
-}
-
-static Visual *find_visual(Display *display,
- int screen,
- int visual_class,
- int visual_id,
- int *depth,
- bool *defaultVisual)
-{
- XVisualInfo *vi, rvi;
- int count;
-
- uint mask = VisualScreenMask;
- rvi.screen = screen;
-
- if (visual_class != -1) {
- rvi.c_class = visual_class;
- mask |= VisualClassMask;
- }
- if (visual_id != -1) {
- rvi.visualid = visual_id;
- mask |= VisualIDMask;
- }
-
- Visual *visual = DefaultVisual(display, screen);
- *defaultVisual = true;
- *depth = DefaultDepth(display, screen);
-
- vi = XGetVisualInfo(display, mask, &rvi, &count);
- if (vi) {
- int best = 0;
- for (int x = 0; x < count; ++x) {
- if (vi[x].depth > vi[best].depth)
- best = x;
- }
- if (best >= 0 && best <= count && vi[best].visualid != XVisualIDFromVisual(visual)) {
- visual = vi[best].visual;
- *defaultVisual = (visual == DefaultVisual(display, screen));
- *depth = vi[best].depth;
- }
- }
- if (vi)
- XFree((char *)vi);
- return visual;
-}
-
-static void query_colormap(QColormapPrivate *d, int screen)
-{
- Display *display = QX11Info::display();
-
- // query existing colormap
- int q_colors = (((1u << d->depth) > 256u) ? 256u : (1u << d->depth));
- XColor queried[256];
- memset(queried, 0, sizeof(queried));
- for (int x = 0; x < q_colors; ++x)
- queried[x].pixel = x;
- XQueryColors(display, d->colormap, queried, q_colors);
-
- d->colors.resize(q_colors);
- for (int x = 0; x < q_colors; ++x) {
- if (queried[x].red == 0
- && queried[x].green == 0
- && queried[x].blue == 0
- && queried[x].pixel != BlackPixel(display, screen)) {
- // unallocated color cell, skip it
- continue;
- }
-
- d->colors[x] = QColor::fromRgbF(queried[x].red / float(USHRT_MAX),
- queried[x].green / float(USHRT_MAX),
- queried[x].blue / float(USHRT_MAX));
- }
-
- // for missing colors, find the closest color in the existing colormap
- Q_ASSERT(d->pixels.size());
- for (int x = 0; x < d->pixels.size(); ++x) {
- if (d->pixels.at(x) != -1)
- continue;
-
- QRgb rgb;
- if (d->mode == QColormap::Indexed) {
- const int r = (x / (d->g_max * d->b_max)) % d->r_max;
- const int g = (x / d->b_max) % d->g_max;
- const int b = x % d->b_max;
- rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1),
- (g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1),
- (b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1));
- } else {
- rgb = qRgb(x, x, x);
- }
-
- // find closest color
- int mindist = INT_MAX, best = -1;
- for (int y = 0; y < q_colors; ++y) {
- int r = qRed(rgb) - (queried[y].red >> 8);
- int g = qGreen(rgb) - (queried[y].green >> 8);
- int b = qBlue(rgb) - (queried[y].blue >> 8);
- int dist = (r * r) + (g * g) + (b * b);
- if (dist < mindist) {
- mindist = dist;
- best = y;
- }
- }
-
- Q_ASSERT(best >= 0 && best < q_colors);
- if (d->visual->c_class & 1) {
- XColor xcolor;
- xcolor.red = queried[best].red;
- xcolor.green = queried[best].green;
- xcolor.blue = queried[best].blue;
- xcolor.pixel = queried[best].pixel;
-
- if (XAllocColor(display, d->colormap, &xcolor)) {
- d->pixels[x] = xcolor.pixel;
- } else {
- // some weird stuff is going on...
- d->pixels[x] = (qGray(rgb) < 127
- ? BlackPixel(display, screen)
- : WhitePixel(display, screen));
- }
- } else {
- d->pixels[x] = best;
- }
- }
-}
-
-static void init_gray(QColormapPrivate *d, int screen)
-{
- d->pixels.resize(d->r_max);
-
- for (int g = 0; g < d->g_max; ++g) {
- const int gray = (g * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1);
- const QRgb rgb = qRgb(gray, gray, gray);
-
- d->pixels[g] = -1;
-
- if (d->visual->c_class & 1) {
- XColor xcolor;
- xcolor.red = qRed(rgb) * 0x101;
- xcolor.green = qGreen(rgb) * 0x101;
- xcolor.blue = qBlue(rgb) * 0x101;
- xcolor.pixel = 0ul;
-
- if (XAllocColor(QX11Info::display(), d->colormap, &xcolor))
- d->pixels[g] = xcolor.pixel;
- }
- }
-
- query_colormap(d, screen);
-}
-
-static void init_indexed(QColormapPrivate *d, int screen)
-{
- d->pixels.resize(d->r_max * d->g_max * d->b_max);
-
- // create color cube
- for (int x = 0, r = 0; r < d->r_max; ++r) {
- for (int g = 0; g < d->g_max; ++g) {
- for (int b = 0; b < d->b_max; ++b, ++x) {
- const QRgb rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1),
- (g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1),
- (b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1));
-
- d->pixels[x] = -1;
-
- if (d->visual->c_class & 1) {
- XColor xcolor;
- xcolor.red = qRed(rgb) * 0x101;
- xcolor.green = qGreen(rgb) * 0x101;
- xcolor.blue = qBlue(rgb) * 0x101;
- xcolor.pixel = 0ul;
-
- if (XAllocColor(QX11Info::display(), d->colormap, &xcolor))
- d->pixels[x] = xcolor.pixel;
- }
- }
- }
- }
-
- query_colormap(d, screen);
-}
-
-static void init_direct(QColormapPrivate *d, bool ownColormap)
-{
- if (d->visual->c_class != DirectColor || !ownColormap)
- return;
-
- // preallocate 768 on the stack, so that we don't have to malloc
- // for the common case (<= 24 bpp)
- QVarLengthArray<XColor, 768> colorTable(d->r_max + d->g_max + d->b_max);
- int i = 0;
-
- for (int r = 0; r < d->r_max; ++r) {
- colorTable[i].red = r << 8 | r;
- colorTable[i].pixel = r << d->r_shift;
- colorTable[i].flags = DoRed;
- ++i;
- }
-
- for (int g = 0; g < d->g_max; ++g) {
- colorTable[i].green = g << 8 | g;
- colorTable[i].pixel = g << d->g_shift;
- colorTable[i].flags = DoGreen;
- ++i;
- }
-
- for (int b = 0; b < d->b_max; ++b) {
- colorTable[i].blue = (b << 8 | b);
- colorTable[i].pixel = b << d->b_shift;
- colorTable[i].flags = DoBlue;
- ++i;
- }
-
- XStoreColors(X11->display, d->colormap, colorTable.data(), colorTable.count());
-}
-
-static QColormap **cmaps = 0;
-
-void QColormap::initialize()
-{
- Display *display = QX11Info::display();
- const int screens = ScreenCount(display);
-
- cmaps = new QColormap*[screens];
-
- for (int i = 0; i < screens; ++i) {
- cmaps[i] = new QColormap;
- QColormapPrivate * const d = cmaps[i]->d;
-
- bool use_stdcmap = false;
- int color_count = X11->color_count;
-
- // defaults
- d->depth = DefaultDepth(display, i);
- d->colormap = DefaultColormap(display, i);
- d->defaultColormap = true;
- d->visual = DefaultVisual(display, i);
- d->defaultVisual = true;
-
- Visual *argbVisual = 0;
-
- if (X11->visual && i == DefaultScreen(display)) {
- // only use the outside colormap on the default screen
- d->visual = find_visual(display, i, X11->visual->c_class,
- XVisualIDFromVisual(X11->visual),
- &d->depth, &d->defaultVisual);
- } else if ((X11->visual_class != -1 && X11->visual_class >= 0 && X11->visual_class < 6)
- || (X11->visual_id != -1)) {
- // look for a specific visual or type of visual
- d->visual = find_visual(display, i, X11->visual_class, X11->visual_id,
- &d->depth, &d->defaultVisual);
- } else if (QApplication::colorSpec() == QApplication::ManyColor) {
- // look for a TrueColor w/ a depth higher than 8bpp
- d->visual = find_visual(display, i, TrueColor, -1, &d->depth, &d->defaultVisual);
- if (d->depth <= 8) {
- d->visual = DefaultVisual(display, i);
- d->defaultVisual = true;
- color_count = 216;
- }
- } else if (!X11->custom_cmap) {
- XStandardColormap *stdcmap = 0;
- int ncmaps = 0;
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- int nvi;
- XVisualInfo templ;
- templ.screen = i;
- templ.depth = 32;
- templ.c_class = TrueColor;
- XVisualInfo *xvi = XGetVisualInfo(X11->display, VisualScreenMask |
- VisualDepthMask |
- VisualClassMask, &templ, &nvi);
- for (int idx = 0; idx < nvi; ++idx) {
- XRenderPictFormat *format = XRenderFindVisualFormat(X11->display,
- xvi[idx].visual);
- if (format->type == PictTypeDirect && format->direct.alphaMask) {
- argbVisual = xvi[idx].visual;
- break;
- }
- }
- XFree(xvi);
- }
-#endif
- if (XGetRGBColormaps(display, RootWindow(display, i),
- &stdcmap, &ncmaps, XA_RGB_DEFAULT_MAP)) {
- if (stdcmap) {
- for (int c = 0; c < ncmaps; ++c) {
- if (!stdcmap[c].red_max ||
- !stdcmap[c].green_max ||
- !stdcmap[c].blue_max ||
- !stdcmap[c].red_mult ||
- !stdcmap[c].green_mult ||
- !stdcmap[c].blue_mult)
- continue; // invalid stdcmap
-
- XVisualInfo proto;
- proto.visualid = stdcmap[c].visualid;
- proto.screen = i;
-
- int nvisuals = 0;
- XVisualInfo *vi = XGetVisualInfo(display, VisualIDMask | VisualScreenMask,
- &proto, &nvisuals);
- if (vi) {
- if (nvisuals > 0) {
- use_stdcmap = true;
-
- d->mode = ((vi[0].visual->c_class < StaticColor)
- ? Gray
- : ((vi[0].visual->c_class < TrueColor)
- ? Indexed
- : Direct));
-
- d->depth = vi[0].depth;
- d->colormap = stdcmap[c].colormap;
- d->defaultColormap = true;
- d->visual = vi[0].visual;
- d->defaultVisual = (d->visual == DefaultVisual(display, i));
-
- d->r_max = stdcmap[c].red_max + 1;
- d->g_max = stdcmap[c].green_max + 1;
- d->b_max = stdcmap[c].blue_max + 1;
-
- if (d->mode == Direct) {
- // calculate offsets
- d->r_shift = lowest_bit(d->visual->red_mask);
- d->g_shift = lowest_bit(d->visual->green_mask);
- d->b_shift = lowest_bit(d->visual->blue_mask);
- } else {
- d->r_shift = 0;
- d->g_shift = 0;
- d->b_shift = 0;
- }
- }
- XFree(vi);
- }
- break;
- }
- XFree(stdcmap);
- }
- }
- }
- if (!use_stdcmap) {
- switch (d->visual->c_class) {
- case StaticGray:
- d->mode = Gray;
-
- d->r_max = d->g_max = d->b_max = d->visual->map_entries;
- break;
-
- case XGrayScale:
- d->mode = Gray;
-
- // follow precedent set in libXmu...
- if (color_count != 0)
- d->r_max = d->g_max = d->b_max = color_count;
- else if (d->visual->map_entries > 65000)
- d->r_max = d->g_max = d->b_max = 4096;
- else if (d->visual->map_entries > 4000)
- d->r_max = d->g_max = d->b_max = 512;
- else if (d->visual->map_entries > 250)
- d->r_max = d->g_max = d->b_max = 12;
- else
- d->r_max = d->g_max = d->b_max = 4;
- break;
-
- case StaticColor:
- d->mode = Indexed;
-
- d->r_max = right_align(d->visual->red_mask) + 1;
- d->g_max = right_align(d->visual->green_mask) + 1;
- d->b_max = right_align(d->visual->blue_mask) + 1;
- break;
-
- case PseudoColor:
- d->mode = Indexed;
-
- // follow precedent set in libXmu...
- if (color_count != 0)
- d->r_max = d->g_max = d->b_max = cube_root(color_count);
- else if (d->visual->map_entries > 65000)
- d->r_max = d->g_max = d->b_max = 27;
- else if (d->visual->map_entries > 4000)
- d->r_max = d->g_max = d->b_max = 12;
- else if (d->visual->map_entries > 250)
- d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries - 125);
- else
- d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries);
- break;
-
- case TrueColor:
- case DirectColor:
- d->mode = Direct;
-
- d->r_max = right_align(d->visual->red_mask) + 1;
- d->g_max = right_align(d->visual->green_mask) + 1;
- d->b_max = right_align(d->visual->blue_mask) + 1;
-
- d->r_shift = lowest_bit(d->visual->red_mask);
- d->g_shift = lowest_bit(d->visual->green_mask);
- d->b_shift = lowest_bit(d->visual->blue_mask);
- break;
- }
- }
-
- bool ownColormap = false;
- if (X11->colormap && i == DefaultScreen(display)) {
- // only use the outside colormap on the default screen
- d->colormap = X11->colormap;
- d->defaultColormap = (d->colormap == DefaultColormap(display, i));
- } else if ((!use_stdcmap
- && (((d->visual->c_class & 1) && X11->custom_cmap)
- || d->visual != DefaultVisual(display, i)))
- || d->visual->c_class == DirectColor) {
- // allocate custom colormap (we always do this when using DirectColor visuals)
- d->colormap =
- XCreateColormap(display, RootWindow(display, i), d->visual,
- d->visual->c_class == DirectColor ? AllocAll : AllocNone);
- d->defaultColormap = false;
- ownColormap = true;
- }
-
- switch (d->mode) {
- case Gray:
- init_gray(d, i);
- break;
- case Indexed:
- init_indexed(d, i);
- break;
- case Direct:
- init_direct(d, ownColormap);
- break;
- }
-
- QX11InfoData *screen = X11->screens + i;
- screen->depth = d->depth;
- screen->visual = d->visual;
- screen->defaultVisual = d->defaultVisual;
- screen->colormap = d->colormap;
- screen->defaultColormap = d->defaultColormap;
- screen->cells = screen->visual->map_entries;
-
- if (argbVisual) {
- X11->argbVisuals[i] = argbVisual;
- X11->argbColormaps[i] = XCreateColormap(display, RootWindow(display, i), argbVisual, AllocNone);
- }
-
- // ###
- // We assume that 8bpp == pseudocolor, but this is not
- // always the case (according to the X server), so we need
- // to make sure that our internal data is setup in a way
- // that is compatible with our assumptions
- if (screen->visual->c_class == TrueColor && screen->depth == 8 && screen->cells == 8)
- screen->cells = 256;
- }
-}
-
-void QColormap::cleanup()
-{
- Display *display = QX11Info::display();
- const int screens = ScreenCount(display);
-
- for (int i = 0; i < screens; ++i)
- delete cmaps[i];
-
- delete [] cmaps;
- cmaps = 0;
-}
-
-
-QColormap QColormap::instance(int screen)
-{
- if (screen == -1)
- screen = QX11Info::appScreen();
- return *cmaps[screen];
-}
-
-/*! \internal
- Constructs a new colormap.
-*/
-QColormap::QColormap()
- : d(new QColormapPrivate)
-{}
-
-QColormap::QColormap(const QColormap &colormap)
- :d (colormap.d)
-{ d->ref.ref(); }
-
-QColormap::~QColormap()
-{
- if (!d->ref.deref()) {
- if (!d->defaultColormap)
- XFreeColormap(QX11Info::display(), d->colormap);
- delete d;
- }
-}
-
-QColormap::Mode QColormap::mode() const
-{ return d->mode; }
-
-int QColormap::depth() const
-{ return d->depth; }
-
-int QColormap::size() const
-{
- return (d->mode == Gray
- ? d->r_max
- : (d->mode == Indexed
- ? d->r_max * d->g_max * d->b_max
- : -1));
-}
-
-uint QColormap::pixel(const QColor &color) const
-{
- const QColor c = color.toRgb();
- const uint r = (c.ct.argb.red * d->r_max) >> 16;
- const uint g = (c.ct.argb.green * d->g_max) >> 16;
- const uint b = (c.ct.argb.blue * d->b_max) >> 16;
- if (d->mode != Direct) {
- if (d->mode == Gray)
- return d->pixels.at((r * 30 + g * 59 + b * 11) / 100);
- return d->pixels.at(r * d->g_max * d->b_max + g * d->b_max + b);
- }
- return (r << d->r_shift) + (g << d->g_shift) + (b << d->b_shift);
-}
-
-const QColor QColormap::colorAt(uint pixel) const
-{
- if (d->mode != Direct) {
- Q_ASSERT(pixel <= (uint)d->colors.size());
- return d->colors.at(pixel);
- }
-
- const int r = (((pixel & d->visual->red_mask) >> d->r_shift) << 8) / d->r_max;
- const int g = (((pixel & d->visual->green_mask) >> d->g_shift) << 8) / d->g_max;
- const int b = (((pixel & d->visual->blue_mask) >> d->b_shift) << 8) / d->b_max;
- return QColor(r, g, b);
-}
-
-const QVector<QColor> QColormap::colormap() const
-{ return d->colors; }
-
-QColormap &QColormap::operator=(const QColormap &colormap)
-{
- qAtomicAssign(d, colormap.d);
- return *this;
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qcursor_x11.cpp b/src/widgets/platforms/x11/qcursor_x11.cpp
deleted file mode 100644
index 1132d3737d..0000000000
--- a/src/widgets/platforms/x11/qcursor_x11.cpp
+++ /dev/null
@@ -1,640 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-#include <qdatastream.h>
-#include <private/qcursor_p.h>
-#include <private/qt_x11_p.h>
-#include <private/qapplication_p.h>
-#include <qbitmap.h>
-#include <qcursor.h>
-#include <X11/cursorfont.h>
-
-#include <qlibrary.h>
-
-#ifndef QT_NO_XCURSOR
-# include <X11/Xcursor/Xcursor.h>
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XFIXES
-#ifndef Status
-#define Status int
-#endif
-# include <X11/extensions/Xfixes.h>
-#endif // QT_NO_XFIXES
-
-#include "qx11info_x11.h"
-#include <private/qpixmap_x11_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
-// use the ugly X11 cursors.
-
-/*****************************************************************************
- Internal QCursorData class
- *****************************************************************************/
-
-QCursorData::QCursorData(Qt::CursorShape s)
- : cshape(s), bm(0), bmm(0), hx(0), hy(0), hcurs(0), pm(0), pmm(0)
-{
- ref = 1;
-}
-
-QCursorData::~QCursorData()
-{
- Display *dpy = X11 ? X11->display : (Display*)0;
-
- // Add in checking for the display too as on HP-UX
- // we seem to get a core dump as the cursor data is
- // deleted again from main() on exit...
- if (hcurs && dpy)
- XFreeCursor(dpy, hcurs);
- if (pm && dpy)
- XFreePixmap(dpy, pm);
- if (pmm && dpy)
- XFreePixmap(dpy, pmm);
- delete bm;
- delete bmm;
-}
-
-#ifndef QT_NO_CURSOR
-QCursor::QCursor(Qt::HANDLE cursor)
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- d = new QCursorData(Qt::CustomCursor);
- d->hcurs = cursor;
-}
-
-#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->ref = 1;
-
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
- d->bm = new QBitmap(qt_toX11Pixmap(bitmap));
- d->bmm = new QBitmap(qt_toX11Pixmap(mask));
-
- d->hcurs = 0;
- d->cshape = Qt::BitmapCursor;
- d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
- d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
- d->fg.red = 0x0000;
- d->fg.green = 0x0000;
- d->fg.blue = 0x0000;
- d->bg.red = 0xffff;
- d->bg.green = 0xffff;
- d->bg.blue = 0xffff;
- return d;
-}
-
-
-
-#ifndef QT_NO_CURSOR
-Qt::HANDLE QCursor::handle() const
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- if (!d->hcurs)
- d->update();
- return d->hcurs;
-}
-#endif
-
-QPoint QCursor::pos()
-{
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint buttons;
- Display* dpy = X11->display;
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
- &win_x, &win_y, &buttons))
-
- return QPoint(root_x, root_y);
- }
- return QPoint();
-}
-
-/*! \internal
-*/
-#ifndef QT_NO_CURSOR
-int QCursor::x11Screen()
-{
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint buttons;
- Display* dpy = X11->display;
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
- &win_x, &win_y, &buttons))
- return i;
- }
- return -1;
-}
-#endif
-
-void QCursor::setPos(int x, int y)
-{
- QPoint current, target(x, y);
-
- // this is copied from pos(), since we need the screen number for the correct
- // root window in the XWarpPointer call
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint buttons;
- Display* dpy = X11->display;
- int screen;
- for (screen = 0; screen < ScreenCount(dpy); ++screen) {
- if (XQueryPointer(dpy, QX11Info::appRootWindow(screen), &root, &child, &root_x, &root_y,
- &win_x, &win_y, &buttons)) {
- current = QPoint(root_x, root_y);
- break;
- }
- }
-
- if (screen >= ScreenCount(dpy))
- return;
-
- // Need to check, since some X servers generate null mouse move
- // events, causing looping in applications which call setPos() on
- // every mouse move event.
- //
- if (current == target)
- return;
-
- XWarpPointer(X11->display, XNone, QX11Info::appRootWindow(screen), 0, 0, 0, 0, x, y);
-}
-
-
-/*!
- \internal
-
- Creates the cursor.
-*/
-
-void QCursorData::update()
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- if (hcurs)
- return;
-
- Display *dpy = X11->display;
- Window rootwin = QX11Info::appRootWindow();
-
- if (cshape == Qt::BitmapCursor) {
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
-#ifndef QT_NO_XRENDER
- if (!pixmap.isNull() && X11->use_xrender) {
- pixmap = qt_toX11Pixmap(pixmap);
- hcurs = XRenderCreateCursor (X11->display, pixmap.x11PictureHandle(), hx, hy);
- } else
-#endif
- {
- hcurs = XCreatePixmapCursor(dpy, bm->handle(), bmm->handle(), &fg, &bg, hx, hy);
- }
- return;
- }
-
- static const char *cursorNames[] = {
- "left_ptr",
- "up_arrow",
- "cross",
- "wait",
- "ibeam",
- "size_ver",
- "size_hor",
- "size_bdiag",
- "size_fdiag",
- "size_all",
- "blank",
- "split_v",
- "split_h",
- "pointing_hand",
- "forbidden",
- "whats_this",
- "left_ptr_watch",
- "openhand",
- "closedhand",
- "copy",
- "move",
- "link"
- };
-
-#ifndef QT_NO_XCURSOR
- if (X11->ptrXcursorLibraryLoadCursor) {
- // special case for non-standard dnd-* cursors
- switch (cshape) {
- case Qt::DragCopyCursor:
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
- break;
- case Qt::DragMoveCursor:
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
- break;
- case Qt::DragLinkCursor:
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
- break;
- default:
- break;
- }
- if (!hcurs)
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
- }
- if (hcurs)
- return;
-#endif // QT_NO_XCURSOR
-
- static const uchar cur_blank_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, 0x00, 0x00, 0x00 };
-
- // Non-standard X11 cursors are created from bitmaps
-
-#ifndef QT_USE_APPROXIMATE_CURSORS
- static const uchar cur_ver_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
- 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
- 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
- static const uchar mcur_ver_bits[] = {
- 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
- 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
- 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
- static const uchar cur_hor_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
- 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar mcur_hor_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
- 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
- 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
- static const uchar cur_bdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
- 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
- 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar mcur_bdiag_bits[] = {
- 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
- 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
- 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
- static const uchar cur_fdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
- 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
- 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
- static const uchar mcur_fdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
- 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
- 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
- static const uchar *cursor_bits16[] = {
- cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
- cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
- 0, 0, cur_blank_bits, cur_blank_bits };
-
- 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 whatsthis_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
- 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
- 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
- 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
- 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
- 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
- 0x80, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
- static const uchar whatsthism_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
- 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
- 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
- 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
- 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
- 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
- 0x80, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
- static const uchar busy_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
- 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
- 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
- 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
- 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
- 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
- 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 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 busym_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
- 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
- 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
- 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
- 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
- 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
- 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 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 * const cursor_bits32[] = {
- vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
- 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
- };
-
- static const uchar forbidden_bits[] = {
- 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
- 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
- 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
- 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
-
- static const uchar forbiddenm_bits[] = {
- 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
- 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
- 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
- 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,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_bits20[] = {
- forbidden_bits, forbiddenm_bits
- };
-
- if ((cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor)
- || cshape == Qt::BlankCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- int i = (cshape - Qt::SizeVerCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i]), 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i + 1]), 16, 16);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
- || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- int i = (cshape - Qt::SplitVCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i]), 32, 32);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i + 1]), 32, 32);
- int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
- || cshape == Qt::BusyCursor) ? 0 : 16;
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, hs, hs);
- } else if (cshape == Qt::ForbiddenCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- int i = (cshape - Qt::ForbiddenCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i]), 20, 20);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i + 1]), 20, 20);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 10, 10);
- } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- bool open = cshape == Qt::OpenHandCursor;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhand_bits : closedhand_bits), 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhandm_bits : closedhandm_bits), 16, 16);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
- || cshape == Qt::DragLinkCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- QImage image = QApplicationPrivate::instance()->getPixmapCursor(cshape).toImage();
- pm = QX11PlatformPixmap::createBitmapFromImage(image);
- pmm = QX11PlatformPixmap::createBitmapFromImage(image.createAlphaMask().convertToFormat(QImage::Format_MonoLSB));
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- }
-
- if (hcurs)
- {
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
- X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
-#endif /* ! QT_NO_XFIXES */
- return;
- }
-
-#endif /* ! QT_USE_APPROXIMATE_CURSORS */
-
- uint sh;
- switch (cshape) { // map Q cursor to X cursor
- case Qt::ArrowCursor:
- sh = XC_left_ptr;
- break;
- case Qt::UpArrowCursor:
- sh = XC_center_ptr;
- break;
- case Qt::CrossCursor:
- sh = XC_crosshair;
- break;
- case Qt::WaitCursor:
- sh = XC_watch;
- break;
- case Qt::IBeamCursor:
- sh = XC_xterm;
- break;
- case Qt::SizeAllCursor:
- sh = XC_fleur;
- break;
- case Qt::PointingHandCursor:
- sh = XC_hand2;
- break;
-#ifdef QT_USE_APPROXIMATE_CURSORS
- case Qt::SizeBDiagCursor:
- sh = XC_top_right_corner;
- break;
- case Qt::SizeFDiagCursor:
- sh = XC_bottom_right_corner;
- break;
- case Qt::BlankCursor:
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- pm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- return;
- break;
- case Qt::SizeVerCursor:
- case Qt::SplitVCursor:
- sh = XC_sb_v_double_arrow;
- break;
- case Qt::SizeHorCursor:
- case Qt::SplitHCursor:
- sh = XC_sb_h_double_arrow;
- break;
- case Qt::WhatsThisCursor:
- sh = XC_question_arrow;
- break;
- case Qt::ForbiddenCursor:
- sh = XC_circle;
- break;
- case Qt::BusyCursor:
- sh = XC_watch;
- break;
- case Qt::DragCopyCursor:
- sh = XC_tcross;
- break;
- case Qt::DragLinkCursor:
- sh = XC_center_ptr;
- break;
- case Qt::DragMoveCursor:
- sh = XC_top_left_arrow;
- break;
-#endif /* QT_USE_APPROXIMATE_CURSORS */
- default:
- qWarning("QCursor::update: Invalid cursor shape %d", cshape);
- return;
- }
- hcurs = XCreateFontCursor(dpy, sh);
-
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
- X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
-#endif /* ! QT_NO_XFIXES */
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qdesktopwidget_x11.cpp b/src/widgets/platforms/x11/qdesktopwidget_x11.cpp
deleted file mode 100644
index 52d3be18e9..0000000000
--- a/src/widgets/platforms/x11/qdesktopwidget_x11.cpp
+++ /dev/null
@@ -1,406 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#include "qlibrary.h"
-#include "qt_x11_p.h"
-#include "qvariant.h"
-#include "qwidget_p.h"
-#include "qx11info_x11.h"
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-// defined in qwidget_x11.cpp
-extern int qt_x11_create_desktop_on_screen;
-
-
-// function to update the workarea of the screen
-static bool qt_desktopwidget_workarea_dirty = true;
-void qt_desktopwidget_update_workarea()
-{
- qt_desktopwidget_workarea_dirty = true;
-}
-
-
-class QSingleDesktopWidget : public QWidget
-{
-public:
- QSingleDesktopWidget();
- ~QSingleDesktopWidget();
-};
-
-QSingleDesktopWidget::QSingleDesktopWidget()
- : QWidget(0, Qt::Desktop)
-{
-}
-
-QSingleDesktopWidget::~QSingleDesktopWidget()
-{
- const QObjectList &childList = children();
- for (int i = childList.size(); i > 0 ;) {
- --i;
- childList.at(i)->setParent(0);
- }
-}
-
-
-class QDesktopWidgetPrivate : public QWidgetPrivate
-{
-public:
- QDesktopWidgetPrivate();
- ~QDesktopWidgetPrivate();
-
- void init();
-
- bool use_xinerama;
- int defaultScreen;
- int screenCount;
-
- QWidget **screens;
- QRect *rects;
- QRect *workareas;
-};
-
-QDesktopWidgetPrivate::QDesktopWidgetPrivate()
- : use_xinerama(false), defaultScreen(0), screenCount(1),
- screens(0), rects(0), workareas(0)
-{
-}
-
-QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
-{
- if (screens) {
- for (int i = 0; i < screenCount; ++i) {
- if (i == defaultScreen) continue;
- delete screens[i];
- screens[i] = 0;
- }
-
- free (screens);
- }
-
- if (rects) delete [] rects;
- if (workareas) delete [] workareas;
-}
-
-void QDesktopWidgetPrivate::init()
-{
- // get the screen count
- int newScreenCount = ScreenCount(X11->display);
-#ifndef QT_NO_XINERAMA
-
- XineramaScreenInfo *xinerama_screeninfo = 0;
-
- // we ignore the Xinerama extension when using the display is
- // using traditional multi-screen (with multiple root windows)
- if (newScreenCount == 1
- && X11->ptrXineramaQueryExtension
- && X11->ptrXineramaIsActive
- && X11->ptrXineramaQueryScreens) {
- int unused;
- use_xinerama = (X11->ptrXineramaQueryExtension(X11->display, &unused, &unused)
- && X11->ptrXineramaIsActive(X11->display));
- }
-
- if (use_xinerama) {
- xinerama_screeninfo =
- X11->ptrXineramaQueryScreens(X11->display, &newScreenCount);
- }
-
- if (xinerama_screeninfo) {
- defaultScreen = 0;
- } else
-#endif // QT_NO_XINERAMA
- {
- defaultScreen = DefaultScreen(X11->display);
- newScreenCount = ScreenCount(X11->display);
- use_xinerama = false;
- }
-
- delete [] rects;
- rects = new QRect[newScreenCount];
- delete [] workareas;
- workareas = new QRect[newScreenCount];
-
- // get the geometry of each screen
- int i, j, x, y, w, h;
- for (i = 0, j = 0; i < newScreenCount; i++, j++) {
-
-#ifndef QT_NO_XINERAMA
- if (use_xinerama) {
- x = xinerama_screeninfo[i].x_org;
- y = xinerama_screeninfo[i].y_org;
- w = xinerama_screeninfo[i].width;
- h = xinerama_screeninfo[i].height;
- } else
-#endif // QT_NO_XINERAMA
- {
- x = 0;
- y = 0;
- w = WidthOfScreen(ScreenOfDisplay(X11->display, i));
- h = HeightOfScreen(ScreenOfDisplay(X11->display, i));
- }
-
- rects[j].setRect(x, y, w, h);
-
- if (use_xinerama && j > 0 && rects[j-1].intersects(rects[j])) {
- // merge a "cloned" screen with the previous, hiding all crtcs
- // that are currently showing a sub-rect of the previous screen
- if ((rects[j].width()*rects[j].height()) >
- (rects[j-1].width()*rects[j-1].height()))
- rects[j-1] = rects[j];
- j--;
- }
-
- workareas[i] = QRect();
- }
-
- if (screens) {
- // leaks QWidget* pointers on purpose, can't delete them as pointer escapes
- screens = q_check_ptr((QWidget**) realloc(screens, j * sizeof(QWidget*)));
- if (j > screenCount)
- memset(&screens[screenCount], 0, (j-screenCount) * sizeof(QWidget*));
- }
-
- screenCount = j;
-
-#ifndef QT_NO_XINERAMA
- if (use_xinerama && screenCount == 1)
- use_xinerama = false;
-
- if (xinerama_screeninfo)
- XFree(xinerama_screeninfo);
-#endif // QT_NO_XINERAMA
-
-}
-
-// the QDesktopWidget itself will be created on the default screen
-// as qt_x11_create_desktop_on_screen defaults to -1
-QDesktopWidget::QDesktopWidget()
- : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
-{
- Q_D(QDesktopWidget);
- d->init();
-}
-
-QDesktopWidget::~QDesktopWidget()
-{
-}
-
-bool QDesktopWidget::isVirtualDesktop() const
-{
- Q_D(const QDesktopWidget);
- return d->use_xinerama;
-}
-
-int QDesktopWidget::primaryScreen() const
-{
- Q_D(const QDesktopWidget);
- return d->defaultScreen;
-}
-
-int QDesktopWidget::numScreens() const
-{
- Q_D(const QDesktopWidget);
- return d->screenCount;
-}
-
-QWidget *QDesktopWidget::screen(int screen)
-{
- Q_D(QDesktopWidget);
- if (d->use_xinerama)
- return this;
-
- if (screen < 0 || screen >= d->screenCount)
- screen = d->defaultScreen;
-
- if (! d->screens) {
- d->screens = (QWidget**) calloc( d->screenCount, sizeof(QWidget*));
- d->screens[d->defaultScreen] = this;
- }
-
- if (! d->screens[screen] || // not created yet
- ! (d->screens[screen]->windowType() == Qt::Desktop)) { // reparented away
- qt_x11_create_desktop_on_screen = screen;
- d->screens[screen] = new QSingleDesktopWidget;
- qt_x11_create_desktop_on_screen = -1;
- }
-
- return d->screens[screen];
-}
-
-const QRect QDesktopWidget::availableGeometry(int screen) const
-{
- Q_D(const QDesktopWidget);
- if (qt_desktopwidget_workarea_dirty) {
- // the workareas are dirty, invalidate them
- for (int i = 0; i < d->screenCount; ++i)
- d->workareas[i] = QRect();
- qt_desktopwidget_workarea_dirty = false;
- }
-
- if (screen < 0 || screen >= d->screenCount)
- screen = d->defaultScreen;
-
- if (d->workareas[screen].isValid())
- return d->workareas[screen];
-
- if (X11->isSupportedByWM(ATOM(_NET_WORKAREA))) {
- int x11Screen = isVirtualDesktop() ? DefaultScreen(X11->display) : screen;
-
- Atom ret;
- int format, e;
- unsigned char *data = 0;
- unsigned long nitems, after;
-
- e = XGetWindowProperty(X11->display,
- QX11Info::appRootWindow(x11Screen),
- ATOM(_NET_WORKAREA), 0, 4, False, XA_CARDINAL,
- &ret, &format, &nitems, &after, &data);
-
- QRect workArea;
- if (e == Success && ret == XA_CARDINAL &&
- format == 32 && nitems == 4) {
- long *workarea = (long *) data;
- workArea = QRect(workarea[0], workarea[1], workarea[2], workarea[3]);
- } else {
- workArea = screenGeometry(screen);
- }
-
- if (isVirtualDesktop()) {
- // intersect the workarea (which spawns all Xinerama screens) with the rect for the
- // requested screen
- workArea &= screenGeometry(screen);
- }
-
- d->workareas[screen] = workArea;
-
- if (data)
- XFree(data);
- } else {
- d->workareas[screen] = screenGeometry(screen);
- }
-
- return d->workareas[screen];
-}
-
-const QRect QDesktopWidget::screenGeometry(int screen) const
-{
- Q_D(const QDesktopWidget);
- if (screen < 0 || screen >= d->screenCount)
- screen = d->defaultScreen;
-
- return d->rects[screen];
-}
-
-int QDesktopWidget::screenNumber(const QWidget *widget) const
-{
- Q_D(const QDesktopWidget);
- if (!widget)
- return d->defaultScreen;
-
-#ifndef QT_NO_XINERAMA
- if (d->use_xinerama) {
- // this is how we do it for xinerama
- 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[i].intersected(frame);
- int size = sect.width() * sect.height();
- if (size > maxSize && sect.width() > 0 && sect.height() > 0) {
- maxSize = size;
- maxScreen = i;
- }
- }
- return maxScreen;
- }
-#endif // QT_NO_XINERAMA
-
- return widget->x11Info().screen();
-}
-
-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[i]);
- if (thisDistance < shortestDistance) {
- shortestDistance = thisDistance;
- closestScreen = i;
- }
- }
- return closestScreen;
-}
-
-void QDesktopWidget::resizeEvent(QResizeEvent *event)
-{
- Q_D(QDesktopWidget);
- int oldScreenCount = d->screenCount;
- QVector<QRect> oldRects(oldScreenCount);
- for (int i = 0; i < oldScreenCount; ++i) {
- oldRects[i] = d->rects[i];
- }
-
- d->init();
-
- for (int i = 0; i < qMin(oldScreenCount, d->screenCount); ++i) {
- if (oldRects.at(i) != d->rects[i])
- emit resized(i);
- }
-
- if (oldScreenCount != d->screenCount) {
- emit screenCountChanged(d->screenCount);
- }
-
- qt_desktopwidget_workarea_dirty = true;
- QWidget::resizeEvent(event);
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qdnd_x11.cpp b/src/widgets/platforms/x11/qdnd_x11.cpp
deleted file mode 100644
index 2718853920..0000000000
--- a/src/widgets/platforms/x11/qdnd_x11.cpp
+++ /dev/null
@@ -1,2072 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#include "qapplication.h"
-
-#ifndef QT_NO_DRAGANDDROP
-
-#include "qwidget.h"
-#include "qpainter.h"
-#include "qpixmap.h"
-#include "qbitmap.h"
-#include "qdesktopwidget.h"
-#include "qevent.h"
-#include "qiodevice.h"
-#include "qpointer.h"
-#include "qcursor.h"
-#include "qelapsedtimer.h"
-#include "qvariant.h"
-#include "qvector.h"
-#include "qurl.h"
-#include "qdebug.h"
-#include "qimagewriter.h"
-#include "qbuffer.h"
-#include "qtextcodec.h"
-
-#include "qdnd_p.h"
-#include "qapplication_p.h"
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-
-#include "qwidget_p.h"
-#include "qcursor_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// #define DND_DEBUG
-#ifdef DND_DEBUG
-#define DEBUG qDebug
-#else
-#define DEBUG if(0) qDebug
-#endif
-
-#ifdef DND_DEBUG
-#define DNDDEBUG qDebug()
-#else
-#define DNDDEBUG if(0) qDebug()
-#endif
-
-static int findXdndDropTransactionByWindow(Window window)
-{
- int at = -1;
- for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
- const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
- if (t.target == window || t.proxy_target == window) {
- at = i;
- break;
- }
- }
- return at;
-}
-
-static int findXdndDropTransactionByTime(Time timestamp)
-{
- int at = -1;
- for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
- const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
- if (t.timestamp == timestamp) {
- at = i;
- break;
- }
- }
- return at;
-}
-
-// timer used to discard old XdndDrop transactions
-static int transaction_expiry_timer = -1;
-enum { XdndDropTransactionTimeout = 5000 }; // 5 seconds
-
-static void restartXdndDropExpiryTimer()
-{
- if (transaction_expiry_timer != -1)
- QDragManager::self()->killTimer(transaction_expiry_timer);
- transaction_expiry_timer = QDragManager::self()->startTimer(XdndDropTransactionTimeout);
-}
-
-
-// find an ancestor with XdndAware on it
-static Window findXdndAwareParent(Window window)
-{
- Window target = 0;
- forever {
- // check if window has XdndAware
- Atom type = 0;
- int f;
- unsigned long n, a;
- unsigned char *data = 0;
- if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
- if (data)
- XFree(data);
- if (type) {
- target = window;
- break;
- }
- }
-
- // try window's parent
- Window root;
- Window parent;
- Window *children;
- uint unused;
- if (!XQueryTree(X11->display, window, &root, &parent, &children, &unused))
- break;
- if (children)
- XFree(children);
- if (window == root)
- break;
- window = parent;
- }
- return target;
-}
-
-
-
-
-// and all this stuff is copied -into- qapp_x11.cpp
-
-static void handle_xdnd_position(QWidget *, const XEvent *, bool);
-static void handle_xdnd_status(QWidget * w, const XEvent * xe, bool /*passive*/);
-
-const int xdnd_version = 5;
-
-static Qt::DropAction xdndaction_to_qtaction(Atom atom)
-{
- if (atom == ATOM(XdndActionCopy) || atom == 0)
- return Qt::CopyAction;
- if (atom == ATOM(XdndActionLink))
- return Qt::LinkAction;
- if (atom == ATOM(XdndActionMove))
- return Qt::MoveAction;
- return Qt::CopyAction;
-}
-
-static int qtaction_to_xdndaction(Qt::DropAction a)
-{
- switch (a) {
- case Qt::CopyAction:
- return ATOM(XdndActionCopy);
- case Qt::LinkAction:
- return ATOM(XdndActionLink);
- case Qt::MoveAction:
- case Qt::TargetMoveAction:
- return ATOM(XdndActionMove);
- case Qt::IgnoreAction:
- return XNone;
- default:
- return ATOM(XdndActionCopy);
- }
-}
-
-// clean up the stuff used.
-static void qt_xdnd_cleanup();
-
-static void qt_xdnd_send_leave();
-
-// real variables:
-// xid of current drag source
-static Atom qt_xdnd_dragsource_xid = 0;
-
-// the types in this drop. 100 is no good, but at least it's big.
-const int qt_xdnd_max_type = 100;
-static Atom qt_xdnd_types[qt_xdnd_max_type + 1];
-
-// timer used when target wants "continuous" move messages (eg. scroll)
-static int heartbeat = -1;
-// rectangle in which the answer will be the same
-static QRect qt_xdnd_source_sameanswer;
-// top-level window we sent position to last.
-static Window qt_xdnd_current_target;
-// window to send events to (always valid if qt_xdnd_current_target)
-static Window qt_xdnd_current_proxy_target;
-static Time qt_xdnd_source_current_time;
-
-// widget we forwarded position to last, and local position
-static QPointer<QWidget> qt_xdnd_current_widget;
-static QPoint qt_xdnd_current_position;
-// timestamp from the XdndPosition and XdndDrop
-static Time qt_xdnd_target_current_time;
-// screen number containing the pointer... -1 means default
-static int qt_xdnd_current_screen = -1;
-// state of dragging... true if dragging, false if not
-bool qt_xdnd_dragging = false;
-
-static bool waiting_for_status = false;
-
-// used to preset each new QDragMoveEvent
-static Qt::DropAction last_target_accepted_action = Qt::IgnoreAction;
-
-// Shift/Ctrl handling, and final drop status
-static Qt::DropAction global_accepted_action = Qt::CopyAction;
-static Qt::DropActions possible_actions = Qt::IgnoreAction;
-
-// for embedding only
-static QWidget* current_embedding_widget = 0;
-static XEvent last_enter_event;
-
-// cursors
-static QCursor *noDropCursor = 0;
-static QCursor *moveCursor = 0;
-static QCursor *copyCursor = 0;
-static QCursor *linkCursor = 0;
-
-static QPixmap *defaultPm = 0;
-
-static const int default_pm_hotx = -2;
-static const int default_pm_hoty = -16;
-static const char* const default_pm[] = {
-"13 9 3 1",
-". c None",
-" c #000000",
-"X c #FFFFFF",
-"X X X X X X X",
-" X X X X X X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X X X X X X ",
-"X X X X X X X"
-};
-
-class QShapedPixmapWidget : public QWidget
-{
- Q_OBJECT
-public:
- QShapedPixmapWidget(QWidget* w) :
- QWidget(w,
- Qt::Tool | Qt::FramelessWindowHint
- | Qt::X11BypassWindowManagerHint
- | Qt::BypassGraphicsProxyWidget)
- {
- setAttribute(Qt::WA_X11NetWmWindowTypeDND);
- }
-
- void setPixmap(const QPixmap &pm)
- {
- QBitmap mask = pm.mask();
- if (!mask.isNull()) {
- setMask(mask);
- } else {
- clearMask();
- }
- resize(pm.width(),pm.height());
- pixmap = pm;
- update();
- }
- QPoint pm_hot;
-
-protected:
- QPixmap pixmap;
- void paintEvent(QPaintEvent*)
- {
- QPainter p(this);
- p.drawPixmap(0, 0, pixmap);
- }
-};
-
-#include "qdnd_x11.moc"
-
-struct XdndData {
- QShapedPixmapWidget *deco;
- QWidget* desktop_proxy;
-};
-
-static XdndData xdnd_data = { 0, 0 };
-
-class QExtraWidget : public QWidget
-{
- Q_DECLARE_PRIVATE(QWidget)
-public:
- inline QWExtra* extraData();
- inline QTLWExtra* topData();
-};
-
-inline QWExtra* QExtraWidget::extraData() { return d_func()->extraData(); }
-inline QTLWExtra* QExtraWidget::topData() { return d_func()->topData(); }
-
-
-static WId xdndProxy(WId w)
-{
- Atom type = XNone;
- int f;
- unsigned long n, a;
- unsigned char *retval = 0;
- XGetWindowProperty(X11->display, w, ATOM(XdndProxy), 0, 1, False,
- XA_WINDOW, &type, &f,&n,&a,&retval);
- WId *proxy_id_ptr = (WId *)retval;
- WId proxy_id = 0;
- if (type == XA_WINDOW && proxy_id_ptr) {
- proxy_id = *proxy_id_ptr;
- XFree(proxy_id_ptr);
- proxy_id_ptr = 0;
- // Already exists. Real?
- X11->ignoreBadwindow();
- XGetWindowProperty(X11->display, proxy_id, ATOM(XdndProxy), 0, 1, False,
- XA_WINDOW, &type, &f,&n,&a,&retval);
- proxy_id_ptr = (WId *)retval;
- if (X11->badwindow() || type != XA_WINDOW || !proxy_id_ptr || *proxy_id_ptr != proxy_id)
- // Bogus - we will overwrite.
- proxy_id = 0;
- }
- if (proxy_id_ptr)
- XFree(proxy_id_ptr);
- return proxy_id;
-}
-
-static bool xdndEnable(QWidget* w, bool on)
-{
- DNDDEBUG << "xdndEnable" << w << on;
- if (on) {
- QWidget * xdnd_widget = 0;
- if ((w->windowType() == Qt::Desktop)) {
- if (xdnd_data.desktop_proxy) // *WE* already have one.
- return false;
-
- // As per Xdnd4, use XdndProxy
- XGrabServer(X11->display);
- Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
- WId proxy_id = xdndProxy(w->effectiveWinId());
-
- if (!proxy_id) {
- xdnd_widget = xdnd_data.desktop_proxy = new QWidget;
- proxy_id = xdnd_data.desktop_proxy->effectiveWinId();
- XChangeProperty (X11->display, w->effectiveWinId(), ATOM(XdndProxy),
- XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
- XChangeProperty (X11->display, proxy_id, ATOM(XdndProxy),
- XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
- }
-
- XUngrabServer(X11->display);
- } else {
- xdnd_widget = w->window();
- }
- if (xdnd_widget) {
- DNDDEBUG << "setting XdndAware for" << xdnd_widget << xdnd_widget->effectiveWinId();
- Atom atm = (Atom)xdnd_version;
- Q_ASSERT(xdnd_widget->testAttribute(Qt::WA_WState_Created));
- XChangeProperty(X11->display, xdnd_widget->effectiveWinId(), ATOM(XdndAware),
- XA_ATOM, 32, PropModeReplace, (unsigned char *)&atm, 1);
- return true;
- } else {
- return false;
- }
- } else {
- if ((w->windowType() == Qt::Desktop)) {
- XDeleteProperty(X11->display, w->internalWinId(), ATOM(XdndProxy));
- delete xdnd_data.desktop_proxy;
- xdnd_data.desktop_proxy = 0;
- } else {
- DNDDEBUG << "not deleting XDndAware";
- }
- return true;
- }
-}
-
-QByteArray QX11Data::xdndAtomToString(Atom a)
-{
- if (!a) return 0;
-
- if (a == XA_STRING || a == ATOM(UTF8_STRING)) {
- return "text/plain"; // some Xdnd clients are dumb
- }
- char *atom = XGetAtomName(display, a);
- QByteArray result = atom;
- XFree(atom);
- return result;
-}
-
-Atom QX11Data::xdndStringToAtom(const char *mimeType)
-{
- if (!mimeType || !*mimeType)
- return 0;
- return XInternAtom(display, mimeType, False);
-}
-
-//$$$
-QString QX11Data::xdndMimeAtomToString(Atom a)
-{
- QString atomName;
- if (a) {
- char *atom = XGetAtomName(display, a);
- atomName = QString::fromLatin1(atom);
- XFree(atom);
- }
- return atomName;
-}
-
-//$$$
-Atom QX11Data::xdndMimeStringToAtom(const QString &mimeType)
-{
- if (mimeType.isEmpty())
- return 0;
- return XInternAtom(display, mimeType.toLatin1().constData(), False);
-}
-
-//$$$ replace ccxdndAtomToString()
-QStringList QX11Data::xdndMimeFormatsForAtom(Atom a)
-{
- QStringList formats;
- if (a) {
- QString atomName = xdndMimeAtomToString(a);
- formats.append(atomName);
-
- // special cases for string type
- if (a == ATOM(UTF8_STRING) || a == XA_STRING
- || a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
- formats.append(QLatin1String("text/plain"));
-
- // special cases for uris
- if (atomName == QLatin1String("text/x-moz-url"))
- formats.append(QLatin1String("text/uri-list"));
-
- // special case for images
- if (a == XA_PIXMAP)
- formats.append(QLatin1String("image/ppm"));
- }
- return formats;
-}
-
-//$$$
-bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat)
-{
- bool ret = false;
- *atomFormat = a;
- *dataFormat = 8;
- QString atomName = xdndMimeAtomToString(a);
- if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
- *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
- if (atomName == QLatin1String("application/x-color"))
- *dataFormat = 16;
- ret = true;
- } else {
- if ((a == ATOM(UTF8_STRING) || a == XA_STRING
- || a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
- && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
- if (a == ATOM(UTF8_STRING)){
- *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
- ret = true;
- } else if (a == XA_STRING) {
- *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
- QLatin1String("text/plain"), mimeData)).toLocal8Bit();
- ret = true;
- } else if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT)) {
- // the ICCCM states that TEXT and COMPOUND_TEXT are in the
- // encoding of choice, so we choose the encoding of the locale
- QByteArray strData = QString::fromUtf8(QInternalMimeData::renderDataHelper(
- QLatin1String("text/plain"), mimeData)).toLocal8Bit();
- char *list[] = { strData.data(), NULL };
-
- XICCEncodingStyle style = (a == ATOM(COMPOUND_TEXT))
- ? XCompoundTextStyle : XStdICCTextStyle;
- XTextProperty textprop;
- if (list[0] != NULL
- && XmbTextListToTextProperty(X11->display, list, 1, style,
- &textprop) == Success) {
- *atomFormat = textprop.encoding;
- *dataFormat = textprop.format;
- *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8);
- ret = true;
-
- DEBUG(" textprop type %lx\n"
- " textprop name '%s'\n"
- " format %d\n"
- " %ld items\n"
- " %d bytes\n",
- textprop.encoding,
- X11->xdndMimeAtomToString(textprop.encoding).toLatin1().data(),
- textprop.format, textprop.nitems, data->size());
-
- XFree(textprop.value);
- }
- }
- } else if (atomName == QLatin1String("text/x-moz-url") &&
- QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
- QByteArray uri = QInternalMimeData::renderDataHelper(
- QLatin1String("text/uri-list"), mimeData).split('\n').first();
- QString mozUri = QString::fromLatin1(uri, uri.size());
- mozUri += QLatin1Char('\n');
- *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
- ret = true;
- } else if ((a == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) {
- QPixmap pm = qvariant_cast<QPixmap>(mimeData->imageData());
- if (a == XA_BITMAP && pm.depth() != 1) {
- QImage img = pm.toImage();
- img = img.convertToFormat(QImage::Format_MonoLSB);
- pm = QPixmap::fromImage(img);
- }
- QDragManager *dm = QDragManager::self();
- if (dm) {
- Pixmap handle = pm.handle();
- *data = QByteArray((const char *) &handle, sizeof(Pixmap));
- dm->xdndMimeTransferedPixmap[dm->xdndMimeTransferedPixmapIndex] = pm;
- dm->xdndMimeTransferedPixmapIndex =
- (dm->xdndMimeTransferedPixmapIndex + 1) % 2;
- ret = true;
- }
- } else {
- DEBUG("QClipboard: xdndMimeDataForAtom(): converting to type '%s' is not supported", qPrintable(atomName));
- }
- }
- return ret && data != 0;
-}
-
-//$$$
-QList<Atom> QX11Data::xdndMimeAtomsForFormat(const QString &format)
-{
- QList<Atom> atoms;
- atoms.append(xdndMimeStringToAtom(format));
-
- // special cases for strings
- if (format == QLatin1String("text/plain")) {
- atoms.append(ATOM(UTF8_STRING));
- atoms.append(XA_STRING);
- atoms.append(ATOM(TEXT));
- atoms.append(ATOM(COMPOUND_TEXT));
- }
-
- // special cases for uris
- if (format == QLatin1String("text/uri-list")) {
- atoms.append(xdndMimeStringToAtom(QLatin1String("text/x-moz-url")));
- }
-
- //special cases for images
- if (format == QLatin1String("image/ppm"))
- atoms.append(XA_PIXMAP);
- if (format == QLatin1String("image/pbm"))
- atoms.append(XA_BITMAP);
-
- return atoms;
-}
-
-//$$$
-QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding)
-{
- QString atomName = xdndMimeAtomToString(a);
- if (atomName == format)
- return data;
-
- if (!encoding.isEmpty()
- && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
-
- if (requestedType == QVariant::String) {
- QTextCodec *codec = QTextCodec::codecForName(encoding);
- if (codec)
- return codec->toUnicode(data);
- }
-
- return data;
- }
-
- // special cases for string types
- if (format == QLatin1String("text/plain")) {
- if (a == ATOM(UTF8_STRING))
- return QString::fromUtf8(data);
- if (a == XA_STRING)
- return QString::fromLatin1(data);
- if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
- // #### might be wrong for COMPUND_TEXT
- return QString::fromLocal8Bit(data, data.size());
- }
-
- // special case for uri types
- if (format == QLatin1String("text/uri-list")) {
- if (atomName == QLatin1String("text/x-moz-url")) {
- // we expect this as utf16 <url><space><title>
- // the first part is a url that should only contain ascci char
- // so it should be safe to check that the second char is 0
- // to verify that it is utf16
- if (data.size() > 1 && data.at(1) == 0)
- return QString::fromRawData((const QChar *)data.constData(),
- data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
- }
- }
-
- // special cas for images
- if (format == QLatin1String("image/ppm")) {
- if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) {
- Pixmap xpm = *((Pixmap*)data.data());
- if (!xpm)
- return QByteArray();
- QPixmap qpm = QPixmap::fromX11Pixmap(xpm);
- QImageWriter imageWriter;
- imageWriter.setFormat("PPMRAW");
- QImage imageToWrite = qpm.toImage();
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- imageWriter.setDevice(&buf);
- imageWriter.write(imageToWrite);
- return buf.buffer();
- }
- }
- return QVariant();
-}
-
-//$$$ middle of xdndObtainData
-Atom QX11Data::xdndMimeAtomForFormat(const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *encoding)
-{
- encoding->clear();
-
- // find matches for string types
- if (format == QLatin1String("text/plain")) {
- if (atoms.contains(ATOM(UTF8_STRING)))
- return ATOM(UTF8_STRING);
- if (atoms.contains(ATOM(COMPOUND_TEXT)))
- return ATOM(COMPOUND_TEXT);
- if (atoms.contains(ATOM(TEXT)))
- return ATOM(TEXT);
- if (atoms.contains(XA_STRING))
- return XA_STRING;
- }
-
- // find matches for uri types
- if (format == QLatin1String("text/uri-list")) {
- Atom a = xdndMimeStringToAtom(format);
- if (a && atoms.contains(a))
- return a;
- a = xdndMimeStringToAtom(QLatin1String("text/x-moz-url"));
- if (a && atoms.contains(a))
- return a;
- }
-
- // find match for image
- if (format == QLatin1String("image/ppm")) {
- if (atoms.contains(XA_PIXMAP))
- return XA_PIXMAP;
- }
-
- // for string/text requests try to use a format with a well-defined charset
- // first to avoid encoding problems
- if (requestedType == QVariant::String
- && format.startsWith(QLatin1String("text/"))
- && !format.contains(QLatin1String("charset="))) {
-
- QString formatWithCharset = format;
- formatWithCharset.append(QLatin1String(";charset=utf-8"));
-
- Atom a = xdndMimeStringToAtom(formatWithCharset);
- if (a && atoms.contains(a)) {
- *encoding = "utf-8";
- return a;
- }
- }
-
- Atom a = xdndMimeStringToAtom(format);
- if (a && atoms.contains(a))
- return a;
-
- return 0;
-}
-
-void QX11Data::xdndSetup() {
- QCursorData::initialize();
- qAddPostRoutine(qt_xdnd_cleanup);
-}
-
-
-void qt_xdnd_cleanup()
-{
- delete noDropCursor;
- noDropCursor = 0;
- delete copyCursor;
- copyCursor = 0;
- delete moveCursor;
- moveCursor = 0;
- delete linkCursor;
- linkCursor = 0;
- delete defaultPm;
- defaultPm = 0;
- delete xdnd_data.desktop_proxy;
- xdnd_data.desktop_proxy = 0;
- delete xdnd_data.deco;
- xdnd_data.deco = 0;
-}
-
-
-static QWidget *find_child(QWidget *tlw, QPoint & p)
-{
- QWidget *widget = tlw;
-
- p = widget->mapFromGlobal(p);
- bool done = false;
- while (!done) {
- done = true;
- if (((QExtraWidget*)widget)->extraData() &&
- ((QExtraWidget*)widget)->extraData()->xDndProxy != 0)
- break; // stop searching for widgets under the mouse cursor if found widget is a proxy.
- QObjectList children = widget->children();
- if (!children.isEmpty()) {
- for(int i = children.size(); i > 0;) {
- --i;
- QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (!w)
- continue;
- if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
- continue;
- if (w->isVisible() &&
- w->geometry().contains(p) &&
- !w->isWindow()) {
- widget = w;
- done = false;
- p = widget->mapFromParent(p);
- break;
- }
- }
- }
- }
- return widget;
-}
-
-
-static bool checkEmbedded(QWidget* w, const XEvent* xe)
-{
- if (!w)
- return false;
-
- if (current_embedding_widget != 0 && current_embedding_widget != w) {
- qt_xdnd_current_target = ((QExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
- qt_xdnd_current_proxy_target = qt_xdnd_current_target;
- qt_xdnd_send_leave();
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- current_embedding_widget = 0;
- }
-
- QWExtra* extra = ((QExtraWidget*)w)->extraData();
- if (extra && extra->xDndProxy != 0) {
-
- if (current_embedding_widget != w) {
-
- last_enter_event.xany.window = extra->xDndProxy;
- XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, &last_enter_event);
- current_embedding_widget = w;
- }
-
- ((XEvent*)xe)->xany.window = extra->xDndProxy;
- XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, (XEvent*)xe);
- if (qt_xdnd_current_widget != w) {
- qt_xdnd_current_widget = w;
- }
- return true;
- }
- current_embedding_widget = 0;
- return false;
-}
-
-void QX11Data::xdndHandleEnter(QWidget *, const XEvent * xe, bool /*passive*/)
-{
- motifdnd_active = false;
-
- last_enter_event.xclient = xe->xclient;
-
- const long *l = xe->xclient.data.l;
- int version = (int)(((unsigned long)(l[1])) >> 24);
-
- if (version > xdnd_version)
- return;
-
- qt_xdnd_dragsource_xid = l[0];
-
- int j = 0;
- if (l[1] & 1) {
- // get the types from XdndTypeList
- Atom type = XNone;
- int f;
- unsigned long n, a;
- unsigned char *retval = 0;
- XGetWindowProperty(X11->display, qt_xdnd_dragsource_xid, ATOM(XdndTypelist), 0,
- qt_xdnd_max_type, False, XA_ATOM, &type, &f,&n,&a,&retval);
- if (retval) {
- Atom *data = (Atom *)retval;
- for (; j<qt_xdnd_max_type && j < (int)n; j++) {
- qt_xdnd_types[j] = data[j];
- }
- XFree((uchar*)data);
- }
- } else {
- // get the types from the message
- int i;
- for(i=2; i < 5; i++) {
- qt_xdnd_types[j++] = l[i];
- }
- }
- qt_xdnd_types[j] = 0;
-}
-
-static void handle_xdnd_position(QWidget *w, const XEvent * xe, bool passive)
-{
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
- QWidget * c = find_child(w, p); // changes p to to c-local coordinates
-
- if (!passive && checkEmbedded(c, xe))
- return;
-
- if (!c || (!c->acceptDrops() && (c->windowType() == Qt::Desktop)))
- return;
-
- if (l[0] != qt_xdnd_dragsource_xid) {
- DEBUG("xdnd drag position from unexpected source (%08lx not %08lx)", l[0], qt_xdnd_dragsource_xid);
- return;
- }
-
- // timestamp from the source
- if (l[3] != 0) {
- // Some X server/client combination swallow the first 32 bit and
- // interpret a set bit 31 as negative sign.
- qt_xdnd_target_current_time = X11->userTime =
- ((sizeof(Time) == 8 && xe->xclient.data.l[3] < 0)
- ? uint(l[3])
- : l[3]);
- }
-
- QDragManager *manager = QDragManager::self();
- QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData;
-
- XClientMessageEvent response;
- response.type = ClientMessage;
- response.window = qt_xdnd_dragsource_xid;
- response.format = 32;
- response.message_type = ATOM(XdndStatus);
- response.data.l[0] = w->effectiveWinId();
- response.data.l[1] = 0; // flags
- response.data.l[2] = 0; // x, y
- response.data.l[3] = 0; // w, h
- response.data.l[4] = 0; // action
-
- if (!passive) { // otherwise just reject
- while (c && !c->acceptDrops() && !c->isWindow()) {
- p = c->mapToParent(p);
- c = c->parentWidget();
- }
- QWidget *target_widget = c && c->acceptDrops() ? c : 0;
-
- QRect answerRect(c->mapToGlobal(p), QSize(1,1));
-
- if (manager->object) {
- possible_actions = manager->dragPrivate()->possible_actions;
- } else {
- possible_actions = Qt::DropActions(xdndaction_to_qtaction(l[4]));
-// possible_actions |= Qt::CopyAction;
- }
- QDragMoveEvent me(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
-
- Qt::DropAction accepted_action = Qt::IgnoreAction;
-
-
- if (target_widget != qt_xdnd_current_widget) {
- if (qt_xdnd_current_widget) {
- QDragLeaveEvent e;
- QApplication::sendEvent(qt_xdnd_current_widget, &e);
- }
- if (qt_xdnd_current_widget != target_widget) {
- qt_xdnd_current_widget = target_widget;
- }
- if (target_widget) {
- qt_xdnd_current_position = p;
-
- last_target_accepted_action = Qt::IgnoreAction;
- QDragEnterEvent de(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
- QApplication::sendEvent(target_widget, &de);
- if (de.isAccepted() && de.dropAction() != Qt::IgnoreAction)
- last_target_accepted_action = de.dropAction();
- }
- }
-
- DEBUG() << "qt_handle_xdnd_position action=" << X11->xdndAtomToString(l[4]);
- if (!target_widget) {
- answerRect = QRect(p, QSize(1, 1));
- } else {
- qt_xdnd_current_widget = c;
- qt_xdnd_current_position = p;
-
- if (last_target_accepted_action != Qt::IgnoreAction) {
- me.setDropAction(last_target_accepted_action);
- me.accept();
- }
- QApplication::sendEvent(c, &me);
- if (me.isAccepted()) {
- response.data.l[1] = 1; // yes
- accepted_action = me.dropAction();
- last_target_accepted_action = accepted_action;
- } else {
- response.data.l[0] = 0;
- last_target_accepted_action = Qt::IgnoreAction;
- }
- answerRect = me.answerRect().intersected(c->rect());
- }
- answerRect = QRect(c->mapToGlobal(answerRect.topLeft()), answerRect.size());
-
- if (answerRect.left() < 0)
- answerRect.setLeft(0);
- if (answerRect.right() > 4096)
- answerRect.setRight(4096);
- if (answerRect.top() < 0)
- answerRect.setTop(0);
- if (answerRect.bottom() > 4096)
- answerRect.setBottom(4096);
- if (answerRect.width() < 0)
- answerRect.setWidth(0);
- if (answerRect.height() < 0)
- answerRect.setHeight(0);
-
- response.data.l[2] = (answerRect.x() << 16) + answerRect.y();
- response.data.l[3] = (answerRect.width() << 16) + answerRect.height();
- response.data.l[4] = qtaction_to_xdndaction(accepted_action);
- }
-
- // reset
- qt_xdnd_target_current_time = CurrentTime;
-
- QWidget * source = QWidget::find(qt_xdnd_dragsource_xid);
- if (source && (source->windowType() == Qt::Desktop) && !source->acceptDrops())
- source = 0;
-
- DEBUG() << "sending XdndStatus";
- if (source)
- handle_xdnd_status(source, (const XEvent *)&response, passive);
- else
- XSendEvent(X11->display, qt_xdnd_dragsource_xid, False, NoEventMask, (XEvent*)&response);
-}
-
-static Bool xdnd_position_scanner(Display *, XEvent *event, XPointer)
-{
- if (event->type != ClientMessage)
- return false;
- XClientMessageEvent *ev = &event->xclient;
-
- if (ev->message_type == ATOM(XdndPosition))
- return true;
-
- return false;
-}
-
-void QX11Data::xdndHandlePosition(QWidget * w, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandlePosition");
- while (XCheckIfEvent(X11->display, (XEvent *)xe, xdnd_position_scanner, 0))
- ;
-
- handle_xdnd_position(w, xe, passive);
-}
-
-
-static void handle_xdnd_status(QWidget *, const XEvent * xe, bool)
-{
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
- // ignore late status messages
- if (l[0] && l[0] != qt_xdnd_current_proxy_target)
- return;
- Qt::DropAction newAction = (l[1] & 0x1) ? xdndaction_to_qtaction(l[4]) : Qt::IgnoreAction;
-
- if ((int)(l[1] & 2) == 0) {
- QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
- QSize s((l[3] & 0xffff0000) >> 16, l[3] & 0x0000ffff);
- qt_xdnd_source_sameanswer = QRect(p, s);
- } else {
- qt_xdnd_source_sameanswer = QRect();
- }
- QDragManager *manager = QDragManager::self();
- manager->willDrop = (l[1] & 0x1);
- if (global_accepted_action != newAction)
- manager->emitActionChanged(newAction);
- global_accepted_action = newAction;
- manager->updateCursor();
- waiting_for_status = false;
-}
-
-static Bool xdnd_status_scanner(Display *, XEvent *event, XPointer)
-{
- if (event->type != ClientMessage)
- return false;
- XClientMessageEvent *ev = &event->xclient;
-
- if (ev->message_type == ATOM(XdndStatus))
- return true;
-
- return false;
-}
-
-void QX11Data::xdndHandleStatus(QWidget * w, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandleStatus");
- while (XCheckIfEvent(X11->display, (XEvent *)xe, xdnd_status_scanner, 0))
- ;
-
- handle_xdnd_status(w, xe, passive);
- DEBUG("xdndHandleStatus end");
-}
-
-void QX11Data::xdndHandleLeave(QWidget *w, const XEvent * xe, bool /*passive*/)
-{
- DEBUG("xdnd leave");
- if (!qt_xdnd_current_widget ||
- w->window() != qt_xdnd_current_widget->window()) {
- return; // sanity
- }
-
- if (checkEmbedded(current_embedding_widget, xe)) {
- current_embedding_widget = 0;
- qt_xdnd_current_widget = 0;
- return;
- }
-
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- QDragLeaveEvent e;
- QApplication::sendEvent(qt_xdnd_current_widget, &e);
-
- if (l[0] != qt_xdnd_dragsource_xid) {
- // This often happens - leave other-process window quickly
- DEBUG("xdnd drag leave from unexpected source (%08lx not %08lx", l[0], qt_xdnd_dragsource_xid);
- qt_xdnd_current_widget = 0;
- return;
- }
-
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_types[0] = 0;
- qt_xdnd_current_widget = 0;
-}
-
-
-void qt_xdnd_send_leave()
-{
- if (!qt_xdnd_current_target)
- return;
-
- QDragManager *manager = QDragManager::self();
-
- XClientMessageEvent leave;
- leave.type = ClientMessage;
- leave.window = qt_xdnd_current_target;
- leave.format = 32;
- leave.message_type = ATOM(XdndLeave);
- leave.data.l[0] = manager->dragPrivate()->source->effectiveWinId();
- leave.data.l[1] = 0; // flags
- leave.data.l[2] = 0; // x, y
- leave.data.l[3] = 0; // w, h
- leave.data.l[4] = 0; // just null
-
- QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);
-
- if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
- w = 0;
-
- if (w)
- X11->xdndHandleLeave(w, (const XEvent *)&leave, false);
- else
- XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
- NoEventMask, (XEvent*)&leave);
-
- // reset the drag manager state
- manager->willDrop = false;
- if (global_accepted_action != Qt::IgnoreAction)
- manager->emitActionChanged(Qt::IgnoreAction);
- global_accepted_action = Qt::IgnoreAction;
- manager->updateCursor();
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- qt_xdnd_source_current_time = 0;
- waiting_for_status = false;
-}
-
-// TODO: remove and use QApplication::currentKeyboardModifiers() in Qt 4.8.
-static Qt::KeyboardModifiers currentKeyboardModifiers()
-{
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint keybstate;
- for (int i = 0; i < ScreenCount(X11->display); ++i) {
- if (XQueryPointer(X11->display, QX11Info::appRootWindow(i), &root, &child,
- &root_x, &root_y, &win_x, &win_y, &keybstate))
- return X11->translateModifiers(keybstate & 0x00ff);
- }
- return 0;
-}
-
-void QX11Data::xdndHandleDrop(QWidget *, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandleDrop");
- if (!qt_xdnd_current_widget) {
- qt_xdnd_dragsource_xid = 0;
- return; // sanity
- }
-
- if (!passive && checkEmbedded(qt_xdnd_current_widget, xe)){
- current_embedding_widget = 0;
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_current_widget = 0;
- return;
- }
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- QDragManager *manager = QDragManager::self();
- DEBUG("xdnd drop");
-
- if (l[0] != qt_xdnd_dragsource_xid) {
- DEBUG("xdnd drop from unexpected source (%08lx not %08lx", l[0], qt_xdnd_dragsource_xid);
- return;
- }
-
- // update the "user time" from the timestamp in the event.
- if (l[2] != 0) {
- // Some X server/client combination swallow the first 32 bit and
- // interpret a set bit 31 as negative sign.
- qt_xdnd_target_current_time = X11->userTime =
- ((sizeof(Time) == 8 && xe->xclient.data.l[2] < 0)
- ? uint(l[2])
- : l[2]);
- }
-
- if (!passive) {
- // this could be a same-application drop, just proxied due to
- // some XEMBEDding, so try to find the real QMimeData used
- // based on the timestamp for this drop.
- QMimeData *dropData = 0;
- int at = findXdndDropTransactionByTime(qt_xdnd_target_current_time);
- if (at != -1)
- dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
- // if we can't find it, then use the data in the drag manager
- if (!dropData)
- dropData = (manager->object) ? manager->dragPrivate()->data : manager->dropData;
-
- // Drop coming from another app? Update keyboard modifiers.
- if (!qt_xdnd_dragging) {
- QApplicationPrivate::modifier_buttons = currentKeyboardModifiers();
- }
-
- QDropEvent de(qt_xdnd_current_position, possible_actions, dropData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
- QApplication::sendEvent(qt_xdnd_current_widget, &de);
- if (!de.isAccepted()) {
- // Ignore a failed drag
- global_accepted_action = Qt::IgnoreAction;
- } else {
- global_accepted_action = de.dropAction();
- }
- XClientMessageEvent finished;
- finished.type = ClientMessage;
- finished.window = qt_xdnd_dragsource_xid;
- finished.format = 32;
- finished.message_type = ATOM(XdndFinished);
- DNDDEBUG << "xdndHandleDrop"
- << "qt_xdnd_current_widget" << qt_xdnd_current_widget
- << (qt_xdnd_current_widget ? qt_xdnd_current_widget->effectiveWinId() : 0)
- << "t_xdnd_current_widget->window()"
- << (qt_xdnd_current_widget ? qt_xdnd_current_widget->window() : 0)
- << (qt_xdnd_current_widget ? qt_xdnd_current_widget->window()->internalWinId() : 0);
- finished.data.l[0] = qt_xdnd_current_widget?qt_xdnd_current_widget->window()->internalWinId():0;
- finished.data.l[1] = de.isAccepted() ? 1 : 0; // flags
- finished.data.l[2] = qtaction_to_xdndaction(global_accepted_action);
- XSendEvent(X11->display, qt_xdnd_dragsource_xid, False,
- NoEventMask, (XEvent*)&finished);
- } else {
- QDragLeaveEvent e;
- QApplication::sendEvent(qt_xdnd_current_widget, &e);
- }
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_current_widget = 0;
- waiting_for_status = false;
-
- // reset
- qt_xdnd_target_current_time = CurrentTime;
-}
-
-
-void QX11Data::xdndHandleFinished(QWidget *, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandleFinished");
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- DNDDEBUG << "xdndHandleFinished, l[0]" << l[0]
- << "qt_xdnd_current_target" << qt_xdnd_current_target
- << "qt_xdnd_current_proxy_targe" << qt_xdnd_current_proxy_target;
-
- if (l[0]) {
- int at = findXdndDropTransactionByWindow(l[0]);
- if (at != -1) {
- restartXdndDropExpiryTimer();
-
- QXdndDropTransaction t = X11->dndDropTransactions.takeAt(at);
- QDragManager *manager = QDragManager::self();
-
- Window target = qt_xdnd_current_target;
- Window proxy_target = qt_xdnd_current_proxy_target;
- QWidget *embedding_widget = current_embedding_widget;
- QDrag *currentObject = manager->object;
-
- qt_xdnd_current_target = t.target;
- qt_xdnd_current_proxy_target = t.proxy_target;
- current_embedding_widget = t.embedding_widget;
- manager->object = t.object;
-
- if (!passive)
- (void) checkEmbedded(qt_xdnd_current_widget, xe);
-
- current_embedding_widget = 0;
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
-
- if (t.object)
- t.object->deleteLater();
-
- qt_xdnd_current_target = target;
- qt_xdnd_current_proxy_target = proxy_target;
- current_embedding_widget = embedding_widget;
- manager->object = currentObject;
- }
- }
- waiting_for_status = false;
-}
-
-
-void QDragManager::timerEvent(QTimerEvent* e)
-{
- if (e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull()) {
- move(QCursor::pos());
- } else if (e->timerId() == transaction_expiry_timer) {
- for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
- const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
- if (t.targetWidget) {
- // dnd within the same process, don't delete these
- continue;
- }
- t.object->deleteLater();
- X11->dndDropTransactions.removeAt(i--);
- }
-
- killTimer(transaction_expiry_timer);
- transaction_expiry_timer = -1;
- }
-}
-
-bool QDragManager::eventFilter(QObject * o, QEvent * e)
-{
- if (beingCancelled) {
- if (e->type() == QEvent::KeyRelease && ((QKeyEvent*)e)->key() == Qt::Key_Escape) {
- qApp->removeEventFilter(this);
- Q_ASSERT(object == 0);
- beingCancelled = false;
- eventLoop->exit();
- return true; // block the key release
- }
- return false;
- }
-
- Q_ASSERT(object != 0);
-
- if (!o->isWidgetType())
- return false;
-
- if (e->type() == QEvent::MouseMove) {
- QMouseEvent* me = (QMouseEvent *)e;
- move(me->globalPos());
- return true;
- } else if (e->type() == QEvent::MouseButtonRelease) {
- DEBUG("pre drop");
- qApp->removeEventFilter(this);
- if (willDrop)
- drop();
- else
- cancel();
- DEBUG("drop, resetting object");
- beingCancelled = false;
- eventLoop->exit();
- return true;
- }
-
- if (e->type() == QEvent::ShortcutOverride) {
- // prevent accelerators from firing while dragging
- e->accept();
- return true;
- }
-
- if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
- QKeyEvent *ke = ((QKeyEvent*)e);
- if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- eventLoop->exit();
- } else {
- qt_xdnd_source_sameanswer = QRect(); // force move
- move(QCursor::pos());
- }
- return true; // Eat all key events
- }
-
- // ### We bind modality to widgets, so we have to do this
- // ### "manually".
- // DnD is modal - eat all other interactive events
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- case QEvent::Wheel:
- case QEvent::ShortcutOverride:
- return true;
- default:
- return false;
- }
-}
-
-void QDragManager::updateCursor()
-{
- if (!noDropCursor) {
-#ifndef QT_NO_CURSOR
- noDropCursor = new QCursor(Qt::ForbiddenCursor);
- moveCursor = new QCursor(Qt::DragMoveCursor);
- copyCursor = new QCursor(Qt::DragCopyCursor);
- linkCursor = new QCursor(Qt::DragLinkCursor);
-#endif
- }
-
- QCursor *c;
- if (willDrop) {
- if (global_accepted_action == Qt::CopyAction) {
- c = copyCursor;
- } else if (global_accepted_action == Qt::LinkAction) {
- c = linkCursor;
- } else {
- c = moveCursor;
- }
- if (xdnd_data.deco) {
- xdnd_data.deco->show();
- xdnd_data.deco->raise();
- }
- } else {
- c = noDropCursor;
- //if (qt_xdnd_deco)
- // qt_xdnd_deco->hide();
- }
-#ifndef QT_NO_CURSOR
- if (c)
- qApp->changeOverrideCursor(*c);
-#endif
-}
-
-
-void QDragManager::cancel(bool deleteSource)
-{
- DEBUG("QDragManager::cancel");
- Q_ASSERT(heartbeat != -1);
- killTimer(heartbeat);
- heartbeat = -1;
- beingCancelled = true;
- qt_xdnd_dragging = false;
-
- if (qt_xdnd_current_target)
- qt_xdnd_send_leave();
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- QApplication::restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
-
- if (deleteSource && object)
- object->deleteLater();
- object = 0;
- qDeleteInEventHandler(xdnd_data.deco);
- xdnd_data.deco = 0;
-
- global_accepted_action = Qt::IgnoreAction;
-}
-
-static
-Window findRealWindow(const QPoint & pos, Window w, int md)
-{
- if (xdnd_data.deco && w == xdnd_data.deco->effectiveWinId())
- return 0;
-
- if (md) {
- X11->ignoreBadwindow();
- XWindowAttributes attr;
- XGetWindowAttributes(X11->display, w, &attr);
- if (X11->badwindow())
- return 0;
-
- if (attr.map_state == IsViewable
- && QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) {
- {
- Atom type = XNone;
- int f;
- unsigned long n, a;
- unsigned char *data;
-
- XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data);
- if (data) XFree(data);
- if (type)
- return w;
- }
-
- Window r, p;
- Window* c;
- uint nc;
- if (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
- r=0;
- for (uint i=nc; !r && i--;) {
- r = findRealWindow(pos-QPoint(attr.x,attr.y),
- c[i], md-1);
- }
- XFree(c);
- if (r)
- return r;
-
- // We didn't find a client window! Just use the
- // innermost window.
- }
-
- // No children!
- return w;
- }
- }
- return 0;
-}
-
-void QDragManager::move(const QPoint & globalPos)
-{
-#ifdef QT_NO_CURSOR
- Q_UNUSED(globalPos);
- return;
-#else
- DEBUG() << "QDragManager::move enter";
- if (!object) {
- // perhaps the target crashed?
- return;
- }
-
- int screen = QCursor::x11Screen();
- if ((qt_xdnd_current_screen == -1 && screen != X11->defaultScreen) || (screen != qt_xdnd_current_screen)) {
- // recreate the pixmap on the new screen...
- delete xdnd_data.deco;
- QWidget* parent = object->source()->window()->x11Info().screen() == screen
- ? object->source()->window() : QApplication::desktop()->screen(screen);
- xdnd_data.deco = new QShapedPixmapWidget(parent);
- if (!QWidget::mouseGrabber()) {
- updatePixmap();
- xdnd_data.deco->grabMouse();
- }
- }
- xdnd_data.deco->move(QCursor::pos() - xdnd_data.deco->pm_hot);
-
- if (qt_xdnd_source_sameanswer.contains(globalPos) && qt_xdnd_source_sameanswer.isValid())
- return;
-
- qt_xdnd_current_screen = screen;
- Window rootwin = QX11Info::appRootWindow(qt_xdnd_current_screen);
- Window target = 0;
- int lx = 0, ly = 0;
- if (!XTranslateCoordinates(X11->display, rootwin, rootwin, globalPos.x(), globalPos.y(), &lx, &ly, &target))
- // some weird error...
- return;
-
- if (target == rootwin) {
- // Ok.
- } else if (target) {
- //me
- Window src = rootwin;
- while (target != 0) {
- DNDDEBUG << "checking target for XdndAware" << QWidget::find(target) << target;
- int lx2, ly2;
- Window t;
- // translate coordinates
- if (!XTranslateCoordinates(X11->display, src, target, lx, ly, &lx2, &ly2, &t)) {
- target = 0;
- break;
- }
- lx = lx2;
- ly = ly2;
- src = target;
-
- // check if it has XdndAware
- Atom type = 0;
- int f;
- unsigned long n, a;
- unsigned char *data = 0;
- XGetWindowProperty(X11->display, target, ATOM(XdndAware), 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data);
- if (data)
- XFree(data);
- if (type) {
- DNDDEBUG << "Found XdndAware on " << QWidget::find(target) << target;
- break;
- }
-
- // find child at the coordinates
- if (!XTranslateCoordinates(X11->display, src, src, lx, ly, &lx2, &ly2, &target)) {
- target = 0;
- break;
- }
- }
- if (xdnd_data.deco && (!target || target == xdnd_data.deco->effectiveWinId())) {
- DNDDEBUG << "need to find real window";
- target = findRealWindow(globalPos, rootwin, 6);
- DNDDEBUG << "real window found" << QWidget::find(target) << target;
- }
- }
-
- QWidget* w;
- if (target) {
- w = QWidget::find((WId)target);
- if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
- w = 0;
- } else {
- w = 0;
- target = rootwin;
- }
-
- DNDDEBUG << "and the final target is " << QWidget::find(target) << target;
- DNDDEBUG << "the widget w is" << w;
-
- WId proxy_target = xdndProxy(target);
- if (!proxy_target)
- proxy_target = target;
- int target_version = 1;
-
- if (proxy_target) {
- Atom type = XNone;
- int r, f;
- unsigned long n, a;
- unsigned char *retval;
- X11->ignoreBadwindow();
- r = XGetWindowProperty(X11->display, proxy_target, ATOM(XdndAware), 0,
- 1, False, AnyPropertyType, &type, &f,&n,&a,&retval);
- int *tv = (int *)retval;
- if (r != Success || X11->badwindow()) {
- target = 0;
- } else {
- target_version = qMin(xdnd_version,tv ? *tv : 1);
- if (tv)
- XFree(tv);
-// if (!(!X11->badwindow() && type))
-// target = 0;
- }
- }
-
- if (target != qt_xdnd_current_target) {
- if (qt_xdnd_current_target)
- qt_xdnd_send_leave();
-
- qt_xdnd_current_target = target;
- qt_xdnd_current_proxy_target = proxy_target;
- if (target) {
- QVector<Atom> types;
- int flags = target_version << 24;
- QStringList fmts = QInternalMimeData::formatsHelper(dragPrivate()->data);
- for (int i = 0; i < fmts.size(); ++i) {
- QList<Atom> atoms = X11->xdndMimeAtomsForFormat(fmts.at(i));
- for (int j = 0; j < atoms.size(); ++j) {
- if (!types.contains(atoms.at(j)))
- types.append(atoms.at(j));
- }
- }
- if (types.size() > 3) {
- XChangeProperty(X11->display,
- dragPrivate()->source->effectiveWinId(), ATOM(XdndTypelist),
- XA_ATOM, 32, PropModeReplace,
- (unsigned char *)types.data(),
- types.size());
- flags |= 0x0001;
- }
- XClientMessageEvent enter;
- enter.type = ClientMessage;
- enter.window = target;
- enter.format = 32;
- enter.message_type = ATOM(XdndEnter);
- enter.data.l[0] = dragPrivate()->source->effectiveWinId();
- enter.data.l[1] = flags;
- enter.data.l[2] = types.size()>0 ? types.at(0) : 0;
- enter.data.l[3] = types.size()>1 ? types.at(1) : 0;
- enter.data.l[4] = types.size()>2 ? types.at(2) : 0;
- // provisionally set the rectangle to 5x5 pixels...
- qt_xdnd_source_sameanswer = QRect(globalPos.x() - 2,
- globalPos.y() -2 , 5, 5);
-
- DEBUG("sending Xdnd enter");
- if (w)
- X11->xdndHandleEnter(w, (const XEvent *)&enter, false);
- else if (target)
- XSendEvent(X11->display, proxy_target, False, NoEventMask, (XEvent*)&enter);
- waiting_for_status = false;
- }
- }
- if (waiting_for_status)
- return;
-
- if (target) {
- waiting_for_status = true;
-
- XClientMessageEvent move;
- move.type = ClientMessage;
- move.window = target;
- move.format = 32;
- move.message_type = ATOM(XdndPosition);
- move.window = target;
- move.data.l[0] = dragPrivate()->source->effectiveWinId();
- move.data.l[1] = 0; // flags
- move.data.l[2] = (globalPos.x() << 16) + globalPos.y();
- move.data.l[3] = X11->time;
- move.data.l[4] = qtaction_to_xdndaction(defaultAction(dragPrivate()->possible_actions, QApplication::keyboardModifiers()));
- DEBUG("sending Xdnd position");
-
- qt_xdnd_source_current_time = X11->time;
-
- if (w)
- handle_xdnd_position(w, (const XEvent *)&move, false);
- else
- XSendEvent(X11->display, proxy_target, False, NoEventMask,
- (XEvent*)&move);
- } else {
- if (willDrop) {
- willDrop = false;
- updateCursor();
- }
- }
- DEBUG() << "QDragManager::move leave";
-#endif
-}
-
-
-void QDragManager::drop()
-{
- Q_ASSERT(heartbeat != -1);
- killTimer(heartbeat);
- heartbeat = -1;
- qt_xdnd_dragging = false;
-
- if (!qt_xdnd_current_target)
- return;
-
- qDeleteInEventHandler(xdnd_data.deco);
- xdnd_data.deco = 0;
-
- XClientMessageEvent drop;
- drop.type = ClientMessage;
- drop.window = qt_xdnd_current_target;
- drop.format = 32;
- drop.message_type = ATOM(XdndDrop);
- drop.data.l[0] = dragPrivate()->source->effectiveWinId();
- drop.data.l[1] = 0; // flags
- drop.data.l[2] = X11->time;
-
- drop.data.l[3] = 0;
- drop.data.l[4] = 0;
-
- QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);
-
- if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
- w = 0;
-
- QXdndDropTransaction t = {
- X11->time,
- qt_xdnd_current_target,
- qt_xdnd_current_proxy_target,
- w,
- current_embedding_widget,
- object
- };
- X11->dndDropTransactions.append(t);
- restartXdndDropExpiryTimer();
-
- if (w)
- X11->xdndHandleDrop(w, (const XEvent *)&drop, false);
- else
- XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
- NoEventMask, (XEvent*)&drop);
-
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- qt_xdnd_source_current_time = 0;
- current_embedding_widget = 0;
- object = 0;
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- QApplication::restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
-}
-
-
-
-bool QX11Data::xdndHandleBadwindow()
-{
- if (qt_xdnd_current_target) {
- QDragManager *manager = QDragManager::self();
- if (manager->object) {
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- manager->object->deleteLater();
- manager->object = 0;
- delete xdnd_data.deco;
- xdnd_data.deco = 0;
- return true;
- }
- }
- if (qt_xdnd_dragsource_xid) {
- qt_xdnd_dragsource_xid = 0;
- if (qt_xdnd_current_widget) {
- QApplication::postEvent(qt_xdnd_current_widget, new QDragLeaveEvent);
- qt_xdnd_current_widget = 0;
- }
- return true;
- }
- return false;
-}
-
-void QX11Data::xdndHandleSelectionRequest(const XSelectionRequestEvent * req)
-{
- if (!req)
- return;
- XEvent evt;
- evt.xselection.type = SelectionNotify;
- evt.xselection.display = req->display;
- evt.xselection.requestor = req->requestor;
- evt.xselection.selection = req->selection;
- evt.xselection.target = XNone;
- evt.xselection.property = XNone;
- evt.xselection.time = req->time;
-
- QDragManager *manager = QDragManager::self();
- QDrag *currentObject = manager->object;
-
- // which transaction do we use? (note: -2 means use current manager->object)
- int at = -1;
-
- // figure out which data the requestor is really interested in
- if (manager->object && req->time == qt_xdnd_source_current_time) {
- // requestor wants the current drag data
- at = -2;
- } else {
- // if someone has requested data in response to XdndDrop, find the corresponding transaction. the
- // spec says to call XConvertSelection() using the timestamp from the XdndDrop
- at = findXdndDropTransactionByTime(req->time);
- if (at == -1) {
- // no dice, perhaps the client was nice enough to use the same window id in XConvertSelection()
- // that we sent the XdndDrop event to.
- at = findXdndDropTransactionByWindow(req->requestor);
- }
- if (at == -1 && req->time == CurrentTime) {
- // previous Qt versions always requested the data on a child of the target window
- // using CurrentTime... but it could be asking for either drop data or the current drag's data
- Window target = findXdndAwareParent(req->requestor);
- if (target) {
- if (qt_xdnd_current_target && qt_xdnd_current_target == target)
- at = -2;
- else
- at = findXdndDropTransactionByWindow(target);
- }
- }
- }
- if (at >= 0) {
- restartXdndDropExpiryTimer();
-
- // use the drag object from an XdndDrop tansaction
- manager->object = X11->dndDropTransactions.at(at).object;
- } else if (at != -2) {
- // no transaction found, we'll have to reject the request
- manager->object = 0;
- }
- if (manager->object) {
- Atom atomFormat = req->target;
- int dataFormat = 0;
- QByteArray data;
- if (X11->xdndMimeDataForAtom(req->target, manager->dragPrivate()->data,
- &data, &atomFormat, &dataFormat)) {
- int dataSize = data.size() / (dataFormat / 8);
- XChangeProperty (X11->display, req->requestor, req->property,
- atomFormat, dataFormat, PropModeReplace,
- (unsigned char *)data.data(), dataSize);
- evt.xselection.property = req->property;
- evt.xselection.target = atomFormat;
- }
- }
-
- // reset manager->object in case we modified it above
- manager->object = currentObject;
-
- // ### this can die if req->requestor crashes at the wrong
- // ### moment
- XSendEvent(X11->display, req->requestor, False, 0, &evt);
-}
-
-static QVariant xdndObtainData(const char *format, QVariant::Type requestedType)
-{
- QByteArray result;
-
- QWidget* w;
- QDragManager *manager = QDragManager::self();
- if (qt_xdnd_dragsource_xid && manager->object &&
- (w=QWidget::find(qt_xdnd_dragsource_xid))
- && (!(w->windowType() == Qt::Desktop) || w->acceptDrops()))
- {
- QDragPrivate * o = QDragManager::self()->dragPrivate();
- if (o->data->hasFormat(QLatin1String(format)))
- result = o->data->data(QLatin1String(format));
- return result;
- }
-
- QList<Atom> atoms;
- int i = 0;
- while ((qt_xdnd_types[i])) {
- atoms.append(qt_xdnd_types[i]);
- ++i;
- }
- QByteArray encoding;
- Atom a = X11->xdndMimeAtomForFormat(QLatin1String(format), requestedType, atoms, &encoding);
- if (!a)
- return result;
-
- if (XGetSelectionOwner(X11->display, ATOM(XdndSelection)) == XNone)
- return result; // should never happen?
-
- QWidget* tw = qt_xdnd_current_widget;
- if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
- tw = new QWidget;
-
- XConvertSelection(X11->display, ATOM(XdndSelection), a, ATOM(XdndSelection), tw->effectiveWinId(),
- qt_xdnd_target_current_time);
- XFlush(X11->display);
-
- XEvent xevent;
- bool got=X11->clipboardWaitForEvent(tw->effectiveWinId(), SelectionNotify, &xevent, 5000);
- if (got) {
- Atom type;
-
- if (X11->clipboardReadProperty(tw->effectiveWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0)) {
- if (type == ATOM(INCR)) {
- int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;
- result = X11->clipboardReadIncrementalProperty(tw->effectiveWinId(), ATOM(XdndSelection), nbytes, false);
- } else if (type != a && type != XNone) {
- DEBUG("Qt clipboard: unknown atom %ld", type);
- }
- }
- }
- if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
- delete tw;
-
- return X11->xdndMimeConvertToFormat(a, result, QLatin1String(format), requestedType, encoding);
-}
-
-
-/*
- Enable drag and drop for widget w by installing the proper
- properties on w's toplevel widget.
-*/
-bool QX11Data::dndEnable(QWidget* w, bool on)
-{
- w = w->window();
-
- if (bool(((QExtraWidget*)w)->topData()->dnd) == on)
- return true; // been there, done that
- ((QExtraWidget*)w)->topData()->dnd = on ? 1 : 0;
-
- motifdndEnable(w, on);
- return xdndEnable(w, on);
-}
-
-Qt::DropAction QDragManager::drag(QDrag * o)
-{
- if (object == o || !o || !o->d_func()->source)
- return Qt::IgnoreAction;
-
- if (object) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- }
-
- if (object) {
- // the last drag and drop operation hasn't finished, so we are going to wait
- // for one second to see if it does... if the finish message comes after this,
- // then we could still have problems, but this is highly unlikely
- QApplication::flush();
-
- QElapsedTimer timer;
- timer.start();
- do {
- XEvent event;
- if (XCheckTypedEvent(X11->display, ClientMessage, &event))
- qApp->x11ProcessEvent(&event);
-
- // sleep 50 ms, so we don't use up CPU cycles all the time.
- struct timeval usleep_tv;
- usleep_tv.tv_sec = 0;
- usleep_tv.tv_usec = 50000;
- select(0, 0, 0, 0, &usleep_tv);
- } while (object && timer.hasExpired(1000));
- }
-
- object = o;
- object->d_func()->target = 0;
- xdnd_data.deco = new QShapedPixmapWidget(object->source()->window());
-
- willDrop = false;
-
- updatePixmap();
-
- qApp->installEventFilter(this);
- XSetSelectionOwner(X11->display, ATOM(XdndSelection), dragPrivate()->source->window()->internalWinId(), X11->time);
- global_accepted_action = Qt::CopyAction;
- qt_xdnd_source_sameanswer = QRect();
-#ifndef QT_NO_CURSOR
- // set the override cursor (must be done here, since it is updated
- // in the call to move() below)
- qApp->setOverrideCursor(Qt::ArrowCursor);
- restoreCursor = true;
-#endif
- move(QCursor::pos());
- heartbeat = startTimer(200);
-
- qt_xdnd_dragging = true;
-
- if (!QWidget::mouseGrabber())
- xdnd_data.deco->grabMouse();
-
- eventLoop = new QEventLoop;
- (void) eventLoop->exec();
- delete eventLoop;
- eventLoop = 0;
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- qApp->restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
-
- // delete cursors as they may be different next drag.
- delete noDropCursor;
- noDropCursor = 0;
- delete copyCursor;
- copyCursor = 0;
- delete moveCursor;
- moveCursor = 0;
- delete linkCursor;
- linkCursor = 0;
-
- delete xdnd_data.deco;
- xdnd_data.deco = 0;
- if (heartbeat != -1)
- killTimer(heartbeat);
- heartbeat = -1;
- qt_xdnd_current_screen = -1;
- qt_xdnd_dragging = false;
-
- return global_accepted_action;
- // object persists until we get an xdnd_finish message
-}
-
-void QDragManager::updatePixmap()
-{
- if (xdnd_data.deco) {
- QPixmap pm;
- QPoint pm_hot(default_pm_hotx,default_pm_hoty);
- if (object) {
- pm = dragPrivate()->pixmap;
- if (!pm.isNull())
- pm_hot = dragPrivate()->hotspot;
- }
- if (pm.isNull()) {
- if (!defaultPm)
- defaultPm = new QPixmap(default_pm);
- pm = *defaultPm;
- }
- xdnd_data.deco->pm_hot = pm_hot;
- xdnd_data.deco->setPixmap(pm);
- xdnd_data.deco->move(QCursor::pos()-pm_hot);
- xdnd_data.deco->show();
- }
-}
-
-QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
-{
- QByteArray mime = mimetype.toLatin1();
- QVariant data = X11->motifdnd_active
- ? X11->motifdndObtainData(mime)
- : xdndObtainData(mime, requestedType);
- return data;
-}
-
-bool QDropData::hasFormat_sys(const QString &format) const
-{
- return formats().contains(format);
-}
-
-QStringList QDropData::formats_sys() const
-{
- QStringList formats;
- if (X11->motifdnd_active) {
- int i = 0;
- QByteArray fmt;
- while (!(fmt = X11->motifdndFormat(i)).isEmpty()) {
- formats.append(QLatin1String(fmt));
- ++i;
- }
- } else {
- int i = 0;
- while ((qt_xdnd_types[i])) {
- QStringList formatsForAtom = X11->xdndMimeFormatsForAtom(qt_xdnd_types[i]);
- for (int j = 0; j < formatsForAtom.size(); ++j) {
- if (!formats.contains(formatsForAtom.at(j)))
- formats.append(formatsForAtom.at(j));
- }
- ++i;
- }
- }
- return formats;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DRAGANDDROP
diff --git a/src/widgets/platforms/x11/qeventdispatcher_x11.cpp b/src/widgets/platforms/x11/qeventdispatcher_x11.cpp
deleted file mode 100644
index e31d8ed301..0000000000
--- a/src/widgets/platforms/x11/qeventdispatcher_x11.cpp
+++ /dev/null
@@ -1,191 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeventdispatcher_x11_p.h"
-
-#include "qapplication.h"
-#include "qx11info_x11.h"
-
-#include "qt_x11_p.h"
-#include <private/qeventdispatcher_unix_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QEventDispatcherX11Private : public QEventDispatcherUNIXPrivate
-{
- Q_DECLARE_PUBLIC(QEventDispatcherX11)
-public:
- inline QEventDispatcherX11Private()
- : xfd(-1)
- { }
- int xfd;
- QList<XEvent> queuedUserInputEvents;
-};
-
-QEventDispatcherX11::QEventDispatcherX11(QObject *parent)
- : QEventDispatcherUNIX(*new QEventDispatcherX11Private, parent)
-{ }
-
-QEventDispatcherX11::~QEventDispatcherX11()
-{ }
-
-bool QEventDispatcherX11::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- Q_D(QEventDispatcherX11);
-
- d->interrupt = false;
- QApplication::sendPostedEvents();
-
- ulong marker = XNextRequest(X11->display);
- int nevents = 0;
- do {
- while (!d->interrupt) {
- XEvent event;
- if (!(flags & QEventLoop::ExcludeUserInputEvents)
- && !d->queuedUserInputEvents.isEmpty()) {
- // process a pending user input event
- event = d->queuedUserInputEvents.takeFirst();
- } else if (XEventsQueued(X11->display, QueuedAlready)) {
- // process events from the X server
- XNextEvent(X11->display, &event);
-
- if (flags & QEventLoop::ExcludeUserInputEvents) {
- // queue user input events
- switch (event.type) {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case XKeyPress:
- case XKeyRelease:
- case EnterNotify:
- case LeaveNotify:
- d->queuedUserInputEvents.append(event);
- continue;
-
- case ClientMessage:
- // only keep the wm_take_focus and
- // _qt_scrolldone protocols, queue all other
- // client messages
- if (event.xclient.format == 32) {
- if (event.xclient.message_type == ATOM(WM_PROTOCOLS) &&
- (Atom) event.xclient.data.l[0] == ATOM(WM_TAKE_FOCUS)) {
- break;
- } else if (event.xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
- break;
- }
- }
- d->queuedUserInputEvents.append(event);
- continue;
-
- default:
- break;
- }
- }
- } else {
- // no event to process
- break;
- }
-
- // send through event filter
- if (filterEvent(&event))
- continue;
-
- nevents++;
- if (qApp->x11ProcessEvent(&event) == 1)
- return true;
-
- if (event.xany.serial >= marker) {
- if (XEventsQueued(X11->display, QueuedAfterFlush))
- flags &= ~QEventLoop::WaitForMoreEvents;
- goto out;
- }
- }
- } while (!d->interrupt && XEventsQueued(X11->display, QueuedAfterFlush));
-
- out:
- if (!d->interrupt) {
- const uint exclude_all =
- QEventLoop::ExcludeSocketNotifiers | QEventLoop::X11ExcludeTimers | QEventLoop::WaitForMoreEvents;
- if (nevents > 0 && ((uint)flags & exclude_all) == exclude_all) {
- QApplication::sendPostedEvents();
- return nevents > 0;
- }
- // return true if we handled events, false otherwise
- return QEventDispatcherUNIX::processEvents(flags) || (nevents > 0);
- }
- return nevents > 0;
-}
-
-bool QEventDispatcherX11::hasPendingEvents()
-{
- extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
- return (qGlobalPostedEventsCount() || XPending(X11->display));
-}
-
-void QEventDispatcherX11::flush()
-{
- XFlush(X11->display);
-}
-
-void QEventDispatcherX11::startingUp()
-{
- Q_D(QEventDispatcherX11);
- d->xfd = XConnectionNumber(X11->display);
-}
-
-void QEventDispatcherX11::closingDown()
-{
- Q_D(QEventDispatcherX11);
- d->xfd = -1;
-}
-
-int QEventDispatcherX11::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timeval *timeout)
-{
- Q_D(QEventDispatcherX11);
- if (d->xfd > 0) {
- nfds = qMax(nfds - 1, d->xfd) + 1;
- FD_SET(d->xfd, readfds);
- }
- return QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout);
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qeventdispatcher_x11_p.h b/src/widgets/platforms/x11/qeventdispatcher_x11_p.h
deleted file mode 100644
index 1b6620d90f..0000000000
--- a/src/widgets/platforms/x11/qeventdispatcher_x11_p.h
+++ /dev/null
@@ -1,86 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEVENTDISPATCHER_X11_P_H
-#define QEVENTDISPATCHER_X11_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 "private/qeventdispatcher_unix_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QEventDispatcherX11Private;
-
-class QEventDispatcherX11 : public QEventDispatcherUNIX
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QEventDispatcherX11)
-
-public:
- explicit QEventDispatcherX11(QObject *parent = 0);
- ~QEventDispatcherX11();
-
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
- bool hasPendingEvents();
-
- void flush();
-
- void startingUp();
- void closingDown();
-
-protected:
- int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timeval *timeout);
-};
-
-QT_END_NAMESPACE
-
-#endif // QEVENTDISPATCHER_X11_P_H
diff --git a/src/widgets/platforms/x11/qfont_x11.cpp b/src/widgets/platforms/x11/qfont_x11.cpp
deleted file mode 100644
index ba69871855..0000000000
--- a/src/widgets/platforms/x11/qfont_x11.cpp
+++ /dev/null
@@ -1,368 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define QT_FATAL_ASSERT
-
-#include "qplatformdefs.h"
-
-#include "qfont.h"
-#include "qapplication.h"
-#include "qfontinfo.h"
-#include "qfontdatabase.h"
-#include "qfontmetrics.h"
-#include "qpaintdevice.h"
-#include "qtextcodec.h"
-#include "qiodevice.h"
-#include "qhash.h"
-
-#include <private/qunicodetables_p.h>
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include "qfontengine_x11_p.h"
-#include "qtextengine_p.h"
-
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-
-#include <time.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#define QFONTLOADER_DEBUG
-#define QFONTLOADER_DEBUG_VERBOSE
-
-QT_BEGIN_NAMESPACE
-
-double qt_pixelSize(double pointSize, int dpi)
-{
- if (pointSize < 0)
- return -1.;
- if (dpi == 75) // the stupid 75 dpi setting on X11
- dpi = 72;
- return (pointSize * dpi) /72.;
-}
-
-double qt_pointSize(double pixelSize, int dpi)
-{
- if (pixelSize < 0)
- return -1.;
- if (dpi == 75) // the stupid 75 dpi setting on X11
- dpi = 72;
- return pixelSize * 72. / ((double) dpi);
-}
-
-/*
- Removes wildcards from an XLFD.
-
- Returns \a xlfd with all wildcards removed if a match for \a xlfd is
- found, otherwise it returns \a xlfd.
-*/
-static QByteArray qt_fixXLFD(const QByteArray &xlfd)
-{
- QByteArray ret = xlfd;
- int count = 0;
- char **fontNames =
- XListFonts(QX11Info::display(), xlfd, 32768, &count);
- if (count > 0)
- ret = fontNames[0];
- XFreeFontNames(fontNames);
- return ret ;
-}
-
-typedef QHash<int, QString> FallBackHash;
-Q_GLOBAL_STATIC(FallBackHash, fallBackHash)
-
-// Returns the user-configured fallback family for the specified script.
-QString qt_fallback_font_family(int script)
-{
- FallBackHash *hash = fallBackHash();
- return hash->value(script);
-}
-
-// Sets the fallback family for the specified script.
-Q_WIDGETS_EXPORT void qt_x11_set_fallback_font_family(int script, const QString &family)
-{
- FallBackHash *hash = fallBackHash();
- if (!family.isEmpty())
- hash->insert(script, family);
- else
- hash->remove(script);
-}
-
-int QFontPrivate::defaultEncodingID = -1;
-
-void QFont::initialize()
-{
- extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp
- QTextCodec *codec = QTextCodec::codecForLocale();
- // determine the default encoding id using the locale, otherwise
- // fallback to latin1 (mib == 4)
- int mib = codec ? codec->mibEnum() : 4;
-
- // for asian locales, use the mib for the font codec instead of the locale codec
- switch (mib) {
- case 38: // eucKR
- mib = 36;
- break;
-
- case 2025: // GB2312
- mib = 57;
- break;
-
- case 113: // GBK
- mib = -113;
- break;
-
- case 114: // GB18030
- mib = -114;
- break;
-
- case 2026: // Big5
- mib = -2026;
- break;
-
- case 2101: // Big5-HKSCS
- mib = -2101;
- break;
-
- case 16: // JIS7
- mib = 15;
- break;
-
- case 17: // SJIS
- case 18: // eucJP
- mib = 63;
- break;
- }
-
- // get the default encoding id for the locale encoding...
- QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib);
-}
-
-void QFont::cleanup()
-{
- QFontCache::cleanup();
-}
-
-/*!
- \internal
- X11 Only: Returns the screen with which this font is associated.
-*/
-int QFont::x11Screen() const
-{
- return d->screen;
-}
-
-/*! \internal
- X11 Only: Associate the font with the specified \a screen.
-*/
-void QFont::x11SetScreen(int screen)
-{
- if (screen < 0) // assume default
- screen = QX11Info::appScreen();
-
- if (screen == d->screen)
- return; // nothing to do
-
- detach();
- d->screen = screen;
-}
-
-Qt::HANDLE 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::XLFD)
- return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
- return 0;
-}
-
-
-FT_Face QFont::freetypeFace() const
-{
-#ifndef QT_NO_FREETYPE
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
-#ifndef QT_NO_FONTCONFIG
- if (engine->type() == QFontEngine::Freetype) {
- const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
- return ft->non_locked_face();
- } else
-#endif
- if (engine->type() == QFontEngine::XLFD) {
- const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
- return xlfd->non_locked_face();
- }
-#endif
- return 0;
-}
-
-QString QFont::rawName() 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::XLFD)
- return QString::fromLatin1(engine->name());
- return QString();
-}
-struct QtFontDesc;
-
-void QFont::setRawName(const QString &name)
-{
- detach();
-
- // from qfontdatabase_x11.cpp
- extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
-
- if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
- qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
-
- setFamily(name);
- setRawMode(true);
- } else {
- resolve_mask = QFont::AllPropertiesResolved;
- }
-}
-
-QString QFont::lastResortFamily() const
-{
- return QString::fromLatin1("Helvetica");
-}
-
-QString QFont::defaultFamily() const
-{
- switch (d->request.styleHint) {
- case QFont::Times:
- return QString::fromLatin1("Times");
-
- case QFont::Courier:
- return QString::fromLatin1("Courier");
-
- case QFont::Monospace:
- return QString::fromLatin1("Courier New");
-
- case QFont::Cursive:
- return QString::fromLatin1("Comic Sans MS");
-
- case QFont::Fantasy:
- return QString::fromLatin1("Impact");
-
- case QFont::Decorative:
- return QString::fromLatin1("Old English");
-
- case QFont::Helvetica:
- case QFont::System:
- default:
- return QString::fromLatin1("Helvetica");
- }
-}
-
-/*
- Returns a last resort raw font name for the font matching algorithm.
- This is used if even the last resort family is not available. It
- returns \e something, almost no matter what. The current
- implementation tries a wide variety of common fonts, returning the
- first one it finds. The implementation may change at any time.
-*/
-static const char * const tryFonts[] = {
- "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
- "6x13",
- "7x13",
- "8x13",
- "9x15",
- "fixed",
- 0
-};
-
-// Returns true if the font exists, false otherwise
-static bool fontExists(const QString &fontName)
-{
- int count;
- char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
- if (fontNames) XFreeFontNames(fontNames);
-
- return count != 0;
-}
-
-QString QFont::lastResortFont() const
-{
- static QString last;
-
- // already found
- if (! last.isNull())
- return last;
-
- int i = 0;
- const char* f;
-
- while ((f = tryFonts[i])) {
- last = QString::fromLatin1(f);
-
- if (fontExists(last))
- return last;
-
- i++;
- }
-
-#if defined(CHECK_NULL)
- qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
-#endif
- return last;
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qfontdatabase_x11.cpp b/src/widgets/platforms/x11/qfontdatabase_x11.cpp
deleted file mode 100644
index 922a97f3aa..0000000000
--- a/src/widgets/platforms/x11/qfontdatabase_x11.cpp
+++ /dev/null
@@ -1,2154 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qplatformdefs.h>
-
-#include <qdebug.h>
-#include <qpaintdevice.h>
-#include <qelapsedtimer.h>
-
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-#include <qdebug.h>
-#include <qfile.h>
-#include <qtemporaryfile.h>
-#include <qabstractfileengine.h>
-#include <qmath.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include <private/qfontengine_x11_p.h>
-
-#ifndef QT_NO_FONTCONFIG
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#if FC_VERSION >= 20402
-#include <fontconfig/fcfreetype.h>
-#endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// from qfont_x11.cpp
-extern double qt_pointSize(double pixelSize, int dpi);
-extern double qt_pixelSize(double pointSize, int dpi);
-
-// from qapplication.cpp
-extern bool qt_is_gui_used;
-
-static inline void capitalize (char *s)
-{
- bool space = true;
- while(*s) {
- if (space)
- *s = toupper(*s);
- space = (*s == ' ');
- ++s;
- }
-}
-
-
-/*
- To regenerate the writingSystems_for_xlfd_encoding table, run
- 'util/unicode/x11/makeencodings' and paste the generated
- 'encodings.c' here.
-*/
-// ----- begin of generated code -----
-
-#define make_tag( c1, c2, c3, c4 ) \
- ((((unsigned int)c1)<<24) | (((unsigned int)c2)<<16) | \
- (((unsigned int)c3)<<8) | ((unsigned int)c4))
-
-struct XlfdEncoding {
- const char *name;
- int id;
- int mib;
- unsigned int hash1;
- unsigned int hash2;
-};
-
-static const XlfdEncoding xlfd_encoding[] = {
- { "iso8859-1", 0, 4, make_tag('i','s','o','8'), make_tag('5','9','-','1') },
- { "iso8859-2", 1, 5, make_tag('i','s','o','8'), make_tag('5','9','-','2') },
- { "iso8859-3", 2, 6, make_tag('i','s','o','8'), make_tag('5','9','-','3') },
- { "iso8859-4", 3, 7, make_tag('i','s','o','8'), make_tag('5','9','-','4') },
- { "iso8859-9", 4, 12, make_tag('i','s','o','8'), make_tag('5','9','-','9') },
- { "iso8859-10", 5, 13, make_tag('i','s','o','8'), make_tag('9','-','1','0') },
- { "iso8859-13", 6, 109, make_tag('i','s','o','8'), make_tag('9','-','1','3') },
- { "iso8859-14", 7, 110, make_tag('i','s','o','8'), make_tag('9','-','1','4') },
- { "iso8859-15", 8, 111, make_tag('i','s','o','8'), make_tag('9','-','1','5') },
- { "hp-roman8", 9, 2004, make_tag('h','p','-','r'), make_tag('m','a','n','8') },
- { "iso8859-5", 10, 8, make_tag('i','s','o','8'), make_tag('5','9','-','5') },
- { "*-cp1251", 11, 2251, 0, make_tag('1','2','5','1') },
- { "koi8-ru", 12, 2084, make_tag('k','o','i','8'), make_tag('8','-','r','u') },
- { "koi8-u", 13, 2088, make_tag('k','o','i','8'), make_tag('i','8','-','u') },
- { "koi8-r", 14, 2084, make_tag('k','o','i','8'), make_tag('i','8','-','r') },
- { "iso8859-7", 15, 10, make_tag('i','s','o','8'), make_tag('5','9','-','7') },
- { "iso8859-8", 16, 85, make_tag('i','s','o','8'), make_tag('5','9','-','8') },
- { "gb18030-0", 17, -114, make_tag('g','b','1','8'), make_tag('3','0','-','0') },
- { "gb18030.2000-0", 18, -113, make_tag('g','b','1','8'), make_tag('0','0','-','0') },
- { "gbk-0", 19, -113, make_tag('g','b','k','-'), make_tag('b','k','-','0') },
- { "gb2312.*-0", 20, 57, make_tag('g','b','2','3'), 0 },
- { "jisx0201*-0", 21, 15, make_tag('j','i','s','x'), 0 },
- { "jisx0208*-0", 22, 63, make_tag('j','i','s','x'), 0 },
- { "ksc5601*-*", 23, 36, make_tag('k','s','c','5'), 0 },
- { "big5hkscs-0", 24, -2101, make_tag('b','i','g','5'), make_tag('c','s','-','0') },
- { "hkscs-1", 25, -2101, make_tag('h','k','s','c'), make_tag('c','s','-','1') },
- { "big5*-*", 26, -2026, make_tag('b','i','g','5'), 0 },
- { "tscii-*", 27, 2028, make_tag('t','s','c','i'), 0 },
- { "tis620*-*", 28, 2259, make_tag('t','i','s','6'), 0 },
- { "iso8859-11", 29, 2259, make_tag('i','s','o','8'), make_tag('9','-','1','1') },
- { "mulelao-1", 30, -4242, make_tag('m','u','l','e'), make_tag('a','o','-','1') },
- { "ethiopic-unicode", 31, 0, make_tag('e','t','h','i'), make_tag('c','o','d','e') },
- { "iso10646-1", 32, 0, make_tag('i','s','o','1'), make_tag('4','6','-','1') },
- { "unicode-*", 33, 0, make_tag('u','n','i','c'), 0 },
- { "*-symbol", 34, 0, 0, make_tag('m','b','o','l') },
- { "*-fontspecific", 35, 0, 0, make_tag('i','f','i','c') },
- { "fontspecific-*", 36, 0, make_tag('f','o','n','t'), 0 },
- { 0, 0, 0, 0, 0 }
-};
-
-static const char writingSystems_for_xlfd_encoding[sizeof(xlfd_encoding)][QFontDatabase::WritingSystemsCount] = {
- // iso8859-1
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-2
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-3
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-4
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-9
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-10
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-13
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-14
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-15
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // hp-roman8
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-5
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // *-cp1251
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // koi8-ru
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // koi8-u
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // koi8-r
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-7
- { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-8
- { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // gb18030-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // gb18030.2000-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // gbk-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // gb2312.*-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // jisx0201*-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0 },
- // jisx0208*-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0 },
- // ksc5601*-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0 },
- // big5hkscs-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0 },
- // hkscs-1
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0 },
- // big5*-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0 },
- // tscii-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // tis620*-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-11
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // mulelao-1
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // ethiopic-unicode
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso10646-1
- { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0, 0 },
- // unicode-*
- { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0, 0 },
- // *-symbol
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0 },
- // *-fontspecific
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0 },
- // fontspecific-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0 }
-
-};
-
-// ----- end of generated code -----
-
-
-const int numEncodings = sizeof(xlfd_encoding) / sizeof(XlfdEncoding) - 1;
-
-int qt_xlfd_encoding_id(const char *encoding)
-{
- // qDebug("looking for encoding id for '%s'", encoding);
- int len = strlen(encoding);
- if (len < 4)
- return -1;
- unsigned int hash1 = make_tag(encoding[0], encoding[1], encoding[2], encoding[3]);
- const char *ch = encoding + len - 4;
- unsigned int hash2 = make_tag(ch[0], ch[1], ch[2], ch[3]);
-
- const XlfdEncoding *enc = xlfd_encoding;
- for (; enc->name; ++enc) {
- if ((enc->hash1 && enc->hash1 != hash1) ||
- (enc->hash2 && enc->hash2 != hash2))
- continue;
- // hashes match, do a compare if strings match
- // the enc->name can contain '*'s we have to interpret correctly
- const char *n = enc->name;
- const char *e = encoding;
- while (1) {
- // qDebug("bol: *e='%c', *n='%c'", *e, *n);
- if (*e == '\0') {
- if (*n)
- break;
- // qDebug("found encoding id %d", enc->id);
- return enc->id;
- }
- if (*e == *n) {
- ++e;
- ++n;
- continue;
- }
- if (*n != '*')
- break;
- ++n;
- // qDebug("skip: *e='%c', *n='%c'", *e, *n);
- while (*e && *e != *n)
- ++e;
- }
- }
- // qDebug("couldn't find encoding %s", encoding);
- return -1;
-}
-
-int qt_mib_for_xlfd_encoding(const char *encoding)
-{
- int id = qt_xlfd_encoding_id(encoding);
- if (id != -1) return xlfd_encoding[id].mib;
- return 0;
-}
-
-int qt_encoding_id_for_mib(int mib)
-{
- const XlfdEncoding *enc = xlfd_encoding;
- for (; enc->name; ++enc) {
- if (enc->mib == mib)
- return enc->id;
- }
- return -1;
-}
-
-static const char * xlfd_for_id(int id)
-{
- // special case: -1 returns the "*-*" encoding, allowing us to do full
- // database population in a single X server round trip.
- if (id < 0 || id > numEncodings)
- return "*-*";
- return xlfd_encoding[id].name;
-}
-
-enum XLFDFieldNames {
- Foundry,
- Family,
- Weight,
- Slant,
- Width,
- AddStyle,
- PixelSize,
- PointSize,
- ResolutionX,
- ResolutionY,
- Spacing,
- AverageWidth,
- CharsetRegistry,
- CharsetEncoding,
- NFontFields
-};
-
-// Splits an X font name into fields separated by '-'
-static bool parseXFontName(char *fontName, char **tokens)
-{
- if (! fontName || fontName[0] == '0' || fontName[0] != '-') {
- tokens[0] = 0;
- return false;
- }
-
- int i;
- ++fontName;
- for (i = 0; i < NFontFields && fontName && fontName[0]; ++i) {
- tokens[i] = fontName;
- for (;; ++fontName) {
- if (*fontName == '-')
- break;
- if (! *fontName) {
- fontName = 0;
- break;
- }
- }
-
- if (fontName) *fontName++ = '\0';
- }
-
- if (i < NFontFields) {
- for (int j = i ; j < NFontFields; ++j)
- tokens[j] = 0;
- return false;
- }
-
- return true;
-}
-
-static inline bool isZero(char *x)
-{
- return (x[0] == '0' && x[1] == 0);
-}
-
-static inline bool isScalable(char **tokens)
-{
- return (isZero(tokens[PixelSize]) &&
- isZero(tokens[PointSize]) &&
- isZero(tokens[AverageWidth]));
-}
-
-static inline bool isSmoothlyScalable(char **tokens)
-{
- return (isZero(tokens[ResolutionX]) &&
- isZero(tokens[ResolutionY]));
-}
-
-static inline bool isFixedPitch(char **tokens)
-{
- return (tokens[Spacing][0] == 'm' ||
- tokens[Spacing][0] == 'c' ||
- tokens[Spacing][0] == 'M' ||
- tokens[Spacing][0] == 'C');
-}
-
-/*
- Fills in a font definition (QFontDef) from an XLFD (X Logical Font
- Description).
-
- Returns true if the given xlfd is valid.
-*/
-bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc)
-{
- char *tokens[NFontFields];
- QByteArray buffer = xlfd;
- if (! parseXFontName(buffer.data(), tokens))
- return false;
-
- capitalize(tokens[Family]);
- capitalize(tokens[Foundry]);
-
- fd->styleStrategy |= QFont::NoAntialias;
- fd->family = QString::fromLatin1(tokens[Family]);
- QString foundry = QString::fromLatin1(tokens[Foundry]);
- if (! foundry.isEmpty() && foundry != QLatin1String("*") && (!desc || desc->family->count > 1))
- fd->family +=
- QLatin1String(" [") + foundry + QLatin1Char(']');
-
- if (qstrlen(tokens[AddStyle]) > 0)
- fd->addStyle = QString::fromLatin1(tokens[AddStyle]);
- else
- fd->addStyle.clear();
-
- fd->pointSize = atoi(tokens[PointSize])/10.;
- fd->styleHint = QFont::AnyStyle; // ### any until we match families
-
- char slant = tolower((uchar) tokens[Slant][0]);
- fd->style = (slant == 'o' ? QFont::StyleOblique : (slant == 'i' ? QFont::StyleItalic : QFont::StyleNormal));
- char fixed = tolower((uchar) tokens[Spacing][0]);
- fd->fixedPitch = (fixed == 'm' || fixed == 'c');
- fd->weight = getFontWeight(QLatin1String(tokens[Weight]));
-
- int r = atoi(tokens[ResolutionY]);
- fd->pixelSize = atoi(tokens[PixelSize]);
- // not "0" or "*", or required DPI
- if (r && fd->pixelSize && r != dpi) {
- // calculate actual pointsize for display DPI
- fd->pointSize = qt_pointSize(fd->pixelSize, dpi);
- } else if (fd->pixelSize == 0 && fd->pointSize) {
- // calculate pixel size from pointsize/dpi
- fd->pixelSize = qRound(qt_pixelSize(fd->pointSize, dpi));
- }
-
- return true;
-}
-
-/*
- Fills in a font definition (QFontDef) from the font properties in an
- XFontStruct.
-
- Returns true if the QFontDef could be filled with properties from
- the XFontStruct.
-*/
-static bool qt_fillFontDef(XFontStruct *fs, QFontDef *fd, int dpi, QtFontDesc *desc)
-{
- unsigned long value;
- if (!fs || !XGetFontProperty(fs, XA_FONT, &value))
- return false;
-
- char *n = XGetAtomName(QX11Info::display(), value);
- QByteArray xlfd(n);
- if (n)
- XFree(n);
- return qt_fillFontDef(xlfd.toLower(), fd, dpi, desc);
-}
-
-
-static QtFontStyle::Key getStyle(char ** tokens)
-{
- QtFontStyle::Key key;
-
- char slant0 = tolower((uchar) tokens[Slant][0]);
-
- if (slant0 == 'r') {
- if (tokens[Slant][1]) {
- char slant1 = tolower((uchar) tokens[Slant][1]);
-
- if (slant1 == 'o')
- key.style = QFont::StyleOblique;
- else if (slant1 == 'i')
- key.style = QFont::StyleItalic;
- }
- } else if (slant0 == 'o')
- key.style = QFont::StyleOblique;
- else if (slant0 == 'i')
- key.style = QFont::StyleItalic;
-
- key.weight = getFontWeight(QLatin1String(tokens[Weight]));
-
- if (qstrcmp(tokens[Width], "normal") == 0) {
- key.stretch = 100;
- } else if (qstrcmp(tokens[Width], "semi condensed") == 0 ||
- qstrcmp(tokens[Width], "semicondensed") == 0) {
- key.stretch = 90;
- } else if (qstrcmp(tokens[Width], "condensed") == 0) {
- key.stretch = 80;
- } else if (qstrcmp(tokens[Width], "narrow") == 0) {
- key.stretch = 60;
- }
-
- return key;
-}
-
-
-static bool xlfdsFullyLoaded = false;
-static unsigned char encodingLoaded[numEncodings];
-
-static void loadXlfds(const char *reqFamily, int encoding_id)
-{
- QFontDatabasePrivate *db = privateDb();
- QtFontFamily *fontFamily = reqFamily ? db->family(QLatin1String(reqFamily)) : 0;
-
- // make sure we don't load twice
- if ((encoding_id == -1 && xlfdsFullyLoaded)
- || (encoding_id != -1 && encodingLoaded[encoding_id]))
- return;
- if (fontFamily && fontFamily->xlfdLoaded)
- return;
-
- int fontCount;
- // force the X server to give us XLFDs
- QByteArray xlfd_pattern("-*-");
- xlfd_pattern += (reqFamily && reqFamily[0] != '\0') ? reqFamily : "*";
- xlfd_pattern += "-*-*-*-*-*-*-*-*-*-*-";
- xlfd_pattern += xlfd_for_id(encoding_id);
-
- char **fontList = XListFonts(QX11Info::display(),
- xlfd_pattern,
- 0xffff, &fontCount);
- // qDebug("requesting xlfd='%s', got %d fonts", xlfd_pattern.data(), fontCount);
-
-
- char *tokens[NFontFields];
-
- for(int i = 0 ; i < fontCount ; i++) {
- if (! parseXFontName(fontList[i], tokens))
- continue;
-
- // get the encoding_id for this xlfd. we need to do this
- // here, since we can pass -1 to this function to do full
- // database population
- *(tokens[CharsetEncoding] - 1) = '-';
- int encoding_id = qt_xlfd_encoding_id(tokens[CharsetRegistry]);
- if (encoding_id == -1)
- continue;
-
- char *familyName = tokens[Family];
- capitalize(familyName);
- char *foundryName = tokens[Foundry];
- capitalize(foundryName);
- QtFontStyle::Key styleKey = getStyle(tokens);
-
- bool smooth_scalable = false;
- bool bitmap_scalable = false;
- if (isScalable(tokens)) {
- if (isSmoothlyScalable(tokens))
- smooth_scalable = true;
- else
- bitmap_scalable = true;
- }
- uint pixelSize = atoi(tokens[PixelSize]);
- uint xpointSize = atoi(tokens[PointSize]);
- uint xres = atoi(tokens[ResolutionX]);
- uint yres = atoi(tokens[ResolutionY]);
- uint avgwidth = atoi(tokens[AverageWidth]);
- bool fixedPitch = isFixedPitch(tokens);
-
- if (avgwidth == 0 && pixelSize != 0) {
- /*
- Ignore bitmap scalable fonts that are automatically
- generated by some X servers. We know they are bitmap
- scalable because even though they have a specified pixel
- size, the average width is zero.
- */
- continue;
- }
-
- QtFontFamily *family = fontFamily ? fontFamily : db->family(QLatin1String(familyName), true);
- family->fontFileIndex = -1;
- family->symbol_checked = true;
- QtFontFoundry *foundry = family->foundry(QLatin1String(foundryName), true);
- QtFontStyle *style = foundry->style(styleKey, QString(), true);
-
- delete [] style->weightName;
- style->weightName = qstrdup(tokens[Weight]);
- delete [] style->setwidthName;
- style->setwidthName = qstrdup(tokens[Width]);
-
- if (smooth_scalable) {
- style->smoothScalable = true;
- style->bitmapScalable = false;
- pixelSize = SMOOTH_SCALABLE;
- }
- if (!style->smoothScalable && bitmap_scalable)
- style->bitmapScalable = true;
- if (!fixedPitch)
- family->fixedPitch = false;
-
- QtFontSize *size = style->pixelSize(pixelSize, true);
- QtFontEncoding *enc =
- size->encodingID(encoding_id, xpointSize, xres, yres, avgwidth, true);
- enc->pitch = *tokens[Spacing];
- if (!enc->pitch) enc->pitch = '*';
-
- for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
- if (writingSystems_for_xlfd_encoding[encoding_id][i])
- family->writingSystems[i] = QtFontFamily::Supported;
- }
- }
- if (!reqFamily) {
- // mark encoding as loaded
- if (encoding_id == -1)
- xlfdsFullyLoaded = true;
- else
- encodingLoaded[encoding_id] = true;
- }
-
- XFreeFontNames(fontList);
-}
-
-
-#ifndef QT_NO_FONTCONFIG
-
-#ifndef FC_WIDTH
-#define FC_WIDTH "width"
-#endif
-
-static int getFCWeight(int fc_weight)
-{
- int qtweight = QFont::Black;
- if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2)
- qtweight = QFont::Light;
- else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
- qtweight = QFont::Normal;
- else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
- qtweight = QFont::DemiBold;
- else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
- qtweight = QFont::Bold;
-
- return qtweight;
-}
-
-QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &request)
-{
- QFontDef fontDef;
- fontDef.styleStrategy = request.styleStrategy;
-
- fontDef.hintingPreference = request.hintingPreference;
- FcChar8 *value = 0;
- if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) == FcResultMatch) {
- fontDef.family = QString::fromUtf8(reinterpret_cast<const char *>(value));
- }
-
- double dpi;
- if (FcPatternGetDouble(pattern, FC_DPI, 0, &dpi) != FcResultMatch) {
- if (X11->display)
- dpi = QX11Info::appDpiY();
- else
- dpi = qt_defaultDpiY();
- }
-
- double size;
- if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
- fontDef.pixelSize = size;
- else
- fontDef.pixelSize = 12;
-
- fontDef.pointSize = qt_pointSize(fontDef.pixelSize, qRound(dpi));
-
- /* ###
- fontDef.styleHint
- */
-
- int weight;
- if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) != FcResultMatch)
- weight = FC_WEIGHT_MEDIUM;
- fontDef.weight = getFCWeight(weight);
-
- int slant;
- if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant) != FcResultMatch)
- slant = FC_SLANT_ROMAN;
- fontDef.style = (slant == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
-
-
- FcBool scalable;
- if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = false;
- if (scalable) {
- fontDef.stretch = request.stretch;
- fontDef.style = request.style;
- } else {
- int width;
- if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width) == FcResultMatch)
- fontDef.stretch = width;
- else
- fontDef.stretch = 100;
- }
-
- int spacing;
- if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing) == FcResultMatch) {
- fontDef.fixedPitch = (spacing >= FC_MONO);
- fontDef.ignorePitch = false;
- } else {
- fontDef.ignorePitch = true;
- }
-
- return fontDef;
-}
-
-static const char *specialLanguages[] = {
- "en", // Common
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "ko", // Hangul
- "", // Ogham
- "", // Runic
- "km", // Khmer
- "" // N'Ko
-};
-enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
-
-static const ushort specialChars[] = {
- 0, // English
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Hangul
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0, // Khmer
- 0x7ca // N'Ko
-};
-enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
-
-// this could become a list of all languages used for each writing
-// system, instead of using the single most common language.
-static const char *languageForWritingSystem[] = {
- 0, // Any
- "en", // Latin
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "km", // Khmer
- "zh-cn", // SimplifiedChinese
- "zh-tw", // TraditionalChinese
- "ja", // Japanese
- "ko", // Korean
- "vi", // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- 0 // N'Ko
-};
-enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-
-// Unfortunately FontConfig doesn't know about some languages. We have to test these through the
-// charset. The lists below contain the systems where we need to do this.
-static const ushort sampleCharForWritingSystem[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0x7ca // N'Ko
-};
-enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
-
-// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
-// open type tables for is directly. Do this so we don't pick some strange
-// pseudo unicode font
-static const char *openType[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- "syrc", // Syriac
- "thaa", // Thaana
- "deva", // Devanagari
- "beng", // Bengali
- "guru", // Gurmukhi
- "gurj", // Gujarati
- "orya", // Oriya
- "taml", // Tamil
- "telu", // Telugu
- "knda", // Kannada
- "mlym", // Malayalam
- "sinh", // Sinhala
- 0, // Thai
- 0, // Lao
- "tibt", // Tibetan
- "mymr", // Myanmar
- 0, // Georgian
- "khmr", // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- "nko " // N'Ko
-};
-enum { OpenTypeCount = sizeof(openType) / sizeof(const char *) };
-
-
-static void loadFontConfig()
-{
- Q_ASSERT_X(X11, "QFontDatabase",
- "A QApplication object needs to be constructed before FontConfig is used.");
- if (!X11->has_fontconfig)
- return;
-
- Q_ASSERT_X(int(QUnicodeTables::ScriptCount) == SpecialLanguageCount,
- "QFontDatabase", "New scripts have been added.");
- Q_ASSERT_X(int(QUnicodeTables::ScriptCount) == SpecialCharCount,
- "QFontDatabase", "New scripts have been added.");
- Q_ASSERT_X(int(QFontDatabase::WritingSystemsCount) == LanguageCount,
- "QFontDatabase", "New writing systems have been added.");
- Q_ASSERT_X(int(QFontDatabase::WritingSystemsCount) == SampleCharCount,
- "QFontDatabase", "New writing systems have been added.");
- Q_ASSERT_X(int(QFontDatabase::WritingSystemsCount) == OpenTypeCount,
- "QFontDatabase", "New writing systems have been added.");
-
- QFontDatabasePrivate *db = privateDb();
- FcFontSet *fonts;
-
- FcPattern *pattern = FcPatternCreate();
- FcDefaultSubstitute(pattern);
- FcChar8 *lang = 0;
- if (FcPatternGetString(pattern, FC_LANG, 0, &lang) == FcResultMatch)
- db->systemLang = QString::fromUtf8((const char *) lang);
- FcPatternDestroy(pattern);
-
- QString familyName;
- FcChar8 *value = 0;
- int weight_value;
- int slant_value;
- int spacing_value;
- FcChar8 *file_value;
- int index_value;
- FcChar8 *foundry_value;
- FcChar8 *style_value;
- FcBool scalable;
-
- {
- FcObjectSet *os = FcObjectSetCreate();
- FcPattern *pattern = FcPatternCreate();
- const char *properties [] = {
- FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
- FC_SPACING, FC_FILE, FC_INDEX,
- FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
- FC_WIDTH,
-#if FC_VERSION >= 20297
- FC_CAPABILITY,
-#endif
- (const char *)0
- };
- const char **p = properties;
- while (*p) {
- FcObjectSetAdd(os, *p);
- ++p;
- }
- fonts = FcFontList(0, pattern, os);
- FcObjectSetDestroy(os);
- FcPatternDestroy(pattern);
- }
-
- for (int i = 0; i < fonts->nfont; i++) {
- if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- familyName = QString::fromUtf8((const char *)value);
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_MEDIUM;
- spacing_value = FC_PROPORTIONAL;
- file_value = 0;
- index_value = 0;
- scalable = FcTrue;
-
- if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_MEDIUM;
- if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
- if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &index_value) != FcResultMatch)
- index_value = 0;
- if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
- if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch)
- style_value = 0;
- QtFontFamily *family = db->family(familyName, true);
-
- FcLangSet *langset = 0;
- FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- for (int i = 1; i < LanguageCount; ++i) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i];
- if (!lang) {
- family->writingSystems[i] |= QtFontFamily::UnsupportedFT;
- } else {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang)
- family->writingSystems[i] = QtFontFamily::Supported;
- else
- family->writingSystems[i] |= QtFontFamily::UnsupportedFT;
- }
- }
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::UnsupportedFT;
- family->ftWritingSystemCheck = true;
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- for (int i = 1; i < LanguageCount; ++i)
- family->writingSystems[i] |= QtFontFamily::UnsupportedFT;
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::Supported;
- }
-
- FcCharSet *cs = 0;
- res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs);
- if (res == FcResultMatch) {
- // some languages are not supported by FontConfig, we rather check the
- // charset to detect these
- for (int i = 1; i < SampleCharCount; ++i) {
- if (!sampleCharForWritingSystem[i])
- continue;
- if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
- family->writingSystems[i] = QtFontFamily::Supported;
- }
- }
-
-#if FC_VERSION >= 20297
- for (int j = 1; j < LanguageCount; ++j) {
- if (family->writingSystems[j] == QtFontFamily::Supported && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- family->writingSystems[j] = QtFontFamily::UnsupportedFT;
- }
- }
-#endif
-
- QByteArray file((const char *)file_value);
- family->fontFilename = file;
- family->fontFileIndex = index_value;
-
- QtFontStyle::Key styleKey;
- QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
- styleKey.style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- styleKey.weight = getFCWeight(weight_value);
- if (!scalable) {
- int width = 100;
- FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
- styleKey.stretch = width;
- }
-
- QtFontFoundry *foundry
- = family->foundry(foundry_value ? QString::fromUtf8((const char *)foundry_value) : QString(), true);
- QtFontStyle *style = foundry->style(styleKey, styleName, true);
-
- if (spacing_value < FC_MONO)
- family->fixedPitch = false;
-
- QtFontSize *size;
- if (scalable) {
- style->smoothScalable = true;
- size = style->pixelSize(SMOOTH_SCALABLE, true);
- } else {
- double pixel_size = 0;
- FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
- size = style->pixelSize((int)pixel_size, true);
- }
- QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
- enc->pitch = (spacing_value >= FC_CHARCELL ? 'c' :
- (spacing_value >= FC_MONO ? 'm' : 'p'));
- }
-
- FcFontSetDestroy (fonts);
-
- struct FcDefaultFont {
- const char *qtname;
- const char *rawname;
- bool fixed;
- };
- const FcDefaultFont defaults[] = {
- { "Serif", "serif", false },
- { "Sans Serif", "sans-serif", false },
- { "Monospace", "monospace", true },
- { 0, 0, false }
- };
- const FcDefaultFont *f = defaults;
- while (f->qtname) {
- QtFontFamily *family = db->family(QLatin1String(f->qtname), true);
- family->fixedPitch = f->fixed;
- family->synthetic = true;
- QtFontFoundry *foundry = family->foundry(QString(), true);
-
- // aliases only make sense for 'common', not for any of the specials
- for (int i = 1; i < LanguageCount; ++i) {
- if (requiresOpenType(i))
- family->writingSystems[i] = QtFontFamily::UnsupportedFT;
- else
- family->writingSystems[i] = QtFontFamily::Supported;
- }
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::UnsupportedFT;
-
- QtFontStyle::Key styleKey;
- for (int i = 0; i < 4; ++i) {
- styleKey.style = (i%2) ? QFont::StyleNormal : QFont::StyleItalic;
- styleKey.weight = (i > 1) ? QFont::Bold : QFont::Normal;
- QtFontStyle *style = foundry->style(styleKey, QString(), true);
- style->smoothScalable = true;
- QtFontSize *size = style->pixelSize(SMOOTH_SCALABLE, true);
- QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
- enc->pitch = (f->fixed ? 'm' : 'p');
- }
- ++f;
- }
-}
-#endif // QT_NO_FONTCONFIG
-
-static void initializeDb();
-
-static void load(const QString &family = QString(), int script = -1, bool forceXLFD = false)
-{
- if (X11->has_fontconfig && !forceXLFD) {
- initializeDb();
- return;
- }
-
-#ifdef QFONTDATABASE_DEBUG
- QElapsedTimer t;
- t.start();
-#endif
-
- if (family.isNull() && script == -1) {
- loadXlfds(0, -1);
- } else {
- if (family.isNull()) {
- // load all families in all writing systems that match \a script
- for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
- if (scriptForWritingSystem[ws] != script)
- continue;
- for (int i = 0; i < numEncodings; ++i) {
- if (writingSystems_for_xlfd_encoding[i][ws])
- loadXlfds(0, i);
- }
- }
- } else {
- QtFontFamily *f = privateDb()->family(family);
- // could reduce this further with some more magic:
- // would need to remember the encodings loaded for the family.
- if (!f || !f->xlfdLoaded)
- loadXlfds(family.toLatin1(), -1);
- }
- }
-
-#ifdef QFONTDATABASE_DEBUG
- FD_DEBUG("QFontDatabase: load(%s, %d) took %d ms",
- family.toLatin1().constData(), script, t.elapsed());
-#endif
-}
-
-static void checkSymbolFont(QtFontFamily *family)
-{
- if (!family || family->symbol_checked || family->fontFilename.isEmpty())
- return;
-// qDebug() << "checking " << family->rawName;
- family->symbol_checked = true;
-
- QFontEngine::FaceId id;
- id.filename = family->fontFilename;
- id.index = family->fontFileIndex;
- QFreetypeFace *f = QFreetypeFace::getFace(id);
- if (!f) {
- qWarning("checkSymbolFonts: Couldn't open face %s (%s/%d)",
- qPrintable(family->name), family->fontFilename.data(), family->fontFileIndex);
- return;
- }
- for (int i = 0; i < f->face->num_charmaps; ++i) {
- FT_CharMap cm = f->face->charmaps[i];
- if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
- || cm->encoding == FT_ENCODING_MS_SYMBOL) {
- for (int x = QFontDatabase::Latin; x < QFontDatabase::Other; ++x)
- family->writingSystems[x] = QtFontFamily::Unsupported;
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::Supported;
- break;
- }
- }
- f->release(id);
-}
-
-static void checkSymbolFonts(const QString &family = QString())
-{
-#ifndef QT_NO_FONTCONFIG
- QFontDatabasePrivate *d = privateDb();
-
- if (family.isEmpty()) {
- for (int i = 0; i < d->count; ++i)
- checkSymbolFont(d->families[i]);
- } else {
- checkSymbolFont(d->family(family));
- }
-#endif
-}
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
-
-static void initializeDb()
-{
- QFontDatabasePrivate *db = privateDb();
- if (!db || db->count)
- return;
-
- QElapsedTimer t;
- t.start();
-
-#ifndef QT_NO_FONTCONFIG
- if (db->reregisterAppFonts) {
- db->reregisterAppFonts = false;
- for (int i = 0; i < db->applicationFonts.count(); ++i)
- if (!db->applicationFonts.at(i).families.isEmpty()) {
- registerFont(&db->applicationFonts[i]);
- }
- }
-
- loadFontConfig();
- FD_DEBUG("QFontDatabase: loaded FontConfig: %d ms", int(t.elapsed()));
-#endif
-
- t.start();
-
-#ifndef QT_NO_FONTCONFIG
- for (int i = 0; i < db->count; i++) {
- for (int j = 0; j < db->families[i]->count; ++j) { // each foundry
- QtFontFoundry *foundry = db->families[i]->foundries[j];
- for (int k = 0; k < foundry->count; ++k) {
- QtFontStyle *style = foundry->styles[k];
- if (style->key.style != QFont::StyleNormal) continue;
-
- QtFontSize *size = style->pixelSize(SMOOTH_SCALABLE);
- if (! size) continue; // should not happen
- QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
- if (! enc) continue; // should not happen either
-
- QtFontStyle::Key key = style->key;
-
- // does this style have an italic equivalent?
- key.style = QFont::StyleItalic;
- QtFontStyle *equiv = foundry->style(key);
- if (equiv) continue;
-
- // does this style have an oblique equivalent?
- key.style = QFont::StyleOblique;
- equiv = foundry->style(key);
- if (equiv) continue;
-
- // let's fake one...
- equiv = foundry->style(key, QString(), true);
- equiv->smoothScalable = true;
-
- QtFontSize *equiv_size = equiv->pixelSize(SMOOTH_SCALABLE, true);
- QtFontEncoding *equiv_enc = equiv_size->encodingID(-1, 0, 0, 0, 0, true);
-
- // keep the same pitch
- equiv_enc->pitch = enc->pitch;
- }
- }
- }
-#endif
-
-
-#ifdef QFONTDATABASE_DEBUG
-#ifndef QT_NO_FONTCONFIG
- if (!X11->has_fontconfig)
-#endif
- // load everything at startup in debug mode.
- loadXlfds(0, -1);
-
- // print the database
- for (int f = 0; f < db->count; f++) {
- QtFontFamily *family = db->families[f];
- FD_DEBUG("'%s' %s fixed=%s", family->name.latin1(), (family->fixedPitch ? "fixed" : ""),
- (family->fixedPitch ? "yes" : "no"));
- for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
- QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i);
- FD_DEBUG("\t%s: %s", QFontDatabase::writingSystemName(ws).toLatin1().constData(),
- ((family->writingSystems[i] & QtFontFamily::Supported) ? "Supported" :
- (family->writingSystems[i] & QtFontFamily::Unsupported) == QtFontFamily::Unsupported ?
- "Unsupported" : "Unknown"));
- }
-
- for (int fd = 0; fd < family->count; fd++) {
- QtFontFoundry *foundry = family->foundries[fd];
- FD_DEBUG("\t\t'%s'", foundry->name.latin1());
- for (int s = 0; s < foundry->count; s++) {
- QtFontStyle *style = foundry->styles[s];
- FD_DEBUG("\t\t\tstyle: style=%d weight=%d (%s)\n"
- "\t\t\tstretch=%d (%s)",
- style->key.style, style->key.weight,
- style->weightName, style->key.stretch,
- style->setwidthName ? style->setwidthName : "nil");
- if (style->smoothScalable)
- FD_DEBUG("\t\t\t\tsmooth scalable");
- else if (style->bitmapScalable)
- FD_DEBUG("\t\t\t\tbitmap scalable");
- if (style->pixelSizes) {
- qDebug("\t\t\t\t%d pixel sizes", style->count);
- for (int z = 0; z < style->count; ++z) {
- QtFontSize *size = style->pixelSizes + z;
- for (int e = 0; e < size->count; ++e) {
- FD_DEBUG("\t\t\t\t size %5d pitch %c encoding %s",
- size->pixelSize,
- size->encodings[e].pitch,
- xlfd_for_id(size->encodings[e].encoding));
- }
- }
- }
- }
- }
- }
-#endif // QFONTDATABASE_DEBUG
-}
-
-
-// --------------------------------------------------------------------------------------
-// font loader
-// --------------------------------------------------------------------------------------
-
-static const char *styleHint(const QFontDef &request)
-{
- const char *stylehint = 0;
- switch (request.styleHint) {
- case QFont::SansSerif:
- stylehint = "sans-serif";
- break;
- case QFont::Serif:
- stylehint = "serif";
- break;
- case QFont::TypeWriter:
- stylehint = "monospace";
- break;
- default:
- if (request.fixedPitch)
- stylehint = "monospace";
- break;
- }
- return stylehint;
-}
-
-#ifndef QT_NO_FONTCONFIG
-
-void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontDef &request)
-{
- double size_value = qMax(qreal(1.), request.pixelSize);
- FcPatternDel(pattern, FC_PIXEL_SIZE);
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
-
- if (X11->display && QX11Info::appDepth(screen) <= 8) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- // can't do antialiasing on 8bpp
- FcPatternAddBool(pattern, FC_ANTIALIAS, false);
- } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- FcPatternAddBool(pattern, FC_ANTIALIAS,
- !(request.styleStrategy & QFont::NoAntialias));
- }
-
- if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
- Q_ASSERT(script < QUnicodeTables::ScriptCount);
- FcLangSet *ls = FcLangSetCreate();
- FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
- FcPatternDel(pattern, FC_LANG);
- FcPatternAddLangSet(pattern, FC_LANG, ls);
- FcLangSetDestroy(ls);
- }
-
- if (!request.styleName.isEmpty()) {
- QByteArray cs = request.styleName.toUtf8();
- FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *) cs.constData());
- return;
- }
-
- int weight_value = FC_WEIGHT_BLACK;
- if (request.weight == 0)
- weight_value = FC_WEIGHT_MEDIUM;
- else if (request.weight < (QFont::Light + QFont::Normal) / 2)
- weight_value = FC_WEIGHT_LIGHT;
- else if (request.weight < (QFont::Normal + QFont::DemiBold) / 2)
- weight_value = FC_WEIGHT_MEDIUM;
- else if (request.weight < (QFont::DemiBold + QFont::Bold) / 2)
- weight_value = FC_WEIGHT_DEMIBOLD;
- else if (request.weight < (QFont::Bold + QFont::Black) / 2)
- weight_value = FC_WEIGHT_BOLD;
- FcPatternDel(pattern, FC_WEIGHT);
- FcPatternAddInteger(pattern, FC_WEIGHT, weight_value);
-
- int slant_value = FC_SLANT_ROMAN;
- if (request.style == QFont::StyleItalic)
- slant_value = FC_SLANT_ITALIC;
- else if (request.style == QFont::StyleOblique)
- slant_value = FC_SLANT_OBLIQUE;
- FcPatternDel(pattern, FC_SLANT);
- FcPatternAddInteger(pattern, FC_SLANT, slant_value);
-
- int stretch = request.stretch;
- if (!stretch)
- stretch = 100;
- FcPatternDel(pattern, FC_WIDTH);
- FcPatternAddInteger(pattern, FC_WIDTH, stretch);
-}
-
-static bool preferScalable(const QFontDef &request)
-{
- return request.styleStrategy & (QFont::PreferOutline|QFont::ForceOutline|QFont::PreferQuality|QFont::PreferAntialias);
-}
-
-
-static FcPattern *getFcPattern(const QFontPrivate *fp, int script, const QFontDef &request)
-{
- if (!X11->has_fontconfig)
- return 0;
-
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return 0;
-
- FcValue value;
- value.type = FcTypeString;
-
- QtFontDesc desc;
- QStringList families_and_foundries = familyList(request);
- for (int i = 0; i < families_and_foundries.size(); ++i) {
- QString family, foundry;
- parseFontName(families_and_foundries.at(i), foundry, family);
- if (!family.isEmpty()) {
- QByteArray cs = family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern, FC_FAMILY, value, FcTrue);
- }
- if (i == 0) {
- QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, -1, &desc);
- if (!foundry.isEmpty()) {
- QByteArray cs = foundry.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FOUNDRY, value, FcTrue);
- }
- }
- }
-
- const char *stylehint = styleHint(request);
- if (stylehint) {
- value.u.s = (const FcChar8 *)stylehint;
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
- }
-
- if (!request.ignorePitch) {
- char pitch_value = FC_PROPORTIONAL;
- if (request.fixedPitch || (desc.family && desc.family->fixedPitch))
- pitch_value = FC_MONO;
- FcPatternAddInteger(pattern, FC_SPACING, pitch_value);
- }
- FcPatternAddBool(pattern, FC_OUTLINE, !(request.styleStrategy & QFont::PreferBitmap));
- if (preferScalable(request) || (desc.style && desc.style->smoothScalable))
- FcPatternAddBool(pattern, FC_SCALABLE, true);
-
- qt_addPatternProps(pattern, fp->screen, script, request);
-
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- // these should only get added to the pattern _after_ substitution
- // append the default fallback font for the specified script
- extern QString qt_fallback_font_family(int);
- QString fallback = qt_fallback_font_family(script);
- if (!fallback.isEmpty()) {
- QByteArray cs = fallback.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
- }
-
- // add the default family
- QString defaultFamily = QApplication::font().family();
- QByteArray cs = defaultFamily.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
-
- // add QFont::defaultFamily() to the list, for compatibility with
- // previous versions
- defaultFamily = QApplication::font().defaultFamily();
- cs = defaultFamily.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
-
- return pattern;
-}
-
-
-static void FcFontSetRemove(FcFontSet *fs, int at)
-{
- Q_ASSERT(at < fs->nfont);
- FcPatternDestroy(fs->fonts[at]);
- int len = (--fs->nfont - at) * sizeof(FcPattern *);;
- if (len > 0)
- memmove(fs->fonts + at, fs->fonts + at + 1, len);
-}
-
-static QFontEngine *tryPatternLoad(FcPattern *match, int screen,
- const QFontDef &request, int script)
-{
-#ifdef FONT_MATCH_DEBUG
- FcChar8 *fam;
- FcPatternGetString(match, FC_FAMILY, 0, &fam);
- FM_DEBUG("==== trying %s\n", fam);
-#endif
- FM_DEBUG("passes charset test\n");
-
- QFontEngineX11FT *engine = 0;
- if (!match) // probably no fonts available.
- goto done;
-
- if (script != QUnicodeTables::Common) {
- // skip font if it doesn't support the language we want
- if (specialChars[script]) {
- // need to check the charset, as the langset doesn't work for these scripts
- FcCharSet *cs;
- if (FcPatternGetCharSet(match, FC_CHARSET, 0, &cs) != FcResultMatch)
- goto done;
- if (!FcCharSetHasChar(cs, specialChars[script]))
- goto done;
- } else if (*specialLanguages[script] != '\0'){
- FcLangSet *langSet = 0;
- if (FcPatternGetLangSet(match, FC_LANG, 0, &langSet) != FcResultMatch)
- goto done;
- if (FcLangSetHasLang(langSet, (const FcChar8*)specialLanguages[script]) != FcLangEqual)
- goto done;
- }
- }
-
- // enforce non-antialiasing if requested. the ft font engine looks at this property.
- if (request.styleStrategy & QFont::NoAntialias) {
- FcPatternDel(match, FC_ANTIALIAS);
- FcPatternAddBool(match, FC_ANTIALIAS, false);
- }
-
- engine = new QFontEngineX11FT(match, qt_FcPatternToQFontDef(match, request), screen);
- if (engine->invalid()) {
- FM_DEBUG(" --> invalid!\n");
- delete engine;
- engine = 0;
- } else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- FM_DEBUG(" OpenType support missing for script\n");
- delete engine;
- engine = 0;
- }
- }
-done:
- return engine;
-}
-
-FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request)
-{
- FcResult result;
- FcFontSet *fs = FcFontSort(0, pattern, FcTrue, 0, &result);
-#ifdef FONT_MATCH_DEBUG
- FM_DEBUG("first font in fontset:\n");
- FcPatternPrint(fs->fonts[0]);
-#endif
-
- FcBool forceScalable = request.styleStrategy & QFont::ForceOutline;
-
- // remove fonts if they are not scalable (and should be)
- if (forceScalable && fs) {
- for (int i = 0; i < fs->nfont; ++i) {
- FcPattern *font = fs->fonts[i];
- FcResult res;
- FcBool scalable;
- res = FcPatternGetBool(font, FC_SCALABLE, 0, &scalable);
- if (res != FcResultMatch || !scalable) {
- FcFontSetRemove(fs, i);
-#ifdef FONT_MATCH_DEBUG
- FM_DEBUG("removing pattern:");
- FcPatternPrint(font);
-#endif
- --i; // go back one
- }
- }
- }
-
- FM_DEBUG("final pattern contains %d fonts\n", fs->nfont);
-
- return fs;
-}
-
-static QFontEngine *loadFc(const QFontPrivate *fp, int script, const QFontDef &request)
-{
- FM_DEBUG("===================== loadFc: script=%d family='%s'\n", script, request.family.toLatin1().data());
- FcPattern *pattern = getFcPattern(fp, script, request);
-
-#ifdef FONT_MATCH_DEBUG
- FM_DEBUG("\n\nfinal FcPattern contains:\n");
- FcPatternPrint(pattern);
-#endif
-
- QFontEngine *fe = 0;
- FcResult res;
- FcPattern *match = FcFontMatch(0, pattern, &res);
- fe = tryPatternLoad(match, fp->screen, request, script);
- if (!fe) {
- FcFontSet *fs = qt_fontSetForPattern(pattern, request);
-
- if (match) {
- FcPatternDestroy(match);
- match = 0;
- }
-
- if (fs) {
- for (int i = 0; !fe && i < fs->nfont; ++i) {
- match = FcFontRenderPrepare(NULL, pattern, fs->fonts[i]);
- fe = tryPatternLoad(match, fp->screen, request, script);
- if (fe)
- break;
- FcPatternDestroy(match);
- match = 0;
- }
- FcFontSetDestroy(fs);
- }
- FM_DEBUG("engine for script %d is %s\n", script, fe ? fe->fontDef.family.toLatin1().data(): "(null)");
- }
- if (fe
- && script == QUnicodeTables::Common
- && !(request.styleStrategy & QFont::NoFontMerging) && !fe->symbol) {
- fe = new QFontEngineMultiFT(fe, match, pattern, fp->screen, request);
- } else {
- FcPatternDestroy(pattern);
- if (match)
- FcPatternDestroy(match);
- }
- return fe;
-}
-
-static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id, FcBlanks *blanks, int *count)
-{
-#if FC_VERSION < 20402
- Q_UNUSED(data)
- return FcFreeTypeQuery(file, id, blanks, count);
-#else
- if (data.isEmpty())
- return FcFreeTypeQuery(file, id, blanks, count);
-
- extern FT_Library qt_getFreetype();
- FT_Library lib = qt_getFreetype();
-
- FcPattern *pattern = 0;
-
- FT_Face face;
- if (!FT_New_Memory_Face(lib, (const FT_Byte *)data.constData(), data.size(), id, &face)) {
- *count = face->num_faces;
-
- pattern = FcFreeTypeQueryFace(face, file, id, blanks);
-
- FT_Done_Face(face);
- }
-
- return pattern;
-#endif
-}
-#endif // QT_NO_FONTCONFIG
-
-static QFontEngine *loadRaw(const QFontPrivate *fp, const QFontDef &request)
-{
- Q_ASSERT(fp && fp->rawMode);
-
- QByteArray xlfd = request.family.toLatin1();
- FM_DEBUG("Loading XLFD (rawmode) '%s'", xlfd.data());
-
- QFontEngine *fe;
- XFontStruct *xfs;
- if (!(xfs = XLoadQueryFont(QX11Info::display(), xlfd.data())))
- if (!(xfs = XLoadQueryFont(QX11Info::display(), "fixed")))
- return 0;
-
- fe = new QFontEngineXLFD(xfs, xlfd, 0);
- if (! qt_fillFontDef(xfs, &fe->fontDef, fp->dpi, 0) &&
- ! qt_fillFontDef(xlfd, &fe->fontDef, fp->dpi, 0))
- fe->fontDef = QFontDef();
- return fe;
-}
-
-QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &request, int force_encoding_id)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QtFontDesc desc;
- FM_DEBUG() << "---> loadXlfd: request is" << request.family;
- QStringList families_and_foundries = familyList(request);
- const char *stylehint = styleHint(request);
- if (stylehint)
- families_and_foundries << QString::fromLatin1(stylehint);
- families_and_foundries << QString();
- FM_DEBUG() << "loadXlfd: list is" << families_and_foundries;
- for (int i = 0; i < families_and_foundries.size(); ++i) {
- QString family, foundry;
- QT_PREPEND_NAMESPACE(parseFontName)(families_and_foundries.at(i), foundry, family);
- FM_DEBUG("loadXlfd: >>>>>>>>>>>>>>trying to match '%s' encoding=%d", family.toLatin1().data(), force_encoding_id);
- QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc, QList<int>(), true);
- if (desc.family)
- break;
- }
-
- QFontEngine *fe = 0;
- if (force_encoding_id != -1
- || (request.styleStrategy & QFont::NoFontMerging)
- || (desc.family && desc.family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) {
- if (desc.family) {
- int px = desc.size->pixelSize;
- if (desc.style->smoothScalable && px == SMOOTH_SCALABLE)
- px = request.pixelSize;
- else if (desc.style->bitmapScalable && px == 0)
- px = request.pixelSize;
-
- QByteArray xlfd("-");
- xlfd += desc.foundry->name.isEmpty() ? QByteArray("*") : desc.foundry->name.toLatin1();
- xlfd += '-';
- xlfd += desc.family->name.isEmpty() ? QByteArray("*") : desc.family->name.toLatin1();
- xlfd += '-';
- xlfd += desc.style->weightName ? desc.style->weightName : "*";
- xlfd += '-';
- xlfd += (desc.style->key.style == QFont::StyleItalic
- ? 'i'
- : (desc.style->key.style == QFont::StyleOblique ? 'o' : 'r'));
- xlfd += '-';
- xlfd += desc.style->setwidthName ? desc.style->setwidthName : "*";
- // ### handle add-style
- xlfd += "-*-";
- xlfd += QByteArray::number(px);
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->xpoint);
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->xres);
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->yres);
- xlfd += '-';
- xlfd += desc.encoding->pitch;
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->avgwidth);
- xlfd += '-';
- xlfd += xlfd_for_id(desc.encoding->encoding);
-
- FM_DEBUG(" using XLFD: %s\n", xlfd.data());
-
- const int mib = xlfd_encoding[desc.encoding->encoding].mib;
- XFontStruct *xfs;
- if ((xfs = XLoadQueryFont(QX11Info::display(), xlfd))) {
- fe = new QFontEngineXLFD(xfs, xlfd, mib);
- const int dpi = QX11Info::appDpiY();
- if (!qt_fillFontDef(xfs, &fe->fontDef, dpi, &desc)
- && !qt_fillFontDef(xlfd, &fe->fontDef, dpi, &desc)) {
- initFontDef(desc, request, &fe->fontDef);
- }
- }
- }
- if (!fe) {
- fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = QFontDef();
- }
- } else {
- QList<int> encodings;
- if (desc.encoding) {
- if (desc.encoding->encoding >= 0)
- encodings.append(int(desc.encoding->encoding));
- }
-
- if (desc.size) {
- // append all other encodings for the matched font
- for (int i = 0; i < desc.size->count; ++i) {
- QtFontEncoding *e = desc.size->encodings + i;
- if (e == desc.encoding || e->encoding < 0)
- continue;
- encodings.append(int(e->encoding));
- }
- }
- // fill in the missing encodings
- const XlfdEncoding *enc = xlfd_encoding;
- for (; enc->name; ++enc) {
- if (!encodings.contains(enc->id) && enc->id >= 0) {
- encodings.append(enc->id);
- }
- }
-
-#if defined(FONT_MATCH_DEBUG)
- FM_DEBUG(" using MultiXLFD, encodings:");
- for (int i = 0; i < encodings.size(); ++i) {
- const int id = encodings.at(i);
- FM_DEBUG(" %2d: %s", xlfd_encoding[id].id, xlfd_encoding[id].name);
- }
-#endif
-
- fe = new QFontEngineMultiXLFD(request, encodings, screen);
- }
- return fe;
-}
-
-#if (defined(QT_ARCH_ARM) || defined(QT_ARCH_ARMV6)) && defined(Q_CC_GNU) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
-#define NEEDS_GCC_BUG_WORKAROUND
-#endif
-
-#ifdef NEEDS_GCC_BUG_WORKAROUND
-static inline void gccBugWorkaround(const QFontDef &req)
-{
- char buffer[8];
- snprintf(buffer, 8, "%f", req.pixelSize);
-}
-#endif
-
-/*! \internal
- Loads a QFontEngine for the specified \a script that matches the
- QFontDef \e request member variable.
-*/
-void QFontDatabase::load(const QFontPrivate *d, int script)
-{
- Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
-
- // normalize the request to get better caching
- QFontDef req = d->request;
- if (req.pixelSize <= 0)
- req.pixelSize = qFloor(qt_pixelSize(req.pointSize, d->dpi) * 100.0 + 0.5) * 0.01;
- if (req.pixelSize < 1)
- req.pixelSize = 1;
-
-#ifdef NEEDS_GCC_BUG_WORKAROUND
- // req.pixelSize ends up with a bogus value unless this workaround is called
- gccBugWorkaround(req);
-#endif
-
- 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;
-
- // set it to the actual pointsize, so QFontInfo will do the right thing
- if (req.pointSize < 0)
- req.pointSize = qt_pointSize(req.pixelSize, d->dpi);
-
-
- QFontEngine *fe = QFontCache::instance()->findEngine(key);
-
- if (!fe) {
- QMutexLocker locker(fontDatabaseMutex());
- if (!privateDb()->count)
- initializeDb();
-
- const bool mainThread = (qApp->thread() == QThread::currentThread());
- if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
- fe = new QTestFontEngine(req.pixelSize);
- fe->fontDef = req;
- } else if (d->rawMode) {
- if (mainThread)
- fe = loadRaw(d, req);
-#ifndef QT_NO_FONTCONFIG
- } else if (X11->has_fontconfig) {
- fe = loadFc(d, script, req);
-#endif
- } else if (mainThread && qt_is_gui_used) {
- fe = loadXlfd(d->screen, script, req);
- }
- if (!fe) {
- fe = new QFontEngineBox(req.pixelSize);
- fe->fontDef = QFontDef();
- }
- }
- if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
- for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
- if (!d->engineData->engines[i]) {
- d->engineData->engines[i] = fe;
- fe->ref.ref();
- }
- }
- } else {
- d->engineData->engines[script] = fe;
- fe->ref.ref();
- }
- QFontCache::instance()->insertEngine(key, fe);
-}
-
-// Needed for fontconfig version < 2.2.97
-#ifndef FC_FAMILYLANG
-#define FC_FAMILYLANG "familylang"
-#endif
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
-{
-#if defined(QT_NO_FONTCONFIG)
- return;
-#else
- if (!X11->has_fontconfig)
- return;
-
- FcConfig *config = FcConfigGetCurrent();
- if (!config)
- return;
-
- FcFontSet *set = FcConfigGetFonts(config, FcSetApplication);
- if (!set) {
- FcConfigAppFontAddFile(config, (const FcChar8 *)":/non-existent");
- set = FcConfigGetFonts(config, FcSetApplication); // try again
- if (!set)
- return;
- }
-
- QString fileNameForQuery = fnt->fileName;
-#if FC_VERSION < 20402
- QTemporaryFile tmp;
-
- if (!fnt->data.isEmpty()) {
- if (!tmp.open())
- return;
- tmp.write(fnt->data);
- tmp.flush();
- fileNameForQuery = tmp.fileName();
- }
-#endif
-
- int id = 0;
- FcBlanks *blanks = FcConfigGetBlanks(0);
- int count = 0;
-
- QStringList families;
- QFontDatabasePrivate *db = privateDb();
-
- FcPattern *pattern = 0;
- do {
- pattern = queryFont((const FcChar8 *)QFile::encodeName(fileNameForQuery).constData(),
- fnt->data, id, blanks, &count);
- if (!pattern)
- return;
-
- FcPatternDel(pattern, FC_FILE);
- QByteArray cs = fnt->fileName.toUtf8();
- FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
-
- FcChar8 *fam = 0, *familylang = 0;
- int i, n = 0;
- for (i = 0; ; i++) {
- if (FcPatternGetString(pattern, FC_FAMILYLANG, i, &familylang) != FcResultMatch)
- break;
- QString familyLang = QString::fromUtf8((const char *) familylang);
- if (familyLang.compare(db->systemLang, Qt::CaseInsensitive) == 0) {
- n = i;
- break;
- }
- }
-
- if (FcPatternGetString(pattern, FC_FAMILY, n, &fam) == FcResultMatch) {
- QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
- families << family;
- }
-
- if (!FcFontSetAdd(set, pattern))
- return;
-
- ++id;
- } while (pattern && id < count);
-
- fnt->families = families;
-#endif
-}
-
-bool QFontDatabase::removeApplicationFont(int handle)
-{
-#if defined(QT_NO_FONTCONFIG)
- return false;
-#else
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (handle < 0 || handle >= db->applicationFonts.count())
- return false;
-
- FcConfigAppFontClear(0);
-
- db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
-
- db->reregisterAppFonts = true;
- db->invalidate();
- return true;
-#endif
-}
-
-bool QFontDatabase::removeAllApplicationFonts()
-{
-#if defined(QT_NO_FONTCONFIG)
- return false;
-#else
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (db->applicationFonts.isEmpty())
- return false;
-
- FcConfigAppFontClear(0);
- db->applicationFonts.clear();
- db->invalidate();
- return true;
-#endif
-}
-
-bool QFontDatabase::supportsThreadedFontRendering()
-{
-#if defined(QT_NO_FONTCONFIG)
- return false;
-#else
- return X11->has_fontconfig;
-#endif
-}
-
-QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
-{
-#if defined(QT_NO_FONTCONFIG)
- return family;
-#else
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return family;
-
- QByteArray cs = family.toUtf8();
- FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData());
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcChar8 *familyAfterSubstitution;
- FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
- QString resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
- FcPatternDestroy(pattern);
-
- return resolved;
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qfontengine_x11.cpp b/src/widgets/platforms/x11/qfontengine_x11.cpp
deleted file mode 100644
index be421976fa..0000000000
--- a/src/widgets/platforms/x11/qfontengine_x11.cpp
+++ /dev/null
@@ -1,1205 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbitmap.h"
-
-// #define FONTENGINE_DEBUG
-
-#include <qapplication.h>
-#include <qbytearray.h>
-#include <qdebug.h>
-#include <qtextcodec.h>
-#include <qthread.h>
-
-#include "qfontdatabase.h"
-#include "qpaintdevice.h"
-#include "qpainter.h"
-#include "qvarlengtharray.h"
-#include "qwidget.h"
-#include "qsettings.h"
-#include "qfile.h"
-
-#include <private/qpaintengine_x11_p.h>
-#include "qfont.h"
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include <qhash.h>
-
-#include <private/qpainter_p.h>
-#include <private/qunicodetables_p.h>
-
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#include "qx11info_x11.h"
-#include "qfontengine_x11_p.h"
-
-#include <limits.h>
-
-#include <ft2build.h>
-#if defined(FT_LCD_FILTER_H)
-#include FT_LCD_FILTER_H
-#endif
-
-#if defined(FC_LCD_FILTER)
-
-#ifndef FC_LCD_FILTER_NONE
-#define FC_LCD_FILTER_NONE FC_LCD_NONE
-#endif
-
-#ifndef FC_LCD_FILTER_DEFAULT
-#define FC_LCD_FILTER_DEFAULT FC_LCD_DEFAULT
-#endif
-
-#ifndef FC_LCD_FILTER_LIGHT
-#define FC_LCD_FILTER_LIGHT FC_LCD_LIGHT
-#endif
-
-#ifndef FC_LCD_FILTER_LEGACY
-#define FC_LCD_FILTER_LEGACY FC_LCD_LEGACY
-#endif
-
-#endif
-
-QT_BEGIN_NAMESPACE
-
-
-// ------------------------------------------------------------------
-// Multi XLFD engine
-// ------------------------------------------------------------------
-
-QFontEngineMultiXLFD::QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s)
- : QFontEngineMulti(l.size()), encodings(l), screen(s), request(r)
-{
- loadEngine(0);
- fontDef = engines[0]->fontDef;
-}
-
-QFontEngineMultiXLFD::~QFontEngineMultiXLFD()
-{ }
-
-void QFontEngineMultiXLFD::loadEngine(int at)
-{
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
- const int encoding = encodings.at(at);
- QFontEngine *fontEngine = QFontDatabase::loadXlfd(0, QUnicodeTables::Common, request, encoding);
- Q_ASSERT(fontEngine != 0);
- fontEngine->ref.ref();
- engines[at] = fontEngine;
-}
-
-// ------------------------------------------------------------------
-// Xlfd font engine
-// ------------------------------------------------------------------
-
-#ifndef QT_NO_FREETYPE
-
-static QStringList *qt_fontpath = 0;
-
-static QStringList fontPath()
-{
- if (qt_fontpath)
- return *qt_fontpath;
-
- // append qsettings fontpath
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
-
- QStringList fontpath;
-
- int npaths;
- char** font_path;
- font_path = XGetFontPath(X11->display, &npaths);
- bool xfsconfig_read = false;
- for (int i=0; i<npaths; i++) {
- // If we're using xfs, append font paths from /etc/X11/fs/config
- // can't hurt, and chances are we'll get all fonts that way.
- if (((font_path[i])[0] != '/') && !xfsconfig_read) {
- // We're using xfs -> read its config
- bool finished = false;
- QFile f(QLatin1String("/etc/X11/fs/config"));
- if (!f.exists())
- f.setFileName(QLatin1String("/usr/X11R6/lib/X11/fs/config"));
- if (!f.exists())
- f.setFileName(QLatin1String("/usr/X11/lib/X11/fs/config"));
- if (f.exists()) {
- f.open(QIODevice::ReadOnly);
- while (f.error()==QFile::NoError && !finished) {
- QString fs = QString::fromLocal8Bit(f.readLine(1024));
- fs=fs.trimmed();
- if (fs.left(9)==QLatin1String("catalogue") && fs.contains(QLatin1Char('='))) {
- fs = fs.mid(fs.indexOf(QLatin1Char('=')) + 1).trimmed();
- bool end = false;
- while (f.error()==QFile::NoError && !end) {
- if (fs[int(fs.length())-1] == QLatin1Char(','))
- fs = fs.left(fs.length()-1);
- else
- end = true;
-
- fs = fs.left(fs.indexOf(QLatin1String(":unscaled")));
- if (fs[0] != QLatin1Char('#'))
- fontpath += fs;
- fs = QLatin1String(f.readLine(1024));
- fs = fs.trimmed();
- if (fs.isEmpty())
- end = true;
- }
- finished = true;
- }
- }
- f.close();
- }
- xfsconfig_read = true;
- } else {
- QString fs = QString::fromLocal8Bit(font_path[i]);
- fontpath += fs.left(fs.indexOf(QLatin1String(":unscaled")));
- }
- }
- XFreeFontPath(font_path);
-
- // append qsettings fontpath
- QStringList fp = settings.value(QLatin1String("fontPath")).toStringList();
- if (!fp.isEmpty())
- fontpath += fp;
-
- qt_fontpath = new QStringList(fontpath);
- return fontpath;
-}
-
-static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth)
-{
- *freetype = 0;
- *synth = 0;
-
- QByteArray xname = _xname.toLower();
-
- int pos = 0;
- int minus = 0;
- while (minus < 5 && (pos = xname.indexOf('-', pos + 1)))
- ++minus;
- QByteArray searchname = xname.left(pos);
- while (minus < 12 && (pos = xname.indexOf('-', pos + 1)))
- ++minus;
- QByteArray encoding = xname.mid(pos + 1);
- //qDebug("xname='%s', searchname='%s', encoding='%s'", xname.data(), searchname.data(), encoding.data());
- QStringList fontpath = fontPath();
- QFontEngine::FaceId face_id;
- face_id.index = 0;
-
- QByteArray best_mapping;
-
- for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) {
- if (!(*it).startsWith(QLatin1Char('/')))
- continue; // not a path name, a font server
- QString fontmapname;
- int num = 0;
- // search font.dir and font.scale for the right file
- while (num < 2) {
- if (num == 0)
- fontmapname = (*it) + QLatin1String("/fonts.scale");
- else
- fontmapname = (*it) + QLatin1String("/fonts.dir");
- ++num;
- //qWarning(fontmapname);
- QFile fontmap(fontmapname);
- if (!fontmap.open(QIODevice::ReadOnly))
- continue;
- while (!fontmap.atEnd()) {
- QByteArray mapping = fontmap.readLine();
- QByteArray lmapping = mapping.toLower();
-
- //qWarning(xfontname);
- //qWarning(mapping);
- if (!lmapping.contains(searchname))
- continue;
- int index = mapping.indexOf(' ');
- QByteArray ffn = mapping.mid(0,index);
- // remove bitmap formats freetype can't handle
- if (ffn.contains(".spd") || ffn.contains(".phont"))
- continue;
- bool best_match = false;
- if (!best_mapping.isEmpty()) {
- if (lmapping.contains("-0-0-0-0-")) { // scalable font
- best_match = true;
- goto found;
- }
- if (lmapping.contains(encoding) && !best_mapping.toLower().contains(encoding))
- goto found;
- continue;
- }
-
- found:
- int colon = ffn.lastIndexOf(':');
- if (colon != -1) {
- QByteArray s = ffn.left(colon);
- ffn = ffn.mid(colon + 1);
- if (s.contains("ds="))
- *synth |= QFontEngine::SynthesizedBold;
- if (s.contains("ai="))
- *synth |= QFontEngine::SynthesizedItalic;
- }
- face_id.filename = (*it).toLocal8Bit() + '/' + ffn;
- best_mapping = mapping;
- if (best_match)
- goto end;
- }
- }
- }
-end:
-// qDebug("fontfile for %s is from '%s'\n got %s synth=%d", xname.data(),
-// best_mapping.data(), face_id.filename.data(), *synth);
- *freetype = QFreetypeFace::getFace(face_id);
- if (!*freetype) {
- face_id.index = 0;
- face_id.filename = QByteArray();
- }
- return face_id;
-}
-
-#endif // QT_NO_FREETYPE
-
-// defined in qfontdatabase_x11.cpp
-extern int qt_mib_for_xlfd_encoding(const char *encoding);
-extern int qt_xlfd_encoding_id(const char *encoding);
-
-static inline XCharStruct *charStruct(XFontStruct *xfs, uint ch)
-{
- XCharStruct *xcs = 0;
- unsigned char r = ch>>8;
- unsigned char c = ch&0xff;
- if (xfs->per_char &&
- r >= xfs->min_byte1 &&
- r <= xfs->max_byte1 &&
- c >= xfs->min_char_or_byte2 &&
- c <= xfs->max_char_or_byte2) {
- xcs = xfs->per_char + ((r - xfs->min_byte1) *
- (xfs->max_char_or_byte2 -
- xfs->min_char_or_byte2 + 1)) +
- (c - xfs->min_char_or_byte2);
- if (xcs->width == 0 && xcs->ascent == 0 && xcs->descent == 0)
- xcs = 0;
- }
- return xcs;
-}
-
-QFontEngineXLFD::QFontEngineXLFD(XFontStruct *fs, const QByteArray &name, int mib)
- : _fs(fs), _name(name), _codec(0), _cmap(mib)
-{
- if (_cmap) _codec = QTextCodec::codecForMib(_cmap);
-
- cache_cost = (((fs->max_byte1 - fs->min_byte1) *
- (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) +
- fs->max_char_or_byte2 - fs->min_char_or_byte2);
- cache_cost = ((fs->max_bounds.ascent + fs->max_bounds.descent) *
- (fs->max_bounds.width * cache_cost / 8));
- lbearing = SHRT_MIN;
- rbearing = SHRT_MIN;
- face_id.index = -1;
- freetype = 0;
- synth = 0;
-}
-
-QFontEngineXLFD::~QFontEngineXLFD()
-{
- XFreeFont(QX11Info::display(), _fs);
- _fs = 0;
-#ifndef QT_NO_FREETYPE
- if (freetype)
- freetype->release(face_id);
-#endif
-}
-
-bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- // filter out surrogates, we can't handle them anyway with XLFD fonts
- QVarLengthArray<ushort> _s(len);
- QChar *str = (QChar *)_s.data();
- for (int i = 0; i < len; ++i) {
- if (i < len - 1
- && s[i].unicode() >= 0xd800 && s[i].unicode() < 0xdc00
- && s[i+1].unicode() >= 0xdc00 && s[i].unicode() < 0xe000) {
- *str = QChar();
- ++i;
- } else {
- *str = s[i];
- }
- ++str;
- }
-
- len = str - (QChar *)_s.data();
- str = (QChar *)_s.data();
-
- bool mirrored = flags & QTextEngine::RightToLeft;
- if (_codec) {
- bool haveNbsp = false;
- for (int i = 0; i < len; i++)
- if (str[i].unicode() == 0xa0) {
- haveNbsp = true;
- break;
- }
-
- QVarLengthArray<unsigned short> ch(len);
- QChar *chars = (QChar *)ch.data();
- if (haveNbsp || mirrored) {
- for (int i = 0; i < len; i++)
- chars[i] = (str[i].unicode() == 0xa0 ? 0x20 :
- (mirrored ? QChar::mirroredChar(str[i].unicode()) : str[i].unicode()));
- } else {
- for (int i = 0; i < len; i++)
- chars[i] = str[i].unicode();
- }
- QTextCodec::ConverterState state;
- state.flags = QTextCodec::ConvertInvalidToNull;
- QByteArray ba = _codec->fromUnicode(chars, len, &state);
- if (ba.length() == 2*len) {
- // double byte encoding
- const uchar *data = (const uchar *)ba.constData();
- for (int i = 0; i < len; i++) {
- glyphs->glyphs[i] = ((ushort)data[0] << 8) + data[1];
- data += 2;
- }
- } else {
- const uchar *data = (const uchar *)ba.constData();
- for (int i = 0; i < len; i++)
- glyphs->glyphs[i] = (ushort)data[i];
- }
- } else {
- int i = len;
- const QChar *c = str + len;
- if (mirrored) {
- while (c != str)
- glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : QChar::mirroredChar(c->unicode());
- } else {
- while (c != str)
- glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode();
- }
- }
- *nglyphs = len;
- glyphs->numGlyphs = len;
-
- if (!(flags & QTextEngine::GlyphIndicesOnly))
- recalcAdvances(glyphs, flags);
- return true;
-}
-
-void QFontEngineXLFD::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags /*flags*/) const
-{
- int i = glyphs->numGlyphs;
- XCharStruct *xcs;
- // inlined for better performance
- if (!_fs->per_char) {
- xcs = &_fs->min_bounds;
- while (i != 0) {
- --i;
- const unsigned char r = glyphs->glyphs[i] >> 8;
- const unsigned char c = glyphs->glyphs[i] & 0xff;
- if (r >= _fs->min_byte1 &&
- r <= _fs->max_byte1 &&
- c >= _fs->min_char_or_byte2 &&
- c <= _fs->max_char_or_byte2) {
- glyphs->advances_x[i] = xcs->width;
- } else {
- glyphs->glyphs[i] = 0;
- }
- }
- }
- else if (!_fs->max_byte1) {
- XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2;
- while (i != 0) {
- unsigned int gl = glyphs->glyphs[--i];
- xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ?
- base + gl : 0;
- if (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) {
- glyphs->glyphs[i] = 0;
- } else {
- glyphs->advances_x[i] = xcs->width;
- }
- }
- }
- else {
- while (i != 0) {
- xcs = charStruct(_fs, glyphs->glyphs[--i]);
- if (!xcs) {
- glyphs->glyphs[i] = 0;
- } else {
- glyphs->advances_x[i] = xcs->width;
- }
- }
- }
-}
-
-glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout &glyphs)
-{
- int i;
-
- glyph_metrics_t overall;
- // initialize with line height, we get the same behaviour on all platforms
- overall.y = -ascent();
- overall.height = ascent() + descent() + 1;
- QFixed ymax;
- QFixed xmax;
- for (i = 0; i < glyphs.numGlyphs; i++) {
- XCharStruct *xcs = charStruct(_fs, glyphs.glyphs[i]);
- if (xcs) {
- QFixed x = overall.xoff + glyphs.offsets[i].x + xcs->lbearing;
- QFixed y = overall.yoff + glyphs.offsets[i].y - xcs->ascent;
- overall.x = qMin(overall.x, x);
- overall.y = qMin(overall.y, y);
- // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
- xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing);
- ymax = qMax(ymax, y + xcs->ascent + xcs->descent);
- overall.xoff += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- } else {
- QFixed size = _fs->ascent;
- overall.x = qMin(overall.x, overall.xoff);
- overall.y = qMin(overall.y, overall.yoff - size);
- ymax = qMax(ymax, overall.yoff);
- overall.xoff += size;
- xmax = qMax(xmax, overall.xoff);
- }
- }
- overall.height = qMax(overall.height, ymax - overall.y);
- overall.width = xmax - overall.x;
-
- return overall;
-}
-
-glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph)
-{
- glyph_metrics_t gm;
- XCharStruct *xcs = charStruct(_fs, glyph);
- if (xcs) {
- // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
- // XCharStruct::width is defined as the advance
- gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,
- xcs->width, 0);
- } else {
- QFixed size = ascent();
- gm = glyph_metrics_t(0, size, size, size, size, 0);
- }
- return gm;
-}
-
-QFixed QFontEngineXLFD::ascent() const
-{
- return _fs->ascent;
-}
-
-QFixed QFontEngineXLFD::descent() const
-{
- return (_fs->descent-1);
-}
-
-QFixed QFontEngineXLFD::leading() const
-{
- QFixed l = QFixed(qMin<int>(_fs->ascent, _fs->max_bounds.ascent)
- + qMin<int>(_fs->descent, _fs->max_bounds.descent)) * QFixed::fromReal(0.15);
- return l.ceil();
-}
-
-qreal QFontEngineXLFD::maxCharWidth() const
-{
- return _fs->max_bounds.width;
-}
-
-
-// Loads the font for the specified script
-static inline int maxIndex(XFontStruct *f) {
- return (((f->max_byte1 - f->min_byte1) *
- (f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) +
- f->max_char_or_byte2 - f->min_char_or_byte2);
-}
-
-qreal QFontEngineXLFD::minLeftBearing() const
-{
- if (lbearing == SHRT_MIN) {
- if (_fs->per_char) {
- XCharStruct *cs = _fs->per_char;
- int nc = maxIndex(_fs) + 1;
- int mx = cs->lbearing;
-
- for (int c = 1; c < nc; c++) {
- // ignore the bearings for characters whose ink is
- // completely outside the normal bounding box
- if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
- (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
- continue;
-
- int nmx = cs[c].lbearing;
-
- if (nmx < mx)
- mx = nmx;
- }
-
- ((QFontEngineXLFD *)this)->lbearing = mx;
- } else
- ((QFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing;
- }
- return lbearing;
-}
-
-qreal QFontEngineXLFD::minRightBearing() const
-{
- if (rbearing == SHRT_MIN) {
- if (_fs->per_char) {
- XCharStruct *cs = _fs->per_char;
- int nc = maxIndex(_fs) + 1;
- int mx = cs->rbearing;
-
- for (int c = 1; c < nc; c++) {
- // ignore the bearings for characters whose ink is
- // completely outside the normal bounding box
- if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
- (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
- continue;
-
- int nmx = cs[c].rbearing;
-
- if (nmx < mx)
- mx = nmx;
- }
-
- ((QFontEngineXLFD *)this)->rbearing = mx;
- } else
- ((QFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing;
- }
- return rbearing;
-}
-
-const char *QFontEngineXLFD::name() const
-{
- return _name;
-}
-
-bool QFontEngineXLFD::canRender(const QChar *string, int len)
-{
- QVarLengthGlyphLayoutArray glyphs(len);
- int nglyphs = len;
- if (stringToCMap(string, len, &glyphs, &nglyphs, 0) == false) {
- glyphs.resize(nglyphs);
- stringToCMap(string, len, &glyphs, &nglyphs, 0);
- }
-
- bool allExist = true;
- for (int i = 0; i < nglyphs; i++) {
- if (!glyphs.glyphs[i] || !charStruct(_fs, glyphs.glyphs[i])) {
- allExist = false;
- break;
- }
- }
-
- return allExist;
-}
-
-QBitmap QFontEngineXLFD::bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags)
-{
- int w = metrics.width.toInt();
- int h = metrics.height.toInt();
- if (w <= 0 || h <= 0)
- return QBitmap();
-
- QPlatformPixmap *data = new QX11PlatformPixmap(QPlatformPixmap::BitmapType);
- data->resize(w, h);
- QPixmap bm(data);
- QPainter p(&bm);
- p.fillRect(0, 0, w, h, Qt::color0);
- p.setPen(Qt::color1);
-
- QTextItemInt item;
- item.flags = flags;
- item.ascent = -metrics.y;
- item.descent = metrics.height - item.ascent;
- item.width = metrics.width;
- item.chars = 0;
- item.num_chars = 0;
- item.logClusters = 0;
- item.glyphs = glyphs;
- item.fontEngine = this;
- item.f = 0;
-
- p.drawTextItem(QPointF(-metrics.x.toReal(), item.ascent.toReal()), item);
- p.end();
-
- return QBitmap(bm);
-}
-
-void QFontEngineXLFD::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- // cannot use QFontEngine::addBitmapFontToPath(), since we don't
- // have direct access to the glyph bitmaps, so we have to draw
- // onto a QBitmap, then convert to QImage, then to path
- glyph_metrics_t metrics = boundingBox(glyphs);
-
- QImage image = bitmapForGlyphs(glyphs, metrics, flags).toImage();
- if (image.isNull())
- return;
-
- image = image.convertToFormat(QImage::Format_Mono);
- const uchar *image_data = image.bits();
- uint bpl = image.bytesPerLine();
- // from qfontengine.cpp
- extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data,
- int bpl, int w, int h, QPainterPath *path);
- qt_addBitmapToPath(x, y + metrics.y.toReal(), image_data, bpl, image.width(), image.height(), path);
-}
-
-QFontEngine::FaceId QFontEngineXLFD::faceId() const
-{
-#ifndef QT_NO_FREETYPE
- if (face_id.index == -1) {
- face_id = fontFile(_name, &freetype, &synth);
- if (_codec)
- face_id.encoding = _codec->mibEnum();
- if (freetype) {
- const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType();
- } else {
- face_id.index = 0;
- face_id.filename = '-' + QFontEngine::properties().postscriptName;
- }
- }
-#endif
-
- return face_id;
-}
-
-QFontEngine::Properties QFontEngineXLFD::properties() const
-{
- if (face_id.index == -1)
- (void)faceId();
-
-#ifndef QT_NO_FREETYPE
- if (freetype)
- return freetype->properties();
-#endif
- return QFontEngine::properties();
-}
-
-void QFontEngineXLFD::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
-{
- if (face_id.index == -1)
- (void)faceId();
-#ifndef QT_NO_FREETYPE
- if (!freetype)
-#endif
- {
- QFontEngine::getUnscaledGlyph(glyph, path, metrics);
- return;
- }
-
-#ifndef QT_NO_FREETYPE
- freetype->lock();
-
- FT_Face face = freetype->face;
- FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0);
- freetype->xsize = face->units_per_EM << 6;
- freetype->ysize = face->units_per_EM << 6;
- FT_Set_Transform(face, 0, 0);
- glyph = glyphIndexToFreetypeGlyphIndex(glyph);
- FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
-
- int left = face->glyph->metrics.horiBearingX;
- int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;
- int top = face->glyph->metrics.horiBearingY;
- int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;
-
- QFixedPoint p;
- p.x = 0;
- p.y = 0;
- metrics->width = QFixed::fromFixed(right-left);
- metrics->height = QFixed::fromFixed(top-bottom);
- metrics->x = QFixed::fromFixed(left);
- metrics->y = QFixed::fromFixed(-top);
- metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);
-
- if (!FT_IS_SCALABLE(freetype->face))
- QFreetypeFace::addBitmapToPath(face->glyph, p, path);
- else
- QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);
-
- FT_Set_Transform(face, &freetype->matrix, 0);
- freetype->unlock();
-#endif // QT_NO_FREETYPE
-}
-
-
-bool QFontEngineXLFD::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
-#ifndef QT_NO_FREETYPE
- if (face_id.index == -1)
- (void)faceId();
- if (!freetype)
- return false;
- return freetype->getSfntTable(tag, buffer, length);
-#else
- Q_UNUSED(tag);
- Q_UNUSED(buffer);
- Q_UNUSED(length);
- return false;
-#endif
-}
-
-int QFontEngineXLFD::synthesized() const
-{
- return synth;
-}
-
-QImage QFontEngineXLFD::alphaMapForGlyph(glyph_t glyph)
-{
- glyph_metrics_t metrics = boundingBox(glyph);
-
-/*
- printf("a) w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n",
- metrics.width.toReal(),
- metrics.height.toReal(),
- metrics.xoff.toReal(),
- metrics.yoff.toReal(),
- metrics.x.toReal(),
- metrics.y.toReal());
-*/
-
- QGlyphLayoutArray<1> glyphs;
- glyphs.glyphs[0] = glyph;
-
- QImage image = bitmapForGlyphs(glyphs, metrics).toImage();
-//image.save(QString::fromLatin1("x11cache-%1.png").arg((int)glyph));
-
- image = image.convertToFormat(QImage::Format_Indexed8);
- QVector<QRgb> colors(256);
- for (int i = 0; i < 256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- image.setColorTable(colors);
-
- int width = image.width();
- int height = image.height();
- for (int y = 0; y < height; ++y) {
- uchar *bits = image.scanLine(y);
- for (int x = 0; x < width; ++x)
- bits[x] = ~(bits[x]-1);
- }
-
- return image;
-}
-
-#ifndef QT_NO_FREETYPE
-
-FT_Face QFontEngineXLFD::non_locked_face() const
-{
- return freetype ? freetype->face : 0;
-}
-
-uint QFontEngineXLFD::toUnicode(glyph_t g) const
-{
- if (_codec) {
- QTextCodec::ConverterState state;
- state.flags = QTextCodec::ConvertInvalidToNull;
- uchar data[2];
- int l = 1;
- if (g > 255) {
- data[0] = (g >> 8);
- data[1] = (g & 255);
- l = 2;
- } else {
- data[0] = g;
- }
- QString s = _codec->toUnicode((char *)data, l, &state);
- Q_ASSERT(s.length() == 1);
- g = s.at(0).unicode();
- }
- return g;
-}
-
-glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const
-{
- return FT_Get_Char_Index(freetype->face, toUnicode(g));
-}
-#endif
-
-#ifndef QT_NO_FONTCONFIG
-
-// ------------------------------------------------------------------
-// Multi FT engine
-// ------------------------------------------------------------------
-
-static QFontEngine *engineForPattern(FcPattern *match, const QFontDef &request, int screen)
-{
- QFontEngineX11FT *engine = new QFontEngineX11FT(match, request, screen);
- if (!engine->invalid())
- return engine;
-
- delete engine;
- QFontEngine *fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = request;
- return fe;
-}
-
-QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *matchedPattern, FcPattern *p, int s, const QFontDef &req)
- : QFontEngineMulti(2), request(req), pattern(p), fontSet(0), screen(s)
-{
- firstEnginePattern = FcPatternDuplicate(matchedPattern);
- engines[0] = fe;
- engines.at(0)->ref.ref();
- fontDef = engines[0]->fontDef;
- cache_cost = 100;
- firstFontIndex = 1;
-}
-
-QFontEngineMultiFT::~QFontEngineMultiFT()
-{
- extern QMutex *qt_fontdatabase_mutex();
- QMutexLocker locker(qt_fontdatabase_mutex());
-
- FcPatternDestroy(pattern);
- if (firstEnginePattern)
- FcPatternDestroy(firstEnginePattern);
- if (fontSet)
- FcFontSetDestroy(fontSet);
-}
-
-
-void QFontEngineMultiFT::loadEngine(int at)
-{
- extern QMutex *qt_fontdatabase_mutex();
- QMutexLocker locker(qt_fontdatabase_mutex());
-
- extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &);
- extern FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request);
-
- Q_ASSERT(at > 0);
- if (!fontSet) {
- fontSet = qt_fontSetForPattern(pattern, request);
-
- // it may happen that the fontset of fallbacks consists of only one font. In this case we
- // have to fall back to the box fontengine as we cannot render the glyph.
- if (fontSet->nfont == 1 && at == 1 && engines.size() == 2) {
- Q_ASSERT(engines.at(at) == 0);
- QFontEngine *fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = request;
- engines[at] = fe;
- return;
- }
-
- if (firstEnginePattern) {
-
- if (!FcPatternEqual(firstEnginePattern, fontSet->fonts[0]))
- firstFontIndex = 0;
-
- FcPatternDestroy(firstEnginePattern);
- firstEnginePattern = 0;
- }
-
- engines.resize(fontSet->nfont + 1 - firstFontIndex);
- }
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
-
- FcPattern *match = FcFontRenderPrepare(NULL, pattern, fontSet->fonts[at + firstFontIndex - 1]);
- QFontDef fontDef = qt_FcPatternToQFontDef(match, this->request);
-
- // note: we use -1 for the script to make sure that we keep real
- // FT engines separate from Multi engines in the font cache
- QFontCache::Key key(fontDef, -1, screen);
- QFontEngine *fontEngine = QFontCache::instance()->findEngine(key);
- if (!fontEngine) {
- fontEngine = engineForPattern(match, request, screen);
- QFontCache::instance()->insertEngine(key, fontEngine);
- }
- FcPatternDestroy(match);
- fontEngine->ref.ref();
- engines[at] = fontEngine;
-}
-
-// ------------------------------------------------------------------
-// X11 FT engine
-// ------------------------------------------------------------------
-
-
-
-Q_WIDGETS_EXPORT void qt_x11ft_convert_pattern(FcPattern *pattern, QByteArray *file_name, int *index, bool *antialias)
-{
- FcChar8 *fileName;
- FcPatternGetString(pattern, FC_FILE, 0, &fileName);
- *file_name = (const char *)fileName;
- if (!FcPatternGetInteger(pattern, FC_INDEX, 0, index))
- index = 0;
- FcBool b;
- if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch)
- *antialias = b;
-}
-
-
-QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen)
- : QFontEngineFT(fd)
-{
-// FcPatternPrint(pattern);
-
- bool antialias = X11->fc_antialias;
- QByteArray file_name;
- int face_index;
- qt_x11ft_convert_pattern(pattern, &file_name, &face_index, &antialias);
- QFontEngine::FaceId face_id;
- face_id.filename = file_name;
- face_id.index = face_index;
-
- canUploadGlyphsToServer = QApplication::testAttribute(Qt::AA_X11InitThreads) || (qApp->thread() == QThread::currentThread());
-
- subpixelType = Subpixel_None;
- if (antialias) {
- int subpixel = X11->display ? X11->screens[screen].subpixel : FC_RGBA_UNKNOWN;
- if (subpixel == FC_RGBA_UNKNOWN)
- (void) FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel);
- if (!antialias || subpixel == FC_RGBA_UNKNOWN)
- subpixel = FC_RGBA_NONE;
-
- switch (subpixel) {
- case FC_RGBA_NONE: subpixelType = Subpixel_None; break;
- case FC_RGBA_RGB: subpixelType = Subpixel_RGB; break;
- case FC_RGBA_BGR: subpixelType = Subpixel_BGR; break;
- case FC_RGBA_VRGB: subpixelType = Subpixel_VRGB; break;
- case FC_RGBA_VBGR: subpixelType = Subpixel_VBGR; break;
- default: break;
- }
- }
-
- if (fd.hintingPreference != QFont::PreferDefaultHinting) {
- switch (fd.hintingPreference) {
- case QFont::PreferNoHinting:
- default_hint_style = HintNone;
- break;
- case QFont::PreferVerticalHinting:
- default_hint_style = HintLight;
- break;
- case QFont::PreferFullHinting:
- default:
- default_hint_style = HintFull;
- break;
- }
- }
-#ifdef FC_HINT_STYLE
- else {
- int hint_style = 0;
- // Try to use Xft.hintstyle from XDefaults first if running in GNOME, to match
- // the behavior of cairo
- if (X11->fc_hint_style > -1 && X11->desktopEnvironment == DE_GNOME)
- hint_style = X11->fc_hint_style;
- else if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch
- && X11->fc_hint_style > -1)
- hint_style = X11->fc_hint_style;
-
- switch (hint_style) {
- case FC_HINT_NONE:
- default_hint_style = HintNone;
- break;
- case FC_HINT_SLIGHT:
- default_hint_style = HintLight;
- break;
- case FC_HINT_MEDIUM:
- default_hint_style = HintMedium;
- break;
- default:
- default_hint_style = HintFull;
- break;
- }
- }
-#endif
-
-#if defined(FC_AUTOHINT) && defined(FT_LOAD_FORCE_AUTOHINT)
- {
- bool autohint = false;
-
- FcBool b;
- if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch)
- autohint = b;
-
- if (autohint)
- default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
- }
-#endif
-
-#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
- {
- int filter = FC_LCD_FILTER_NONE;
- if (FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter) == FcResultMatch) {
- switch (filter) {
- case FC_LCD_FILTER_NONE:
- lcdFilterType = FT_LCD_FILTER_NONE;
- break;
- case FC_LCD_FILTER_DEFAULT:
- lcdFilterType = FT_LCD_FILTER_DEFAULT;
- break;
- case FC_LCD_FILTER_LIGHT:
- lcdFilterType = FT_LCD_FILTER_LIGHT;
- break;
- case FC_LCD_FILTER_LEGACY:
- lcdFilterType = FT_LCD_FILTER_LEGACY;
- break;
- default:
- // new unknown lcd filter type?!
- break;
- }
- }
- }
-#endif
-
-#ifdef FC_EMBEDDED_BITMAP
- {
- FcBool b;
- if (FcPatternGetBool(pattern, FC_EMBEDDED_BITMAP, 0, &b) == FcResultMatch)
- embeddedbitmap = b;
- }
-#endif
-
- GlyphFormat defaultFormat = Format_None;
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- int format = PictStandardA8;
- if (!antialias)
- format = PictStandardA1;
- else if (subpixelType == Subpixel_RGB
- || subpixelType == Subpixel_BGR
- || subpixelType == Subpixel_VRGB
- || subpixelType == Subpixel_VBGR)
- format = PictStandardARGB32;
- xglyph_format = format;
-
- if (subpixelType != QFontEngineFT::Subpixel_None)
- defaultFormat = Format_A32;
- else if (antialias)
- defaultFormat = Format_A8;
- else
- defaultFormat = Format_Mono;
- }
-#endif
-
- if (!init(face_id, antialias, defaultFormat))
- return;
-
- if (!freetype->charset) {
- FcCharSet *cs;
- FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs);
- freetype->charset = FcCharSetCopy(cs);
- }
-}
-
-QFontEngineX11FT::~QFontEngineX11FT()
-{
- freeGlyphSets();
-}
-
-unsigned long QFontEngineX11FT::allocateServerGlyphSet()
-{
-#ifndef QT_NO_XRENDER
- if (!canUploadGlyphsToServer || !X11->use_xrender)
- return 0;
- return XRenderCreateGlyphSet(X11->display, XRenderFindStandardFormat(X11->display, xglyph_format));
-#else
- return 0;
-#endif
-}
-
-void QFontEngineX11FT::freeServerGlyphSet(unsigned long id)
-{
-#ifndef QT_NO_XRENDER
- if (!id)
- return;
- XRenderFreeGlyphSet(X11->display, id);
-#endif
-}
-
-bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const
-{
-#ifndef QT_NO_XRENDER
- if (!canUploadGlyphsToServer)
- return false;
- if (g->format == Format_Mono) {
- /*
- * swap bit order around; FreeType is always MSBFirst
- */
- if (BitmapBitOrder(X11->display) != MSBFirst) {
- unsigned char *line = g->data;
- int i = glyphDataSize;
- while (i--) {
- unsigned char c;
- c = *line;
- c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
- c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
- c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
- *line++ = c;
- }
- }
- }
-
- ::Glyph xglyph = glyphid;
- XRenderAddGlyphs (X11->display, set->id, &xglyph, info, 1, (const char *)g->data, glyphDataSize);
- delete [] g->data;
- g->data = 0;
- g->format = Format_None;
- g->uploadedToServer = true;
- return true;
-#else
- return false;
-#endif
-}
-
-QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
-{
- QFontDef fontDef;
- fontDef.pixelSize = pixelSize;
- QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
- if (!fe->initFromFontEngine(this)) {
- delete fe;
- return 0;
- } else {
-#ifndef QT_NO_XRENDER
- fe->xglyph_format = xglyph_format;
-#endif
- return fe;
- }
-}
-
-#endif // QT_NO_FONTCONFIG
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qfontengine_x11_p.h b/src/widgets/platforms/x11/qfontengine_x11_p.h
deleted file mode 100644
index b12fbc28d4..0000000000
--- a/src/widgets/platforms/x11/qfontengine_x11_p.h
+++ /dev/null
@@ -1,180 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTENGINE_X11_P_H
-#define QFONTENGINE_X11_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 <private/qt_x11_p.h>
-
-#include <private/qfontengine_ft_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFreetypeFace;
-
-// --------------------------------------------------------------------------
-
-class QFontEngineMultiXLFD : public QFontEngineMulti
-{
-public:
- QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s);
- ~QFontEngineMultiXLFD();
-
- void loadEngine(int at);
-
-private:
- QList<int> encodings;
- int screen;
- QFontDef request;
-};
-
-/**
- * \internal The font engine for X Logical Font Description (XLFD) fonts, which is for X11 systems without freetype.
- */
-class QFontEngineXLFD : public QFontEngine
-{
-public:
- QFontEngineXLFD(XFontStruct *f, const QByteArray &name, int mib);
- ~QFontEngineXLFD();
-
- virtual QFontEngine::FaceId faceId() const;
- QFontEngine::Properties properties() const;
- virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
- virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
- virtual int synthesized() const;
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
- QTextEngine::ShaperFlags flags) const;
- virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
-
- virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- virtual glyph_metrics_t boundingBox(glyph_t glyph);
-
- virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags);
- virtual QFixed ascent() const;
- virtual QFixed descent() const;
- virtual QFixed leading() const;
- virtual qreal maxCharWidth() const;
- virtual qreal minLeftBearing() const;
- virtual qreal minRightBearing() const;
- virtual QImage alphaMapForGlyph(glyph_t);
-
- virtual inline Type type() const
- { return QFontEngine::XLFD; }
-
- virtual bool canRender(const QChar *string, int len);
- virtual const char *name() const;
-
- inline XFontStruct *fontStruct() const
- { return _fs; }
-
-#ifndef QT_NO_FREETYPE
- FT_Face non_locked_face() const;
- glyph_t glyphIndexToFreetypeGlyphIndex(glyph_t g) const;
-#endif
- uint toUnicode(glyph_t g) const;
-
-private:
- QBitmap bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags = 0);
-
- XFontStruct *_fs;
- QByteArray _name;
- QTextCodec *_codec;
- int _cmap;
- int lbearing, rbearing;
- mutable QFontEngine::FaceId face_id;
- mutable QFreetypeFace *freetype;
- mutable int synth;
-};
-
-#ifndef QT_NO_FONTCONFIG
-
-class Q_WIDGETS_EXPORT QFontEngineMultiFT : public QFontEngineMulti
-{
-public:
- QFontEngineMultiFT(QFontEngine *fe, FcPattern *firstEnginePattern, FcPattern *p, int s, const QFontDef &request);
- ~QFontEngineMultiFT();
-
- void loadEngine(int at);
-
-private:
- QFontDef request;
- FcPattern *pattern;
- FcPattern *firstEnginePattern;
- FcFontSet *fontSet;
- int screen;
- int firstFontIndex; // first font in fontset
-};
-
-class Q_WIDGETS_EXPORT QFontEngineX11FT : public QFontEngineFT
-{
-public:
- explicit QFontEngineX11FT(const QFontDef &fontDef) : QFontEngineFT(fontDef) {}
- explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
- ~QFontEngineX11FT();
-
- QFontEngine *cloneWithSize(qreal pixelSize) const;
-
-#ifndef QT_NO_XRENDER
- int xglyph_format;
-#endif
-
-protected:
- virtual bool uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const;
- virtual unsigned long allocateServerGlyphSet();
- virtual void freeServerGlyphSet(unsigned long id);
-};
-
-#endif // QT_NO_FONTCONFIG
-
-QT_END_NAMESPACE
-
-#endif // QFONTENGINE_X11_P_H
diff --git a/src/widgets/platforms/x11/qkde.cpp b/src/widgets/platforms/x11/qkde.cpp
deleted file mode 100644
index b89951b5cd..0000000000
--- a/src/widgets/platforms/x11/qkde.cpp
+++ /dev/null
@@ -1,176 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qkde_p.h"
-#include <QtCore/QLibrary>
-#include <QtCore/QDir>
-#include <QtCore/qdebug.h>
-#include <QtCore/QSettings>
-#include "QtGui/qstylefactory.h"
-#include "qt_x11_p.h"
-
-#if defined(Q_WS_X11)
-
-QT_BEGIN_NAMESPACE
-
-/*! \internal
-Gets the current KDE home path
-like "/home/troll/.kde"
-*/
-QString QKde::kdeHome()
-{
- static QString kdeHomePath;
- if (kdeHomePath.isEmpty()) {
- kdeHomePath = QString::fromLocal8Bit(qgetenv("KDEHOME"));
- if (kdeHomePath.isEmpty()) {
- QDir homeDir(QDir::homePath());
- QString kdeConfDir(QLatin1String("/.kde"));
- if (4 == X11->desktopVersion && homeDir.exists(QLatin1String(".kde4")))
- kdeConfDir = QLatin1String("/.kde4");
- kdeHomePath = QDir::homePath() + kdeConfDir;
- }
- }
- return kdeHomePath;
-}
-
-/*!\internal
- Reads the color from the config, and store it in the palette with the given color role if found
- */
-static bool kdeColor(QPalette *pal, QPalette::ColorRole role, const QSettings &kdeSettings, const QString &kde4Key, const QString &kde3Key = QString())
-{
- QVariant variant = kdeSettings.value(kde4Key);
- if (!variant.isValid())
- QVariant variant = kdeSettings.value(kde3Key);
- if (variant.isValid()) {
- QStringList values = variant.toStringList();
- if (values.size() == 3) {
- int r = values[0].toInt();
- int g = values[1].toInt();
- int b = values[2].toInt();
- pal->setBrush(role, QColor(r, g, b));
- return true;
- }
- }
- return false;
-}
-
-
-/*!\internal
- Returns the KDE palette
-*/
-QPalette QKde::kdePalette()
-{
- const QSettings theKdeSettings(QKde::kdeHome() +
- QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
- QPalette pal;
-
- // Setup KDE palette
- kdeColor(&pal, QPalette::Button, theKdeSettings, QLatin1String("Colors:Button/BackgroundNormal"), QLatin1String("buttonBackground"));
- kdeColor(&pal, QPalette::Window, theKdeSettings, QLatin1String("Colors:Window/BackgroundNormal"), QLatin1String("background"));
- kdeColor(&pal, QPalette::Text, theKdeSettings, QLatin1String("Colors:View/ForegroundNormal"), QLatin1String("foreground"));
- kdeColor(&pal, QPalette::WindowText, theKdeSettings, QLatin1String("Colors:Window/ForegroundNormal"), QLatin1String("windowForeground"));
- kdeColor(&pal, QPalette::Base, theKdeSettings, QLatin1String("Colors:View/BackgroundNormal"), QLatin1String("windowBackground"));
- kdeColor(&pal, QPalette::Highlight, theKdeSettings, QLatin1String("Colors:Selection/BackgroundNormal"), QLatin1String("selectBackground"));
- kdeColor(&pal, QPalette::HighlightedText, theKdeSettings, QLatin1String("Colors:Selection/ForegroundNormal"), QLatin1String("selectForeground"));
- kdeColor(&pal, QPalette::AlternateBase, theKdeSettings, QLatin1String("Colors:View/BackgroundAlternate"), QLatin1String("alternateBackground"));
- kdeColor(&pal, QPalette::ButtonText, theKdeSettings, QLatin1String("Colors:Button/ForegroundNormal"), QLatin1String("buttonForeground"));
- kdeColor(&pal, QPalette::Link, theKdeSettings, QLatin1String("Colors:View/ForegroundLink"), QLatin1String("linkColor"));
- kdeColor(&pal, QPalette::LinkVisited, theKdeSettings, QLatin1String("Colors:View/ForegroundVisited"), QLatin1String("visitedLinkColor"));
- //## TODO tooltip color
-
- return pal;
-}
-
-/*!\internal
- Returns the name of the QStyle to use.
- (read from the kde config if needed)
-*/
-QString QKde::kdeStyle()
-{
- if (X11->desktopVersion >= 4) {
- QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
- QString style = kdeSettings.value(QLatin1String("widgetStyle"), QLatin1String("Oxygen")).toString();
-
- QStringList availableStyles = QStyleFactory::keys();
- if(availableStyles.contains(style, Qt::CaseInsensitive))
- return style;
- }
-
- if (X11->use_xrender)
- return QLatin1String("plastique");
- else
- return QLatin1String("windows");
-}
-
-
-int QKde::kdeToolButtonStyle()
-{
- QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"),
- QSettings::IniFormat);
- settings.beginGroup(QLatin1String("Toolbar style"));
- QString toolbarStyle = settings.value(QLatin1String("ToolButtonStyle"), QLatin1String("TextBesideIcon")).toString();
- if (toolbarStyle == QLatin1String("TextBesideIcon"))
- return Qt::ToolButtonTextBesideIcon;
- else if (toolbarStyle == QLatin1String("TextOnly"))
- return Qt::ToolButtonTextOnly;
- else if (toolbarStyle == QLatin1String("TextUnderIcon"))
- return Qt::ToolButtonTextUnderIcon;
-
- return Qt::ToolButtonTextBesideIcon;
-}
-
-int QKde::kdeToolBarIconSize()
-{
- static int iconSize = -1;
- if (iconSize == -1) {
- QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"),
- QSettings::IniFormat);
- settings.beginGroup(QLatin1String("ToolbarIcons"));
- iconSize = settings.value(QLatin1String("Size")).toInt();
- }
- return iconSize;
-}
-
-QT_END_NAMESPACE
-
-#endif //Q_WS_X11
-
diff --git a/src/widgets/platforms/x11/qkde_p.h b/src/widgets/platforms/x11/qkde_p.h
deleted file mode 100644
index 5abe824a72..0000000000
--- a/src/widgets/platforms/x11/qkde_p.h
+++ /dev/null
@@ -1,81 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKDE_H
-#define QKDE_H
-
-#include <QtCore/qglobal.h>
-#include <QtGui/QPalette>
-#include <QtWidgets/QIcon>
-
-//
-// 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.
-//
-#if defined(Q_WS_X11)
-
-
-QT_BEGIN_NAMESPACE
-
-/*!\internal
- This namespace contains helper function to help KDE integration
- They are only used if we detect the use of KDE and the KDE platform plugin is not found (old KDE version)
- Or if the detected KDE version is KDE3
-*/
-namespace QKde {
- QString kdeHome();
- QString kdeStyle();
- QPalette kdePalette();
- int kdeToolButtonStyle();
- int kdeToolBarIconSize();
-}
-
-
-QT_END_NAMESPACE
-
-#endif // Q_WS_X11
-#endif // QKDE_H
diff --git a/src/widgets/platforms/x11/qkeymapper_x11.cpp b/src/widgets/platforms/x11/qkeymapper_x11.cpp
deleted file mode 100644
index 7e348b3385..0000000000
--- a/src/widgets/platforms/x11/qkeymapper_x11.cpp
+++ /dev/null
@@ -1,1857 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkeymapper_p.h"
-
-#include "qdebug.h"
-#include "qtextcodec.h"
-#include "qwidget.h"
-
-#include "qapplication_p.h"
-#include "qevent_p.h"
-#include "qt_x11_p.h"
-
-#ifndef QT_NO_XKB
-# include <X11/XKBlib.h>
-#endif
-
-#define XK_MISCELLANY
-#define XK_LATIN1
-#define XK_KOREAN
-#define XK_XKB_KEYS
-#include <X11/keysymdef.h>
-
-#include <ctype.h>
-
-#ifdef QT_LINUXBASE
-// LSB's IsKeypadKey define is wrong - see
-// http://bugs.linuxbase.org/show_bug.cgi?id=2521
-#undef IsKeypadKey
-#define IsKeypadKey(keysym) \
- (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal))
-
-#undef IsPrivateKeypadKey
-#define IsPrivateKeypadKey(keysym) \
- (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_XKB
-
-// bring in the auto-generated xkbLayoutData
-#include "qkeymapper_x11_p.cpp"
-
-QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName)
-{
- int i = 0;
- while (xkbLayoutData[i].layout != 0) {
- if (layoutName == xkbLayoutData[i].layout && variantName == xkbLayoutData[i].variant)
- return QLocale(xkbLayoutData[i].language, xkbLayoutData[i].country);
- ++i;
- }
- return QLocale::c();
-}
-#endif // QT_NO_XKB
-
-// from qapplication_x11.cpp
-extern uchar qt_alt_mask;
-extern uchar qt_meta_mask;
-extern uchar qt_super_mask;
-extern uchar qt_hyper_mask;
-extern uchar qt_mode_switch_mask;
-uchar qt_num_lock_mask = 0;
-extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
-
-// ### we should really resolve conflicts with other masks by
-// ### decomposing the Qt::KeyboardModifers in possibleKeys()
-#define SETMASK(sym, mask) \
- do { \
- if (qt_alt_mask == 0 \
- && qt_meta_mask != mask \
- && qt_super_mask != mask \
- && qt_hyper_mask != mask \
- && (sym == XK_Alt_L || sym == XK_Alt_R)) { \
- qt_alt_mask = mask; \
- } \
- if (qt_meta_mask == 0 \
- && qt_alt_mask != mask \
- && qt_super_mask != mask \
- && qt_hyper_mask != mask \
- && (sym == XK_Meta_L || sym == XK_Meta_R)) { \
- qt_meta_mask = mask; \
- } \
- if (qt_super_mask == 0 \
- && qt_alt_mask != mask \
- && qt_meta_mask != mask \
- && qt_hyper_mask != mask \
- && (sym == XK_Super_L || sym == XK_Super_R)) { \
- qt_super_mask = mask; \
- } \
- if (qt_hyper_mask == 0 \
- && qt_alt_mask != mask \
- && qt_meta_mask != mask \
- && qt_super_mask != mask \
- && (sym == XK_Hyper_L || sym == XK_Hyper_R)) { \
- qt_hyper_mask = mask; \
- } \
- if (qt_mode_switch_mask == 0 \
- && qt_alt_mask != mask \
- && qt_meta_mask != mask \
- && qt_super_mask != mask \
- && qt_hyper_mask != mask \
- && sym == XK_Mode_switch) { \
- qt_mode_switch_mask = mask; \
- } \
- if (qt_num_lock_mask == 0 \
- && sym == XK_Num_Lock) { \
- qt_num_lock_mask = mask; \
- } \
- } while(false)
-
-// qt_XTranslateKey() is based on _XTranslateKey() taken from:
-
-/* $Xorg: KeyBind.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */
-
-/*
-
-Copyright 1985, 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-static int
-qt_XTranslateKey(register QXCoreDesc *dpy,
- KeyCode keycode,
- register unsigned int modifiers,
- unsigned int *modifiers_return,
- KeySym *keysym_return)
-{
- int per;
- register KeySym *syms;
- KeySym sym, lsym, usym;
-
- if (! dpy->keysyms)
- return 0;
- *modifiers_return = ((ShiftMask|LockMask)
- | dpy->mode_switch | dpy->num_lock);
- if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
- {
- *keysym_return = NoSymbol;
- return 1;
- }
- per = dpy->keysyms_per_keycode;
- syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
- while ((per > 2) && (syms[per - 1] == NoSymbol))
- per--;
- if ((per > 2) && (modifiers & dpy->mode_switch)) {
- syms += 2;
- per -= 2;
- }
- if ((modifiers & dpy->num_lock) &&
- (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
- if ((modifiers & ShiftMask) ||
- ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
- *keysym_return = syms[0];
- else
- *keysym_return = syms[1];
- } else if (!(modifiers & ShiftMask) &&
- (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
- if ((per == 1) || (syms[1] == NoSymbol))
- XConvertCase(syms[0], keysym_return, &usym);
- else
- *keysym_return = syms[0];
- } else if (!(modifiers & LockMask) ||
- (dpy->lock_meaning != XK_Caps_Lock)) {
- if ((per == 1) || ((usym = syms[1]) == NoSymbol))
- XConvertCase(syms[0], &lsym, &usym);
- *keysym_return = usym;
- } else {
- if ((per == 1) || ((sym = syms[1]) == NoSymbol))
- sym = syms[0];
- XConvertCase(sym, &lsym, &usym);
- if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
- ((sym != usym) || (lsym == usym)))
- XConvertCase(syms[0], &lsym, &usym);
- *keysym_return = usym;
- }
- if (*keysym_return == XK_VoidSymbol)
- *keysym_return = NoSymbol;
- return 1;
-}
-
-
-
-
-QKeyMapperPrivate::QKeyMapperPrivate()
- : keyboardInputDirection(Qt::LeftToRight), xkb_currentGroup(0)
-{
- memset(&coreDesc, 0, sizeof(coreDesc));
-
-#ifndef QT_NO_XKB
- if (X11->use_xkb) {
- // get the current group
- XkbStateRec xkbState;
- if (XkbGetState(X11->display, XkbUseCoreKbd, &xkbState) == Success)
- xkb_currentGroup = xkbState.group;
- }
-#endif
-}
-
-QKeyMapperPrivate::~QKeyMapperPrivate()
-{
- if (coreDesc.keysyms)
- XFree(coreDesc.keysyms);
-}
-
-QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *event)
-{
-#ifndef QT_NO_XKB
- if (X11->use_xkb)
- return possibleKeysXKB(event);
-#endif
- return possibleKeysCore(event);
-}
-
-enum { MaxBits = sizeof(uint) * 8 };
-static QString translateKeySym(KeySym keysym, uint xmodifiers,
- int &code, Qt::KeyboardModifiers &modifiers,
- QByteArray &chars, int &count);
-
-QList<int> QKeyMapperPrivate::possibleKeysXKB(QKeyEvent *event)
-{
-#ifndef QT_NO_XKB
- const int xkeycode = event->nativeScanCode();
- const uint xmodifiers = event->nativeModifiers();
-
- // first, translate key only using lock modifiers (there are no Qt equivalents for these, so we must
- // always use them when determining the baseKeySym)
- KeySym baseKeySym;
- uint consumedModifiers;
- if (!XkbLookupKeySym(X11->display, xkeycode, (xmodifiers & (LockMask | qt_num_lock_mask)),
- &consumedModifiers, &baseKeySym))
- return QList<int>();
-
- QList<int> result;
-
- // translate sym -> code
- Qt::KeyboardModifiers baseModifiers = 0;
- int baseCode = -1;
- QByteArray chars;
- int count = 0;
- QString text = translateKeySym(baseKeySym, xmodifiers, baseCode, baseModifiers, chars, count);
- if (baseCode == -1) {
- if (text.isEmpty())
- return QList<int>();
- baseCode = text.at(0).unicode();
- }
-
- if (baseCode && baseCode < 0xfffe)
- baseCode = QChar(baseCode).toUpper().unicode();
- result += (baseCode | baseModifiers);
-
- int pos1Bits[MaxBits];
- int num1Bits = 0;
-
- for (int i = 0; i < MaxBits; ++i) {
- if (consumedModifiers & (1 << i))
- pos1Bits[num1Bits++] = i;
- }
-
- const int numPerms = (1 << num1Bits);
-
- // translate the key again using each permutation of consumedModifiers
- for (int i = 1; i < numPerms; ++i) {
- uint val = 0;
- for (int j = 0; j < num1Bits; ++j) {
- if (i & (1 << j))
- val |= (1 << pos1Bits[j]);
- }
-
- if ((xmodifiers & val) != val)
- continue;
-
- KeySym sym;
- uint mods;
- if (!XkbLookupKeySym(X11->display, xkeycode, val, &mods, &sym))
- continue;
-
- // translate sym -> code
- Qt::KeyboardModifiers modifiers = 0;
- int code = -1;
- chars.clear();
- count = 0;
- // mask out the modifiers needed to translate keycode
- text = translateKeySym(sym, xmodifiers & ~val, code, modifiers, chars, count);
- if (code == -1) {
- if (text.isEmpty())
- continue;
- code = text.at(0).unicode();
- }
-
- if (code && code < 0xfffe)
- code = QChar(code).toUpper().unicode();
-
- if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
- // map shift+tab to shift+backtab
- code = Qt::Key_Backtab;
- text = QString();
- }
-
- if (code == baseCode)
- continue;
-
- result += (code | modifiers);
- }
-
-#if 0
- qDebug() << "possibleKeysXKB()" << hex << result;
-#endif
- return result;
-#else
- Q_UNUSED(event);
- return QList<int>();
-#endif // QT_NO_XKB
-}
-
-QList<int> QKeyMapperPrivate::possibleKeysCore(QKeyEvent *event)
-{
- const int xkeycode = event->nativeScanCode();
- const uint xmodifiers = event->nativeModifiers();
-
- // first, translate key only using lock modifiers (there are no Qt equivalents for these, so we must
- // always use them when determining the baseKeySym)
- KeySym baseKeySym;
- uint consumedModifiers;
- if (!qt_XTranslateKey(&coreDesc, xkeycode, (xmodifiers & (LockMask | qt_num_lock_mask)),
- &consumedModifiers, &baseKeySym))
- return QList<int>();
-
- QList<int> result;
-
- // translate sym -> code
- Qt::KeyboardModifiers baseModifiers = 0;
- int baseCode = -1;
- QByteArray chars;
- int count = 0;
- QString text = translateKeySym(baseKeySym, xmodifiers, baseCode, baseModifiers, chars, count);
- if (baseCode == -1) {
- if (text.isEmpty())
- return QList<int>();
- baseCode = text.at(0).unicode();
- }
-
- if (baseCode && baseCode < 0xfffe)
- baseCode = QChar(baseCode).toUpper().unicode();
- result += (baseCode | baseModifiers);
-
- int pos1Bits[MaxBits];
- int num1Bits = 0;
-
- for (int i = 0; i < MaxBits; ++i) {
- if (consumedModifiers & (1 << i))
- pos1Bits[num1Bits++] = i;
- }
-
- const int numPerms = (1 << num1Bits);
-
- // translate the key again using each permutation of consumedModifiers
- for (int i = 1; i < numPerms; ++i) {
- uint val = 0;
- for (int j = 0; j < num1Bits; ++j) {
- if (i & (1 << j))
- val |= (1 << pos1Bits[j]);
- }
-
- if ((xmodifiers & val) != val)
- continue;
-
- KeySym sym;
- uint mods;
- if (!qt_XTranslateKey(&coreDesc, xkeycode, val, &mods, &sym))
- continue;
-
- // translate sym -> code
- Qt::KeyboardModifiers modifiers = 0;
- int code = -1;
- chars.clear();
- count = 0;
- // mask out the modifiers needed to translate keycode
- text = translateKeySym(sym, xmodifiers & ~val, code, modifiers, chars, count);
- if (code == -1) {
- if (text.isEmpty())
- continue;
- code = text.at(0).unicode();
- }
-
- if (code && code < 0xfffe)
- code = QChar(code).toUpper().unicode();
-
- if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
- // map shift+tab to shift+backtab
- code = Qt::Key_Backtab;
- text = QString();
- }
-
- if (code == baseCode)
- continue;
-
- result += (code | modifiers);
- }
-
-#if 0
- qDebug() << "possibleKeysCore()" << hex << result;
-#endif
- return result;
-}
-
-// for parsing the _XKB_RULES_NAMES property
-enum {
- RulesFileIndex = 0,
- ModelIndex = 1,
- LayoutIndex = 2,
- VariantIndex = 3,
- OptionsIndex = 4
-};
-
-void QKeyMapperPrivate::clearMappings()
-{
-#ifndef QT_NO_XKB
- if (X11->use_xkb) {
- // try to determine the layout name and input direction by reading the _XKB_RULES_NAMES property off
- // the root window
- QByteArray layoutName;
- QByteArray variantName;
-
- Atom type = XNone;
- int format = 0;
- ulong nitems = 0;
- ulong bytesAfter = 0;
- uchar *data = 0;
- if (XGetWindowProperty(X11->display, RootWindow(X11->display, 0), ATOM(_XKB_RULES_NAMES), 0, 1024,
- false, XA_STRING, &type, &format, &nitems, &bytesAfter, &data) == Success
- && type == XA_STRING && format == 8 && nitems > 2) {
- /*
- index 0 == rules file name
- index 1 == model name
- index 2 == layout name
- index 3 == variant name
- index 4 == options
- */
- char *names[5] = { 0, 0, 0, 0, 0 };
- char *p = reinterpret_cast<char *>(data), *end = p + nitems;
- int i = 0;
- do {
- names[i++] = p;
- p += qstrlen(p) + 1;
- } while (p < end);
-
- // the layout names and variants are saved in the _XKB_RULES_NAMES property as a comma separated list
- QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(',');
- if (uint(xkb_currentGroup) < uint(layoutNames.count()))
- layoutName = layoutNames.at(xkb_currentGroup);
- QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(',');
- if (uint(xkb_currentGroup) < uint(variantNames.count()))
- variantName = variantNames.at(xkb_currentGroup);
- }
-
- // ### ???
- // if (keyboardLayoutName.isEmpty())
- // qWarning("Qt: unable to determine keyboard layout, please talk to qt-info@nokia.com"); ?
-
- keyboardInputLocale = q_getKeyboardLocale(layoutName, variantName);
- keyboardInputDirection = keyboardInputLocale.textDirection();
-
-#if 0
- qDebug() << "keyboard input locale ="
- << keyboardInputLocale.name()
- << "direction ="
- << keyboardInputDirection;
-#endif
- if (data)
- XFree(data);
- } else
-#endif // QT_NO_XKB
- {
- if (coreDesc.keysyms)
- XFree(coreDesc.keysyms);
-
- coreDesc.min_keycode = 8;
- coreDesc.max_keycode = 255;
- XDisplayKeycodes(X11->display, &coreDesc.min_keycode, &coreDesc.max_keycode);
-
- coreDesc.keysyms_per_keycode = 0;
- coreDesc.keysyms = XGetKeyboardMapping(X11->display,
- coreDesc.min_keycode,
- coreDesc.max_keycode - coreDesc.min_keycode + 1,
- &coreDesc.keysyms_per_keycode);
-
-#if 0
- qDebug() << "min_keycode =" << coreDesc.min_keycode;
- qDebug() << "max_keycode =" << coreDesc.max_keycode;
- qDebug() << "keysyms_per_keycode =" << coreDesc.keysyms_per_keycode;
- qDebug() << "keysyms =" << coreDesc.keysyms;
-#endif
-
- // ### cannot get/guess the locale with the core protocol
- keyboardInputLocale = QLocale::c();
- // ### could examine group 0 for RTL keys
- keyboardInputDirection = Qt::LeftToRight;
- }
-
- qt_alt_mask = 0;
- qt_meta_mask = 0;
- qt_super_mask = 0;
- qt_hyper_mask = 0;
- qt_mode_switch_mask = 0;
-
- // look at the modifier mapping, and get the correct masks for alt, meta, super, hyper, and mode_switch
-#ifndef QT_NO_XKB
- if (X11->use_xkb) {
- XkbDescPtr xkbDesc = XkbGetMap(X11->display, XkbAllClientInfoMask, XkbUseCoreKbd);
- for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) {
- const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0;
- if (mask == 0) {
- // key is not bound to a modifier
- continue;
- }
-
- for (int j = 0; j < XkbKeyGroupsWidth(xkbDesc, i); ++j) {
- KeySym keySym = XkbKeySym(xkbDesc, i, j);
- if (keySym == NoSymbol)
- continue;
- SETMASK(keySym, mask);
- }
- }
- XkbFreeKeyboard(xkbDesc, XkbAllComponentsMask, true);
- } else
-#endif // QT_NO_XKB
- {
- coreDesc.lock_meaning = NoSymbol;
-
- XModifierKeymap *map = XGetModifierMapping(X11->display);
-
- if (map) {
- int i, maskIndex = 0, mapIndex = 0;
- for (maskIndex = 0; maskIndex < 8; maskIndex++) {
- for (i = 0; i < map->max_keypermod; i++) {
- if (map->modifiermap[mapIndex]) {
- KeySym sym;
- int x = 0;
- do {
- sym = XKeycodeToKeysym(X11->display, map->modifiermap[mapIndex], x++);
- } while (sym == NoSymbol && x < coreDesc.keysyms_per_keycode);
- const uchar mask = 1 << maskIndex;
- SETMASK(sym, mask);
- }
- mapIndex++;
- }
- }
-
- // determine the meaning of the Lock modifier
- for (i = 0; i < map->max_keypermod; ++i) {
- for (int x = 0; x < coreDesc.keysyms_per_keycode; ++x) {
- KeySym sym = XKeycodeToKeysym(X11->display, map->modifiermap[LockMapIndex], x);
- if (sym == XK_Caps_Lock || sym == XK_ISO_Lock) {
- coreDesc.lock_meaning = XK_Caps_Lock;
- break;
- } else if (sym == XK_Shift_Lock) {
- coreDesc.lock_meaning = XK_Shift_Lock;
- }
- }
- }
-
- XFreeModifiermap(map);
- }
-
- // for qt_XTranslateKey()
- coreDesc.num_lock = qt_num_lock_mask;
- coreDesc.mode_switch = qt_mode_switch_mask;
-
-#if 0
- qDebug() << "lock_meaning =" << coreDesc.lock_meaning;
- qDebug() << "num_lock =" << coreDesc.num_lock;
- qDebug() << "mode_switch =" << coreDesc.mode_switch;
-#endif
- }
-
- // set default modifier masks if needed
- if( qt_alt_mask == 0 )
- qt_alt_mask = Mod1Mask;
- if( qt_meta_mask == 0 )
- qt_meta_mask = Mod4Mask;
-
- // if we don't have a meta key (or it's hidden behind alt), use super or hyper to generate
- // Qt::Key_Meta and Qt::MetaModifier, since most newer XFree86/Xorg installations map the Windows
- // key to Super
- if (qt_meta_mask == 0 || qt_meta_mask == qt_alt_mask) {
- // no meta keys... s,meta,super,
- qt_meta_mask = qt_super_mask;
- if (qt_meta_mask == 0 || qt_meta_mask == qt_alt_mask) {
- // no super keys either? guess we'll use hyper then
- qt_meta_mask = qt_hyper_mask;
- }
- }
-
-#if 0
- qDebug() << "qt_alt_mask =" << hex << qt_alt_mask;
- qDebug() << "qt_meta_mask =" << hex << qt_meta_mask;
- qDebug() << "qt_super_mask =" << hex << qt_super_mask;
- qDebug() << "qt_hyper_mask =" << hex << qt_hyper_mask;
- qDebug() << "qt_mode_switch_mask =" << hex << qt_mode_switch_mask;
- qDebug() << "qt_num_lock_mask =" << hex << qt_num_lock_mask;
-#endif
-}
-
-extern bool qt_sm_blockUserInput;
-
-//
-// Keyboard event translation
-//
-
-#ifndef XK_ISO_Left_Tab
-#define XK_ISO_Left_Tab 0xFE20
-#endif
-
-#ifndef XK_dead_hook
-#define XK_dead_hook 0xFE61
-#endif
-
-#ifndef XK_dead_horn
-#define XK_dead_horn 0xFE62
-#endif
-
-#ifndef XK_Codeinput
-#define XK_Codeinput 0xFF37
-#endif
-
-#ifndef XK_Kanji_Bangou
-#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */
-#endif
-
-// Fix old X libraries
-#ifndef XK_KP_Home
-#define XK_KP_Home 0xFF95
-#endif
-#ifndef XK_KP_Left
-#define XK_KP_Left 0xFF96
-#endif
-#ifndef XK_KP_Up
-#define XK_KP_Up 0xFF97
-#endif
-#ifndef XK_KP_Right
-#define XK_KP_Right 0xFF98
-#endif
-#ifndef XK_KP_Down
-#define XK_KP_Down 0xFF99
-#endif
-#ifndef XK_KP_Prior
-#define XK_KP_Prior 0xFF9A
-#endif
-#ifndef XK_KP_Next
-#define XK_KP_Next 0xFF9B
-#endif
-#ifndef XK_KP_End
-#define XK_KP_End 0xFF9C
-#endif
-#ifndef XK_KP_Insert
-#define XK_KP_Insert 0xFF9E
-#endif
-#ifndef XK_KP_Delete
-#define XK_KP_Delete 0xFF9F
-#endif
-
-// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
-// multimedia keys. They are included here as not every system has them.
-#define XF86XK_MonBrightnessUp 0x1008FF02
-#define XF86XK_MonBrightnessDown 0x1008FF03
-#define XF86XK_KbdLightOnOff 0x1008FF04
-#define XF86XK_KbdBrightnessUp 0x1008FF05
-#define XF86XK_KbdBrightnessDown 0x1008FF06
-#define XF86XK_Standby 0x1008FF10
-#define XF86XK_AudioLowerVolume 0x1008FF11
-#define XF86XK_AudioMute 0x1008FF12
-#define XF86XK_AudioRaiseVolume 0x1008FF13
-#define XF86XK_AudioPlay 0x1008FF14
-#define XF86XK_AudioStop 0x1008FF15
-#define XF86XK_AudioPrev 0x1008FF16
-#define XF86XK_AudioNext 0x1008FF17
-#define XF86XK_HomePage 0x1008FF18
-#define XF86XK_Mail 0x1008FF19
-#define XF86XK_Start 0x1008FF1A
-#define XF86XK_Search 0x1008FF1B
-#define XF86XK_AudioRecord 0x1008FF1C
-#define XF86XK_Calculator 0x1008FF1D
-#define XF86XK_Memo 0x1008FF1E
-#define XF86XK_ToDoList 0x1008FF1F
-#define XF86XK_Calendar 0x1008FF20
-#define XF86XK_PowerDown 0x1008FF21
-#define XF86XK_ContrastAdjust 0x1008FF22
-#define XF86XK_Back 0x1008FF26
-#define XF86XK_Forward 0x1008FF27
-#define XF86XK_Stop 0x1008FF28
-#define XF86XK_Refresh 0x1008FF29
-#define XF86XK_PowerOff 0x1008FF2A
-#define XF86XK_WakeUp 0x1008FF2B
-#define XF86XK_Eject 0x1008FF2C
-#define XF86XK_ScreenSaver 0x1008FF2D
-#define XF86XK_WWW 0x1008FF2E
-#define XF86XK_Sleep 0x1008FF2F
-#define XF86XK_Favorites 0x1008FF30
-#define XF86XK_AudioPause 0x1008FF31
-#define XF86XK_AudioMedia 0x1008FF32
-#define XF86XK_MyComputer 0x1008FF33
-#define XF86XK_LightBulb 0x1008FF35
-#define XF86XK_Shop 0x1008FF36
-#define XF86XK_History 0x1008FF37
-#define XF86XK_OpenURL 0x1008FF38
-#define XF86XK_AddFavorite 0x1008FF39
-#define XF86XK_HotLinks 0x1008FF3A
-#define XF86XK_BrightnessAdjust 0x1008FF3B
-#define XF86XK_Finance 0x1008FF3C
-#define XF86XK_Community 0x1008FF3D
-#define XF86XK_AudioRewind 0x1008FF3E
-#define XF86XK_BackForward 0x1008FF3F
-#define XF86XK_Launch0 0x1008FF40
-#define XF86XK_Launch1 0x1008FF41
-#define XF86XK_Launch2 0x1008FF42
-#define XF86XK_Launch3 0x1008FF43
-#define XF86XK_Launch4 0x1008FF44
-#define XF86XK_Launch5 0x1008FF45
-#define XF86XK_Launch6 0x1008FF46
-#define XF86XK_Launch7 0x1008FF47
-#define XF86XK_Launch8 0x1008FF48
-#define XF86XK_Launch9 0x1008FF49
-#define XF86XK_LaunchA 0x1008FF4A
-#define XF86XK_LaunchB 0x1008FF4B
-#define XF86XK_LaunchC 0x1008FF4C
-#define XF86XK_LaunchD 0x1008FF4D
-#define XF86XK_LaunchE 0x1008FF4E
-#define XF86XK_LaunchF 0x1008FF4F
-#define XF86XK_ApplicationLeft 0x1008FF50
-#define XF86XK_ApplicationRight 0x1008FF51
-#define XF86XK_Book 0x1008FF52
-#define XF86XK_CD 0x1008FF53
-#define XF86XK_Calculater 0x1008FF54
-#define XF86XK_Clear 0x1008FF55
-#define XF86XK_ClearGrab 0x1008FE21
-#define XF86XK_Close 0x1008FF56
-#define XF86XK_Copy 0x1008FF57
-#define XF86XK_Cut 0x1008FF58
-#define XF86XK_Display 0x1008FF59
-#define XF86XK_DOS 0x1008FF5A
-#define XF86XK_Documents 0x1008FF5B
-#define XF86XK_Excel 0x1008FF5C
-#define XF86XK_Explorer 0x1008FF5D
-#define XF86XK_Game 0x1008FF5E
-#define XF86XK_Go 0x1008FF5F
-#define XF86XK_iTouch 0x1008FF60
-#define XF86XK_LogOff 0x1008FF61
-#define XF86XK_Market 0x1008FF62
-#define XF86XK_Meeting 0x1008FF63
-#define XF86XK_MenuKB 0x1008FF65
-#define XF86XK_MenuPB 0x1008FF66
-#define XF86XK_MySites 0x1008FF67
-#define XF86XK_News 0x1008FF69
-#define XF86XK_OfficeHome 0x1008FF6A
-#define XF86XK_Option 0x1008FF6C
-#define XF86XK_Paste 0x1008FF6D
-#define XF86XK_Phone 0x1008FF6E
-#define XF86XK_Reply 0x1008FF72
-#define XF86XK_Reload 0x1008FF73
-#define XF86XK_RotateWindows 0x1008FF74
-#define XF86XK_RotationPB 0x1008FF75
-#define XF86XK_RotationKB 0x1008FF76
-#define XF86XK_Save 0x1008FF77
-#define XF86XK_Send 0x1008FF7B
-#define XF86XK_Spell 0x1008FF7C
-#define XF86XK_SplitScreen 0x1008FF7D
-#define XF86XK_Support 0x1008FF7E
-#define XF86XK_TaskPane 0x1008FF7F
-#define XF86XK_Terminal 0x1008FF80
-#define XF86XK_Tools 0x1008FF81
-#define XF86XK_Travel 0x1008FF82
-#define XF86XK_Video 0x1008FF87
-#define XF86XK_Word 0x1008FF89
-#define XF86XK_Xfer 0x1008FF8A
-#define XF86XK_ZoomIn 0x1008FF8B
-#define XF86XK_ZoomOut 0x1008FF8C
-#define XF86XK_Away 0x1008FF8D
-#define XF86XK_Messenger 0x1008FF8E
-#define XF86XK_WebCam 0x1008FF8F
-#define XF86XK_MailForward 0x1008FF90
-#define XF86XK_Pictures 0x1008FF91
-#define XF86XK_Music 0x1008FF92
-#define XF86XK_Battery 0x1008FF93
-#define XF86XK_Bluetooth 0x1008FF94
-#define XF86XK_WLAN 0x1008FF95
-#define XF86XK_UWB 0x1008FF96
-#define XF86XK_AudioForward 0x1008FF97
-#define XF86XK_AudioRepeat 0x1008FF98
-#define XF86XK_AudioRandomPlay 0x1008FF99
-#define XF86XK_Subtitle 0x1008FF9A
-#define XF86XK_AudioCycleTrack 0x1008FF9B
-#define XF86XK_Time 0x1008FF9F
-#define XF86XK_Select 0x1008FFA0
-#define XF86XK_View 0x1008FFA1
-#define XF86XK_TopMenu 0x1008FFA2
-#define XF86XK_Suspend 0x1008FFA7
-#define XF86XK_Hibernate 0x1008FFA8
-
-
-// end of XF86keysyms.h
-
-// Special keys used by Qtopia, mapped into the X11 private keypad range.
-#define QTOPIAXK_Select 0x11000601
-#define QTOPIAXK_Yes 0x11000602
-#define QTOPIAXK_No 0x11000603
-#define QTOPIAXK_Cancel 0x11000604
-#define QTOPIAXK_Printer 0x11000605
-#define QTOPIAXK_Execute 0x11000606
-#define QTOPIAXK_Sleep 0x11000607
-#define QTOPIAXK_Play 0x11000608
-#define QTOPIAXK_Zoom 0x11000609
-#define QTOPIAXK_Context1 0x1100060A
-#define QTOPIAXK_Context2 0x1100060B
-#define QTOPIAXK_Context3 0x1100060C
-#define QTOPIAXK_Context4 0x1100060D
-#define QTOPIAXK_Call 0x1100060E
-#define QTOPIAXK_Hangup 0x1100060F
-#define QTOPIAXK_Flip 0x11000610
-
-// keyboard mapping table
-static const unsigned int KeyTbl[] = {
-
- // misc keys
-
- XK_Escape, Qt::Key_Escape,
- XK_Tab, Qt::Key_Tab,
- XK_ISO_Left_Tab, Qt::Key_Backtab,
- XK_BackSpace, Qt::Key_Backspace,
- XK_Return, Qt::Key_Return,
- XK_Insert, Qt::Key_Insert,
- XK_Delete, Qt::Key_Delete,
- XK_Clear, Qt::Key_Delete,
- XK_Pause, Qt::Key_Pause,
- XK_Print, Qt::Key_Print,
- 0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq
- 0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq
-
- // cursor movement
-
- XK_Home, Qt::Key_Home,
- XK_End, Qt::Key_End,
- XK_Left, Qt::Key_Left,
- XK_Up, Qt::Key_Up,
- XK_Right, Qt::Key_Right,
- XK_Down, Qt::Key_Down,
- XK_Prior, Qt::Key_PageUp,
- XK_Next, Qt::Key_PageDown,
-
- // modifiers
-
- XK_Shift_L, Qt::Key_Shift,
- XK_Shift_R, Qt::Key_Shift,
- XK_Shift_Lock, Qt::Key_Shift,
- XK_Control_L, Qt::Key_Control,
- XK_Control_R, Qt::Key_Control,
- XK_Meta_L, Qt::Key_Meta,
- XK_Meta_R, Qt::Key_Meta,
- XK_Alt_L, Qt::Key_Alt,
- XK_Alt_R, Qt::Key_Alt,
- XK_Caps_Lock, Qt::Key_CapsLock,
- XK_Num_Lock, Qt::Key_NumLock,
- XK_Scroll_Lock, Qt::Key_ScrollLock,
- XK_Super_L, Qt::Key_Super_L,
- XK_Super_R, Qt::Key_Super_R,
- XK_Menu, Qt::Key_Menu,
- XK_Hyper_L, Qt::Key_Hyper_L,
- XK_Hyper_R, Qt::Key_Hyper_R,
- XK_Help, Qt::Key_Help,
- 0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab
- 0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11)
- 0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12)
-
- // numeric and function keypad keys
-
- XK_KP_Space, Qt::Key_Space,
- XK_KP_Tab, Qt::Key_Tab,
- XK_KP_Enter, Qt::Key_Enter,
- //XK_KP_F1, Qt::Key_F1,
- //XK_KP_F2, Qt::Key_F2,
- //XK_KP_F3, Qt::Key_F3,
- //XK_KP_F4, Qt::Key_F4,
- XK_KP_Home, Qt::Key_Home,
- XK_KP_Left, Qt::Key_Left,
- XK_KP_Up, Qt::Key_Up,
- XK_KP_Right, Qt::Key_Right,
- XK_KP_Down, Qt::Key_Down,
- XK_KP_Prior, Qt::Key_PageUp,
- XK_KP_Next, Qt::Key_PageDown,
- XK_KP_End, Qt::Key_End,
- XK_KP_Begin, Qt::Key_Clear,
- XK_KP_Insert, Qt::Key_Insert,
- XK_KP_Delete, Qt::Key_Delete,
- XK_KP_Equal, Qt::Key_Equal,
- XK_KP_Multiply, Qt::Key_Asterisk,
- XK_KP_Add, Qt::Key_Plus,
- XK_KP_Separator, Qt::Key_Comma,
- XK_KP_Subtract, Qt::Key_Minus,
- XK_KP_Decimal, Qt::Key_Period,
- XK_KP_Divide, Qt::Key_Slash,
-
- // International input method support keys
-
- // International & multi-key character composition
- XK_ISO_Level3_Shift, Qt::Key_AltGr,
- XK_Multi_key, Qt::Key_Multi_key,
- XK_Codeinput, Qt::Key_Codeinput,
- XK_SingleCandidate, Qt::Key_SingleCandidate,
- XK_MultipleCandidate, Qt::Key_MultipleCandidate,
- XK_PreviousCandidate, Qt::Key_PreviousCandidate,
-
- // Misc Functions
- XK_Mode_switch, Qt::Key_Mode_switch,
- XK_script_switch, Qt::Key_Mode_switch,
-
- // Japanese keyboard support
- XK_Kanji, Qt::Key_Kanji,
- XK_Muhenkan, Qt::Key_Muhenkan,
- //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
- XK_Henkan_Mode, Qt::Key_Henkan,
- XK_Henkan, Qt::Key_Henkan,
- XK_Romaji, Qt::Key_Romaji,
- XK_Hiragana, Qt::Key_Hiragana,
- XK_Katakana, Qt::Key_Katakana,
- XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
- XK_Zenkaku, Qt::Key_Zenkaku,
- XK_Hankaku, Qt::Key_Hankaku,
- XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
- XK_Touroku, Qt::Key_Touroku,
- XK_Massyo, Qt::Key_Massyo,
- XK_Kana_Lock, Qt::Key_Kana_Lock,
- XK_Kana_Shift, Qt::Key_Kana_Shift,
- XK_Eisu_Shift, Qt::Key_Eisu_Shift,
- XK_Eisu_toggle, Qt::Key_Eisu_toggle,
- //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
- //XK_Zen_Koho, Qt::Key_Zen_Koho,
- //XK_Mae_Koho, Qt::Key_Mae_Koho,
- XK_Kanji_Bangou, Qt::Key_Codeinput,
- XK_Zen_Koho, Qt::Key_MultipleCandidate,
- XK_Mae_Koho, Qt::Key_PreviousCandidate,
-
-#ifdef XK_KOREAN
- // Korean keyboard support
- XK_Hangul, Qt::Key_Hangul,
- XK_Hangul_Start, Qt::Key_Hangul_Start,
- XK_Hangul_End, Qt::Key_Hangul_End,
- XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
- XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
- XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
- //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
- XK_Hangul_Codeinput, Qt::Key_Codeinput,
- XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
- XK_Hangul_Banja, Qt::Key_Hangul_Banja,
- XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
- XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
- //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
- //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
- //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
- XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
- XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
- XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
- XK_Hangul_Special, Qt::Key_Hangul_Special,
- //XK_Hangul_switch, Qt::Key_Hangul_switch,
- XK_Hangul_switch, Qt::Key_Mode_switch,
-#endif // XK_KOREAN
-
- // dead keys
- XK_dead_grave, Qt::Key_Dead_Grave,
- XK_dead_acute, Qt::Key_Dead_Acute,
- XK_dead_circumflex, Qt::Key_Dead_Circumflex,
- XK_dead_tilde, Qt::Key_Dead_Tilde,
- XK_dead_macron, Qt::Key_Dead_Macron,
- XK_dead_breve, Qt::Key_Dead_Breve,
- XK_dead_abovedot, Qt::Key_Dead_Abovedot,
- XK_dead_diaeresis, Qt::Key_Dead_Diaeresis,
- XK_dead_abovering, Qt::Key_Dead_Abovering,
- XK_dead_doubleacute, Qt::Key_Dead_Doubleacute,
- XK_dead_caron, Qt::Key_Dead_Caron,
- XK_dead_cedilla, Qt::Key_Dead_Cedilla,
- XK_dead_ogonek, Qt::Key_Dead_Ogonek,
- XK_dead_iota, Qt::Key_Dead_Iota,
- XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
- XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
- XK_dead_belowdot, Qt::Key_Dead_Belowdot,
- XK_dead_hook, Qt::Key_Dead_Hook,
- XK_dead_horn, Qt::Key_Dead_Horn,
-
- // Special keys from X.org - This include multimedia keys,
- // wireless/bluetooth/uwb keys, special launcher keys, etc.
- XF86XK_Back, Qt::Key_Back,
- XF86XK_Forward, Qt::Key_Forward,
- XF86XK_Stop, Qt::Key_Stop,
- XF86XK_Refresh, Qt::Key_Refresh,
- XF86XK_Favorites, Qt::Key_Favorites,
- XF86XK_AudioMedia, Qt::Key_LaunchMedia,
- XF86XK_OpenURL, Qt::Key_OpenUrl,
- XF86XK_HomePage, Qt::Key_HomePage,
- XF86XK_Search, Qt::Key_Search,
- XF86XK_AudioLowerVolume, Qt::Key_VolumeDown,
- XF86XK_AudioMute, Qt::Key_VolumeMute,
- XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp,
- XF86XK_AudioPlay, Qt::Key_MediaPlay,
- XF86XK_AudioStop, Qt::Key_MediaStop,
- XF86XK_AudioPrev, Qt::Key_MediaPrevious,
- XF86XK_AudioNext, Qt::Key_MediaNext,
- XF86XK_AudioRecord, Qt::Key_MediaRecord,
- XF86XK_Mail, Qt::Key_LaunchMail,
- XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 5: remap properly
- XF86XK_Calculator, Qt::Key_Launch1,
- XF86XK_Memo, Qt::Key_Memo,
- XF86XK_ToDoList, Qt::Key_ToDoList,
- XF86XK_Calendar, Qt::Key_Calendar,
- XF86XK_PowerDown, Qt::Key_PowerDown,
- XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust,
- XF86XK_Standby, Qt::Key_Standby,
- XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp,
- XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown,
- XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff,
- XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp,
- XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown,
- XF86XK_PowerOff, Qt::Key_PowerOff,
- XF86XK_WakeUp, Qt::Key_WakeUp,
- XF86XK_Eject, Qt::Key_Eject,
- XF86XK_ScreenSaver, Qt::Key_ScreenSaver,
- XF86XK_WWW, Qt::Key_WWW,
- XF86XK_Sleep, Qt::Key_Sleep,
- XF86XK_LightBulb, Qt::Key_LightBulb,
- XF86XK_Shop, Qt::Key_Shop,
- XF86XK_History, Qt::Key_History,
- XF86XK_AddFavorite, Qt::Key_AddFavorite,
- XF86XK_HotLinks, Qt::Key_HotLinks,
- XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust,
- XF86XK_Finance, Qt::Key_Finance,
- XF86XK_Community, Qt::Key_Community,
- XF86XK_AudioRewind, Qt::Key_AudioRewind,
- XF86XK_BackForward, Qt::Key_BackForward,
- XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft,
- XF86XK_ApplicationRight, Qt::Key_ApplicationRight,
- XF86XK_Book, Qt::Key_Book,
- XF86XK_CD, Qt::Key_CD,
- XF86XK_Calculater, Qt::Key_Calculator,
- XF86XK_Clear, Qt::Key_Clear,
- XF86XK_ClearGrab, Qt::Key_ClearGrab,
- XF86XK_Close, Qt::Key_Close,
- XF86XK_Copy, Qt::Key_Copy,
- XF86XK_Cut, Qt::Key_Cut,
- XF86XK_Display, Qt::Key_Display,
- XF86XK_DOS, Qt::Key_DOS,
- XF86XK_Documents, Qt::Key_Documents,
- XF86XK_Excel, Qt::Key_Excel,
- XF86XK_Explorer, Qt::Key_Explorer,
- XF86XK_Game, Qt::Key_Game,
- XF86XK_Go, Qt::Key_Go,
- XF86XK_iTouch, Qt::Key_iTouch,
- XF86XK_LogOff, Qt::Key_LogOff,
- XF86XK_Market, Qt::Key_Market,
- XF86XK_Meeting, Qt::Key_Meeting,
- XF86XK_MenuKB, Qt::Key_MenuKB,
- XF86XK_MenuPB, Qt::Key_MenuPB,
- XF86XK_MySites, Qt::Key_MySites,
- XF86XK_News, Qt::Key_News,
- XF86XK_OfficeHome, Qt::Key_OfficeHome,
- XF86XK_Option, Qt::Key_Option,
- XF86XK_Paste, Qt::Key_Paste,
- XF86XK_Phone, Qt::Key_Phone,
- XF86XK_Reply, Qt::Key_Reply,
- XF86XK_Reload, Qt::Key_Reload,
- XF86XK_RotateWindows, Qt::Key_RotateWindows,
- XF86XK_RotationPB, Qt::Key_RotationPB,
- XF86XK_RotationKB, Qt::Key_RotationKB,
- XF86XK_Save, Qt::Key_Save,
- XF86XK_Send, Qt::Key_Send,
- XF86XK_Spell, Qt::Key_Spell,
- XF86XK_SplitScreen, Qt::Key_SplitScreen,
- XF86XK_Support, Qt::Key_Support,
- XF86XK_TaskPane, Qt::Key_TaskPane,
- XF86XK_Terminal, Qt::Key_Terminal,
- XF86XK_Tools, Qt::Key_Tools,
- XF86XK_Travel, Qt::Key_Travel,
- XF86XK_Video, Qt::Key_Video,
- XF86XK_Word, Qt::Key_Word,
- XF86XK_Xfer, Qt::Key_Xfer,
- XF86XK_ZoomIn, Qt::Key_ZoomIn,
- XF86XK_ZoomOut, Qt::Key_ZoomOut,
- XF86XK_Away, Qt::Key_Away,
- XF86XK_Messenger, Qt::Key_Messenger,
- XF86XK_WebCam, Qt::Key_WebCam,
- XF86XK_MailForward, Qt::Key_MailForward,
- XF86XK_Pictures, Qt::Key_Pictures,
- XF86XK_Music, Qt::Key_Music,
- XF86XK_Battery, Qt::Key_Battery,
- XF86XK_Bluetooth, Qt::Key_Bluetooth,
- XF86XK_WLAN, Qt::Key_WLAN,
- XF86XK_UWB, Qt::Key_UWB,
- XF86XK_AudioForward, Qt::Key_AudioForward,
- XF86XK_AudioRepeat, Qt::Key_AudioRepeat,
- XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay,
- XF86XK_Subtitle, Qt::Key_Subtitle,
- XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack,
- XF86XK_Time, Qt::Key_Time,
- XF86XK_Select, Qt::Key_Select,
- XF86XK_View, Qt::Key_View,
- XF86XK_TopMenu, Qt::Key_TopMenu,
- XF86XK_Bluetooth, Qt::Key_Bluetooth,
- XF86XK_Suspend, Qt::Key_Suspend,
- XF86XK_Hibernate, Qt::Key_Hibernate,
- XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly
- XF86XK_Launch1, Qt::Key_Launch3,
- XF86XK_Launch2, Qt::Key_Launch4,
- XF86XK_Launch3, Qt::Key_Launch5,
- XF86XK_Launch4, Qt::Key_Launch6,
- XF86XK_Launch5, Qt::Key_Launch7,
- XF86XK_Launch6, Qt::Key_Launch8,
- XF86XK_Launch7, Qt::Key_Launch9,
- XF86XK_Launch8, Qt::Key_LaunchA,
- XF86XK_Launch9, Qt::Key_LaunchB,
- XF86XK_LaunchA, Qt::Key_LaunchC,
- XF86XK_LaunchB, Qt::Key_LaunchD,
- XF86XK_LaunchC, Qt::Key_LaunchE,
- XF86XK_LaunchD, Qt::Key_LaunchF,
- XF86XK_LaunchE, Qt::Key_LaunchG,
- XF86XK_LaunchF, Qt::Key_LaunchH,
-
- // Qtopia keys
- QTOPIAXK_Select, Qt::Key_Select,
- QTOPIAXK_Yes, Qt::Key_Yes,
- QTOPIAXK_No, Qt::Key_No,
- QTOPIAXK_Cancel, Qt::Key_Cancel,
- QTOPIAXK_Printer, Qt::Key_Printer,
- QTOPIAXK_Execute, Qt::Key_Execute,
- QTOPIAXK_Sleep, Qt::Key_Sleep,
- QTOPIAXK_Play, Qt::Key_Play,
- QTOPIAXK_Zoom, Qt::Key_Zoom,
- QTOPIAXK_Context1, Qt::Key_Context1,
- QTOPIAXK_Context2, Qt::Key_Context2,
- QTOPIAXK_Context3, Qt::Key_Context3,
- QTOPIAXK_Context4, Qt::Key_Context4,
- QTOPIAXK_Call, Qt::Key_Call,
- QTOPIAXK_Hangup, Qt::Key_Hangup,
- QTOPIAXK_Flip, Qt::Key_Flip,
-
- 0, 0
-};
-
-static int translateKeySym(uint key)
-{
- int code = -1;
- int i = 0; // any other keys
- while (KeyTbl[i]) {
- if (key == KeyTbl[i]) {
- code = (int)KeyTbl[i+1];
- break;
- }
- i += 2;
- }
- if (qt_meta_mask) {
- // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
- if (qt_meta_mask == qt_super_mask && (code == Qt::Key_Super_L || code == Qt::Key_Super_R)) {
- code = Qt::Key_Meta;
- } else if (qt_meta_mask == qt_hyper_mask && (code == Qt::Key_Hyper_L || code == Qt::Key_Hyper_R)) {
- code = Qt::Key_Meta;
- }
- }
- return code;
-}
-
-#if !defined(QT_NO_XIM)
-static const unsigned short katakanaKeysymsToUnicode[] = {
- 0x0000, 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1,
- 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3,
- 0x30FC, 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD,
- 0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD,
- 0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC,
- 0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE,
- 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9,
- 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C
-};
-
-static const unsigned short cyrillicKeysymsToUnicode[] = {
- 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
- 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f,
- 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
- 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f,
- 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
- 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
- 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
- 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
- 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
- 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
- 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
- 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a
-};
-
-static const unsigned short greekKeysymsToUnicode[] = {
- 0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c,
- 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015,
- 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc,
- 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
- 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
- 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
- 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
- 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
- 0x03c8, 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
-
-static const unsigned short technicalKeysymsToUnicode[] = {
- 0x0000, 0x23B7, 0x250C, 0x2500, 0x2320, 0x2321, 0x2502, 0x23A1,
- 0x23A3, 0x23A4, 0x23A6, 0x239B, 0x239D, 0x239E, 0x23A0, 0x23A8,
- 0x23AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222B,
- 0x2234, 0x221D, 0x221E, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000,
- 0x223C, 0x2243, 0x0000, 0x0000, 0x0000, 0x21D4, 0x21D2, 0x2261,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221A, 0x0000,
- 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222A, 0x2227, 0x2228,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193, 0x0000
-};
-
-static const unsigned short specialKeysymsToUnicode[] = {
- 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x0000, 0x0000,
- 0x2424, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
- 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C,
- 0x2502, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
-
-static const unsigned short publishingKeysymsToUnicode[] = {
- 0x0000, 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009,
- 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025,
- 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a,
- 0x2105, 0x0000, 0x0000, 0x2012, 0x2329, 0x0000, 0x232a, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000,
- 0x0000, 0x2122, 0x2613, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25af,
- 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033,
- 0x0000, 0x271d, 0x0000, 0x25ac, 0x25c0, 0x25b6, 0x25cf, 0x25ae,
- 0x25e6, 0x25ab, 0x25ad, 0x25b3, 0x25bd, 0x2606, 0x2022, 0x25aa,
- 0x25b2, 0x25bc, 0x261c, 0x261e, 0x2663, 0x2666, 0x2665, 0x0000,
- 0x2720, 0x2020, 0x2021, 0x2713, 0x2717, 0x266f, 0x266d, 0x2642,
- 0x2640, 0x260e, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e, 0x0000
-};
-
-static const unsigned short aplKeysymsToUnicode[] = {
- 0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003e, 0x0000,
- 0x2228, 0x2227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x00af, 0x0000, 0x22a5, 0x2229, 0x230a, 0x0000, 0x005f, 0x0000,
- 0x0000, 0x0000, 0x2218, 0x0000, 0x2395, 0x0000, 0x22a4, 0x25cb,
- 0x0000, 0x0000, 0x0000, 0x2308, 0x0000, 0x0000, 0x222a, 0x0000,
- 0x2283, 0x0000, 0x2282, 0x0000, 0x22a2, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x22a3, 0x0000, 0x0000, 0x0000
-};
-
-static const unsigned short koreanKeysymsToUnicode[] = {
- 0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
- 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
- 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147,
- 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f,
- 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157,
- 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f,
- 0x3160, 0x3161, 0x3162, 0x3163, 0x11a8, 0x11a9, 0x11aa, 0x11ab,
- 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3,
- 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb,
- 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x316d,
- 0x3171, 0x3178, 0x317f, 0x3181, 0x3184, 0x3186, 0x318d, 0x318e,
- 0x11eb, 0x11f0, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9
-};
-
-static QChar keysymToUnicode(unsigned char byte3, unsigned char byte4)
-{
- switch (byte3) {
- case 0x04:
- // katakana
- if (byte4 > 0xa0 && byte4 < 0xe0)
- return QChar(katakanaKeysymsToUnicode[byte4 - 0xa0]);
- else if (byte4 == 0x7e)
- return QChar(0x203e); // Overline
- break;
- case 0x06:
- // russian, use lookup table
- if (byte4 > 0xa0)
- return QChar(cyrillicKeysymsToUnicode[byte4 - 0xa0]);
- break;
- case 0x07:
- // greek
- if (byte4 > 0xa0)
- return QChar(greekKeysymsToUnicode[byte4 - 0xa0]);
- break;
- case 0x08:
- // technical
- if (byte4 > 0xa0)
- return QChar(technicalKeysymsToUnicode[byte4 - 0xa0]);
- break;
- case 0x09:
- // special
- if (byte4 >= 0xe0)
- return QChar(specialKeysymsToUnicode[byte4 - 0xe0]);
- break;
- case 0x0a:
- // publishing
- if (byte4 > 0xa0)
- return QChar(publishingKeysymsToUnicode[byte4 - 0xa0]);
- break;
- case 0x0b:
- // APL
- if (byte4 > 0xa0)
- return QChar(aplKeysymsToUnicode[byte4 - 0xa0]);
- break;
- case 0x0e:
- // Korean
- if (byte4 > 0xa0)
- return QChar(koreanKeysymsToUnicode[byte4 - 0xa0]);
- break;
- default:
- break;
- }
- return QChar(0x0);
-}
-#endif
-
-static QString translateKeySym(KeySym keysym, uint xmodifiers,
- int &code, Qt::KeyboardModifiers &modifiers,
- QByteArray &chars, int &count)
-{
- // all keysyms smaller than 0xff00 are actally keys that can be mapped to unicode chars
-
- extern QTextCodec *qt_input_mapper; // from qapplication_x11.cpp
- QTextCodec *mapper = qt_input_mapper;
- QChar converted;
-
- if (count == 0 && keysym < 0xff00) {
- unsigned char byte3 = (unsigned char)(keysym >> 8);
- int mib = -1;
- switch(byte3) {
- case 0: // Latin 1
- case 1: // Latin 2
- case 2: //latin 3
- case 3: // latin4
- mib = byte3 + 4; break;
- case 5: // arabic
- mib = 82; break;
- case 12: // Hebrew
- mib = 85; break;
- case 13: // Thai
- mib = 2259; break;
- case 4: // kana
- case 6: // cyrillic
- case 7: // greek
- case 8: // technical, no mapping here at the moment
- case 9: // Special
- case 10: // Publishing
- case 11: // APL
- case 14: // Korean, no mapping
- mib = -1; // manual conversion
- mapper = 0;
-#if !defined(QT_NO_XIM)
- converted = keysymToUnicode(byte3, keysym & 0xff);
-#endif
- case 0x20:
- // currency symbols
- if (keysym >= 0x20a0 && keysym <= 0x20ac) {
- mib = -1; // manual conversion
- mapper = 0;
- converted = (uint)keysym;
- }
- break;
- default:
- break;
- }
- if (mib != -1) {
- mapper = QTextCodec::codecForMib(mib);
- if (chars.isEmpty())
- chars.resize(1);
- chars[0] = (unsigned char) (keysym & 0xff); // get only the fourth bit for conversion later
- count++;
- }
- } else if (keysym >= 0x1000000 && keysym <= 0x100ffff) {
- converted = (ushort) (keysym - 0x1000000);
- mapper = 0;
- }
- if (count < (int)chars.size()-1)
- chars[count] = '\0';
-
- QString text;
- if (!mapper && converted.unicode() != 0x0) {
- text = converted;
- } else if (!chars.isEmpty()) {
- // convert chars (8bit) to text (unicode).
- if (mapper)
- text = mapper->toUnicode(chars.data(), count, 0);
- if (text.isEmpty()) {
- // no mapper, or codec couldn't convert to unicode (this
- // can happen when running in the C locale or with no LANG
- // set). try converting from latin-1
- text = QString::fromLatin1(chars);
- }
- }
-
- modifiers = X11->translateModifiers(xmodifiers);
-
- // Commentary in X11/keysymdef says that X codes match ASCII, so it
- // is safe to use the locale functions to process X codes in ISO8859-1.
- //
- // This is mainly for compatibility - applications should not use the
- // Qt keycodes between 128 and 255, but should rather use the
- // QKeyEvent::text().
- //
- extern QTextCodec *qt_input_mapper; // from qapplication_x11.cpp
- if (keysym < 128 || (keysym < 256 && (!qt_input_mapper || qt_input_mapper->mibEnum()==4))) {
- // upper-case key, if known
- code = isprint((int)keysym) ? toupper((int)keysym) : 0;
- } else if (keysym >= XK_F1 && keysym <= XK_F35) {
- // function keys
- code = Qt::Key_F1 + ((int)keysym - XK_F1);
- } else if (keysym >= XK_KP_Space && keysym <= XK_KP_9) {
- if (keysym >= XK_KP_0) {
- // numeric keypad keys
- code = Qt::Key_0 + ((int)keysym - XK_KP_0);
- } else {
- code = translateKeySym(keysym);
- }
- modifiers |= Qt::KeypadModifier;
- } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f && text.unicode()->unicode() != 0x7f && !(keysym >= XK_dead_grave && keysym <= XK_dead_horn)) {
- code = text.unicode()->toUpper().unicode();
- } else {
- // any other keys
- code = translateKeySym(keysym);
-
- if (code == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) {
- // map shift+tab to shift+backtab, QShortcutMap knows about it
- // and will handle it.
- code = Qt::Key_Backtab;
- text = QString();
- }
- }
-
- return text;
-}
-
-extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp
-
-bool QKeyMapperPrivate::translateKeyEventInternal(QWidget *keyWidget,
- const XEvent *event,
- KeySym &keysym,
- int& count,
- QString& text,
- Qt::KeyboardModifiers &modifiers,
- int& code,
- QEvent::Type &type,
- bool statefulTranslation)
-{
- XKeyEvent xkeyevent = event->xkey;
- int keycode = event->xkey.keycode;
- // save the modifier state, we will use the keystate uint later by passing
- // it to translateButtonState
- uint keystate = event->xkey.state;
-
- type = (event->type == XKeyPress) ? QEvent::KeyPress : QEvent::KeyRelease;
-
- static int directionKeyEvent = 0;
- static unsigned int lastWinId = 0;
-
- // translate pending direction change
- if (statefulTranslation && qt_use_rtl_extensions && type == QEvent::KeyRelease) {
- if (directionKeyEvent == Qt::Key_Direction_R || directionKeyEvent == Qt::Key_Direction_L) {
- type = QEvent::KeyPress;
- code = directionKeyEvent;
- text = QString();
- directionKeyEvent = 0;
- lastWinId = 0;
- return true;
- } else {
- directionKeyEvent = 0;
- lastWinId = 0;
- }
- }
-
- // some XmbLookupString implementations don't return buffer overflow correctly,
- // so we increase the input buffer to allow for long strings...
- // 256 chars * 2 bytes + 1 null-term == 513 bytes
- QByteArray chars;
- chars.resize(513);
-
- count = XLookupString(&xkeyevent, chars.data(), chars.size(), &keysym, 0);
- if (count && !keycode) {
- extern int qt_ximComposingKeycode; // from qapplication_x11.cpp
- keycode = qt_ximComposingKeycode;
- qt_ximComposingKeycode = 0;
- }
-
- // translate the keysym + xmodifiers to Qt::Key_* + Qt::KeyboardModifiers
- text = translateKeySym(keysym, keystate, code, modifiers, chars, count);
-
- // Watch for keypresses and if its a key belonging to the Ctrl-Shift
- // direction-changing accel, remember it.
- // We keep track of those keys instead of using the event's state
- // (to figure out whether the Ctrl modifier is held while Shift is pressed,
- // or Shift is held while Ctrl is pressed) since the 'state' doesn't tell
- // us whether the modifier held is Left or Right.
- if (statefulTranslation && qt_use_rtl_extensions && type == QEvent::KeyPress) {
- if (keysym == XK_Control_L || keysym == XK_Control_R
- || keysym == XK_Shift_L || keysym == XK_Shift_R) {
- if (!directionKeyEvent) {
- directionKeyEvent = keysym;
- // This code exists in order to check that
- // the event is occurred in the same widget.
- lastWinId = keyWidget->internalWinId();
- }
- } else {
- // this can no longer be a direction-changing accel.
- // if any other key was pressed.
- directionKeyEvent = Qt::Key_Space;
- }
-
- if (directionKeyEvent && lastWinId == keyWidget->internalWinId()) {
- if ((keysym == XK_Shift_L && directionKeyEvent == XK_Control_L)
- || (keysym == XK_Control_L && directionKeyEvent == XK_Shift_L)) {
- directionKeyEvent = Qt::Key_Direction_L;
- } else if ((keysym == XK_Shift_R && directionKeyEvent == XK_Control_R)
- || (keysym == XK_Control_R && directionKeyEvent == XK_Shift_R)) {
- directionKeyEvent = Qt::Key_Direction_R;
- }
- } else if (directionKeyEvent == Qt::Key_Direction_L
- || directionKeyEvent == Qt::Key_Direction_R) {
- directionKeyEvent = Qt::Key_Space; // invalid
- }
- }
-
- return true;
-}
-
-
-struct qt_auto_repeat_data
-{
- // match the window and keycode with timestamp delta of 10 ms
- Window window;
- KeyCode keycode;
- Time timestamp;
-
- // queue scanner state
- bool release;
- bool error;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool qt_keypress_scanner(Display *, XEvent *event, XPointer arg)
-{
- if (event->type != XKeyPress && event->type != XKeyRelease)
- return false;
-
- qt_auto_repeat_data *data = (qt_auto_repeat_data *) arg;
- if (data->error)
- return false;
-
- if (event->xkey.window != data->window ||
- event->xkey.keycode != data->keycode) {
- // deal breakers: key events in a different window or an event
- // with a different key code
- data->error = true;
- return false;
- }
-
- if (event->type == XKeyPress) {
- data->error = (! data->release || event->xkey.time - data->timestamp > 10);
- return (! data->error);
- }
-
- // must be XKeyRelease event
- if (data->release) {
- // found a second release
- data->error = true;
- return false;
- }
-
- // found a single release
- data->release = true;
- data->timestamp = event->xkey.time;
-
- return false;
-}
-
-static Bool qt_keyrelease_scanner(Display *, XEvent *event, XPointer arg)
-{
- const qt_auto_repeat_data *data = (const qt_auto_repeat_data *) arg;
- return (event->type == XKeyRelease &&
- event->xkey.window == data->window &&
- event->xkey.keycode == data->keycode);
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-bool QKeyMapperPrivate::translateKeyEvent(QWidget *keyWidget, const XEvent *event, bool grab)
-{
- int code = -1;
- int count = 0;
- Qt::KeyboardModifiers modifiers;
-
- if (qt_sm_blockUserInput) // block user interaction during session management
- return true;
-
- Display *dpy = X11->display;
-
- if (!keyWidget->isEnabled())
- return true;
-
- QEvent::Type type;
- bool autor = false;
- QString text;
-
- KeySym keysym = 0;
- translateKeyEventInternal(keyWidget, event, keysym, count, text, modifiers, code, type);
-
- // was this the last auto-repeater?
- qt_auto_repeat_data auto_repeat_data;
- auto_repeat_data.window = event->xkey.window;
- auto_repeat_data.keycode = event->xkey.keycode;
- auto_repeat_data.timestamp = event->xkey.time;
-
- static uint curr_autorep = 0;
- if (event->type == XKeyPress) {
- if (curr_autorep == event->xkey.keycode) {
- autor = true;
- curr_autorep = 0;
- }
- } else {
- // look ahead for auto-repeat
- XEvent nextpress;
-
- auto_repeat_data.release = true;
- auto_repeat_data.error = false;
- if (XCheckIfEvent(dpy, &nextpress, &qt_keypress_scanner,
- (XPointer) &auto_repeat_data)) {
- autor = true;
-
- // Put it back... we COULD send the event now and not need
- // the static curr_autorep variable.
- XPutBackEvent(dpy,&nextpress);
- }
- curr_autorep = autor ? event->xkey.keycode : 0;
- }
-
-#ifndef QT_NO_IM
- QInputContext *qic = keyWidget->inputContext();
-#endif
-
- // compress keys
- if (!text.isEmpty() && keyWidget->testAttribute(Qt::WA_KeyCompression) &&
-#ifndef QT_NO_IM
- // Ordinary input methods require discrete key events to work
- // properly, so key compression has to be disabled when input
- // context exists.
- //
- // And further consideration, some complex input method
- // require all key press/release events discretely even if
- // the input method awares of key compression and compressed
- // keys are ordinary alphabets. For example, the uim project
- // is planning to implement "combinational shift" feature for
- // a Japanese input method, uim-skk. It will work as follows.
- //
- // 1. press "r"
- // 2. press "u"
- // 3. release both "r" and "u" in arbitrary order
- // 4. above key sequence generates "Ru"
- //
- // Of course further consideration about other participants
- // such as key repeat mechanism is required to implement such
- // feature.
- !qic &&
-#endif // QT_NO_IM
- // do not compress keys if the key event we just got above matches
- // one of the key ranges used to compute stopCompression
- !((code >= Qt::Key_Escape && code <= Qt::Key_SysReq)
- || (code >= Qt::Key_Home && code <= Qt::Key_PageDown)
- || (code >= Qt::Key_Super_L && code <= Qt::Key_Direction_R)
- || (code == 0)
- || (text.length() == 1 && text.unicode()->unicode() == '\n'))) {
- // the widget wants key compression so it gets it
-
- // sync the event queue, this makes key compress work better
- XSync(dpy, false);
-
- for (;;) {
- XEvent evRelease;
- XEvent evPress;
- if (!XCheckTypedWindowEvent(dpy,event->xkey.window,
- XKeyRelease,&evRelease))
- break;
- if (!XCheckTypedWindowEvent(dpy,event->xkey.window,
- XKeyPress,&evPress)) {
- XPutBackEvent(dpy, &evRelease);
- break;
- }
- QString textIntern;
- int codeIntern = -1;
- int countIntern = 0;
- Qt::KeyboardModifiers modifiersIntern;
- QEvent::Type t;
- KeySym keySymIntern;
- translateKeyEventInternal(keyWidget, &evPress, keySymIntern, countIntern, textIntern,
- modifiersIntern, codeIntern, t);
- // use stopCompression to stop key compression for the following
- // key event ranges:
- bool stopCompression =
- // 1) misc keys
- (codeIntern >= Qt::Key_Escape && codeIntern <= Qt::Key_SysReq)
- // 2) cursor movement
- || (codeIntern >= Qt::Key_Home && codeIntern <= Qt::Key_PageDown)
- // 3) extra keys
- || (codeIntern >= Qt::Key_Super_L && codeIntern <= Qt::Key_Direction_R)
- // 4) something that a) doesn't translate to text or b) translates
- // to newline text
- || (codeIntern == 0)
- || (textIntern.length() == 1 && textIntern.unicode()->unicode() == '\n')
- || (codeIntern == Qt::Key_unknown);
-
- if (modifiersIntern == modifiers && !textIntern.isEmpty() && !stopCompression) {
- text += textIntern;
- count += countIntern;
- } else {
- XPutBackEvent(dpy, &evPress);
- XPutBackEvent(dpy, &evRelease);
- break;
- }
- }
- }
-
- // autorepeat compression makes sense for all widgets (Windows
- // does it automatically ....)
- if (event->type == XKeyPress && text.length() <= 1
-#ifndef QT_NO_IM
- // input methods need discrete key events
- && !qic
-#endif// QT_NO_IM
- ) {
- XEvent dummy;
-
- for (;;) {
- auto_repeat_data.release = false;
- auto_repeat_data.error = false;
- if (! XCheckIfEvent(dpy, &dummy, &qt_keypress_scanner,
- (XPointer) &auto_repeat_data))
- break;
- if (! XCheckIfEvent(dpy, &dummy, &qt_keyrelease_scanner,
- (XPointer) &auto_repeat_data))
- break;
-
- count++;
- if (!text.isEmpty())
- text += text[0];
- }
- }
-
- return QKeyMapper::sendKeyEvent(keyWidget, grab, type, code, modifiers, text, autor,
- qMax(qMax(count,1), int(text.length())),
- event->xkey.keycode, keysym, event->xkey.state);
-}
-
-bool QKeyMapper::sendKeyEvent(QWidget *keyWidget, bool grab,
- QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
- const QString &text, bool autorepeat, int count,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- bool *)
-{
- // try the menukey first
- if (type == QEvent::KeyPress && code == Qt::Key_Menu) {
- QVariant v = keyWidget->inputMethodQuery(Qt::ImMicroFocus);
- QPoint globalPos;
- QPoint pos;
- if (v.isNull()) {
- globalPos = QCursor::pos();
- pos = keyWidget->mapFromGlobal(globalPos);
- } else {
- pos = v.toRect().center();
- globalPos = keyWidget->mapToGlobal(pos);
- }
- QContextMenuEvent e(QContextMenuEvent::Keyboard, pos, globalPos);
- qt_sendSpontaneousEvent(keyWidget, &e);
- if(e.isAccepted())
- return true;
- }
-
- Q_UNUSED(grab);
- QKeyEventEx e(type, code, modifiers, text, autorepeat, qMax(qMax(count,1), int(text.length())),
- nativeScanCode, nativeVirtualKey, nativeModifiers);
- return qt_sendSpontaneousEvent(keyWidget, &e);
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qkeymapper_x11_p.cpp b/src/widgets/platforms/x11/qkeymapper_x11_p.cpp
deleted file mode 100644
index 80352ee797..0000000000
--- a/src/widgets/platforms/x11/qkeymapper_x11_p.cpp
+++ /dev/null
@@ -1,489 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// This file is auto-generated, do not edit!
-// (Generated using util/xkbdatagen)
-
-static struct {
- const char *layout;
- const char *variant; // 0 means any variant
- Qt::LayoutDirection direction;
- QLocale::Language language;
- QLocale::Country country;
-} xkbLayoutData[] = {
- // name = us, description = U.S. English
- { "us", "", Qt::LeftToRight, QLocale::English, QLocale::UnitedStates },
- // name = us:intl, description = U.S. English
- { "us", "intl", Qt::LeftToRight, QLocale::English, QLocale::UnitedStates },
- // name = us:alt-intl, description = U.S. English
- { "us", "alt-intl", Qt::LeftToRight, QLocale::English, QLocale::UnitedStates },
- // name = us:dvorak, description = U.S. English
- { "us", "dvorak", Qt::LeftToRight, QLocale::English, QLocale::UnitedStates },
- // name = us:rus, description = U.S. English
- { "us", "rus", Qt::LeftToRight, QLocale::Russian, QLocale::UnitedStates },
- // name = ara, description = Arabic
- { "ara", "", Qt::RightToLeft, QLocale::Arabic, QLocale::UnitedArabEmirates },
- // name = ara:azerty, description = Arabic
- { "ara", "azerty", Qt::RightToLeft, QLocale::Arabic, QLocale::UnitedArabEmirates },
- // name = ara:azerty_digits, description = Arabic
- { "ara", "azerty_digits", Qt::RightToLeft, QLocale::Arabic, QLocale::UnitedArabEmirates },
- // name = ara:digits, description = Arabic
- { "ara", "digits", Qt::RightToLeft, QLocale::Arabic, QLocale::UnitedArabEmirates },
- // name = ara:qwerty, description = Arabic
- { "ara", "qwerty", Qt::RightToLeft, QLocale::Arabic, QLocale::UnitedArabEmirates },
- // name = ara:qwerty_digits, description = Arabic
- { "ara", "qwerty_digits", Qt::RightToLeft, QLocale::Arabic, QLocale::UnitedArabEmirates },
- // name = al, description = Albania
- { "al", "", Qt::LeftToRight, QLocale::Albanian, QLocale::Albania },
- // name = am, description = Armenia
- { "am", "", Qt::LeftToRight, QLocale::Armenian, QLocale::Armenia },
- // name = am:phonetic, description = Armenia
- { "am", "phonetic", Qt::LeftToRight, QLocale::Armenian, QLocale::Armenia },
- // name = az, description = Azerbaijan
- { "az", "", Qt::LeftToRight, QLocale::Azerbaijani, QLocale::Azerbaijan },
- // name = az:cyrillic, description = Azerbaijan
- { "az", "cyrillic", Qt::LeftToRight, QLocale::Azerbaijani, QLocale::Azerbaijan },
- // name = by, description = Belarus
- { "by", "", Qt::LeftToRight, QLocale::Byelorussian, QLocale::Belarus },
- // name = by:winkeys, description = Belarus
- { "by", "winkeys", Qt::LeftToRight, QLocale::Byelorussian, QLocale::Belarus },
- // name = be, description = Belgium
- { "be", "", Qt::LeftToRight, QLocale::Dutch, QLocale::Belgium },
- // name = be:iso-alternate, description = Belgium
- { "be", "iso-alternate", Qt::LeftToRight, QLocale::Dutch, QLocale::Belgium },
- // name = be:nodeadkeys, description = Belgium
- { "be", "nodeadkeys", Qt::LeftToRight, QLocale::Dutch, QLocale::Belgium },
- // name = be:sundeadkeys, description = Belgium
- { "be", "sundeadkeys", Qt::LeftToRight, QLocale::Dutch, QLocale::Belgium },
- // name = bd, description = Bangladesh
- { "bd", "", Qt::LeftToRight, QLocale::Bengali, QLocale::Bangladesh },
- // name = bd:probhat, description = Bangladesh
- { "bd", "probhat", Qt::LeftToRight, QLocale::Bengali, QLocale::Bangladesh },
- // name = in, description = India
- { "in", "", Qt::LeftToRight, QLocale::Hindi, QLocale::India },
- // name = in:ben, description = India
- { "in", "ben", Qt::LeftToRight, QLocale::Bengali, QLocale::India },
- // name = in:ben_probhat, description = India
- { "in", "ben_probhat", Qt::LeftToRight, QLocale::Bengali, QLocale::India },
- // name = in:guj, description = India
- { "in", "guj", Qt::LeftToRight, QLocale::Gujarati, QLocale::India },
- // name = in:guru, description = India
- { "in", "guru", Qt::LeftToRight, QLocale::Punjabi, QLocale::India },
- // name = in:kan, description = India
- { "in", "kan", Qt::LeftToRight, QLocale::Kannada, QLocale::India },
- // name = in:mal, description = India
- { "in", "mal", Qt::LeftToRight, QLocale::Malayalam, QLocale::India },
- // name = in:ori, description = India
- { "in", "ori", Qt::LeftToRight, QLocale::Oriya, QLocale::India },
- // name = in:tam_unicode, description = India
- { "in", "tam_unicode", Qt::LeftToRight, QLocale::Tamil, QLocale::India },
- // name = in:tam_TAB, description = India
- { "in", "tam_TAB", Qt::LeftToRight, QLocale::Tamil, QLocale::India },
- // name = in:tam_TSCII, description = India
- { "in", "tam_TSCII", Qt::LeftToRight, QLocale::Tamil, QLocale::India },
- // name = in:tam, description = India
- { "in", "tam", Qt::LeftToRight, QLocale::Tamil, QLocale::India },
- // name = in:tel, description = India
- { "in", "tel", Qt::LeftToRight, QLocale::Telugu, QLocale::India },
- // name = in:urd, description = India
- { "in", "urd", Qt::RightToLeft, QLocale::Urdu, QLocale::India },
- // name = ba, description = Bosnia and Herzegovina
- { "ba", "", Qt::LeftToRight, QLocale::Bosnian, QLocale::BosniaAndHerzegowina },
- // name = br, description = Brazil
- { "br", "", Qt::LeftToRight, QLocale::Portuguese, QLocale::Brazil },
- // name = br:nodeadkeys, description = Brazil
- { "br", "nodeadkeys", Qt::LeftToRight, QLocale::Portuguese, QLocale::Brazil },
- // name = bg, description = Bulgaria
- { "bg", "", Qt::LeftToRight, QLocale::Bulgarian, QLocale::Bulgaria },
- // name = bg:phonetic, description = Bulgaria
- { "bg", "phonetic", Qt::LeftToRight, QLocale::Bulgarian, QLocale::Bulgaria },
- // name = mm, description = Myanmar
- { "mm", "", Qt::LeftToRight, QLocale::Burmese, QLocale::Myanmar },
- // name = ca, description = Canada
- { "ca", "", Qt::LeftToRight, QLocale::English, QLocale::Canada },
- // name = ca:fr-dvorak, description = Canada
- { "ca", "fr-dvorak", Qt::LeftToRight, QLocale::French, QLocale::Canada },
- // name = ca:fr-legacy, description = Canada
- { "ca", "fr-legacy", Qt::LeftToRight, QLocale::French, QLocale::Canada },
- // name = ca:multi, description = Canada
- { "ca", "multi", Qt::LeftToRight, QLocale::English, QLocale::Canada },
- // name = ca:multi-2gr, description = Canada
- { "ca", "multi-2gr", Qt::LeftToRight, QLocale::English, QLocale::Canada },
- // name = ca:ike, description = Canada
- { "ca", "ike", Qt::LeftToRight, QLocale::Inuktitut, QLocale::Canada },
- // name = hr, description = Croatia
- { "hr", "", Qt::LeftToRight, QLocale::Croatian, QLocale::Croatia },
- // name = hr:us, description = Croatia
- { "hr", "us", Qt::LeftToRight, QLocale::Croatian, QLocale::Croatia },
- // name = cz, description = Czechia
- { "cz", "", Qt::LeftToRight, QLocale::Czech, QLocale::CzechRepublic },
- // name = cz:bksl, description = Czechia
- { "cz", "bksl", Qt::LeftToRight, QLocale::Czech, QLocale::CzechRepublic },
- // name = cz:qwerty, description = Czechia
- { "cz", "qwerty", Qt::LeftToRight, QLocale::Czech, QLocale::CzechRepublic },
- // name = cz:qwerty_bksl, description = Czechia
- { "cz", "qwerty_bksl", Qt::LeftToRight, QLocale::Czech, QLocale::CzechRepublic },
- // name = dk, description = Denmark
- { "dk", "", Qt::LeftToRight, QLocale::Danish, QLocale::Denmark },
- // name = dk:nodeadkeys, description = Denmark
- { "dk", "nodeadkeys", Qt::LeftToRight, QLocale::Danish, QLocale::Denmark },
- // name = nl, description = Netherlands
- { "nl", "", Qt::LeftToRight, QLocale::Dutch, QLocale::Netherlands },
- // name = bt, description = Bhutan
- { "bt", "", Qt::LeftToRight, QLocale::Bhutani, QLocale::Bhutan },
- // name = ee, description = Estonia
- { "ee", "", Qt::LeftToRight, QLocale::Estonian, QLocale::Estonia },
- // name = ee:nodeadkeys, description = Estonia
- { "ee", "nodeadkeys", Qt::LeftToRight, QLocale::Estonian, QLocale::Estonia },
- // name = ir, description = Iran
- { "ir", "", Qt::RightToLeft, QLocale::Persian, QLocale::Iran },
- // name = fo, description = Faroe Islands
- { "fo", "", Qt::LeftToRight, QLocale::Faroese, QLocale::FaroeIslands },
- // name = fo:nodeadkeys, description = Faroe Islands
- { "fo", "nodeadkeys", Qt::LeftToRight, QLocale::Faroese, QLocale::FaroeIslands },
- // name = fi, description = Finland
- { "fi", "", Qt::LeftToRight, QLocale::Finnish, QLocale::Finland },
- // name = fi:nodeadkeys, description = Finland
- { "fi", "nodeadkeys", Qt::LeftToRight, QLocale::Finnish, QLocale::Finland },
- // name = fi:smi, description = Finland
- { "fi", "smi", Qt::LeftToRight, QLocale::Finnish, QLocale::Finland },
- // name = fr, description = France
- { "fr", "", Qt::LeftToRight, QLocale::French, QLocale::France },
- // name = fr:nodeadkeys, description = France
- { "fr", "nodeadkeys", Qt::LeftToRight, QLocale::French, QLocale::France },
- // name = fr:sundeadkeys, description = France
- { "fr", "sundeadkeys", Qt::LeftToRight, QLocale::French, QLocale::France },
- // name = fr:latin9, description = France
- { "fr", "latin9", Qt::LeftToRight, QLocale::French, QLocale::France },
- // name = fr:latin9_nodeadkeys, description = France
- { "fr", "latin9_nodeadkeys", Qt::LeftToRight, QLocale::French, QLocale::France },
- // name = fr:latin9_sundeadkeys, description = France
- { "fr", "latin9_sundeadkeys", Qt::LeftToRight, QLocale::French, QLocale::France },
- // name = fr:dvorak, description = France
- { "fr", "dvorak", Qt::LeftToRight, QLocale::French, QLocale::France },
- // name = ge, description = Georgia
- { "ge", "", Qt::LeftToRight, QLocale::Georgian, QLocale::Georgia },
- // name = ge:ru, description = Georgia
- { "ge", "ru", Qt::LeftToRight, QLocale::Russian, QLocale::Georgia },
- // name = de, description = Germany
- { "de", "", Qt::LeftToRight, QLocale::German, QLocale::Germany },
- // name = de:deadacute, description = Germany
- { "de", "deadacute", Qt::LeftToRight, QLocale::German, QLocale::Germany },
- // name = de:deadgraveacute, description = Germany
- { "de", "deadgraveacute", Qt::LeftToRight, QLocale::German, QLocale::Germany },
- // name = de:nodeadkeys, description = Germany
- { "de", "nodeadkeys", Qt::LeftToRight, QLocale::German, QLocale::Germany },
- // name = de:ro, description = Germany
- { "de", "ro", Qt::LeftToRight, QLocale::Romanian, QLocale::Germany },
- // name = de:ro_nodeadkeys, description = Germany
- { "de", "ro_nodeadkeys", Qt::LeftToRight, QLocale::Romanian, QLocale::Germany },
- // name = de:dvorak, description = Germany
- { "de", "dvorak", Qt::LeftToRight, QLocale::German, QLocale::Germany },
- // name = gr, description = Greece
- { "gr", "", Qt::LeftToRight, QLocale::Greek, QLocale::Greece },
- // name = gr:extended, description = Greece
- { "gr", "extended", Qt::LeftToRight, QLocale::Greek, QLocale::Greece },
- // name = gr:nodeadkeys, description = Greece
- { "gr", "nodeadkeys", Qt::LeftToRight, QLocale::Greek, QLocale::Greece },
- // name = gr:polytonic, description = Greece
- { "gr", "polytonic", Qt::LeftToRight, QLocale::Greek, QLocale::Greece },
- // name = hu, description = Hungary
- { "hu", "", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:standard, description = Hungary
- { "hu", "standard", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:nodeadkeys, description = Hungary
- { "hu", "nodeadkeys", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:qwerty, description = Hungary
- { "hu", "qwerty", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwertz_comma_dead, description = Hungary
- { "hu", "101_qwertz_comma_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwertz_comma_nodead, description = Hungary
- { "hu", "101_qwertz_comma_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwertz_dot_dead, description = Hungary
- { "hu", "101_qwertz_dot_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwertz_dot_nodead, description = Hungary
- { "hu", "101_qwertz_dot_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwerty_comma_dead, description = Hungary
- { "hu", "101_qwerty_comma_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwerty_comma_nodead, description = Hungary
- { "hu", "101_qwerty_comma_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwerty_dot_dead, description = Hungary
- { "hu", "101_qwerty_dot_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:101_qwerty_dot_nodead, description = Hungary
- { "hu", "101_qwerty_dot_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwertz_comma_dead, description = Hungary
- { "hu", "102_qwertz_comma_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwertz_comma_nodead, description = Hungary
- { "hu", "102_qwertz_comma_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwertz_dot_dead, description = Hungary
- { "hu", "102_qwertz_dot_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwertz_dot_nodead, description = Hungary
- { "hu", "102_qwertz_dot_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwerty_comma_dead, description = Hungary
- { "hu", "102_qwerty_comma_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwerty_comma_nodead, description = Hungary
- { "hu", "102_qwerty_comma_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwerty_dot_dead, description = Hungary
- { "hu", "102_qwerty_dot_dead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = hu:102_qwerty_dot_nodead, description = Hungary
- { "hu", "102_qwerty_dot_nodead", Qt::LeftToRight, QLocale::Hungarian, QLocale::Hungary },
- // name = is, description = Iceland
- { "is", "", Qt::LeftToRight, QLocale::Icelandic, QLocale::Iceland },
- // name = is:Sundeadkeys, description = Iceland
- { "is", "Sundeadkeys", Qt::LeftToRight, QLocale::Icelandic, QLocale::Iceland },
- // name = is:nodeadkeys, description = Iceland
- { "is", "nodeadkeys", Qt::LeftToRight, QLocale::Icelandic, QLocale::Iceland },
- // name = il, description = Israel
- { "il", "", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel },
- // name = il:lyx, description = Israel
- { "il", "lyx", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel },
- // name = il:si1452, description = Israel
- { "il", "si1452", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel },
- // name = il:phonetic, description = Israel
- { "il", "phonetic", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel },
- // name = it, description = Italy
- { "it", "", Qt::LeftToRight, QLocale::Italian, QLocale::Italy },
- // name = it:nodeadkeys, description = Italy
- { "it", "nodeadkeys", Qt::LeftToRight, QLocale::Italian, QLocale::Italy },
- // name = jp, description = Japan
- { "jp", "", Qt::LeftToRight, QLocale::Japanese, QLocale::Japan },
- // name = kg, description = Kyrgyzstan
- { "kg", "", Qt::LeftToRight, QLocale::Kirghiz, QLocale::Kyrgyzstan },
- // name = la, description = Laos
- { "la", "", Qt::LeftToRight, QLocale::Laothian, QLocale::Lao },
- // name = latam, description = Latin American
- { "latam", "", Qt::LeftToRight, QLocale::Spanish, QLocale::Mexico },
- // name = latam:nodeadkeys, description = Latin American
- { "latam", "nodeadkeys", Qt::LeftToRight, QLocale::Spanish, QLocale::Mexico },
- // name = latam:sundeadkeys, description = Latin American
- { "latam", "sundeadkeys", Qt::LeftToRight, QLocale::Spanish, QLocale::Mexico },
- // name = lt, description = Lithuania
- { "lt", "", Qt::LeftToRight, QLocale::Lithuanian, QLocale::Lithuania },
- // name = lt:std, description = Lithuania
- { "lt", "std", Qt::LeftToRight, QLocale::Lithuanian, QLocale::Lithuania },
- // name = lt:us, description = Lithuania
- { "lt", "us", Qt::LeftToRight, QLocale::Lithuanian, QLocale::Lithuania },
- // name = lv, description = Latvia
- { "lv", "", Qt::LeftToRight, QLocale::Latvian, QLocale::Latvia },
- // name = lv:apostrophe, description = Latvia
- { "lv", "apostrophe", Qt::LeftToRight, QLocale::Latvian, QLocale::Latvia },
- // name = lv:tilde, description = Latvia
- { "lv", "tilde", Qt::LeftToRight, QLocale::Latvian, QLocale::Latvia },
- // name = lv:fkey, description = Latvia
- { "lv", "fkey", Qt::LeftToRight, QLocale::Latvian, QLocale::Latvia },
- // name = mao, description = Maori
- { "mao", "", Qt::LeftToRight, QLocale::Maori, QLocale::NewZealand },
- // name = mkd, description = Macedonian
- { "mkd", "", Qt::LeftToRight, QLocale::Macedonian, QLocale::Macedonia },
- // name = mkd:nodeadkeys, description = Macedonian
- { "mkd", "nodeadkeys", Qt::LeftToRight, QLocale::Macedonian, QLocale::Macedonia },
- // name = mt, description = Malta
- { "mt", "", Qt::LeftToRight, QLocale::Maltese, QLocale::Malta },
- // name = mt:us, description = Malta
- { "mt", "us", Qt::LeftToRight, QLocale::Maltese, QLocale::Malta },
- // name = mn, description = Mongolia
- { "mn", "", Qt::LeftToRight, QLocale::Mongolian, QLocale::Mongolia },
- // name = no, description = Norway
- { "no", "", Qt::LeftToRight, QLocale::Norwegian, QLocale::Norway },
- // name = no:nodeadkeys, description = Norway
- { "no", "nodeadkeys", Qt::LeftToRight, QLocale::Norwegian, QLocale::Norway },
- // name = no:dvorak, description = Norway
- { "no", "dvorak", Qt::LeftToRight, QLocale::Norwegian, QLocale::Norway },
- // name = no:smi, description = Norway
- { "no", "smi", Qt::LeftToRight, QLocale::Norwegian, QLocale::Norway },
- // name = no:smi_nodeadkeys, description = Norway
- { "no", "smi_nodeadkeys", Qt::LeftToRight, QLocale::Norwegian, QLocale::Norway },
- // name = pl, description = Poland
- { "pl", "", Qt::LeftToRight, QLocale::Polish, QLocale::Poland },
- // name = pl:qwertz, description = Poland
- { "pl", "qwertz", Qt::LeftToRight, QLocale::Polish, QLocale::Poland },
- // name = pl:dvorak, description = Poland
- { "pl", "dvorak", Qt::LeftToRight, QLocale::Polish, QLocale::Poland },
- // name = pl:dvorak_quotes, description = Poland
- { "pl", "dvorak_quotes", Qt::LeftToRight, QLocale::Polish, QLocale::Poland },
- // name = pl:dvorak_altquotes, description = Poland
- { "pl", "dvorak_altquotes", Qt::LeftToRight, QLocale::Polish, QLocale::Poland },
- // name = pt, description = Portugal
- { "pt", "", Qt::LeftToRight, QLocale::Portuguese, QLocale::Portugal },
- // name = pt:nodeadkeys, description = Portugal
- { "pt", "nodeadkeys", Qt::LeftToRight, QLocale::Portuguese, QLocale::Portugal },
- // name = pt:sundeadkeys, description = Portugal
- { "pt", "sundeadkeys", Qt::LeftToRight, QLocale::Portuguese, QLocale::Portugal },
- // name = ro, description = Romania
- { "ro", "", Qt::LeftToRight, QLocale::Romanian, QLocale::Romania },
- // name = ro:us, description = Romania
- { "ro", "us", Qt::LeftToRight, QLocale::English, QLocale::Romania },
- // name = ro:de, description = Romania
- { "ro", "de", Qt::LeftToRight, QLocale::German, QLocale::Romania },
- // name = ru, description = Russia
- { "ru", "", Qt::LeftToRight, QLocale::Russian, QLocale::RussianFederation },
- // name = ru:phonetic, description = Russia
- { "ru", "phonetic", Qt::LeftToRight, QLocale::Russian, QLocale::RussianFederation },
- // name = ru:typewriter, description = Russia
- { "ru", "typewriter", Qt::LeftToRight, QLocale::Russian, QLocale::RussianFederation },
- // name = ru:winkeys, description = Russia
- { "ru", "winkeys", Qt::LeftToRight, QLocale::Russian, QLocale::RussianFederation },
- // name = srp, description = Serbian
- { "srp", "", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = srp:yz, description = Serbian
- { "srp", "yz", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = srp:latin, description = Serbian
- { "srp", "latin", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = srp:latinunicode, description = Serbian
- { "srp", "latinunicode", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = srp:latinyz, description = Serbian
- { "srp", "latinyz", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = srp:latinunicodeyz, description = Serbian
- { "srp", "latinunicodeyz", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = srp:alternatequotes, description = Serbian
- { "srp", "alternatequotes", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = srp:latinalternatequotes, description = Serbian
- { "srp", "latinalternatequotes", Qt::LeftToRight, QLocale::Serbian, QLocale::SerbiaAndMontenegro },
- // name = si, description = Slovenia
- { "si", "", Qt::LeftToRight, QLocale::Slovenian, QLocale::Slovenia },
- // name = sk, description = Slovakia
- { "sk", "", Qt::LeftToRight, QLocale::Slovak, QLocale::Slovakia },
- // name = sk:bksl, description = Slovakia
- { "sk", "bksl", Qt::LeftToRight, QLocale::Slovak, QLocale::Slovakia },
- // name = sk:qwerty, description = Slovakia
- { "sk", "qwerty", Qt::LeftToRight, QLocale::Slovak, QLocale::Slovakia },
- // name = sk:qwerty_bksl, description = Slovakia
- { "sk", "qwerty_bksl", Qt::LeftToRight, QLocale::Slovak, QLocale::Slovakia },
- // name = es, description = Spain
- { "es", "", Qt::LeftToRight, QLocale::Spanish, QLocale::Spain },
- // name = es:nodeadkeys, description = Spain
- { "es", "nodeadkeys", Qt::LeftToRight, QLocale::Spanish, QLocale::Spain },
- // name = es:sundeadkeys, description = Spain
- { "es", "sundeadkeys", Qt::LeftToRight, QLocale::Spanish, QLocale::Spain },
- // name = es:dvorak, description = Spain
- { "es", "dvorak", Qt::LeftToRight, QLocale::Spanish, QLocale::Spain },
- // name = se, description = Sweden
- { "se", "", Qt::LeftToRight, QLocale::Swedish, QLocale::Sweden },
- // name = se:nodeadkeys, description = Sweden
- { "se", "nodeadkeys", Qt::LeftToRight, QLocale::Swedish, QLocale::Sweden },
- // name = se:dvorak, description = Sweden
- { "se", "dvorak", Qt::LeftToRight, QLocale::Swedish, QLocale::Sweden },
- // name = se:rus, description = Sweden
- { "se", "rus", Qt::LeftToRight, QLocale::Russian, QLocale::Sweden },
- // name = se:rus_nodeadkeys, description = Sweden
- { "se", "rus_nodeadkeys", Qt::LeftToRight, QLocale::Russian, QLocale::Sweden },
- // name = se:smi, description = Sweden
- { "se", "smi", Qt::LeftToRight, QLocale::Swedish, QLocale::Sweden },
- // name = ch, description = Switzerland
- { "ch", "", Qt::LeftToRight, QLocale::German, QLocale::Switzerland },
- // name = ch:de_nodeadkeys, description = Switzerland
- { "ch", "de_nodeadkeys", Qt::LeftToRight, QLocale::German, QLocale::Switzerland },
- // name = ch:de_sundeadkeys, description = Switzerland
- { "ch", "de_sundeadkeys", Qt::LeftToRight, QLocale::German, QLocale::Switzerland },
- // name = ch:fr, description = Switzerland
- { "ch", "fr", Qt::LeftToRight, QLocale::French, QLocale::Switzerland },
- // name = ch:fr_nodeadkeys, description = Switzerland
- { "ch", "fr_nodeadkeys", Qt::LeftToRight, QLocale::French, QLocale::Switzerland },
- // name = ch:fr_sundeadkeys, description = Switzerland
- { "ch", "fr_sundeadkeys", Qt::LeftToRight, QLocale::French, QLocale::Switzerland },
- // name = sy, description = Syria
- { "sy", "", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic },
- // name = sy:syc, description = Syria
- { "sy", "syc", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic },
- // name = sy:syc_phonetic, description = Syria
- { "sy", "syc_phonetic", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic },
- // name = tj, description = Tajikistan
- { "tj", "", Qt::LeftToRight, QLocale::Tajik, QLocale::Tajikistan },
- // name = lk, description = Sri Lanka
- { "lk", "", Qt::LeftToRight, QLocale::Singhalese, QLocale::SriLanka },
- // name = lk:tam_unicode, description = Sri Lanka
- { "lk", "tam_unicode", Qt::LeftToRight, QLocale::Tamil, QLocale::SriLanka },
- // name = lk:tam_TAB, description = Sri Lanka
- { "lk", "tam_TAB", Qt::LeftToRight, QLocale::Tamil, QLocale::SriLanka },
- // name = lk:tam_TSCII, description = Sri Lanka
- { "lk", "tam_TSCII", Qt::LeftToRight, QLocale::Tamil, QLocale::SriLanka },
- // name = lk:sin_phonetic, description = Sri Lanka
- { "lk", "sin_phonetic", Qt::LeftToRight, QLocale::Singhalese, QLocale::SriLanka },
- // name = th, description = Thailand
- { "th", "", Qt::LeftToRight, QLocale::Thai, QLocale::Thailand },
- // name = th:tis, description = Thailand
- { "th", "tis", Qt::LeftToRight, QLocale::Thai, QLocale::Thailand },
- // name = th:pat, description = Thailand
- { "th", "pat", Qt::LeftToRight, QLocale::Thai, QLocale::Thailand },
- // name = tr, description = Turkish
- { "tr", "", Qt::LeftToRight, QLocale::Turkish, QLocale::Turkey },
- // name = tr:f, description = Turkish
- { "tr", "f", Qt::LeftToRight, QLocale::Turkish, QLocale::Turkey },
- // name = tr:alt, description = Turkish
- { "tr", "alt", Qt::LeftToRight, QLocale::Turkish, QLocale::Turkey },
- // name = ua, description = Ukraine
- { "ua", "", Qt::LeftToRight, QLocale::Ukrainian, QLocale::Ukraine },
- // name = ua:phonetic, description = Ukraine
- { "ua", "phonetic", Qt::LeftToRight, QLocale::Ukrainian, QLocale::Ukraine },
- // name = ua:typewriter, description = Ukraine
- { "ua", "typewriter", Qt::LeftToRight, QLocale::Ukrainian, QLocale::Ukraine },
- // name = ua:winkeys, description = Ukraine
- { "ua", "winkeys", Qt::LeftToRight, QLocale::Ukrainian, QLocale::Ukraine },
- // name = ua:rstu, description = Ukraine
- { "ua", "rstu", Qt::LeftToRight, QLocale::Ukrainian, QLocale::Ukraine },
- // name = ua:rstu_ru, description = Ukraine
- { "ua", "rstu_ru", Qt::LeftToRight, QLocale::Ukrainian, QLocale::Ukraine },
- // name = gb, description = United Kingdom
- { "gb", "", Qt::LeftToRight, QLocale::English, QLocale::UnitedKingdom },
- // name = gb:intl, description = United Kingdom
- { "gb", "intl", Qt::LeftToRight, QLocale::English, QLocale::UnitedKingdom },
- // name = gb:dvorak, description = United Kingdom
- { "gb", "dvorak", Qt::LeftToRight, QLocale::English, QLocale::UnitedKingdom },
- // name = uz, description = Uzbekistan
- { "uz", "", Qt::LeftToRight, QLocale::Uzbek, QLocale::Uzbekistan },
- // name = vn, description = Vietnam
- { "vn", "", Qt::LeftToRight, QLocale::Vietnamese, QLocale::VietNam },
- // name = nec_vndr/jp, description = PC-98xx Series
- { "nec_vndr/jp", "", Qt::LeftToRight, QLocale::Japanese, QLocale::Japan },
- // name = ie, description = Ireland
- { "ie", "", Qt::LeftToRight, QLocale::Irish, QLocale::Ireland },
- // name = ie:CloGaelach, description = Ireland
- { "ie", "CloGaelach", Qt::LeftToRight, QLocale::Gaelic, QLocale::Ireland },
- // name = ie:UnicodeExpert, description = Ireland
- { "ie", "UnicodeExpert", Qt::LeftToRight, QLocale::Irish, QLocale::Ireland },
- // name = ie:ogam, description = Ireland
- { "ie", "ogam", Qt::LeftToRight, QLocale::Gaelic, QLocale::Ireland },
- // name = ie:ogam_is434, description = Ireland
- { "ie", "ogam_is434", Qt::LeftToRight, QLocale::Gaelic, QLocale::Ireland },
- // name = pk, description = Pakistan
- { "pk", "", Qt::RightToLeft, QLocale::Urdu, QLocale::Pakistan },
- { 0, 0, Qt::LeftToRight, QLocale::C, QLocale::AnyCountry }
-};
diff --git a/src/widgets/platforms/x11/qmotifdnd_x11.cpp b/src/widgets/platforms/x11/qmotifdnd_x11.cpp
deleted file mode 100644
index 77f6ce5827..0000000000
--- a/src/widgets/platforms/x11/qmotifdnd_x11.cpp
+++ /dev/null
@@ -1,1031 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/* The following copyright notice pertains to the code as contributed
-to Qt, not to Nokia's modifications. It is replicated
-in doc/dnd.doc, where the documentation system can see it. */
-
-/* Copyright 1996 Daniel Dardailler.
-
- Permission to use, copy, modify, distribute, and sell this software
- for any purpose is hereby granted without fee, provided that the above
- copyright notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting documentation,
- and that the name of Daniel Dardailler not be used in advertising or
- publicity pertaining to distribution of the software without specific,
- written prior permission. Daniel Dardailler makes no representations
- about the suitability of this software for any purpose. It is
- provided "as is" without express or implied warranty.
-
- Modifications Copyright 1999 Matt Koss, under the same license as
- above.
-************************************************************/
-
-/***********************************************************/
-/* Motif Drag&Drop Dynamic Protocol messaging API code */
-/* Only requires Xlib layer - not MT safe */
-/* Author: Daniel Dardailler, daniel@x.org */
-/* Adapted by: Matt Koss, koss@napri.sk */
-/* Further adaptions by: Nokia Corporation and/or its subsidiary(-ies) */
-/***********************************************************/
-
-#include "qplatformdefs.h"
-
-#include "qapplication.h"
-
-#ifndef QT_NO_DRAGANDDROP
-
-#include "qdebug.h"
-#include "qtextcodec.h"
-#include "qwidget.h"
-#include "qevent.h"
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-#include "qiodevice.h"
-#include "qdnd_p.h"
-
-#include <stdlib.h>
-
-QT_BEGIN_NAMESPACE
-
-static Window sourceWindow = XNone;
-static QWidget *dropWidget = 0;
-static Qt::DropAction lastAcceptedAction = Qt::IgnoreAction;
-
-static Atom Dnd_selection = 0;
-static Time Dnd_selection_time;
-
-static Atom * src_targets ;
-static ushort num_src_targets ;
-
-// Motif definitions
-#define DndVersion 1
-#define DndRevision 0
-#define DndIncludeVersion (DndVersion * 10 + DndRevision)
-
-/* The following values are used in the DndData structure */
-
-/* protocol style */
-#define DND_DRAG_NONE 0
-#define DND_DRAG_DROP_ONLY 1
-#define DND_DRAG_DYNAMIC 5
-
-/* message type */
-#define DND_TOP_LEVEL_ENTER 0
-#define DND_TOP_LEVEL_LEAVE 1
-#define DND_DRAG_MOTION 2
-#define DND_DROP_SITE_ENTER 3
-#define DND_DROP_SITE_LEAVE 4
-#define DND_DROP_START 5
-#define DND_OPERATION_CHANGED 8
-
-/* operation(s) */
-#define DND_NOOP 0L
-#define DND_MOVE (1L << 0)
-#define DND_COPY (1L << 1)
-#define DND_LINK (1L << 2)
-
-static Qt::DropActions DndOperationsToQtDropActions(uchar op)
-{
- Qt::DropActions actions = Qt::IgnoreAction;
- if (op | DND_MOVE)
- actions |= Qt::MoveAction;
- if (op | DND_COPY)
- actions |= Qt::CopyAction;
- if (op | DND_LINK)
- actions |= Qt::LinkAction;
- return actions;
-}
-
-static uchar QtDropActionToDndOperation(Qt::DropAction action)
-{
- switch (action & Qt::ActionMask) {
- case Qt::CopyAction:
- default:
- return DND_COPY;
- case Qt::MoveAction:
- return DND_MOVE;
- case Qt::LinkAction:
- return DND_LINK;
- }
-}
-
-
-/* status */
-#define DND_NO_DROP_SITE 1
-#define DND_INVALID_DROP_SITE 2
-#define DND_VALID_DROP_SITE 3
-
-/* completion */
-#define DND_DROP 0
-#define DND_DROP_HELP 1
-#define DND_DROP_CANCEL 2
-
-#define BYTE unsigned char
-#define CARD32 unsigned int
-#define CARD16 unsigned short
-#define INT16 signed short
-
-/* Client side structure used in the API */
-typedef struct {
- unsigned char reason; /* message type: DND_TOP_LEVEL_ENTER, etc */
- Time time ;
- unsigned char operation;
- unsigned char operations;
- unsigned char status;
- unsigned char completion;
- short x ;
- short y ;
- Window src_window ;
- Atom property ;
-} DndData ;
-
-
-typedef struct _DndSrcProp {
- BYTE byte_order ;
- BYTE protocol_version ;
- CARD16 target_index ;
- CARD32 selection ;
-} DndSrcProp ;
-
-typedef struct _DndReceiverProp {
- BYTE byte_order ;
- BYTE protocol_version ;
- BYTE protocol_style ;
- BYTE pad1;
- CARD32 proxy_window;
- CARD16 num_drop_sites ;
- CARD16 pad2;
- CARD32 total_size;
-} DndReceiverProp ;
-
-/* need to use some union hack since window and property are in
- different order depending on the message ... */
-typedef struct _DndTop {
- CARD32 src_window;
- CARD32 property;
-} DndTop ;
-
-typedef struct _DndPot {
- INT16 x;
- INT16 y;
- CARD32 property;
- CARD32 src_window;
-} DndPot ;
-
-typedef struct _DndMessage {
- BYTE reason;
- BYTE byte_order;
- CARD16 flags;
- CARD32 time;
- union {
- DndTop top ;
- DndPot pot ;
- } data ;
-} DndMessage ;
-
-typedef struct {
- BYTE byte_order;
- BYTE protocol_version;
- CARD16 num_target_lists;
- CARD32 data_size;
- /* then come series of CARD16,CARD32,CARD32,CARD32... */
-} DndTargets;
-
-
-/* protocol version */
-#define DND_PROTOCOL_VERSION 0
-
-
-#define DND_EVENT_TYPE_MASK ((BYTE)0x80)
-#define DND_EVENT_TYPE_SHIFT 7
-#define DND_CLEAR_EVENT_TYPE ((BYTE)0x7F)
-
-/* message_type is data[0] of the client_message
- this return 1 (receiver bit up) or 0 (initiator) */
-#define DND_GET_EVENT_TYPE(message_type) \
-((char) (((message_type) & DND_EVENT_TYPE_MASK) >> DND_EVENT_TYPE_SHIFT))
-
-/* event_type can be 0 (initiator) or 1 (receiver) */
-#define DND_SET_EVENT_TYPE(event_type) \
-(((BYTE)(event_type) << DND_EVENT_TYPE_SHIFT) & DND_EVENT_TYPE_MASK)
-
-
-#define DND_OPERATION_MASK ((CARD16) 0x000F)
-#define DND_OPERATION_SHIFT 0
-#define DND_STATUS_MASK ((CARD16) 0x00F0)
-#define DND_STATUS_SHIFT 4
-#define DND_OPERATIONS_MASK ((CARD16) 0x0F00)
-#define DND_OPERATIONS_SHIFT 8
-#define DND_COMPLETION_MASK ((CARD16) 0xF000)
-#define DND_COMPLETION_SHIFT 12
-
-#define DND_GET_OPERATION(flags) \
-((unsigned char) \
-(((flags) & DND_OPERATION_MASK) >> DND_OPERATION_SHIFT))
-
-#define DND_SET_OPERATION(operation) \
-(((CARD16)(operation) << DND_OPERATION_SHIFT)\
-& DND_OPERATION_MASK)
-
-#define DND_GET_STATUS(flags) \
-((unsigned char) \
-(((flags) & DND_STATUS_MASK) >> DND_STATUS_SHIFT))
-
-#define DND_SET_STATUS(status) \
-(((CARD16)(status) << DND_STATUS_SHIFT)\
-& DND_STATUS_MASK)
-
-#define DND_GET_OPERATIONS(flags) \
-((unsigned char) \
-(((flags) & DND_OPERATIONS_MASK) >> DND_OPERATIONS_SHIFT))
-
-#define DND_SET_OPERATIONS(operation) \
-(((CARD16)(operation) << DND_OPERATIONS_SHIFT)\
-& DND_OPERATIONS_MASK)
-
-#define DND_GET_COMPLETION(flags) \
-((unsigned char) \
-(((flags) & DND_COMPLETION_MASK) >> DND_COMPLETION_SHIFT))
-
-#define DND_SET_COMPLETION(completion) \
-(((CARD16)(completion) << DND_COMPLETION_SHIFT)\
-& DND_COMPLETION_MASK)
-
-
-#define SWAP4BYTES(l) {\
-struct { unsigned t :32;} bit32;\
-char n, *tp = (char *) &bit32;\
-bit32.t = l;\
-n = tp[0]; tp[0] = tp[3]; tp[3] = n;\
-n = tp[1]; tp[1] = tp[2]; tp[2] = n;\
-l = bit32.t;\
-}
-
-#define SWAP2BYTES(s) {\
-struct { unsigned t :16; } bit16;\
-char n, *tp = (char *) &bit16;\
-bit16.t = s;\
-n = tp[0]; tp[0] = tp[1]; tp[1] = n;\
-s = bit16.t;\
-}
-
-
-/** Private extern functions */
-
-static unsigned char DndByteOrder ();
-
-
-/***** Targets/Index stuff */
-
-typedef struct {
- int num_targets;
- Atom *targets;
-} DndTargetsTableEntryRec, * DndTargetsTableEntry;
-
-typedef struct {
- int num_entries;
- DndTargetsTableEntry entries;
-} DndTargetsTableRec, * DndTargetsTable;
-
-
-static ushort _DndIndexToTargets(Display * display,
- int index,
- Atom ** targets);
-
-extern void qt_x11_intern_atom(const char *, Atom *);
-
-/////////////////////////////////////////////////////////////////
-
-static unsigned char DndByteOrder ()
-{
- static unsigned char byte_order = 0;
-
- if (!byte_order) {
- unsigned int endian = 1;
- byte_order = (*((char *)&endian))?'l':'B';
- }
- return byte_order ;
-}
-
-
-
-static void DndReadSourceProperty(Display * dpy,
- Window window, Atom dnd_selection,
- Atom ** targets, unsigned short * num_targets)
-{
- unsigned char *retval = 0;
- Atom type ;
- int format ;
- unsigned long bytesafter, lengthRtn;
-
- if ((XGetWindowProperty (dpy, window, dnd_selection, 0L, 100000L,
- False, ATOM(_MOTIF_DRAG_INITIATOR_INFO), &type,
- &format, &lengthRtn, &bytesafter,
- &retval) != Success)
- || (type == XNone)) {
- *num_targets = 0;
- return ;
- }
-
- DndSrcProp * src_prop = (DndSrcProp *)retval;
-
- if (src_prop->byte_order != DndByteOrder()) {
- SWAP2BYTES(src_prop->target_index);
- SWAP4BYTES(src_prop->selection);
- }
-
- *num_targets = _DndIndexToTargets(dpy, src_prop->target_index, targets);
-
- XFree((char*)src_prop);
-}
-
-
-/* Position the _MOTIF_DRAG_RECEIVER_INFO property on the dropsite window.
- Called by the receiver of the drop to indicate the
- supported protocol style : dynamic, drop_only or none */
-static void DndWriteReceiverProperty(Display * dpy, Window window,
- unsigned char protocol_style)
-{
- DndReceiverProp receiver_prop;
-
- // squelch potential valgrind errors about uninitialized reads
- memset(&receiver_prop, 0, sizeof(receiver_prop));
-
- receiver_prop.byte_order = DndByteOrder() ;
- receiver_prop.protocol_version = DND_PROTOCOL_VERSION;
- receiver_prop.protocol_style = protocol_style ;
- receiver_prop.proxy_window = XNone ;
- receiver_prop.num_drop_sites = 0 ;
- receiver_prop.total_size = sizeof(DndReceiverProp);
-
- /* write the buffer to the property */
- XChangeProperty (dpy, window, ATOM(_MOTIF_DRAG_RECEIVER_INFO), ATOM(_MOTIF_DRAG_RECEIVER_INFO),
- 8, PropModeReplace,
- (unsigned char *)&receiver_prop,
- sizeof(DndReceiverProp));
-}
-
-
-/* protocol style equiv (preregister stuff really) */
-#define DND_DRAG_DROP_ONLY_EQUIV 3
-#define DND_DRAG_DYNAMIC_EQUIV1 2
-#define DND_DRAG_DYNAMIC_EQUIV2 4
-
-
-/* Produce a client message to be sent by the caller */
-static void DndFillClientMessage(Display * dpy, Window window,
- XClientMessageEvent *cm,
- DndData * dnd_data,
- char receiver)
-{
- DndMessage * dnd_message = (DndMessage*)&cm->data.b[0] ;
-
- cm->display = dpy;
- cm->type = ClientMessage;
- cm->serial = LastKnownRequestProcessed(dpy);
- cm->send_event = True;
- cm->window = window;
- cm->format = 8;
- cm->message_type = ATOM(_MOTIF_DRAG_AND_DROP_MESSAGE);
-
- dnd_message->reason = dnd_data->reason | DND_SET_EVENT_TYPE(receiver);
-
- dnd_message->byte_order = DndByteOrder();
-
- /* we're filling in flags with more stuff that necessary,
- depending on the reason, but it doesn't matter */
- dnd_message->flags = 0 ;
- dnd_message->flags |= DND_SET_STATUS(dnd_data->status) ;
- dnd_message->flags |= DND_SET_OPERATION(dnd_data->operation) ;
- dnd_message->flags |= DND_SET_OPERATIONS(dnd_data->operations) ;
- dnd_message->flags |= DND_SET_COMPLETION(dnd_data->completion) ;
-
- dnd_message->time = dnd_data->time ;
-
- switch(dnd_data->reason) {
- case DND_DROP_SITE_LEAVE: break ;
- case DND_TOP_LEVEL_ENTER:
- case DND_TOP_LEVEL_LEAVE:
- dnd_message->data.top.src_window = dnd_data->src_window ;
- dnd_message->data.top.property = dnd_data->property ;
- break ; /* cannot fall through since the byte layout is different in
- both set of messages, see top and pot union stuff */
-
- case DND_DRAG_MOTION:
- case DND_OPERATION_CHANGED:
- case DND_DROP_SITE_ENTER:
- case DND_DROP_START:
- dnd_message->data.pot.x = dnd_data->x ; /* mouse position */
- dnd_message->data.pot.y = dnd_data->y ;
- dnd_message->data.pot.src_window = dnd_data->src_window ;
- dnd_message->data.pot.property = dnd_data->property ;
- break ;
- default:
- break ;
- }
-
-}
-
-static Bool DndParseClientMessage(XClientMessageEvent *cm, DndData * dnd_data,
- char * receiver)
-{
- DndMessage * dnd_message = (DndMessage*)&cm->data.b[0] ;
-
- if (cm->message_type != ATOM(_MOTIF_DRAG_AND_DROP_MESSAGE)) {
- return False ;
- }
-
- if (dnd_message->byte_order != DndByteOrder()) {
- SWAP2BYTES(dnd_message->flags);
- SWAP4BYTES(dnd_message->time);
- } /* do the rest in the switch */
-
- dnd_data->reason = dnd_message->reason ;
- if (DND_GET_EVENT_TYPE(dnd_data->reason))
- *receiver = 1 ;
- else
- *receiver = 0 ;
- dnd_data->reason &= DND_CLEAR_EVENT_TYPE ;
-
- dnd_data->time = dnd_message->time ;
-
- /* we're reading in more stuff that necessary. but who cares */
- dnd_data->status = DND_GET_STATUS(dnd_message->flags) ;
- dnd_data->operation = DND_GET_OPERATION(dnd_message->flags) ;
- dnd_data->operations = DND_GET_OPERATIONS(dnd_message->flags) ;
- dnd_data->completion = DND_GET_COMPLETION(dnd_message->flags) ;
-
- switch(dnd_data->reason) {
- case DND_TOP_LEVEL_ENTER:
- case DND_TOP_LEVEL_LEAVE:
- if (dnd_message->byte_order != DndByteOrder()) {
- SWAP4BYTES(dnd_message->data.top.src_window);
- SWAP4BYTES(dnd_message->data.top.property);
- }
- dnd_data->src_window = dnd_message->data.top.src_window ;
- dnd_data->property = dnd_message->data.top.property ;
- break ; /* cannot fall through, see above comment in write msg */
-
- case DND_DRAG_MOTION:
- case DND_OPERATION_CHANGED:
- case DND_DROP_SITE_ENTER:
- case DND_DROP_START:
- if (dnd_message->byte_order != DndByteOrder()) {
- SWAP2BYTES(dnd_message->data.pot.x);
- SWAP2BYTES(dnd_message->data.pot.y);
- SWAP4BYTES(dnd_message->data.pot.property);
- SWAP4BYTES(dnd_message->data.pot.src_window);
- }
- dnd_data->x = dnd_message->data.pot.x ;
- dnd_data->y = dnd_message->data.pot.y ;
- dnd_data->property = dnd_message->data.pot.property ;
- dnd_data->src_window = dnd_message->data.pot.src_window ;
- break ;
-
- case DND_DROP_SITE_LEAVE:
- break;
- default:
- break ;
- }
-
- return True ;
-}
-
-
-static Window MotifWindow(Display *display)
-{
- Atom type;
- int format;
- unsigned long size;
- unsigned long bytes_after;
- unsigned char *property = 0;
- Window motif_window ;
-
- /* this version does no caching, so it's slow: round trip each time */
-
- if ((XGetWindowProperty (display, RootWindow(display, 0),
- ATOM(_MOTIF_DRAG_WINDOW),
- 0L, 100000L, False, AnyPropertyType,
- &type, &format, &size, &bytes_after,
- &property) == Success) &&
- (type != XNone)) {
- motif_window = *(Window *)property;
- } else {
- XSetWindowAttributes sAttributes;
-
- /* really, this should be done on a separate connection,
- with XSetCloseDownMode (RetainPermanent), so that
- others don't have to recreate it; hopefully, some real
- Motif application will be around to do it */
-
- sAttributes.override_redirect = True;
- sAttributes.event_mask = PropertyChangeMask;
- motif_window = XCreateWindow (display,
- RootWindow (display, 0),
- -170, -560, 1, 1, 0, 0,
- InputOnly, CopyFromParent,
- (CWOverrideRedirect |CWEventMask),
- &sAttributes);
- XMapWindow (display, motif_window);
- }
-
- if (property) {
- XFree ((char *)property);
- }
-
- return (motif_window);
-}
-
-
-static DndTargetsTable TargetsTable(Display *display)
-{
- Atom type;
- int format;
- unsigned long size;
- unsigned long bytes_after;
- Window motif_window = MotifWindow(display) ;
- unsigned char *retval;
- DndTargetsTable targets_table ;
- int i,j ;
- char * target_data ;
-
- /* this version does no caching, so it's slow: round trip each time */
- /* ideally, register for property notify on this target_list
- atom and update when necessary only */
-
- if ((XGetWindowProperty (display, motif_window,
- ATOM(_MOTIF_DRAG_TARGETS), 0L, 100000L,
- False, ATOM(_MOTIF_DRAG_TARGETS),
- &type, &format, &size, &bytes_after,
- &retval) != Success) ||
- type == XNone) {
- qWarning("QMotifDND: Cannot get property on Motif window");
- return 0;
- }
-
- DndTargets * target_prop = (DndTargets *)retval;
-
- if (target_prop->protocol_version != DND_PROTOCOL_VERSION) {
- qWarning("QMotifDND: Protocol mismatch");
- }
-
- if (target_prop->byte_order != DndByteOrder()) {
- /* need to swap num_target_lists and size */
- SWAP2BYTES(target_prop->num_target_lists);
- SWAP4BYTES(target_prop->data_size);
- }
-
- /* now parse DndTarget prop data in a TargetsTable */
-
- targets_table = (DndTargetsTable)malloc(sizeof(DndTargetsTableRec));
- targets_table->num_entries = target_prop->num_target_lists ;
- targets_table->entries = (DndTargetsTableEntry)
- malloc(sizeof(DndTargetsTableEntryRec) * target_prop->num_target_lists);
-
- target_data = (char*)target_prop + sizeof(*target_prop) ;
-
- for (i = 0 ; i < targets_table->num_entries; i++) {
- CARD16 num_targets ;
- CARD32 atom ;
-
- memcpy(&num_targets, target_data, 2);
- target_data += 2;
-
- /* potential swap needed here */
- if (target_prop->byte_order != DndByteOrder())
- SWAP2BYTES(num_targets);
-
- targets_table->entries[i].num_targets = num_targets ;
- targets_table->entries[i].targets = (Atom *)
- malloc(sizeof(Atom) * targets_table->entries[i].num_targets);
-
-
- for (j = 0; j < num_targets; j++) {
- memcpy(&atom, target_data, 4);
- target_data += 4;
-
- /* another potential swap needed here */
- if (target_prop->byte_order != DndByteOrder())
- SWAP4BYTES(atom);
-
- targets_table->entries[i].targets[j] = (Atom) atom ;
- }
- }
-
- if (target_prop) {
- XFree((char *)target_prop);
- }
-
- return targets_table ;
-}
-
-
-static ushort _DndIndexToTargets(Display * display,
- int index,
- Atom ** targets)
-{
- DndTargetsTable targets_table;
- int i ;
-
- /* again, slow: no caching here, alloc/free each time */
-
- if (!(targets_table = TargetsTable (display)) ||
- (index >= targets_table->num_entries)) {
- if (targets_table)
- XFree((char*)targets_table);
- return 0;
- }
-
- /* transfer the correct target list index */
- *targets = (Atom*)malloc(sizeof(Atom)*targets_table->
- entries[index].num_targets);
- memcpy((char*)*targets,
- (char*)targets_table->entries[index].targets,
- sizeof(Atom)*targets_table->entries[index].num_targets);
-
- /* free the target table and its guts */
- for (i=0 ; i < targets_table->num_entries; i++)
- XFree((char*)targets_table->entries[i].targets);
-
- int tmp = targets_table->entries[index].num_targets;
- XFree((char*)targets_table);
-
- return tmp; // targets_table->entries[index].num_targets;
-}
-
-
-QByteArray QX11Data::motifdndFormat(int n)
-{
- if (!motifdnd_active)
- return 0; // should not happen
-
- if (n >= num_src_targets)
- return 0;
-
- Atom target = src_targets[n];
-
- if (target == XA_STRING)
- return "text/plain;charset=ISO-8859-1";
- if (target == ATOM(UTF8_STRING))
- return "text/plain;charset=UTF-8";
- if (target == ATOM(COMPOUND_TEXT))
- return QByteArray("text/plain;charset=") + QTextCodec::codecForLocale()->name();
- if (target == ATOM(TEXT))
- return "text/plain";
-
- return ("x-motif-dnd/" + X11->xdndAtomToString(target));
-}
-
-
-QVariant QX11Data::motifdndObtainData(const char *mimeType)
-{
- QByteArray result;
-
- if (Dnd_selection == 0 || !dropWidget)
- return result;
-
- // try to convert the selection to the requested property
- // qDebug("trying to convert to '%s'", mimeType);
-
- int n=0;
- QByteArray f;
- do {
- f = motifdndFormat(n);
- if (f.isEmpty())
- return result;
- n++;
- } while(qstricmp(mimeType, f.data()));
-
- Atom conversion_type = XNone;
- if (f == "text/plain;charset=ISO-8859-1") {
- conversion_type = XA_STRING;
- } else if (f == "text/plain;charset=UTF-8") {
- conversion_type = ATOM(UTF8_STRING);
- } else if (f == (QByteArray("text/plain;charset=") + QTextCodec::codecForLocale()->name())) {
- conversion_type = ATOM(COMPOUND_TEXT);
- } else if (f == "text/plain") {
- conversion_type = ATOM(TEXT);
- } else if (f.startsWith("x-motif-dnd/")) {
- // strip off the "x-motif-dnd/" prefix
- conversion_type = X11->xdndStringToAtom(f.remove(0, 12));
- }
-
- if (XGetSelectionOwner(X11->display, Dnd_selection) == XNone) {
- return result; // should never happen?
- }
-
- QWidget* tw = dropWidget;
- if ((dropWidget->windowType() == Qt::Desktop)) {
- tw = new QWidget;
- }
-
- // convert selection to the appropriate type
- XConvertSelection (X11->display, Dnd_selection, conversion_type,
- Dnd_selection, tw->internalWinId(), Dnd_selection_time);
-
- XFlush(X11->display);
-
- XEvent xevent;
- bool got=X11->clipboardWaitForEvent(tw->internalWinId(), SelectionNotify, &xevent, 5000);
- if (got) {
- Atom type;
-
- if (X11->clipboardReadProperty(tw->internalWinId(), Dnd_selection, true, &result, 0, &type, 0)) {
- }
- }
-
- // we have to convert selection in order to indicate success to the initiator
- XConvertSelection (X11->display, Dnd_selection, ATOM(XmTRANSFER_SUCCESS),
- Dnd_selection, tw->internalWinId(), Dnd_selection_time);
-
- // wait again for SelectionNotify event
- X11->clipboardWaitForEvent(tw->internalWinId(), SelectionNotify, &xevent, 5000);
-
- if ((dropWidget->windowType() == Qt::Desktop)) {
- delete tw;
- }
-
- return result;
-}
-
-
-void QX11Data::motifdndEnable(QWidget *widget, bool)
-{
- DndWriteReceiverProperty(display, widget->internalWinId(), DND_DRAG_DYNAMIC);
-}
-
-
-void QX11Data::motifdndHandle(QWidget *widget, const XEvent * xe, bool /* passive */)
-{
- XEvent event = *xe;
- XClientMessageEvent cm ;
- DndData dnd_data ;
- char receiver ;
-
- if (!(DndParseClientMessage ((XClientMessageEvent*)&event,
- &dnd_data, &receiver))) {
- return;
- }
-
- switch (dnd_data.reason) {
-
- case DND_DRAG_MOTION:
- {
- QPoint p = widget->mapFromGlobal(QPoint(dnd_data.x, dnd_data.y));
- QWidget *c = widget->childAt(p);
-
- if (!c || !c->acceptDrops()) {
- // not over a drop site
- if (dropWidget) {
- QDragLeaveEvent dragLeaveEvent;
- QApplication::sendEvent(dropWidget, &dragLeaveEvent);
-
- dropWidget = 0;
- lastAcceptedAction = Qt::IgnoreAction;
-
- dnd_data.reason = DND_DROP_SITE_LEAVE;
- dnd_data.time = X11->time;
- DndFillClientMessage (event.xclient.display, sourceWindow, &cm, &dnd_data, receiver);
- XSendEvent(event.xbutton.display, sourceWindow, False, 0, (XEvent *)&cm) ;
- } else {
- dnd_data.reason = DND_DRAG_MOTION;
- dnd_data.status = DND_NO_DROP_SITE;
- dnd_data.time = X11->time;
- dnd_data.operation = DND_NOOP;
- dnd_data.operations = DND_NOOP;
- DndFillClientMessage (event.xclient.display, sourceWindow, &cm, &dnd_data, receiver);
- XSendEvent(event.xbutton.display, sourceWindow, False, 0, (XEvent *)&cm) ;
- }
- } else {
- Q_ASSERT(c != 0);
- p = c->mapFrom(widget, p);
-
- if (dropWidget != c) {
- if (dropWidget) {
- QDragLeaveEvent le;
- QApplication::sendEvent(dropWidget, &le);
- }
-
- dropWidget = c;
- lastAcceptedAction = Qt::IgnoreAction;
-
- const Qt::DropActions possibleActions =
- DndOperationsToQtDropActions(dnd_data.operations);
- QDragEnterEvent de(p, possibleActions, QDragManager::self()->dropData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
- QApplication::sendEvent(dropWidget, &de);
-
- dnd_data.reason = DND_DROP_SITE_ENTER;
- dnd_data.time = X11->time;
- if (de.isAccepted()) {
- lastAcceptedAction = de.dropAction();
-
- dnd_data.status = DND_VALID_DROP_SITE;
- dnd_data.operation = QtDropActionToDndOperation(lastAcceptedAction);
- } else {
- dnd_data.status = DND_INVALID_DROP_SITE;
- dnd_data.operation = DND_NOOP;
- dnd_data.operations = DND_NOOP;
- }
- DndFillClientMessage (event.xclient.display, sourceWindow, &cm, &dnd_data, receiver);
- XSendEvent(event.xbutton.display, sourceWindow, False, 0, (XEvent *)&cm);
- } else {
- const Qt::DropActions possibleActions =
- DndOperationsToQtDropActions(dnd_data.operations);
- QDragMoveEvent me(p, possibleActions, QDragManager::self()->dropData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
- if (lastAcceptedAction != Qt::IgnoreAction) {
- me.setDropAction(lastAcceptedAction);
- me.accept();
- }
- QApplication::sendEvent(dropWidget, &me);
-
- dnd_data.reason = DND_DRAG_MOTION;
- dnd_data.time = X11->time;
-
- if (me.isAccepted()) {
- lastAcceptedAction = me.dropAction();
-
- dnd_data.status = DND_VALID_DROP_SITE;
- dnd_data.operation = QtDropActionToDndOperation(lastAcceptedAction);
- } else {
- dnd_data.status = DND_INVALID_DROP_SITE;
- dnd_data.operation = DND_NOOP;
- dnd_data.operations = DND_NOOP;
- }
-
- DndFillClientMessage (event.xclient.display, sourceWindow, &cm, &dnd_data, receiver);
- XSendEvent(event.xbutton.display, sourceWindow, False, 0, (XEvent *)&cm);
- }
- }
-
- break;
- }
-
- case DND_TOP_LEVEL_ENTER:
- {
- /* get the size of our drop site for later use */
-
- motifdnd_active = true;
- sourceWindow = dnd_data.src_window;
-
- /* no answer needed, just read source property */
- DndReadSourceProperty (event.xclient.display,
- sourceWindow,
- dnd_data.property,
- &src_targets, &num_src_targets);
-
- break;
- }
-
- case DND_TOP_LEVEL_LEAVE:
- {
- XEvent nextEvent;
- if (XCheckTypedWindowEvent(X11->display, widget->winId(), ClientMessage, &nextEvent)) {
- // we just want to check, not eat (should use XPeekIfEvent)
- XPutBackEvent(X11->display, &nextEvent);
-
- if (DndParseClientMessage (&nextEvent.xclient, &dnd_data, &receiver)
- && dnd_data.reason == DND_DROP_START) {
- // expecting drop next, keeping DnD alive
- break;
- }
- }
-
- // not expecting drop, need to send drag leave events and such here
- if (dropWidget) {
- QDragLeaveEvent le;
- QApplication::sendEvent(dropWidget, &le);
- }
-
- sourceWindow = XNone;
- dropWidget = 0;
- lastAcceptedAction = Qt::IgnoreAction;
-
- motifdnd_active = false;
-
- break;
- }
-
- case DND_OPERATION_CHANGED:
- // ### need to echo
- break;
-
- case DND_DROP_START:
- {
- Q_ASSERT(motifdnd_active);
- Q_ASSERT(sourceWindow == dnd_data.src_window);
-
- if (!dropWidget || lastAcceptedAction == Qt::IgnoreAction) {
- // echo DROP_START
- dnd_data.reason = DND_DROP_START;
- dnd_data.status = DND_NO_DROP_SITE;
- dnd_data.operation = DND_NOOP;
- dnd_data.operations = DND_NOOP;
- DndFillClientMessage (event.xclient.display, sourceWindow, &cm, &dnd_data, 0);
- XSendEvent(event.xbutton.display, sourceWindow, False, 0, (XEvent *)&cm);
-
- // we have to convert selection in order to indicate failure to the initiator
- XConvertSelection (X11->display, dnd_data.property, ATOM(XmTRANSFER_FAILURE),
- dnd_data.property, dnd_data.src_window, dnd_data.time);
-
- if (dropWidget) {
- QDragLeaveEvent e;
- QApplication::sendEvent(dropWidget, &e);
- }
-
- motifdnd_active = false;
- sourceWindow = XNone;
- dropWidget = 0;
- lastAcceptedAction = Qt::IgnoreAction;
-
- return;
- }
-
- // store selection and its time
- Dnd_selection = dnd_data.property;
- Dnd_selection_time = dnd_data.time;
-
- QPoint p(dnd_data.x, dnd_data.y);
- QDropEvent de(dropWidget->mapFromGlobal(p), Qt::CopyAction, QDragManager::self()->dropData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
- if (lastAcceptedAction != Qt::IgnoreAction) {
- de.setDropAction(lastAcceptedAction);
- de.accept();
- }
- QApplication::sendEvent(dropWidget, &de);
-
- // reset
- Dnd_selection = XNone;
- Dnd_selection_time = 0;
-
- // echo DROP_START depending on the result of the dropEvent
- if (de.isAccepted()) {
- dnd_data.reason = DND_DROP_START;
- dnd_data.status = DND_VALID_DROP_SITE;
- dnd_data.operation = QtDropActionToDndOperation(de.dropAction());
- } else {
- dnd_data.reason = DND_DROP_START;
- dnd_data.status = DND_NO_DROP_SITE;
- dnd_data.operation = DND_NOOP;
- dnd_data.operations = DND_NOOP;
- }
- DndFillClientMessage (event.xclient.display, sourceWindow, &cm, &dnd_data, 0);
- XSendEvent(event.xbutton.display, sourceWindow, False, 0, (XEvent *)&cm);
-
- sourceWindow = XNone;
- dropWidget = 0;
- lastAcceptedAction = Qt::IgnoreAction;
-
- motifdnd_active = false;
-
- break;
- }
-
- default:
- break;
- } // end of switch (dnd_data.reason)
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DRAGANDDROP
diff --git a/src/widgets/platforms/x11/qpaintdevice_x11.cpp b/src/widgets/platforms/x11/qpaintdevice_x11.cpp
deleted file mode 100644
index d7ecb06885..0000000000
--- a/src/widgets/platforms/x11/qpaintdevice_x11.cpp
+++ /dev/null
@@ -1,84 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpaintdevice.h"
-#include "qpainter.h"
-#include "qwidget.h"
-#include "qbitmap.h"
-#include "qapplication.h"
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-
-QT_BEGIN_NAMESPACE
-
-/*! \internal
-
- Returns the X11 Drawable of the paint device. 0 is returned if it
- can't be obtained.
-*/
-
-Drawable Q_WIDGETS_EXPORT qt_x11Handle(const QPaintDevice *pd)
-{
- if (!pd) return 0;
- if (pd->devType() == QInternal::Widget)
- return static_cast<const QWidget *>(pd)->handle();
- else if (pd->devType() == QInternal::Pixmap)
- return static_cast<const QPixmap *>(pd)->handle();
- return 0;
-}
-
-/*!
- \relates QPaintDevice
-
- Returns the QX11Info structure for the \a pd paint device. 0 is
- returned if it can't be obtained.
-*/
-const Q_WIDGETS_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd)
-{
- if (!pd) return 0;
- if (pd->devType() == QInternal::Widget)
- return &static_cast<const QWidget *>(pd)->x11Info();
- else if (pd->devType() == QInternal::Pixmap)
- return &static_cast<const QPixmap *>(pd)->x11Info();
- return 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qpaintengine_x11.cpp b/src/widgets/platforms/x11/qpaintengine_x11.cpp
deleted file mode 100644
index 3cb3e3caf7..0000000000
--- a/src/widgets/platforms/x11/qpaintengine_x11.cpp
+++ /dev/null
@@ -1,2499 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#include "private/qpixmap_x11_p.h"
-
-#include "qapplication.h"
-#include "qdebug.h"
-#include "qfont.h"
-#include "qwidget.h"
-#include "qbitmap.h"
-#include "qpixmapcache.h"
-#include "qtextcodec.h"
-#include "qcoreevent.h"
-#include "qiodevice.h"
-#include <qmath.h>
-
-#include "qpainter_p.h"
-#include <qtextlayout.h>
-#include <qvarlengtharray.h>
-#include <private/qfont_p.h>
-#include <private/qtextengine_p.h>
-#include <private/qpaintengine_x11_p.h>
-#include <private/qfontengine_x11_p.h>
-#include <private/qwidget_p.h>
-#include <private/qpainterpath_p.h>
-
-#include "qpen.h"
-#include "qcolor.h"
-#include "qcolormap.h"
-
-#include <private/qpaintengine_p.h>
-#include "qpaintengine_x11_p.h"
-
-#include <private/qt_x11_p.h>
-#include <private/qnumeric_p.h>
-#include <limits.h>
-
-#ifndef QT_NO_XRENDER
-#include <private/qtessellator_p.h>
-#endif
-
-#include <private/qhexstring_p.h>
-
-QT_BEGIN_NAMESPACE
-
-extern Drawable qt_x11Handle(const QPaintDevice *pd);
-extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
-extern QPixmap qt_pixmapForBrush(int brushStyle, bool invert); //in qbrush.cpp
-extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
-
-// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
-static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-
-#undef X11 // defined in qt_x11_p.h
-/*!
- Returns the X11 specific pen GC for the painter \a p. Note that
- QPainter::begin() must be called before this function returns a
- valid GC.
-*/
-Q_WIDGETS_EXPORT GC qt_x11_get_pen_gc(QPainter *p)
-{
- if (p && p->paintEngine()
- && p->paintEngine()->isActive()
- && p->paintEngine()->type() == QPaintEngine::X11) {
- return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc;
- }
- return 0;
-}
-
-/*!
- Returns the X11 specific brush GC for the painter \a p. Note that
- QPainter::begin() must be called before this function returns a
- valid GC.
-*/
-Q_WIDGETS_EXPORT GC qt_x11_get_brush_gc(QPainter *p)
-{
- if (p && p->paintEngine()
- && p->paintEngine()->isActive()
- && p->paintEngine()->type() == QPaintEngine::X11) {
- return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc_brush;
- }
- return 0;
-}
-#define X11 qt_x11Data
-
-#ifndef QT_NO_XRENDER
-static const int compositionModeToRenderOp[QPainter::CompositionMode_Xor + 1] = {
- PictOpOver, //CompositionMode_SourceOver,
- PictOpOverReverse, //CompositionMode_DestinationOver,
- PictOpClear, //CompositionMode_Clear,
- PictOpSrc, //CompositionMode_Source,
- PictOpDst, //CompositionMode_Destination,
- PictOpIn, //CompositionMode_SourceIn,
- PictOpInReverse, //CompositionMode_DestinationIn,
- PictOpOut, //CompositionMode_SourceOut,
- PictOpOutReverse, //CompositionMode_DestinationOut,
- PictOpAtop, //CompositionMode_SourceAtop,
- PictOpAtopReverse, //CompositionMode_DestinationAtop,
- PictOpXor //CompositionMode_Xor
-};
-
-static inline int qpainterOpToXrender(QPainter::CompositionMode mode)
-{
- Q_ASSERT(mode <= QPainter::CompositionMode_Xor);
- return compositionModeToRenderOp[mode];
-}
-#endif
-
-// hack, so we don't have to make QRegion::clipRectangles() public or include
-// X11 headers in qregion.h
-Q_WIDGETS_EXPORT void *qt_getClipRects(const QRegion &r, int &num)
-{
- return r.clipRectangles(num);
-}
-
-static inline void x11SetClipRegion(Display *dpy, GC gc, GC gc2,
-#ifndef QT_NO_XRENDER
- Picture picture,
-#else
- Qt::HANDLE picture,
-#endif
- const QRegion &r)
-{
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(r, num);
-
- if (gc)
- XSetClipRectangles( dpy, gc, 0, 0, rects, num, YXBanded );
- if (gc2)
- XSetClipRectangles( dpy, gc2, 0, 0, rects, num, YXBanded );
-
-#ifndef QT_NO_XRENDER
- if (picture)
- XRenderSetPictureClipRectangles(dpy, picture, 0, 0, rects, num);
-#else
- Q_UNUSED(picture);
-#endif // QT_NO_XRENDER
-}
-
-
-static inline void x11ClearClipRegion(Display *dpy, GC gc, GC gc2,
-#ifndef QT_NO_XRENDER
- Picture picture
-#else
- Qt::HANDLE picture
-#endif
- )
-{
- if (gc)
- XSetClipMask(dpy, gc, XNone);
- if (gc2)
- XSetClipMask(dpy, gc2, XNone);
-
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderPictureAttributes attrs;
- attrs.clip_mask = XNone;
- XRenderChangePicture (dpy, picture, CPClipMask, &attrs);
- }
-#else
- Q_UNUSED(picture);
-#endif // QT_NO_XRENDER
-}
-
-
-#define DITHER_SIZE 16
-static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = {
- { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
- { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
- { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
- { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
- { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
- { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
- { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
- { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
- { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
- { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
- { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
- { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
- { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
- { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
- { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
- { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
-};
-
-static QPixmap qt_patternForAlpha(uchar alpha, int screen)
-{
- QPixmap pm;
- QString key = QLatin1Literal("$qt-alpha-brush$")
- % HexString<uchar>(alpha)
- % HexString<int>(screen);
-
- if (!QPixmapCache::find(key, pm)) {
- // #### why not use a mono image here????
- QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32);
- pattern.fill(0xffffffff);
- for (int y = 0; y < DITHER_SIZE; ++y) {
- for (int x = 0; x < DITHER_SIZE; ++x) {
- if (base_dither_matrix[x][y] <= alpha)
- pattern.setPixel(x, y, 0x00000000);
- }
- }
- pm = QBitmap::fromImage(pattern);
- pm.x11SetScreen(screen);
- QPixmapCache::insert(key, pm);
- }
- return pm;
-}
-
-#if !defined(QT_NO_XRENDER)
-
-class QXRenderTessellator : public QTessellator
-{
-public:
- QXRenderTessellator() : traps(0), allocated(0), size(0) {}
- ~QXRenderTessellator() { free(traps); }
- XTrapezoid *traps;
- int allocated;
- int size;
- void addTrap(const Trapezoid &trap);
- QRect tessellate(const QPointF *points, int nPoints, bool winding) {
- size = 0;
- setWinding(winding);
- return QTessellator::tessellate(points, nPoints).toRect();
- }
- void done() {
- if (allocated > 64) {
- free(traps);
- traps = 0;
- allocated = 0;
- }
- }
-};
-
-void QXRenderTessellator::addTrap(const Trapezoid &trap)
-{
- if (size == allocated) {
- allocated = qMax(2*allocated, 64);
- traps = q_check_ptr((XTrapezoid *)realloc(traps, allocated * sizeof(XTrapezoid)));
- }
- traps[size].top = Q27Dot5ToXFixed(trap.top);
- traps[size].bottom = Q27Dot5ToXFixed(trap.bottom);
- traps[size].left.p1.x = Q27Dot5ToXFixed(trap.topLeft->x);
- traps[size].left.p1.y = Q27Dot5ToXFixed(trap.topLeft->y);
- traps[size].left.p2.x = Q27Dot5ToXFixed(trap.bottomLeft->x);
- traps[size].left.p2.y = Q27Dot5ToXFixed(trap.bottomLeft->y);
- traps[size].right.p1.x = Q27Dot5ToXFixed(trap.topRight->x);
- traps[size].right.p1.y = Q27Dot5ToXFixed(trap.topRight->y);
- traps[size].right.p2.x = Q27Dot5ToXFixed(trap.bottomRight->x);
- traps[size].right.p2.y = Q27Dot5ToXFixed(trap.bottomRight->y);
- ++size;
-}
-
-#endif // !defined(QT_NO_XRENDER)
-
-
-#ifndef QT_NO_XRENDER
-static Picture getPatternFill(int screen, const QBrush &b)
-{
- if (!X11->use_xrender)
- return XNone;
-
- XRenderColor color = X11->preMultiply(b.color());
- XRenderColor bg_color;
-
- bg_color = X11->preMultiply(QColor(0, 0, 0, 0));
-
- for (int i = 0; i < X11->pattern_fill_count; ++i) {
- if (X11->pattern_fills[i].screen == screen
- && X11->pattern_fills[i].opaque == false
- && X11->pattern_fills[i].style == b.style()
- && X11->pattern_fills[i].color.alpha == color.alpha
- && X11->pattern_fills[i].color.red == color.red
- && X11->pattern_fills[i].color.green == color.green
- && X11->pattern_fills[i].color.blue == color.blue
- && X11->pattern_fills[i].bg_color.alpha == bg_color.alpha
- && X11->pattern_fills[i].bg_color.red == bg_color.red
- && X11->pattern_fills[i].bg_color.green == bg_color.green
- && X11->pattern_fills[i].bg_color.blue == bg_color.blue)
- return X11->pattern_fills[i].picture;
- }
- // none found, replace one
- int i = qrand() % 16;
-
- if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) {
- XRenderFreePicture (X11->display, X11->pattern_fills[i].picture);
- X11->pattern_fills[i].picture = 0;
- }
-
- if (!X11->pattern_fills[i].picture) {
- Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 8, 8, 32);
- XRenderPictureAttributes attrs;
- attrs.repeat = True;
- X11->pattern_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32),
- CPRepeat, &attrs);
- XFreePixmap (X11->display, pixmap);
- }
-
- X11->pattern_fills[i].screen = screen;
- X11->pattern_fills[i].color = color;
- X11->pattern_fills[i].bg_color = bg_color;
- X11->pattern_fills[i].opaque = false;
- X11->pattern_fills[i].style = b.style();
-
- XRenderFillRectangle(X11->display, PictOpSrc, X11->pattern_fills[i].picture, &bg_color, 0, 0, 8, 8);
-
- QPixmap pattern(qt_pixmapForBrush(b.style(), true));
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(X11->display, pattern.x11PictureHandle(), CPRepeat, &attrs);
-
- Picture fill_fg = X11->getSolidFill(screen, b.color());
- XRenderComposite(X11->display, PictOpOver, fill_fg, pattern.x11PictureHandle(),
- X11->pattern_fills[i].picture,
- 0, 0, 0, 0, 0, 0, 8, 8);
-
- return X11->pattern_fills[i].picture;
-}
-
-static void qt_render_bitmap(Display *dpy, int scrn, Picture src, Picture dst,
- int sx, int sy, int x, int y, int sw, int sh,
- const QPen &pen)
-{
- Picture fill_fg = X11->getSolidFill(scrn, pen.color());
- XRenderComposite(dpy, PictOpOver,
- fill_fg, src, dst, sx, sy, sx, sy, x, y, sw, sh);
-}
-#endif
-
-void QX11PaintEnginePrivate::init()
-{
- dpy = 0;
- scrn = 0;
- hd = 0;
- picture = 0;
- xinfo = 0;
-#ifndef QT_NO_XRENDER
- current_brush = 0;
- composition_mode = PictOpOver;
- tessellator = new QXRenderTessellator;
-#endif
-}
-
-void QX11PaintEnginePrivate::setupAdaptedOrigin(const QPoint &p)
-{
- if (adapted_pen_origin)
- XSetTSOrigin(dpy, gc, p.x(), p.y());
- if (adapted_brush_origin)
- XSetTSOrigin(dpy, gc_brush, p.x(), p.y());
-}
-
-void QX11PaintEnginePrivate::resetAdaptedOrigin()
-{
- if (adapted_pen_origin)
- XSetTSOrigin(dpy, gc, 0, 0);
- if (adapted_brush_origin)
- XSetTSOrigin(dpy, gc_brush, 0, 0);
-}
-
-void QX11PaintEnginePrivate::clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly)
-{
- int clipped_count = 0;
- qt_float_point *clipped_points = 0;
- polygonClipper.clipPolygon((qt_float_point *) poly.data(), poly.size(),
- &clipped_points, &clipped_count);
- clipped_poly->resize(clipped_count);
- for (int i=0; i<clipped_count; ++i)
- (*clipped_poly)[i] = *((QPointF *)(&clipped_points[i]));
-}
-
-void QX11PaintEnginePrivate::systemStateChanged()
-{
- Q_Q(QX11PaintEngine);
- QPainter *painter = q->state ? static_cast<QPainterState *>(q->state)->painter : 0;
- if (painter && painter->hasClipping()) {
- if (q->testDirty(QPaintEngine::DirtyTransform))
- q->updateMatrix(q->state->transform());
- QPolygonF clip_poly_dev(matrix.map(painter->clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- q->updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
- } else {
- q->updateClipRegion_dev(QRegion(), Qt::NoClip);
- }
-}
-
-static QPaintEngine::PaintEngineFeatures qt_decide_features()
-{
- QPaintEngine::PaintEngineFeatures features =
- QPaintEngine::PrimitiveTransform
- | QPaintEngine::PatternBrush
- | QPaintEngine::AlphaBlend
- | QPaintEngine::PainterPaths
- | QPaintEngine::RasterOpModes;
-
- if (X11->use_xrender) {
- features |= QPaintEngine::Antialiasing;
- features |= QPaintEngine::PorterDuff;
- features |= QPaintEngine::MaskedBrush;
-#if 0
- if (X11->xrender_version > 10) {
- features |= QPaintEngine::LinearGradientFill;
- // ###
- }
-#endif
- }
-
- return features;
-}
-
-/*
- * QX11PaintEngine members
- */
-
-QX11PaintEngine::QX11PaintEngine()
- : QPaintEngine(*(new QX11PaintEnginePrivate), qt_decide_features())
-{
- d_func()->init();
-}
-
-QX11PaintEngine::QX11PaintEngine(QX11PaintEnginePrivate &dptr)
- : QPaintEngine(dptr, qt_decide_features())
-{
- d_func()->init();
-}
-
-QX11PaintEngine::~QX11PaintEngine()
-{
-#ifndef QT_NO_XRENDER
- Q_D(QX11PaintEngine);
- delete d->tessellator;
-#endif
-}
-
-bool QX11PaintEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QX11PaintEngine);
- d->xinfo = qt_x11Info(pdev);
- QWidget *w = d->pdev->devType() == QInternal::Widget ? static_cast<QWidget *>(d->pdev) : 0;
- const bool isAlienWidget = w && !w->internalWinId() && w->testAttribute(Qt::WA_WState_Created);
-#ifndef QT_NO_XRENDER
- if (w) {
- if (isAlienWidget)
- d->picture = (::Picture)w->nativeParentWidget()->x11PictureHandle();
- else
- d->picture = (::Picture)w->x11PictureHandle();
- } else if (pdev->devType() == QInternal::Pixmap) {
- const QPixmap *pm = static_cast<const QPixmap *>(pdev);
- QX11PlatformPixmap *data = static_cast<QX11PlatformPixmap*>(pm->data.data());
- if (X11->use_xrender && data->depth() != 32 && data->x11_mask)
- data->convertToARGB32();
- d->picture = (::Picture)static_cast<const QPixmap *>(pdev)->x11PictureHandle();
- }
-#else
- d->picture = 0;
-#endif
- d->hd = !isAlienWidget ? qt_x11Handle(pdev) : qt_x11Handle(w->nativeParentWidget());
-
- Q_ASSERT(d->xinfo != 0);
- d->dpy = d->xinfo->display(); // get display variable
- d->scrn = d->xinfo->screen(); // get screen variable
-
- d->crgn = QRegion();
- d->gc = XCreateGC(d->dpy, d->hd, 0, 0);
- d->gc_brush = XCreateGC(d->dpy, d->hd, 0, 0);
- d->has_alpha_brush = false;
- d->has_alpha_pen = false;
- d->has_clipping = false;
- d->has_complex_xform = false;
- d->has_scaling_xform = false;
- d->has_non_scaling_xform = true;
- d->xform_scale = 1;
- d->has_custom_pen = false;
- d->matrix = QTransform();
- d->pdev_depth = d->pdev->depth();
- d->render_hints = 0;
- d->txop = QTransform::TxNone;
- d->use_path_fallback = false;
-#if !defined(QT_NO_XRENDER)
- d->composition_mode = PictOpOver;
-#endif
- d->xlibMaxLinePoints = 32762; // a safe number used to avoid, call to XMaxRequestSize(d->dpy) - 3;
- d->opacity = 1;
-
- // Set up the polygon clipper. Note: This will only work in
- // polyline mode as long as we have a buffer zone, since a
- // polyline may be clipped into several non-connected polylines.
- const int BUFFERZONE = 1000;
- QRect devClipRect(-BUFFERZONE, -BUFFERZONE,
- pdev->width() + 2*BUFFERZONE, pdev->height() + 2*BUFFERZONE);
- d->polygonClipper.setBoundingRect(devClipRect);
-
- if (isAlienWidget) {
- // Set system clip for alien widgets painting outside the paint event.
- // This is not a problem with native windows since the windowing system
- // will handle the clip.
- QWidgetPrivate *wd = w->d_func();
- QRegion widgetClip(wd->clipRect());
- wd->clipToEffectiveMask(widgetClip);
- wd->subtractOpaqueSiblings(widgetClip);
- widgetClip.translate(w->mapTo(w->nativeParentWidget(), QPoint()));
- setSystemClip(widgetClip);
- }
-
- QPixmap::x11SetDefaultScreen(d->xinfo->screen());
-
- if (w && w->testAttribute(Qt::WA_PaintUnclipped)) { // paint direct on device
- updatePen(QPen(Qt::black));
- updateBrush(QBrush(Qt::white), QPoint());
- XSetSubwindowMode(d->dpy, d->gc, IncludeInferiors);
- XSetSubwindowMode(d->dpy, d->gc_brush, IncludeInferiors);
-#ifndef QT_NO_XRENDER
- XRenderPictureAttributes attrs;
- attrs.subwindow_mode = IncludeInferiors;
- XRenderChangePicture(d->dpy, d->picture, CPSubwindowMode, &attrs);
-#endif
- }
-
- setDirty(QPaintEngine::DirtyClipRegion);
- setDirty(QPaintEngine::DirtyPen);
- setDirty(QPaintEngine::DirtyBrush);
- setDirty(QPaintEngine::DirtyBackground);
-
- return true;
-}
-
-bool QX11PaintEngine::end()
-{
- Q_D(QX11PaintEngine);
-
-#if !defined(QT_NO_XRENDER)
- if (d->picture) {
- // reset clipping/subwindow mode on our render picture
- XRenderPictureAttributes attrs;
- attrs.subwindow_mode = ClipByChildren;
- attrs.clip_mask = XNone;
- XRenderChangePicture(d->dpy, d->picture, CPClipMask|CPSubwindowMode, &attrs);
- }
-#endif
-
- if (d->gc_brush && d->pdev->painters < 2) {
- XFreeGC(d->dpy, d->gc_brush);
- d->gc_brush = 0;
- }
-
- if (d->gc && d->pdev->painters < 2) {
- XFreeGC(d->dpy, d->gc);
- d->gc = 0;
- }
-
- // Restore system clip for alien widgets painting outside the paint event.
- if (d->pdev->devType() == QInternal::Widget && !static_cast<QWidget *>(d->pdev)->internalWinId())
- setSystemClip(QRegion());
-
- return true;
-}
-
-static bool clipLine(QLineF *line, const QRect &rect)
-{
- qreal x1 = line->x1();
- qreal x2 = line->x2();
- qreal y1 = line->y1();
- qreal y2 = line->y2();
-
- qreal left = rect.x();
- qreal right = rect.x() + rect.width() - 1;
- qreal top = rect.y();
- qreal bottom = rect.y() + rect.height() - 1;
-
- enum { Left, Right, Top, Bottom };
- // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html
- int p1 = ((x1 < left) << Left)
- | ((x1 > right) << Right)
- | ((y1 < top) << Top)
- | ((y1 > bottom) << Bottom);
- int p2 = ((x2 < left) << Left)
- | ((x2 > right) << Right)
- | ((y2 < top) << Top)
- | ((y2 > bottom) << Bottom);
-
- if (p1 & p2)
- // completely outside
- return false;
-
- if (p1 | p2) {
- qreal dx = x2 - x1;
- qreal dy = y2 - y1;
-
- // clip x coordinates
- if (x1 < left) {
- y1 += dy/dx * (left - x1);
- x1 = left;
- } else if (x1 > right) {
- y1 -= dy/dx * (x1 - right);
- x1 = right;
- }
- if (x2 < left) {
- y2 += dy/dx * (left - x2);
- x2 = left;
- } else if (x2 > right) {
- y2 -= dy/dx * (x2 - right);
- x2 = right;
- }
- p1 = ((y1 < top) << Top)
- | ((y1 > bottom) << Bottom);
- p2 = ((y2 < top) << Top)
- | ((y2 > bottom) << Bottom);
- if (p1 & p2)
- return false;
- // clip y coordinates
- if (y1 < top) {
- x1 += dx/dy * (top - y1);
- y1 = top;
- } else if (y1 > bottom) {
- x1 -= dx/dy * (y1 - bottom);
- y1 = bottom;
- }
- if (y2 < top) {
- x2 += dx/dy * (top - y2);
- y2 = top;
- } else if (y2 > bottom) {
- x2 -= dx/dy * (y2 - bottom);
- y2 = bottom;
- }
- *line = QLineF(QPointF(x1, y1), QPointF(x2, y2));
- }
- return true;
-}
-
-void QX11PaintEngine::drawLines(const QLine *lines, int lineCount)
-{
- Q_ASSERT(lines);
- Q_ASSERT(lineCount);
- Q_D(QX11PaintEngine);
- if (d->has_alpha_brush
- || d->has_alpha_pen
- || d->has_custom_pen
- || (d->cpen.widthF() > 0 && d->has_complex_xform
- && !d->has_non_scaling_xform)
- || (d->render_hints & QPainter::Antialiasing)) {
- for (int i = 0; i < lineCount; ++i) {
- QPainterPath path(lines[i].p1());
- path.lineTo(lines[i].p2());
- drawPath(path);
- }
- return;
- }
-
- if (d->has_pen) {
- for (int i = 0; i < lineCount; ++i) {
- QLineF linef;
- if (d->txop == QTransform::TxNone) {
- linef = lines[i];
- } else {
- linef = d->matrix.map(QLineF(lines[i]));
- }
- if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
- int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
- int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
- int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
-
- XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
- }
- }
- }
-}
-
-void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_ASSERT(lines);
- Q_ASSERT(lineCount);
- Q_D(QX11PaintEngine);
- if (d->has_alpha_brush
- || d->has_alpha_pen
- || d->has_custom_pen
- || (d->cpen.widthF() > 0 && d->has_complex_xform
- && !d->has_non_scaling_xform)
- || (d->render_hints & QPainter::Antialiasing)) {
- for (int i = 0; i < lineCount; ++i) {
- QPainterPath path(lines[i].p1());
- path.lineTo(lines[i].p2());
- drawPath(path);
- }
- return;
- }
-
- if (d->has_pen) {
- for (int i = 0; i < lineCount; ++i) {
- QLineF linef = d->matrix.map(lines[i]);
- if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
- int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
- int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
- int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
-
- XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
- }
- }
- }
-}
-
-static inline QLine clipStraightLine(const QRect &clip, const QLine &l)
-{
- if (l.p1().x() == l.p2().x()) {
- int x = qBound(clip.left(), l.p1().x(), clip.right());
- int y1 = qBound(clip.top(), l.p1().y(), clip.bottom());
- int y2 = qBound(clip.top(), l.p2().y(), clip.bottom());
-
- return QLine(x, y1, x, y2);
- } else {
- Q_ASSERT(l.p1().y() == l.p2().y());
-
- int x1 = qBound(clip.left(), l.p1().x(), clip.right());
- int x2 = qBound(clip.left(), l.p2().x(), clip.right());
- int y = qBound(clip.top(), l.p1().y(), clip.bottom());
-
- return QLine(x1, y, x2, y);
- }
-}
-
-void QX11PaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QX11PaintEngine);
- Q_ASSERT(rects);
- Q_ASSERT(rectCount);
-
- if (rectCount != 1
- || d->has_pen
- || d->has_alpha_brush
- || d->has_complex_xform
- || d->has_custom_pen
- || d->cbrush.style() != Qt::SolidPattern)
- {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
-
- QPoint alignedOffset;
- if (d->txop == QTransform::TxTranslate) {
- QPointF offset(d->matrix.dx(), d->matrix.dy());
- alignedOffset = offset.toPoint();
- if (offset != QPointF(alignedOffset)) {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
- }
-
- const QRectF& r = rects[0];
- QRect alignedRect = r.toAlignedRect();
- if (r != QRectF(alignedRect)) {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
- alignedRect.translate(alignedOffset);
-
- QRect clip(d->polygonClipper.boundingRect());
- alignedRect = alignedRect.intersected(clip);
- if (alignedRect.isEmpty())
- return;
-
- // simple-case:
- // the rectangle is pixel-aligned
- // the fill brush is just a solid non-alpha color
- // the painter transform is only integer translation
- // ignore: antialiasing and just XFillRectangles directly
- XRectangle xrect;
- xrect.x = short(alignedRect.x());
- xrect.y = short(alignedRect.y());
- xrect.width = ushort(alignedRect.width());
- xrect.height = ushort(alignedRect.height());
- XFillRectangles(d->dpy, d->hd, d->gc_brush, &xrect, 1);
-}
-
-void QX11PaintEngine::drawRects(const QRect *rects, int rectCount)
-{
- Q_D(QX11PaintEngine);
- Q_ASSERT(rects);
- Q_ASSERT(rectCount);
-
- if (d->has_alpha_pen
- || d->has_complex_xform
- || d->has_custom_pen
- || (d->render_hints & QPainter::Antialiasing))
- {
- for (int i = 0; i < rectCount; ++i) {
- QPainterPath path;
- path.addRect(rects[i]);
- drawPath(path);
- }
- return;
- }
-
- QRect clip(d->polygonClipper.boundingRect());
- QPoint offset(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
-#if !defined(QT_NO_XRENDER)
- ::Picture pict = d->picture;
-
- if (X11->use_xrender && pict && d->has_brush && d->pdev_depth != 1
- && (d->has_texture || d->has_alpha_brush))
- {
- XRenderColor xc;
- if (!d->has_texture && !d->has_pattern)
- xc = X11->preMultiply(d->cbrush.color());
-
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- if (d->has_pen) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- }
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty())
- continue;
- if (d->has_texture || d->has_pattern) {
- XRenderComposite(d->dpy, d->composition_mode, d->current_brush, 0, pict,
- qRound(r.x() - d->bg_origin.x()), qRound(r.y() - d->bg_origin.y()),
- 0, 0, r.x(), r.y(), r.width(), r.height());
- } else {
- XRenderFillRectangle(d->dpy, d->composition_mode, pict, &xc, r.x(), r.y(), r.width(), r.height());
- }
- if (d->has_pen)
- XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
- }
- } else
-#endif // !QT_NO_XRENDER
- {
- if (d->has_brush && d->has_pen) {
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty())
- continue;
- d->setupAdaptedOrigin(r.topLeft());
- XFillRectangle(d->dpy, d->hd, d->gc_brush, r.x(), r.y(), r.width(), r.height());
- XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
- }
- d->resetAdaptedOrigin();
- } else {
- QVarLengthArray<XRectangle> xrects(rectCount);
- int numClipped = rectCount;
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- --numClipped;
- if (d->has_pen) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- }
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty()) {
- --numClipped;
- continue;
- }
- xrects[i].x = short(r.x());
- xrects[i].y = short(r.y());
- xrects[i].width = ushort(r.width());
- xrects[i].height = ushort(r.height());
- }
- if (numClipped) {
- d->setupAdaptedOrigin(rects[0].topLeft());
- if (d->has_brush)
- XFillRectangles(d->dpy, d->hd, d->gc_brush, xrects.data(), numClipped);
- else if (d->has_pen)
- XDrawRectangles(d->dpy, d->hd, d->gc, xrects.data(), numClipped);
- d->resetAdaptedOrigin();
- }
- }
- }
-}
-
-static inline void setCapStyle(int cap_style, GC gc)
-{
- ulong mask = GCCapStyle;
- XGCValues vals;
- vals.cap_style = cap_style;
- XChangeGC(X11->display, gc, mask, &vals);
-}
-
-void QX11PaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
- Q_ASSERT(points);
- Q_ASSERT(pointCount);
- Q_D(QX11PaintEngine);
-
- if (!d->has_pen)
- return;
-
- // use the same test here as in drawPath to ensure that we don't use the path fallback
- // and end up in XDrawLines for pens with width <= 1
- if (d->cpen.widthF() > 1.0f
- || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate))
- {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapProjecting, d->gc);
- d->cpen.setCapStyle(Qt::SquareCap);
- }
- const QPoint *end = points + pointCount;
- while (points < end) {
- QPainterPath path;
- path.moveTo(*points);
- path.lineTo(points->x()+.005, points->y());
- drawPath(path);
- ++points;
- }
-
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapButt, d->gc);
- d->cpen.setCapStyle(capStyle);
- }
- return;
- }
-
- static const int BUF_SIZE = 1024;
- XPoint xPoints[BUF_SIZE];
- int i = 0, j = 0;
- while (i < pointCount) {
- while (i < pointCount && j < BUF_SIZE) {
- const QPoint &xformed = d->matrix.map(points[i]);
- int x = xformed.x();
- int y = xformed.y();
- if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
- xPoints[j].x = x;
- xPoints[j].y = y;
- ++j;
- }
- ++i;
- }
- if (j)
- XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
-
- j = 0;
- }
-}
-
-void QX11PaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- Q_ASSERT(points);
- Q_ASSERT(pointCount);
- Q_D(QX11PaintEngine);
-
- if (!d->has_pen)
- return;
-
- // use the same test here as in drawPath to ensure that we don't use the path fallback
- // and end up in XDrawLines for pens with width <= 1
- if (d->cpen.widthF() > 1.0f
- || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate))
- {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapProjecting, d->gc);
- d->cpen.setCapStyle(Qt::SquareCap);
- }
-
- const QPointF *end = points + pointCount;
- while (points < end) {
- QPainterPath path;
- path.moveTo(*points);
- path.lineTo(points->x() + 0.005, points->y());
- drawPath(path);
- ++points;
- }
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapButt, d->gc);
- d->cpen.setCapStyle(capStyle);
- }
- return;
- }
-
- static const int BUF_SIZE = 1024;
- XPoint xPoints[BUF_SIZE];
- int i = 0, j = 0;
- while (i < pointCount) {
- while (i < pointCount && j < BUF_SIZE) {
- const QPointF &xformed = d->matrix.map(points[i]);
- int x = qFloor(xformed.x());
- int y = qFloor(xformed.y());
-
- if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
- xPoints[j].x = x;
- xPoints[j].y = y;
- ++j;
- }
- ++i;
- }
- if (j)
- XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
-
- j = 0;
- }
-}
-
-QPainter::RenderHints QX11PaintEngine::supportedRenderHints() const
-{
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender)
- return QPainter::Antialiasing;
-#endif
- return QFlag(0);
-}
-
-void QX11PaintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QX11PaintEngine);
- QPaintEngine::DirtyFlags flags = state.state();
-
-
- if (flags & DirtyOpacity) {
- d->opacity = state.opacity();
- // Force update pen/brush as to get proper alpha colors propagated
- flags |= DirtyPen;
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyTransform) updateMatrix(state.transform());
- if (flags & DirtyPen) updatePen(state.pen());
- if (flags & (DirtyBrush | DirtyBrushOrigin)) updateBrush(state.brush(), state.brushOrigin());
- if (flags & DirtyFont) updateFont(state.font());
-
- if (state.state() & DirtyClipEnabled) {
- if (state.isClipEnabled()) {
- QPolygonF clip_poly_dev(d->matrix.map(painter()->clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
- } else {
- updateClipRegion_dev(QRegion(), Qt::NoClip);
- }
- }
-
- if (flags & DirtyClipPath) {
- QPolygonF clip_poly_dev(d->matrix.map(state.clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon(), state.clipPath().fillRule()),
- state.clipOperation());
- } else if (flags & DirtyClipRegion) {
- extern QPainterPath qt_regionToPath(const QRegion &region);
- QPainterPath clip_path = qt_regionToPath(state.clipRegion());
- QPolygonF clip_poly_dev(d->matrix.map(clip_path.toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), state.clipOperation());
- }
- if (flags & DirtyHints) updateRenderHints(state.renderHints());
- if (flags & DirtyCompositionMode) {
- int function = GXcopy;
- if (state.compositionMode() >= QPainter::RasterOp_SourceOrDestination) {
- switch (state.compositionMode()) {
- case QPainter::RasterOp_SourceOrDestination:
- function = GXor;
- break;
- case QPainter::RasterOp_SourceAndDestination:
- function = GXand;
- break;
- case QPainter::RasterOp_SourceXorDestination:
- function = GXxor;
- break;
- case QPainter::RasterOp_NotSourceAndNotDestination:
- function = GXnor;
- break;
- case QPainter::RasterOp_NotSourceOrNotDestination:
- function = GXnand;
- break;
- case QPainter::RasterOp_NotSourceXorDestination:
- function = GXequiv;
- break;
- case QPainter::RasterOp_NotSource:
- function = GXcopyInverted;
- break;
- case QPainter::RasterOp_SourceAndNotDestination:
- function = GXandReverse;
- break;
- case QPainter::RasterOp_NotSourceAndDestination:
- function = GXandInverted;
- break;
- default:
- function = GXcopy;
- }
- }
-#if !defined(QT_NO_XRENDER)
- else {
- d->composition_mode =
- qpainterOpToXrender(state.compositionMode());
- }
-#endif
- XSetFunction(X11->display, d->gc, function);
- XSetFunction(X11->display, d->gc_brush, function);
- }
- d->decidePathFallback();
- d->decideCoordAdjust();
-}
-
-void QX11PaintEngine::updateRenderHints(QPainter::RenderHints hints)
-{
- Q_D(QX11PaintEngine);
- d->render_hints = hints;
-
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender && d->picture) {
- XRenderPictureAttributes attrs;
- attrs.poly_edge = (hints & QPainter::Antialiasing) ? PolyEdgeSmooth : PolyEdgeSharp;
- XRenderChangePicture(d->dpy, d->picture, CPPolyEdge, &attrs);
- }
-#endif
-}
-
-void QX11PaintEngine::updatePen(const QPen &pen)
-{
- Q_D(QX11PaintEngine);
- d->cpen = pen;
- int cp = CapButt;
- int jn = JoinMiter;
- int ps = pen.style();
-
- if (d->opacity < 1.0) {
- QColor c = d->cpen.color();
- c.setAlpha(qRound(c.alpha()*d->opacity));
- d->cpen.setColor(c);
- }
-
- d->has_pen = (ps != Qt::NoPen);
- d->has_alpha_pen = (pen.color().alpha() != 255);
-
- switch (pen.capStyle()) {
- case Qt::SquareCap:
- cp = CapProjecting;
- break;
- case Qt::RoundCap:
- cp = CapRound;
- break;
- case Qt::FlatCap:
- default:
- cp = CapButt;
- break;
- }
- switch (pen.joinStyle()) {
- case Qt::BevelJoin:
- jn = JoinBevel;
- break;
- case Qt::RoundJoin:
- jn = JoinRound;
- break;
- case Qt::MiterJoin:
- default:
- jn = JoinMiter;
- break;
- }
-
- d->adapted_pen_origin = false;
-
- char dashes[10]; // custom pen dashes
- int dash_len = 0; // length of dash list
- int xStyle = LineSolid;
-
- /*
- We are emulating Windows here. Windows treats cpen.width() == 1
- (or 0) as a very special case. The fudge variable unifies this
- case with the general case.
- */
- qreal pen_width = pen.widthF();
- int scale = qRound(pen_width < 1 ? 1 : pen_width);
- int space = (pen_width < 1 && pen_width > 0 ? 1 : (2 * scale));
- int dot = 1 * scale;
- int dash = 4 * scale;
-
- d->has_custom_pen = false;
-
- switch (ps) {
- case Qt::NoPen:
- case Qt::SolidLine:
- xStyle = LineSolid;
- break;
- case Qt::DashLine:
- dashes[0] = dash;
- dashes[1] = space;
- dash_len = 2;
- xStyle = LineOnOffDash;
- break;
- case Qt::DotLine:
- dashes[0] = dot;
- dashes[1] = space;
- dash_len = 2;
- xStyle = LineOnOffDash;
- break;
- case Qt::DashDotLine:
- dashes[0] = dash;
- dashes[1] = space;
- dashes[2] = dot;
- dashes[3] = space;
- dash_len = 4;
- xStyle = LineOnOffDash;
- break;
- case Qt::DashDotDotLine:
- dashes[0] = dash;
- dashes[1] = space;
- dashes[2] = dot;
- dashes[3] = space;
- dashes[4] = dot;
- dashes[5] = space;
- dash_len = 6;
- xStyle = LineOnOffDash;
- break;
- case Qt::CustomDashLine:
- d->has_custom_pen = true;
- break;
- }
-
- ulong mask = GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth
- | GCCapStyle | GCJoinStyle | GCLineStyle;
- XGCValues vals;
- vals.graphics_exposures = false;
- if (d->pdev_depth == 1) {
- vals.foreground = qGray(pen.color().rgb()) > 127 ? 0 : 1;
- vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
- } else if (d->pdev->devType() == QInternal::Pixmap && d->pdev_depth == 32
- && X11->use_xrender) {
- vals.foreground = pen.color().rgba();
- vals.background = QColor(Qt::transparent).rgba();
- } else {
- QColormap cmap = QColormap::instance(d->scrn);
- vals.foreground = cmap.pixel(pen.color());
- vals.background = cmap.pixel(QColor(Qt::transparent));
- }
-
-
- vals.line_width = qRound(pen.widthF());
- vals.cap_style = cp;
- vals.join_style = jn;
- vals.line_style = xStyle;
-
- XChangeGC(d->dpy, d->gc, mask, &vals);
-
- if (dash_len) { // make dash list
- XSetDashes(d->dpy, d->gc, 0, dashes, dash_len);
- }
-
- if (!d->has_clipping) { // if clipping is set the paintevent clip region is merged with the clip region
- QRegion sysClip = systemClip();
- if (!sysClip.isEmpty())
- x11SetClipRegion(d->dpy, d->gc, 0, d->picture, sysClip);
- else
- x11ClearClipRegion(d->dpy, d->gc, 0, d->picture);
- }
-}
-
-void QX11PaintEngine::updateBrush(const QBrush &brush, const QPointF &origin)
-{
- Q_D(QX11PaintEngine);
- d->cbrush = brush;
- d->bg_origin = origin;
- d->adapted_brush_origin = false;
-#if !defined(QT_NO_XRENDER)
- d->current_brush = 0;
-#endif
- if (d->opacity < 1.0) {
- QColor c = d->cbrush.color();
- c.setAlpha(qRound(c.alpha()*d->opacity));
- d->cbrush.setColor(c);
- }
-
- int s = FillSolid;
- int bs = d->cbrush.style();
- d->has_brush = (bs != Qt::NoBrush);
- d->has_pattern = bs >= Qt::Dense1Pattern && bs <= Qt::DiagCrossPattern;
- d->has_texture = bs == Qt::TexturePattern;
- d->has_alpha_brush = brush.color().alpha() != 255;
- d->has_alpha_texture = d->has_texture && d->cbrush.texture().hasAlphaChannel();
-
- ulong mask = GCForeground | GCBackground | GCGraphicsExposures
- | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle;
- XGCValues vals;
- vals.graphics_exposures = false;
- if (d->pdev_depth == 1) {
- vals.foreground = qGray(d->cbrush.color().rgb()) > 127 ? 0 : 1;
- vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
- } else if (X11->use_xrender && d->pdev->devType() == QInternal::Pixmap
- && d->pdev_depth == 32) {
- vals.foreground = d->cbrush.color().rgba();
- vals.background = QColor(Qt::transparent).rgba();
- } else {
- QColormap cmap = QColormap::instance(d->scrn);
- vals.foreground = cmap.pixel(d->cbrush.color());
- vals.background = cmap.pixel(QColor(Qt::transparent));
-
- if (!X11->use_xrender && d->has_brush && !d->has_pattern && !brush.isOpaque()) {
- QPixmap pattern = qt_patternForAlpha(brush.color().alpha(), d->scrn);
- mask |= GCStipple;
- vals.stipple = pattern.handle();
- s = FillStippled;
- d->adapted_brush_origin = true;
- }
- }
- vals.cap_style = CapButt;
- vals.join_style = JoinMiter;
- vals.line_style = LineSolid;
-
- if (d->has_pattern || d->has_texture) {
- if (bs == Qt::TexturePattern) {
- d->brush_pm = qt_toX11Pixmap(d->cbrush.texture());
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender) {
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, d->brush_pm.x11PictureHandle(), CPRepeat, &attrs);
- QX11PlatformPixmap *data = static_cast<QX11PlatformPixmap*>(d->brush_pm.data.data());
- if (data->mask_picture)
- XRenderChangePicture(d->dpy, data->mask_picture, CPRepeat, &attrs);
- }
-#endif
- } else {
- d->brush_pm = qt_toX11Pixmap(qt_pixmapForBrush(bs, true));
- }
- d->brush_pm.x11SetScreen(d->scrn);
- if (d->brush_pm.depth() == 1) {
- mask |= GCStipple;
- vals.stipple = d->brush_pm.handle();
- s = FillStippled;
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender) {
- d->bitmap_texture = QPixmap(d->brush_pm.size());
- d->bitmap_texture.fill(Qt::transparent);
- d->bitmap_texture = qt_toX11Pixmap(d->bitmap_texture);
- d->bitmap_texture.x11SetScreen(d->scrn);
-
- ::Picture src = X11->getSolidFill(d->scrn, d->cbrush.color());
- XRenderComposite(d->dpy, PictOpSrc, src, d->brush_pm.x11PictureHandle(),
- d->bitmap_texture.x11PictureHandle(),
- 0, 0, d->brush_pm.width(), d->brush_pm.height(),
- 0, 0, d->brush_pm.width(), d->brush_pm.height());
-
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, d->bitmap_texture.x11PictureHandle(), CPRepeat, &attrs);
-
- d->current_brush = d->bitmap_texture.x11PictureHandle();
- }
-#endif
- } else {
- mask |= GCTile;
-#ifndef QT_NO_XRENDER
- if (d->pdev_depth == 32 && d->brush_pm.depth() != 32) {
- d->brush_pm.detach();
- QX11PlatformPixmap *brushData = static_cast<QX11PlatformPixmap*>(d->brush_pm.data.data());
- brushData->convertToARGB32();
- }
-#endif
- vals.tile = (d->brush_pm.depth() == d->pdev_depth
- ? d->brush_pm.handle()
- : static_cast<QX11PlatformPixmap*>(d->brush_pm.data.data())->x11ConvertToDefaultDepth());
- s = FillTiled;
-#if !defined(QT_NO_XRENDER)
- d->current_brush = d->cbrush.texture().x11PictureHandle();
-#endif
- }
-
- mask |= GCTileStipXOrigin | GCTileStipYOrigin;
- vals.ts_x_origin = qRound(origin.x());
- vals.ts_y_origin = qRound(origin.y());
- }
-#if !defined(QT_NO_XRENDER)
- else if (d->has_alpha_brush) {
- d->current_brush = X11->getSolidFill(d->scrn, d->cbrush.color());
- }
-#endif
-
- vals.fill_style = s;
- XChangeGC(d->dpy, d->gc_brush, mask, &vals);
- if (!d->has_clipping) {
- QRegion sysClip = systemClip();
- if (!sysClip.isEmpty())
- x11SetClipRegion(d->dpy, d->gc_brush, 0, d->picture, sysClip);
- else
- x11ClearClipRegion(d->dpy, d->gc_brush, 0, d->picture);
- }
-}
-
-void QX11PaintEngine::drawEllipse(const QRectF &rect)
-{
- QRect aligned = rect.toAlignedRect();
- if (aligned == rect)
- drawEllipse(aligned);
- else
- QPaintEngine::drawEllipse(rect);
-}
-
-void QX11PaintEngine::drawEllipse(const QRect &rect)
-{
- if (rect.isEmpty()) {
- drawRects(&rect, 1);
- return;
- }
-
- Q_D(QX11PaintEngine);
- QRect devclip(SHRT_MIN, SHRT_MIN, SHRT_MAX*2 - 1, SHRT_MAX*2 - 1);
- QRect r(rect);
- if (d->txop < QTransform::TxRotate) {
- r = d->matrix.mapRect(rect);
- } else if (d->txop == QTransform::TxRotate && rect.width() == rect.height()) {
- QPainterPath path;
- path.addEllipse(rect);
- r = d->matrix.map(path).boundingRect().toRect();
- }
-
- if (d->has_alpha_brush || d->has_alpha_pen || d->has_custom_pen || (d->render_hints & QPainter::Antialiasing)
- || d->has_alpha_texture || devclip.intersected(r) != r
- || (d->has_complex_xform
- && !(d->has_non_scaling_xform && rect.width() == rect.height())))
- {
- QPainterPath path;
- path.addEllipse(rect);
- drawPath(path);
- return;
- }
-
- int x = r.x();
- int y = r.y();
- int w = r.width();
- int h = r.height();
- if (w < 1 || h < 1)
- return;
- if (w == 1 && h == 1) {
- XDrawPoint(d->dpy, d->hd, d->has_pen ? d->gc : d->gc_brush, x, y);
- return;
- }
- d->setupAdaptedOrigin(rect.topLeft());
- if (d->has_brush) { // draw filled ellipse
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
- if (!d->has_pen) // make smoother outline
- XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
- }
- if (d->has_pen) // draw outline
- XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64);
- d->resetAdaptedOrigin();
-}
-
-
-
-void QX11PaintEnginePrivate::fillPolygon_translated(const QPointF *polygonPoints, int pointCount,
- QX11PaintEnginePrivate::GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode)
-{
-
- QVarLengthArray<QPointF> translated_points(pointCount);
- QPointF offset(matrix.dx(), matrix.dy());
-
- qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
- if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing))
- offset += QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta);
-
- for (int i = 0; i < pointCount; ++i) {
- translated_points[i] = polygonPoints[i] + offset;
-
- translated_points[i].rx() = qRound(translated_points[i].x()) + offs;
- translated_points[i].ry() = qRound(translated_points[i].y()) + offs;
- }
-
- fillPolygon_dev(translated_points.data(), pointCount, gcMode, mode);
-}
-
-#ifndef QT_NO_XRENDER
-static void qt_XRenderCompositeTrapezoids(Display *dpy,
- int op,
- Picture src,
- Picture dst,
- _Xconst XRenderPictFormat *maskFormat,
- int xSrc,
- int ySrc,
- const XTrapezoid *traps, int size)
-{
- const int MAX_TRAPS = 50000;
- while (size) {
- int to_draw = size;
- if (to_draw > MAX_TRAPS)
- to_draw = MAX_TRAPS;
- XRenderCompositeTrapezoids(dpy, op, src, dst,
- maskFormat,
- xSrc, ySrc,
- traps, to_draw);
- size -= to_draw;
- traps += to_draw;
- }
-}
-#endif
-
-void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
- QX11PaintEnginePrivate::GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode)
-{
- Q_Q(QX11PaintEngine);
-
- int clippedCount = 0;
- qt_float_point *clippedPoints = 0;
-
-#ifndef QT_NO_XRENDER
- //can change if we switch to pen if gcMode != BrushGC
- bool has_fill_texture = has_texture;
- bool has_fill_pattern = has_pattern;
- ::Picture src;
-#endif
- QBrush fill;
- GC fill_gc;
- if (gcMode == BrushGC) {
- fill = cbrush;
- fill_gc = gc_brush;
-#ifndef QT_NO_XRENDER
- if (current_brush)
- src = current_brush;
- else
- src = X11->getSolidFill(scrn, fill.color());
-#endif
- } else {
- fill = QBrush(cpen.brush());
- fill_gc = gc;
-#ifndef QT_NO_XRENDER
- //we use the pens brush
- has_fill_texture = (fill.style() == Qt::TexturePattern);
- has_fill_pattern = (fill.style() >= Qt::Dense1Pattern && fill.style() <= Qt::DiagCrossPattern);
- if (has_fill_texture)
- src = fill.texture().x11PictureHandle();
- else if (has_fill_pattern)
- src = getPatternFill(scrn, fill);
- else
- src = X11->getSolidFill(scrn, fill.color());
-#endif
- }
-
- polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
- &clippedPoints, &clippedCount);
-
-#ifndef QT_NO_XRENDER
- bool solid_fill = fill.color().alpha() == 255;
- if (has_fill_texture && fill.texture().depth() == 1 && solid_fill) {
- has_fill_texture = false;
- has_fill_pattern = true;
- }
-
- bool antialias = render_hints & QPainter::Antialiasing;
-
- if (X11->use_xrender
- && picture
- && !has_fill_pattern
- && (clippedCount > 0)
- && (fill.style() != Qt::NoBrush)
- && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush))
- {
- if (tessellator->size > 0) {
- XRenderPictureAttributes attrs;
- attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp;
- XRenderChangePicture(dpy, picture, CPPolyEdge, &attrs);
- int x_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.x) - bg_origin.x());
- int y_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.y) - bg_origin.y());
- qt_XRenderCompositeTrapezoids(dpy, composition_mode, src, picture,
- antialias
- ? XRenderFindStandardFormat(dpy, PictStandardA8)
- : XRenderFindStandardFormat(dpy, PictStandardA1),
- x_offset, y_offset,
- tessellator->traps, tessellator->size);
- tessellator->done();
- }
- } else
-#endif
- if (fill.style() != Qt::NoBrush) {
- if (clippedCount > 200000) {
- QPolygon poly;
- for (int i = 0; i < clippedCount; ++i)
- poly << QPoint(qFloor(clippedPoints[i].x), qFloor(clippedPoints[i].y));
-
- const QRect bounds = poly.boundingRect();
- const QRect aligned = bounds
- & QRect(QPoint(), QSize(pdev->width(), pdev->height()));
-
- QImage img(aligned.size(), QImage::Format_ARGB32_Premultiplied);
- img.fill(0);
-
- QPainter painter(&img);
- painter.translate(-aligned.x(), -aligned.y());
- painter.setPen(Qt::NoPen);
- painter.setBrush(fill);
- if (gcMode == BrushGC)
- painter.setBrushOrigin(q->painter()->brushOrigin());
- painter.drawPolygon(poly);
- painter.end();
-
- q->drawImage(aligned, img, img.rect(), Qt::AutoColor);
- } else if (clippedCount > 0) {
- QVarLengthArray<XPoint> xpoints(clippedCount);
- for (int i = 0; i < clippedCount; ++i) {
- xpoints[i].x = qFloor(clippedPoints[i].x);
- xpoints[i].y = qFloor(clippedPoints[i].y);
- }
- if (mode == QPaintEngine::WindingMode)
- XSetFillRule(dpy, fill_gc, WindingRule);
- setupAdaptedOrigin(QPoint(xpoints[0].x, xpoints[0].y));
- XFillPolygon(dpy, hd, fill_gc,
- xpoints.data(), clippedCount,
- mode == QPaintEngine::ConvexMode ? Convex : Complex, CoordModeOrigin);
- resetAdaptedOrigin();
- if (mode == QPaintEngine::WindingMode)
- XSetFillRule(dpy, fill_gc, EvenOddRule);
- }
- }
-}
-
-void QX11PaintEnginePrivate::strokePolygon_translated(const QPointF *polygonPoints, int pointCount, bool close)
-{
- QVarLengthArray<QPointF> translated_points(pointCount);
- QPointF offset(matrix.dx(), matrix.dy());
- for (int i = 0; i < pointCount; ++i)
- translated_points[i] = polygonPoints[i] + offset;
- strokePolygon_dev(translated_points.data(), pointCount, close);
-}
-
-void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int pointCount, bool close)
-{
- int clippedCount = 0;
- qt_float_point *clippedPoints = 0;
- polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
- &clippedPoints, &clippedCount, close);
-
- if (clippedCount > 0) {
- QVarLengthArray<XPoint> xpoints(clippedCount);
- for (int i = 0; i < clippedCount; ++i) {
- xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta);
- xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta);
- }
- uint numberPoints = qMin(clippedCount, xlibMaxLinePoints);
- XPoint *pts = xpoints.data();
- XDrawLines(dpy, hd, gc, pts, numberPoints, CoordModeOrigin);
- pts += numberPoints;
- clippedCount -= numberPoints;
- numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
- while (clippedCount) {
- XDrawLines(dpy, hd, gc, pts-1, numberPoints+1, CoordModeOrigin);
- pts += numberPoints;
- clippedCount -= numberPoints;
- numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
- }
- }
-}
-
-void QX11PaintEngine::drawPolygon(const QPointF *polygonPoints, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QX11PaintEngine);
- if (d->use_path_fallback) {
- QPainterPath path(polygonPoints[0]);
- for (int i = 1; i < pointCount; ++i)
- path.lineTo(polygonPoints[i]);
- if (mode == PolylineMode) {
- QBrush oldBrush = d->cbrush;
- d->cbrush = QBrush(Qt::NoBrush);
- path.setFillRule(Qt::WindingFill);
- drawPath(path);
- d->cbrush = oldBrush;
- } else {
- path.setFillRule(mode == OddEvenMode ? Qt::OddEvenFill : Qt::WindingFill);
- path.closeSubpath();
- drawPath(path);
- }
- return;
- }
- if (mode != PolylineMode && d->has_brush)
- d->fillPolygon_translated(polygonPoints, pointCount, QX11PaintEnginePrivate::BrushGC, mode);
-
- if (d->has_pen)
- d->strokePolygon_translated(polygonPoints, pointCount, mode != PolylineMode);
-}
-
-
-void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEnginePrivate::GCMode gc_mode, bool transform)
-{
- qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
-
- QPainterPath clippedPath;
- QPainterPath clipPath;
- clipPath.addRect(polygonClipper.boundingRect());
-
- if (transform)
- clippedPath = (path*matrix).intersected(clipPath);
- else
- clippedPath = path.intersected(clipPath);
-
- QList<QPolygonF> polys = clippedPath.toFillPolygons();
- for (int i = 0; i < polys.size(); ++i) {
- QVarLengthArray<QPointF> translated_points(polys.at(i).size());
-
- for (int j = 0; j < polys.at(i).size(); ++j) {
- translated_points[j] = polys.at(i).at(j);
- if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing)) {
- translated_points[j].rx() = qRound(translated_points[j].rx() + aliasedCoordinateDelta) + offs;
- translated_points[j].ry() = qRound(translated_points[j].ry() + aliasedCoordinateDelta) + offs;
- }
- }
-
- fillPolygon_dev(translated_points.data(), polys.at(i).size(), gc_mode,
- path.fillRule() == Qt::OddEvenFill ? QPaintEngine::OddEvenMode : QPaintEngine::WindingMode);
- }
-}
-
-void QX11PaintEngine::drawPath(const QPainterPath &path)
-{
- Q_D(QX11PaintEngine);
- if (path.isEmpty())
- return;
-
- if (d->has_brush)
- d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true);
- if (d->has_pen
- && ((X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate
- && !d->has_non_scaling_xform)
- || (d->cpen.style() == Qt::CustomDashLine))) {
- QPainterPathStroker stroker;
- if (d->cpen.style() == Qt::CustomDashLine) {
- stroker.setDashPattern(d->cpen.dashPattern());
- stroker.setDashOffset(d->cpen.dashOffset());
- } else {
- stroker.setDashPattern(d->cpen.style());
- }
- stroker.setCapStyle(d->cpen.capStyle());
- stroker.setJoinStyle(d->cpen.joinStyle());
- QPainterPath stroke;
- qreal width = d->cpen.widthF();
- QPolygonF poly;
- QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height());
- // necessary to get aliased alphablended primitives to be drawn correctly
- if (d->cpen.isCosmetic() || d->has_scaling_xform) {
- if (d->cpen.isCosmetic())
- stroker.setWidth(width == 0 ? 1 : width);
- else
- stroker.setWidth(width * d->xform_scale);
- stroker.d_ptr->stroker.setClipRect(deviceRect);
- stroke = stroker.createStroke(path * d->matrix);
- if (stroke.isEmpty())
- return;
- stroke.setFillRule(Qt::WindingFill);
- d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false);
- } else {
- stroker.setWidth(width);
- stroker.d_ptr->stroker.setClipRect(d->matrix.inverted().mapRect(deviceRect));
- stroke = stroker.createStroke(path);
- if (stroke.isEmpty())
- return;
- stroke.setFillRule(Qt::WindingFill);
- d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, true);
- }
- } else if (d->has_pen) {
- // if we have a cosmetic pen - use XDrawLine() for speed
- QList<QPolygonF> polys = path.toSubpathPolygons(d->matrix);
- for (int i = 0; i < polys.size(); ++i)
- d->strokePolygon_dev(polys.at(i).data(), polys.at(i).size(), false);
- }
-}
-
-Q_WIDGETS_EXPORT void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image,
- Drawable hd, GC gc, Display *dpy, Visual *visual, int depth)
-{
- Q_ASSERT(image.format() == QImage::Format_RGB32);
- Q_ASSERT(image.depth() == 32);
-
- XImage *xi;
- // Note: this code assumes either RGB or BGR, 8 bpc server layouts
- const uint red_mask = (uint) visual->red_mask;
- bool bgr_layout = (red_mask == 0xff);
-
- const int w = rect.width();
- const int h = rect.height();
-
- QImage im;
- int image_byte_order = ImageByteOrder(X11->display);
- if ((QSysInfo::ByteOrder == QSysInfo::BigEndian && ((image_byte_order == LSBFirst) || bgr_layout))
- || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)
- || (image_byte_order == LSBFirst && bgr_layout))
- {
- im = image.copy(rect);
- const int iw = im.bytesPerLine() / 4;
- uint *data = (uint *)im.bits();
- for (int i=0; i < h; i++) {
- uint *p = data;
- uint *end = p + w;
- if (bgr_layout && image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
- while (p < end) {
- *p = ((*p << 8) & 0xffffff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- } else if ((image_byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
- || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {
- while (p < end) {
- *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
- | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- } else if ((image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
- || (image_byte_order == LSBFirst && bgr_layout))
- {
- while (p < end) {
- *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)
- | ((*p ) & 0xff00ff00);
- p++;
- }
- }
- data += iw;
- }
- xi = XCreateImage(dpy, visual, depth, ZPixmap,
- 0, (char *) im.bits(), w, h, 32, im.bytesPerLine());
- } else {
- xi = XCreateImage(dpy, visual, depth, ZPixmap,
- 0, (char *) image.scanLine(rect.y())+rect.x()*sizeof(uint), w, h, 32, image.bytesPerLine());
- }
- XPutImage(dpy, hd, gc, xi, 0, 0, pos.x(), pos.y(), w, h);
- xi->data = 0; // QImage owns these bits
- XDestroyImage(xi);
-}
-
-void QX11PaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags)
-{
- Q_D(QX11PaintEngine);
-
- if (image.format() == QImage::Format_RGB32
- && d->pdev_depth >= 24 && image.depth() == 32
- && r.size() == sr.size())
- {
- int sx = qRound(sr.x());
- int sy = qRound(sr.y());
- int x = qRound(r.x());
- int y = qRound(r.y());
- int w = qRound(r.width());
- int h = qRound(r.height());
-
- qt_x11_drawImage(QRect(sx, sy, w, h), QPoint(x, y), image, d->hd, d->gc, d->dpy,
- (Visual *)d->xinfo->visual(), d->pdev_depth);
- } else {
- QPaintEngine::drawImage(r, image, sr, flags);
- }
-}
-
-void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRectF &_sr)
-{
- Q_D(QX11PaintEngine);
- QRectF sr = _sr;
- int x = qRound(r.x());
- int y = qRound(r.y());
- int sx = qRound(sr.x());
- int sy = qRound(sr.y());
- int sw = qRound(sr.width());
- int sh = qRound(sr.height());
-
- QPixmap pixmap = qt_toX11Pixmap(px);
- if(pixmap.isNull())
- return;
-
- if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())
- || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {
- QPixmap* p = const_cast<QPixmap *>(&pixmap);
- p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));
- }
-
- QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen());
-
-#ifndef QT_NO_XRENDER
- ::Picture src_pict = static_cast<QX11PlatformPixmap*>(pixmap.data.data())->picture;
- if (src_pict && d->picture) {
- const int pDepth = pixmap.depth();
- if (pDepth == 1 && (d->has_alpha_pen)) {
- qt_render_bitmap(d->dpy, d->scrn, src_pict, d->picture,
- sx, sy, x, y, sw, sh, d->cpen);
- return;
- } else if (pDepth != 1 && (pDepth == 32 || pDepth != d->pdev_depth)) {
- XRenderComposite(d->dpy, d->composition_mode,
- src_pict, 0, d->picture, sx, sy, 0, 0, x, y, sw, sh);
- return;
- }
- }
-#endif
-
- bool mono_src = pixmap.depth() == 1;
- bool mono_dst = d->pdev_depth == 1;
- bool restore_clip = false;
-
- if (static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask) { // pixmap has a mask
- QBitmap comb(sw, sh);
- GC cgc = XCreateGC(d->dpy, comb.handle(), 0, 0);
- XSetForeground(d->dpy, cgc, 0);
- XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);
- XSetBackground(d->dpy, cgc, 0);
- XSetForeground(d->dpy, cgc, 1);
- if (!d->crgn.isEmpty()) {
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
- XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);
- } else if (d->has_clipping) {
- XSetClipRectangles(d->dpy, cgc, 0, 0, 0, 0, Unsorted);
- }
- XSetFillStyle(d->dpy, cgc, FillOpaqueStippled);
- XSetTSOrigin(d->dpy, cgc, -sx, -sy);
- XSetStipple(d->dpy, cgc,
- static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask);
- XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);
- XFreeGC(d->dpy, cgc);
-
- XSetClipOrigin(d->dpy, d->gc, x, y);
- XSetClipMask(d->dpy, d->gc, comb.handle());
- restore_clip = true;
- }
-
- if (mono_src) {
- if (!d->crgn.isEmpty()) {
- Pixmap comb = XCreatePixmap(d->dpy, d->hd, sw, sh, 1);
- GC cgc = XCreateGC(d->dpy, comb, 0, 0);
- XSetForeground(d->dpy, cgc, 0);
- XFillRectangle(d->dpy, comb, cgc, 0, 0, sw, sh);
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
- XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);
- XCopyArea(d->dpy, pixmap.handle(), comb, cgc, sx, sy, sw, sh, 0, 0);
- XFreeGC(d->dpy, cgc);
-
- XSetClipMask(d->dpy, d->gc, comb);
- XSetClipOrigin(d->dpy, d->gc, x, y);
- XFreePixmap(d->dpy, comb);
- } else {
- XSetClipMask(d->dpy, d->gc, pixmap.handle());
- XSetClipOrigin(d->dpy, d->gc, x - sx, y - sy);
- }
-
- if (mono_dst) {
- XSetForeground(d->dpy, d->gc, qGray(d->cpen.color().rgb()) > 127 ? 0 : 1);
- } else {
- QColormap cmap = QColormap::instance(d->scrn);
- XSetForeground(d->dpy, d->gc, cmap.pixel(d->cpen.color()));
- }
- XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);
- restore_clip = true;
- } else if (mono_dst && !mono_src) {
- QBitmap bitmap(pixmap);
- XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
- } else {
- XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
- }
-
- if (d->pdev->devType() == QInternal::Pixmap) {
- const QPixmap *px = static_cast<const QPixmap*>(d->pdev);
- Pixmap src_mask = static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask;
- Pixmap dst_mask = static_cast<QX11PlatformPixmap*>(px->data.data())->x11_mask;
- if (dst_mask) {
- GC cgc = XCreateGC(d->dpy, dst_mask, 0, 0);
- if (src_mask) { // copy src mask into dst mask
- XCopyArea(d->dpy, src_mask, dst_mask, cgc, sx, sy, sw, sh, x, y);
- } else { // no src mask, but make sure the area copied is opaque in dest
- XSetBackground(d->dpy, cgc, 0);
- XSetForeground(d->dpy, cgc, 1);
- XFillRectangle(d->dpy, dst_mask, cgc, x, y, sw, sh);
- }
- XFreeGC(d->dpy, cgc);
- }
- }
-
- if (restore_clip) {
- XSetClipOrigin(d->dpy, d->gc, 0, 0);
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
- if (num == 0)
- XSetClipMask(d->dpy, d->gc, XNone);
- else
- XSetClipRectangles(d->dpy, d->gc, 0, 0, rects, num, Unsorted);
- }
-}
-
-void QX11PaintEngine::updateMatrix(const QTransform &mtx)
-{
- Q_D(QX11PaintEngine);
- d->txop = mtx.type();
- d->matrix = mtx;
-
- d->has_complex_xform = (d->txop > QTransform::TxTranslate);
-
- extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
- bool scaling = qt_scaleForTransform(d->matrix, &d->xform_scale);
- d->has_scaling_xform = scaling && d->xform_scale != 1.0;
- d->has_non_scaling_xform = scaling && d->xform_scale == 1.0;
-}
-
-/*
- NB! the clip region is expected to be in dev coordinates
-*/
-void QX11PaintEngine::updateClipRegion_dev(const QRegion &clipRegion, Qt::ClipOperation op)
-{
- Q_D(QX11PaintEngine);
- QRegion sysClip = systemClip();
- if (op == Qt::NoClip) {
- d->has_clipping = false;
- d->crgn = sysClip;
- if (!sysClip.isEmpty()) {
- x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, sysClip);
- } else {
- x11ClearClipRegion(d->dpy, d->gc, d->gc_brush, d->picture);
- }
- return;
- }
-
- switch (op) {
- case Qt::IntersectClip:
- if (d->has_clipping) {
- d->crgn &= clipRegion;
- break;
- }
- // fall through
- case Qt::ReplaceClip:
- if (!sysClip.isEmpty())
- d->crgn = clipRegion.intersected(sysClip);
- else
- d->crgn = clipRegion;
- break;
- default:
- break;
- }
- d->has_clipping = true;
- x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, d->crgn);
-}
-
-void QX11PaintEngine::updateFont(const QFont &)
-{
-}
-
-Qt::HANDLE QX11PaintEngine::handle() const
-{
- Q_D(const QX11PaintEngine);
- Q_ASSERT(isActive());
- Q_ASSERT(d->hd);
- return d->hd;
-}
-
-extern void qt_draw_tile(QPaintEngine *, qreal, qreal, qreal, qreal, const QPixmap &,
- qreal, qreal);
-
-void QX11PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p)
-{
- int x = qRound(r.x());
- int y = qRound(r.y());
- int w = qRound(r.width());
- int h = qRound(r.height());
- int sx = qRound(p.x());
- int sy = qRound(p.y());
-
- bool mono_src = pixmap.depth() == 1;
- Q_D(QX11PaintEngine);
-
- if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())
- || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {
- QPixmap* p = const_cast<QPixmap *>(&pixmap);
- p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));
- }
-
- QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen());
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender && d->picture && pixmap.x11PictureHandle()) {
-#if 0
- // ### Qt 5: enable this
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, pixmap.x11PictureHandle(), CPRepeat, &attrs);
-
- if (mono_src) {
- qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture,
- sx, sy, x, y, w, h, d->cpen);
- } else {
- XRenderComposite(d->dpy, d->composition_mode,
- pixmap.x11PictureHandle(), XNone, d->picture,
- sx, sy, 0, 0, x, y, w, h);
- }
-#else
- const int numTiles = (w / pixmap.width()) * (h / pixmap.height());
- if (numTiles < 100) {
- // this is essentially qt_draw_tile(), inlined for
- // the XRenderComposite call
- int yPos, xPos, drawH, drawW, yOff, xOff;
- yPos = y;
- yOff = sy;
- while(yPos < y + h) {
- drawH = pixmap.height() - yOff; // Cropping first row
- if (yPos + drawH > y + h) // Cropping last row
- drawH = y + h - yPos;
- xPos = x;
- xOff = sx;
- while(xPos < x + w) {
- drawW = pixmap.width() - xOff; // Cropping first column
- if (xPos + drawW > x + w) // Cropping last column
- drawW = x + w - xPos;
- if (mono_src) {
- qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture,
- xOff, yOff, xPos, yPos, drawW, drawH, d->cpen);
- } else {
- XRenderComposite(d->dpy, d->composition_mode,
- pixmap.x11PictureHandle(), XNone, d->picture,
- xOff, yOff, 0, 0, xPos, yPos, drawW, drawH);
- }
- xPos += drawW;
- xOff = 0;
- }
- yPos += drawH;
- yOff = 0;
- }
- } else {
- w = qMin(w, d->pdev->width() - x);
- h = qMin(h, d->pdev->height() - y);
- if (w <= 0 || h <= 0)
- return;
-
- const int pw = w + sx;
- const int ph = h + sy;
- QPixmap pm(pw, ph);
- if (pixmap.hasAlpha() || mono_src)
- pm.fill(Qt::transparent);
-
- const int mode = pixmap.hasAlpha() ? PictOpOver : PictOpSrc;
- const ::Picture pmPicture = pm.x11PictureHandle();
-
- // first tile
- XRenderComposite(d->dpy, mode,
- pixmap.x11PictureHandle(), XNone, pmPicture,
- 0, 0, 0, 0, 0, 0, qMin(pw, pixmap.width()), qMin(ph, pixmap.height()));
-
- // first row of tiles
- int xPos = pixmap.width();
- const int sh = qMin(ph, pixmap.height());
- while (xPos < pw) {
- const int sw = qMin(xPos, pw - xPos);
- XRenderComposite(d->dpy, mode,
- pmPicture, XNone, pmPicture,
- 0, 0, 0, 0, xPos, 0, sw, sh);
- xPos *= 2;
- }
-
- // remaining rows
- int yPos = pixmap.height();
- const int sw = pw;
- while (yPos < ph) {
- const int sh = qMin(yPos, ph - yPos);
- XRenderComposite(d->dpy, mode,
- pmPicture, XNone, pmPicture,
- 0, 0, 0, 0, 0, yPos, sw, sh);
- yPos *= 2;
- }
-
- // composite
- if (mono_src)
- qt_render_bitmap(d->dpy, d->scrn, pmPicture, d->picture,
- sx, sy, x, y, w, h, d->cpen);
- else
- XRenderComposite(d->dpy, d->composition_mode,
- pmPicture, XNone, d->picture,
- sx, sy, 0, 0, x, y, w, h);
- }
-#endif
- } else
-#endif // !QT_NO_XRENDER
- if (pixmap.depth() > 1 && !static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask) {
- XSetTile(d->dpy, d->gc, pixmap.handle());
- XSetFillStyle(d->dpy, d->gc, FillTiled);
- XSetTSOrigin(d->dpy, d->gc, x-sx, y-sy);
- XFillRectangle(d->dpy, d->hd, d->gc, x, y, w, h);
- XSetTSOrigin(d->dpy, d->gc, 0, 0);
- XSetFillStyle(d->dpy, d->gc, FillSolid);
- } else {
- qt_draw_tile(this, x, y, w, h, pixmap, sx, sy);
- }
-}
-
-void QX11PaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- switch(ti.fontEngine->type()) {
- case QFontEngine::TestFontEngine:
- case QFontEngine::Box:
- d_func()->drawBoxTextItem(p, ti);
- break;
- case QFontEngine::XLFD:
- drawXLFD(p, ti);
- break;
-#ifndef QT_NO_FONTCONFIG
- case QFontEngine::Freetype:
- drawFreetype(p, ti);
- break;
-#endif
- default:
- Q_ASSERT(false);
- }
-}
-
-void QX11PaintEngine::drawXLFD(const QPointF &p, const QTextItemInt &ti)
-{
- Q_D(QX11PaintEngine);
-
- if (d->txop > QTransform::TxTranslate) {
- // XServer or font don't support server side transformations, need to do it by hand
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- if (!ti.glyphs.numGlyphs)
- return;
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix = d->matrix;
- matrix.translate(p.x(), p.y());
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- QFontEngineXLFD *xlfd = static_cast<QFontEngineXLFD *>(ti.fontEngine);
- Qt::HANDLE font_id = xlfd->fontStruct()->fid;
-
- XSetFont(d->dpy, d->gc, font_id);
-
- const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
- for (int i = 0; i < glyphs.size(); i++) {
- int xp = qRound(positions[i].x + offs);
- int yp = qRound(positions[i].y + offs);
- if (xp < SHRT_MAX && xp > SHRT_MIN && yp > SHRT_MIN && yp < SHRT_MAX) {
- XChar2b ch;
- ch.byte1 = glyphs[i] >> 8;
- ch.byte2 = glyphs[i] & 0xff;
- XDrawString16(d->dpy, d->hd, d->gc, xp, yp, &ch, 1);
- }
- }
-}
-
-#ifndef QT_NO_FONTCONFIG
-static QPainterPath path_for_glyphs(const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions,
- const QFontEngineFT *ft)
-{
- QPainterPath path;
- path.setFillRule(Qt::WindingFill);
- ft->lockFace();
- int i = 0;
- while (i < glyphs.size()) {
- QFontEngineFT::Glyph *glyph = ft->loadGlyph(glyphs[i], QFontEngineFT::Format_Mono);
- // #### fix case where we don't get a glyph
- if (!glyph)
- break;
-
- Q_ASSERT(glyph->format == QFontEngineFT::Format_Mono);
- int n = 0;
- int h = glyph->height;
- int xp = qRound(positions[i].x);
- int yp = qRound(positions[i].y);
-
- xp += glyph->x;
- yp += -glyph->y + glyph->height;
- int pitch = ((glyph->width + 31) & ~31) >> 3;
-
- uchar *src = glyph->data;
- while (h--) {
- for (int x = 0; x < glyph->width; ++x) {
- bool set = src[x >> 3] & (0x80 >> (x & 7));
- if (set) {
- QRect r(xp + x, yp - h, 1, 1);
- while (x < glyph->width-1 && src[(x+1) >> 3] & (0x80 >> ((x+1) & 7))) {
- ++x;
- r.setRight(r.right()+1);
- }
-
- path.addRect(r);
- ++n;
- }
- }
- src += pitch;
- }
- ++i;
- }
- ft->unlockFace();
- return path;
-}
-
-void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti)
-{
- Q_D(QX11PaintEngine);
- if (!ti.glyphs.numGlyphs)
- return;
-
- QFontEngineX11FT *ft = static_cast<QFontEngineX11FT *>(ti.fontEngine);
-
- if (!d->cpen.isSolid()) {
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- const bool xrenderPath = (X11->use_xrender
- && !(d->pdev->devType() == QInternal::Pixmap
- && static_cast<const QPixmap *>(d->pdev)->data->pixelType() == QPlatformPixmap::BitmapType));
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix;
-
- if (xrenderPath)
- matrix = d->matrix;
- matrix.translate(p.x(), p.y());
- ft->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- if (glyphs.count() == 0)
- return;
-
-#ifndef QT_NO_XRENDER
- QFontEngineFT::QGlyphSet *set = ft->defaultGlyphs();
- if (d->txop >= QTransform::TxScale && xrenderPath)
- set = ft->loadTransformedGlyphSet(d->matrix);
-
- if (!set || set->outline_drawing
- || !ft->loadGlyphs(set, glyphs.constData(), glyphs.size(), positions.constData(), QFontEngineFT::Format_Render))
- {
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- if (xrenderPath) {
- GlyphSet glyphSet = set->id;
- const QColor &pen = d->cpen.color();
- ::Picture src = X11->getSolidFill(d->scrn, pen);
- XRenderPictFormat *maskFormat = 0;
- if (ft->xglyph_format != PictStandardA1)
- maskFormat = XRenderFindStandardFormat(X11->display, ft->xglyph_format);
-
- enum { t_min = SHRT_MIN, t_max = SHRT_MAX };
-
- int i = 0;
- for (; i < glyphs.size()
- && (positions[i].x < t_min || positions[i].x > t_max
- || positions[i].y < t_min || positions[i].y > t_max);
- ++i)
- ;
-
- if (i >= glyphs.size())
- return;
- ++i;
-
- QFixed xp = positions[i - 1].x;
- QFixed yp = positions[i - 1].y;
- QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
-
- XGlyphElt32 elt;
- elt.glyphset = glyphSet;
- elt.chars = &glyphs[i - 1];
- elt.nchars = 1;
- elt.xOff = qRound(xp + offs);
- elt.yOff = qRound(yp + offs);
- for (; i < glyphs.size(); ++i) {
- if (positions[i].x < t_min || positions[i].x > t_max
- || positions[i].y < t_min || positions[i].y > t_max) {
- break;
- }
- QFontEngineFT::Glyph *g = ft->cachedGlyph(glyphs[i - 1]);
- if (g
- && positions[i].x == xp + g->advance
- && positions[i].y == yp
- && elt.nchars < 253 // don't draw more than 253 characters as some X servers
- // hang with it
- ) {
- elt.nchars++;
- xp += g->advance;
- } else {
- xp = positions[i].x;
- yp = positions[i].y;
-
- XRenderCompositeText32(X11->display, PictOpOver, src, d->picture,
- maskFormat, 0, 0, 0, 0,
- &elt, 1);
- elt.chars = &glyphs[i];
- elt.nchars = 1;
- elt.xOff = qRound(xp + offs);
- elt.yOff = qRound(yp + offs);
- }
- }
- XRenderCompositeText32(X11->display, PictOpOver, src, d->picture,
- maskFormat, 0, 0, 0, 0,
- &elt, 1);
-
- return;
-
- }
-#endif
-
- QPainterPath path = path_for_glyphs(glyphs, positions, ft);
- if (path.elementCount() <= 1)
- return;
- Q_ASSERT((path.elementCount() % 5) == 0);
- if (d->txop >= QTransform::TxScale) {
- painter()->save();
- painter()->setBrush(d->cpen.brush());
- painter()->setPen(Qt::NoPen);
- painter()->drawPath(path);
- painter()->restore();
- return;
- }
-
- const int rectcount = 256;
- XRectangle rects[rectcount];
- int num_rects = 0;
-
- QPoint delta(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
- QRect clip(d->polygonClipper.boundingRect());
- for (int i=0; i < path.elementCount(); i+=5) {
- int x = qRound(path.elementAt(i).x);
- int y = qRound(path.elementAt(i).y);
- int w = qRound(path.elementAt(i+1).x) - x;
- int h = qRound(path.elementAt(i+2).y) - y;
-
- QRect rect = QRect(x + delta.x(), y + delta.y(), w, h);
- rect = rect.intersected(clip);
- if (rect.isEmpty())
- continue;
-
- rects[num_rects].x = short(rect.x());
- rects[num_rects].y = short(rect.y());
- rects[num_rects].width = ushort(rect.width());
- rects[num_rects].height = ushort(rect.height());
- ++num_rects;
- if (num_rects == rectcount) {
- XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
- num_rects = 0;
- }
- }
- if (num_rects > 0)
- XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
-
-}
-#endif // !QT_NO_XRENDER
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qpaintengine_x11_p.h b/src/widgets/platforms/x11/qpaintengine_x11_p.h
deleted file mode 100644
index 2ff339bbe1..0000000000
--- a/src/widgets/platforms/x11/qpaintengine_x11_p.h
+++ /dev/null
@@ -1,246 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_X11_P_H
-#define QPAINTENGINE_X11_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 "QtGui/qpaintengine.h"
-#include "QtGui/qregion.h"
-#include "QtGui/qpen.h"
-#include "QtCore/qpoint.h"
-#include "private/qpaintengine_p.h"
-#include "private/qpainter_p.h"
-#include "private/qpolygonclipper_p.h"
-
-typedef unsigned long Picture;
-
-QT_BEGIN_NAMESPACE
-
-class QX11PaintEnginePrivate;
-class QFontEngineFT;
-class QXRenderTessellator;
-
-struct qt_float_point
-{
- qreal x, y;
-};
-
-class QX11PaintEngine : public QPaintEngine
-{
- Q_DECLARE_PRIVATE(QX11PaintEngine)
-public:
- QX11PaintEngine();
- ~QX11PaintEngine();
-
- bool begin(QPaintDevice *pdev);
- bool end();
-
- void updateState(const QPaintEngineState &state);
-
- void updatePen(const QPen &pen);
- void updateBrush(const QBrush &brush, const QPointF &pt);
- void updateRenderHints(QPainter::RenderHints hints);
- void updateFont(const QFont &font);
- void updateMatrix(const QTransform &matrix);
- void updateClipRegion_dev(const QRegion &region, Qt::ClipOperation op);
-
- void drawLines(const QLine *lines, int lineCount);
- void drawLines(const QLineF *lines, int lineCount);
-
- void drawRects(const QRect *rects, int rectCount);
- void drawRects(const QRectF *rects, int rectCount);
-
- void drawPoints(const QPoint *points, int pointCount);
- void drawPoints(const QPointF *points, int pointCount);
-
- void drawEllipse(const QRect &r);
- void drawEllipse(const QRectF &r);
-
- virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
- { QPaintEngine::drawPolygon(points, pointCount, mode); }
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
- void drawPath(const QPainterPath &path);
- void drawTextItem(const QPointF &p, const QTextItem &textItem);
- void drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
-
- virtual Qt::HANDLE handle() const;
- inline Type type() const { return QPaintEngine::X11; }
-
- QPainter::RenderHints supportedRenderHints() const;
-
-protected:
- QX11PaintEngine(QX11PaintEnginePrivate &dptr);
-
- void drawXLFD(const QPointF &p, const QTextItemInt &si);
-#ifndef QT_NO_FONTCONFIG
- void drawFreetype(const QPointF &p, const QTextItemInt &si);
-#endif
-
- friend class QPixmap;
- friend class QFontEngineBox;
- friend Q_WIDGETS_EXPORT GC qt_x11_get_pen_gc(QPainter *);
- friend Q_WIDGETS_EXPORT GC qt_x11_get_brush_gc(QPainter *);
-
-private:
- Q_DISABLE_COPY(QX11PaintEngine)
-};
-
-class QX11PaintEnginePrivate : public QPaintEnginePrivate
-{
- Q_DECLARE_PUBLIC(QX11PaintEngine)
-public:
- QX11PaintEnginePrivate()
- {
- scrn = -1;
- hd = 0;
- picture = 0;
- gc = gc_brush = 0;
- dpy = 0;
- xinfo = 0;
- txop = QTransform::TxNone;
- has_clipping = false;
- render_hints = 0;
- xform_scale = 1;
-#ifndef QT_NO_XRENDER
- tessellator = 0;
-#endif
- }
- enum GCMode {
- PenGC,
- BrushGC
- };
-
- void init();
- void fillPolygon_translated(const QPointF *points, int pointCount, GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode);
- void fillPolygon_dev(const QPointF *points, int pointCount, GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode);
- void fillPath(const QPainterPath &path, GCMode gcmode, bool transform);
- void strokePolygon_dev(const QPointF *points, int pointCount, bool close);
- void strokePolygon_translated(const QPointF *points, int pointCount, bool close);
- void setupAdaptedOrigin(const QPoint &p);
- void resetAdaptedOrigin();
- void decidePathFallback() {
- use_path_fallback = has_alpha_brush
- || has_alpha_pen
- || has_custom_pen
- || has_complex_xform
- || (render_hints & QPainter::Antialiasing);
- }
- void decideCoordAdjust() {
- adjust_coords = !(render_hints & QPainter::Antialiasing)
- && (has_alpha_pen
- || (has_alpha_brush && has_pen && !has_alpha_pen)
- || (cpen.style() > Qt::SolidLine));
- }
- void clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly);
- void systemStateChanged();
-
- Display *dpy;
- int scrn;
- int pdev_depth;
- Qt::HANDLE hd;
- QPixmap brush_pm;
-#if !defined (QT_NO_XRENDER)
- Qt::HANDLE picture;
- Qt::HANDLE current_brush;
- QPixmap bitmap_texture;
- int composition_mode;
-#else
- Qt::HANDLE picture;
-#endif
- GC gc;
- GC gc_brush;
-
- QPen cpen;
- QBrush cbrush;
- QRegion crgn;
- QTransform matrix;
- qreal opacity;
-
- uint has_complex_xform : 1;
- uint has_scaling_xform : 1;
- uint has_non_scaling_xform : 1;
- uint has_custom_pen : 1;
- uint use_path_fallback : 1;
- uint adjust_coords : 1;
- uint has_clipping : 1;
- uint adapted_brush_origin : 1;
- uint adapted_pen_origin : 1;
- uint has_pen : 1;
- uint has_brush : 1;
- uint has_texture : 1;
- uint has_alpha_texture : 1;
- uint has_pattern : 1;
- uint has_alpha_pen : 1;
- uint has_alpha_brush : 1;
- uint render_hints;
-
- const QX11Info *xinfo;
- QPointF bg_origin;
- QTransform::TransformationType txop;
- qreal xform_scale;
- QPolygonClipper<qt_float_point, qt_float_point, float> polygonClipper;
-
- int xlibMaxLinePoints;
-#ifndef QT_NO_XRENDER
- QXRenderTessellator *tessellator;
-#endif
-};
-
-QT_END_NAMESPACE
-
-#endif // QPAINTENGINE_X11_P_H
diff --git a/src/widgets/platforms/x11/qpixmap_x11.cpp b/src/widgets/platforms/x11/qpixmap_x11.cpp
deleted file mode 100644
index 500d1e3ddf..0000000000
--- a/src/widgets/platforms/x11/qpixmap_x11.cpp
+++ /dev/null
@@ -1,2419 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// Uncomment the next line to enable the MIT Shared Memory extension
-//
-// WARNING: This has some problems:
-//
-// 1. Consumes a 800x600 pixmap
-// 2. Qt does not handle the ShmCompletion message, so you will
-// get strange effects if you xForm() repeatedly.
-//
-// #define QT_MITSHM
-
-#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
-#undef QT_MITSHM
-#endif
-
-#include "qplatformdefs.h"
-
-#include "qdebug.h"
-#include "qiodevice.h"
-#include "qpixmap_x11_p.h"
-#include "qbitmap.h"
-#include "qcolormap.h"
-#include "qimage.h"
-#include "qmatrix.h"
-#include "qapplication.h"
-#include <private/qpaintengine_x11_p.h>
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-#include <stdlib.h>
-
-#if defined(Q_CC_MIPS)
-# define for if(0){}else for
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QPixmap qt_toX11Pixmap(const QImage &image)
-{
- QPlatformPixmap *data =
- new QX11PlatformPixmap(image.depth() == 1
- ? QPlatformPixmap::BitmapType
- : QPlatformPixmap::PixmapType);
-
- data->fromImage(image, Qt::AutoColor);
-
- return QPixmap(data);
-}
-
-QPixmap qt_toX11Pixmap(const QPixmap &pixmap)
-{
- if (pixmap.isNull())
- return QPixmap();
-
- if (QPixmap(pixmap).data_ptr()->classId() == QPlatformPixmap::X11Class)
- return pixmap;
-
- return qt_toX11Pixmap(pixmap.toImage());
-}
-
-// For thread-safety:
-// image->data does not belong to X11, so we must free it ourselves.
-
-inline static void qSafeXDestroyImage(XImage *x)
-{
- if (x->data) {
- free(x->data);
- x->data = 0;
- }
- XDestroyImage(x);
-}
-
-QBitmap QX11PlatformPixmap::mask_to_bitmap(int screen) const
-{
- if (!x11_mask)
- return QBitmap();
- QPixmap::x11SetDefaultScreen(screen);
- QBitmap bm(w, h);
- GC gc = XCreateGC(X11->display, bm.handle(), 0, 0);
- XCopyArea(X11->display, x11_mask, bm.handle(), gc, 0, 0,
- bm.data->width(), bm.data->height(), 0, 0);
- XFreeGC(X11->display, gc);
- return bm;
-}
-
-Qt::HANDLE QX11PlatformPixmap::bitmap_to_mask(const QBitmap &bitmap, int screen)
-{
- if (bitmap.isNull())
- return 0;
- QBitmap bm = bitmap;
- bm.x11SetScreen(screen);
-
- Pixmap mask = XCreatePixmap(X11->display, RootWindow(X11->display, screen),
- bm.data->width(), bm.data->height(), 1);
- GC gc = XCreateGC(X11->display, mask, 0, 0);
- XCopyArea(X11->display, bm.handle(), mask, gc, 0, 0,
- bm.data->width(), bm.data->height(), 0, 0);
- XFreeGC(X11->display, gc);
- return mask;
-}
-
-
-/*****************************************************************************
- MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
- *****************************************************************************/
-
-#if defined(QT_MITSHM)
-
-static bool xshminit = false;
-static XShmSegmentInfo xshminfo;
-static XImage *xshmimg = 0;
-static Pixmap xshmpm = 0;
-
-static void qt_cleanup_mitshm()
-{
- if (xshmimg == 0)
- return;
- Display *dpy = QX11Info::appDisplay();
- if (xshmpm) {
- XFreePixmap(dpy, xshmpm);
- xshmpm = 0;
- }
- XShmDetach(dpy, &xshminfo); xshmimg->data = 0;
- qSafeXDestroyImage(xshmimg); xshmimg = 0;
- shmdt(xshminfo.shmaddr);
- shmctl(xshminfo.shmid, IPC_RMID, 0);
-}
-
-static bool qt_create_mitshm_buffer(const QPaintDevice* dev, int w, int h)
-{
- static int major, minor;
- static Bool pixmaps_ok;
- Display *dpy = dev->data->xinfo->display();
- int dd = dev->x11Depth();
- Visual *vis = (Visual*)dev->x11Visual();
-
- if (xshminit) {
- qt_cleanup_mitshm();
- } else {
- if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok))
- return false; // MIT Shm not supported
- qAddPostRoutine(qt_cleanup_mitshm);
- xshminit = true;
- }
-
- xshmimg = XShmCreateImage(dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h);
- if (!xshmimg)
- return false;
-
- bool ok;
- xshminfo.shmid = shmget(IPC_PRIVATE,
- xshmimg->bytes_per_line * xshmimg->height,
- IPC_CREAT | 0777);
- ok = xshminfo.shmid != -1;
- if (ok) {
- xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
- xshminfo.shmaddr = xshmimg->data;
- ok = (xshminfo.shmaddr != (char*)-1);
- }
- xshminfo.readOnly = false;
- if (ok)
- ok = XShmAttach(dpy, &xshminfo);
- if (!ok) {
- qSafeXDestroyImage(xshmimg);
- xshmimg = 0;
- if (xshminfo.shmaddr)
- shmdt(xshminfo.shmaddr);
- if (xshminfo.shmid != -1)
- shmctl(xshminfo.shmid, IPC_RMID, 0);
- return false;
- }
- if (pixmaps_ok)
- xshmpm = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), xshmimg->data,
- &xshminfo, w, h, dd);
-
- return true;
-}
-
-#else
-
-// If extern, need a dummy.
-//
-// static bool qt_create_mitshm_buffer(QPaintDevice*, int, int)
-// {
-// return false;
-// }
-
-#endif // QT_MITSHM
-
-
-/*****************************************************************************
- Internal functions
- *****************************************************************************/
-
-extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
-
-// Returns position of highest bit set or -1 if none
-static int highest_bit(uint v)
-{
- int i;
- uint b = (uint)1 << 31;
- for (i=31; ((b & v) == 0) && i>=0; i--)
- b >>= 1;
- return i;
-}
-
-// Returns position of lowest set bit in 'v' as an integer (0-31), or -1
-static int lowest_bit(uint v)
-{
- int i;
- ulong lb;
- lb = 1;
- for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1) {}
- return i==32 ? -1 : i;
-}
-
-// Counts the number of bits set in 'v'
-static uint n_bits(uint v)
-{
- int i = 0;
- while (v) {
- v = v & (v - 1);
- i++;
- }
- return i;
-}
-
-static uint *red_scale_table = 0;
-static uint *green_scale_table = 0;
-static uint *blue_scale_table = 0;
-
-static void cleanup_scale_tables()
-{
- delete[] red_scale_table;
- delete[] green_scale_table;
- delete[] blue_scale_table;
-}
-
-/*
- Could do smart bitshifting, but the "obvious" algorithm only works for
- nBits >= 4. This is more robust.
-*/
-static void build_scale_table(uint **table, uint nBits)
-{
- if (nBits > 7) {
- qWarning("build_scale_table: internal error, nBits = %i", nBits);
- return;
- }
- if (!*table) {
- static bool firstTable = true;
- if (firstTable) {
- qAddPostRoutine(cleanup_scale_tables);
- firstTable = false;
- }
- *table = new uint[256];
- }
- int maxVal = (1 << nBits) - 1;
- int valShift = 8 - nBits;
- int i;
- for(i = 0 ; i < maxVal + 1 ; i++)
- (*table)[i << valShift] = i*255/maxVal;
-}
-
-static int defaultScreen = -1;
-
-/*****************************************************************************
- QPixmap member functions
- *****************************************************************************/
-
-QBasicAtomicInt qt_pixmap_serial = Q_BASIC_ATOMIC_INITIALIZER(0);
-int Q_WIDGETS_EXPORT qt_x11_preferred_pixmap_depth = 0;
-
-QX11PlatformPixmap::QX11PlatformPixmap(PixelType type)
- : QPlatformPixmap(type, X11Class), gl_surface(0), hd(0),
- flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0),
- share_mode(QPixmap::ImplicitlyShared), pengine(0)
-{
-}
-
-QPlatformPixmap *QX11PlatformPixmap::createCompatiblePlatformPixmap() const
-{
- return new QX11PlatformPixmap(pixelType());
-}
-
-void QX11PlatformPixmap::resize(int width, int height)
-{
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
-
- if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
- QX11InfoData* xd = xinfo.getX11Data(true);
- xd->screen = defaultScreen;
- xd->depth = QX11Info::appDepth(xd->screen);
- xd->cells = QX11Info::appCells(xd->screen);
- xd->colormap = QX11Info::appColormap(xd->screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
- xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
- xinfo.setX11Data(xd);
- }
-
- int dd = xinfo.depth();
-
- if (qt_x11_preferred_pixmap_depth)
- dd = qt_x11_preferred_pixmap_depth;
-
- bool make_null = w <= 0 || h <= 0; // create null pixmap
- d = (pixelType() == BitmapType ? 1 : dd);
- if (make_null || d == 0) {
- w = 0;
- h = 0;
- is_null = true;
- hd = 0;
- picture = 0;
- d = 0;
- if (!make_null)
- qWarning("QPixmap: Invalid pixmap parameters");
- return;
- }
- hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, xinfo.screen()),
- w, h, d);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 1
- ? XRenderFindStandardFormat(X11->display, PictStandardA1)
- : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-}
-
-struct QX11AlphaDetector
-{
- bool hasAlpha() const {
- if (checked)
- return has;
- // Will implicitly also check format and return quickly for opaque types...
- checked = true;
- has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
- return has;
- }
-
- bool hasXRenderAndAlpha() const {
- if (!X11->use_xrender)
- return false;
- return hasAlpha();
- }
-
- QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
- : image(i), checked(false), has(false)
- {
- if (flags & Qt::NoOpaqueDetection) {
- checked = true;
- has = image->hasAlphaChannel();
- }
- }
-
- const QImage *image;
- mutable bool checked;
- mutable bool has;
-};
-
-void QX11PlatformPixmap::fromImage(const QImage &img,
- Qt::ImageConversionFlags flags)
-{
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- w = img.width();
- h = img.height();
- d = img.depth();
- is_null = (w <= 0 || h <= 0);
-
- if (is_null) {
- w = h = 0;
- return;
- }
-
- if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
- QX11InfoData* xd = xinfo.getX11Data(true);
- xd->screen = defaultScreen;
- xd->depth = QX11Info::appDepth(xd->screen);
- xd->cells = QX11Info::appCells(xd->screen);
- xd->colormap = QX11Info::appColormap(xd->screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
- xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
- xinfo.setX11Data(xd);
- }
-
- if (pixelType() == BitmapType) {
- bitmapFromImage(img);
- return;
- }
-
- if (uint(w) >= 32768 || uint(h) >= 32768) {
- w = h = 0;
- is_null = true;
- return;
- }
-
- QX11AlphaDetector alphaCheck(&img, flags);
- int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
-
- if (qt_x11_preferred_pixmap_depth)
- dd = qt_x11_preferred_pixmap_depth;
-
- QImage image = img;
-
- // must be monochrome
- if (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly) {
- if (d != 1) {
- // dither
- image = image.convertToFormat(QImage::Format_MonoLSB, flags);
- d = 1;
- }
- } else { // can be both
- bool conv8 = false;
- if (d > 8 && dd <= 8) { // convert to 8 bit
- if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
- flags = (flags & ~Qt::DitherMode_Mask)
- | Qt::PreferDither;
- conv8 = true;
- } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
- conv8 = (d == 1); // native depth wanted
- } else if (d == 1) {
- if (image.colorCount() == 2) {
- QRgb c0 = image.color(0); // Auto: convert to best
- QRgb c1 = image.color(1);
- conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
- } else {
- // eg. 1-color monochrome images (they do exist).
- conv8 = true;
- }
- }
- if (conv8) {
- image = image.convertToFormat(QImage::Format_Indexed8, flags);
- d = 8;
- }
- }
-
- if (d == 1 || d == 16 || d == 24) {
- image = image.convertToFormat(QImage::Format_RGB32, flags);
- fromImage(image, Qt::AutoColor);
- return;
- }
-
- Display *dpy = X11->display;
- Visual *visual = (Visual *)xinfo.visual();
- XImage *xi = 0;
- bool trucol = (visual->c_class >= TrueColor);
- int nbytes = image.byteCount();
- uchar *newbits= 0;
-
-#ifndef QT_NO_XRENDER
- if (alphaCheck.hasXRenderAndAlpha()) {
- const QImage &cimage = image;
-
- d = 32;
-
- if (QX11Info::appDepth() != d) {
- if (xinfo.x11data) {
- xinfo.x11data->depth = d;
- } else {
- QX11InfoData *xd = xinfo.getX11Data(true);
- xd->screen = QX11Info::appScreen();
- xd->depth = d;
- xd->cells = QX11Info::appCells();
- xd->colormap = QX11Info::appColormap();
- xd->defaultColormap = QX11Info::appDefaultColormap();
- xd->visual = (Visual *)QX11Info::appVisual();
- xd->defaultVisual = QX11Info::appDefaultVisual();
- xinfo.setX11Data(xd);
- }
- }
-
- hd = (Qt::HANDLE)XCreatePixmap(dpy, RootWindow(dpy, xinfo.screen()),
- w, h, d);
- picture = XRenderCreatePicture(X11->display, hd,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
-
- xi = XCreateImage(dpy, visual, d, ZPixmap, 0, 0, w, h, 32, 0);
- Q_CHECK_PTR(xi);
- newbits = (uchar *)malloc(xi->bytes_per_line*h);
- Q_CHECK_PTR(newbits);
- xi->data = (char *)newbits;
-
- switch(cimage.format()) {
- case QImage::Format_Indexed8: {
- QVector<QRgb> colorTable = cimage.colorTable();
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const uchar *p = cimage.scanLine(y);
- for (int x = 0; x < w; ++x) {
- const QRgb rgb = colorTable[p[x]];
- const int a = qAlpha(rgb);
- if (a == 0xff)
- *xidata = rgb;
- else
- // RENDER expects premultiplied alpha
- *xidata = qRgba(qt_div_255(qRed(rgb) * a),
- qt_div_255(qGreen(rgb) * a),
- qt_div_255(qBlue(rgb) * a),
- a);
- ++xidata;
- }
- }
- }
- break;
- case QImage::Format_RGB32: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- for (int x = 0; x < w; ++x)
- *xidata++ = p[x] | 0xff000000;
- }
- }
- break;
- case QImage::Format_ARGB32: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- for (int x = 0; x < w; ++x) {
- const QRgb rgb = p[x];
- const int a = qAlpha(rgb);
- if (a == 0xff)
- *xidata = rgb;
- else
- // RENDER expects premultiplied alpha
- *xidata = qRgba(qt_div_255(qRed(rgb) * a),
- qt_div_255(qGreen(rgb) * a),
- qt_div_255(qBlue(rgb) * a),
- a);
- ++xidata;
- }
- }
-
- }
- break;
- case QImage::Format_ARGB32_Premultiplied: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- memcpy(xidata, p, w*sizeof(QRgb));
- xidata += w;
- }
- }
- break;
- default:
- Q_ASSERT(false);
- }
-
- if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
- uint *xidata = (uint *)xi->data;
- uint *xiend = xidata + w*h;
- while (xidata < xiend) {
- *xidata = (*xidata >> 24)
- | ((*xidata >> 8) & 0xff00)
- | ((*xidata << 8) & 0xff0000)
- | (*xidata << 24);
- ++xidata;
- }
- }
-
- GC gc = XCreateGC(dpy, hd, 0, 0);
- XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
- XFreeGC(dpy, gc);
-
- qSafeXDestroyImage(xi);
-
- return;
- }
-#endif // QT_NO_XRENDER
-
- if (trucol) { // truecolor display
- if (image.format() == QImage::Format_ARGB32_Premultiplied)
- image = image.convertToFormat(QImage::Format_ARGB32);
-
- const QImage &cimage = image;
- QRgb pix[256]; // pixel translation table
- const bool d8 = (d == 8);
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit(red_mask) - 7;
- const int green_shift = highest_bit(green_mask) - 7;
- const int blue_shift = highest_bit(blue_mask) - 7;
- const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
- const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
- const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
-
- if (d8) { // setup pixel translation
- QVector<QRgb> ctable = cimage.colorTable();
- for (int i=0; i < cimage.colorCount(); i++) {
- int r = qRed (ctable[i]);
- int g = qGreen(ctable[i]);
- int b = qBlue (ctable[i]);
- r = red_shift > 0 ? r << red_shift : r >> -red_shift;
- g = green_shift > 0 ? g << green_shift : g >> -green_shift;
- b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
- pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
- | ~(blue_mask | green_mask | red_mask);
- }
- }
-
- xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
- Q_CHECK_PTR(xi);
- newbits = (uchar *)malloc(xi->bytes_per_line*h);
- Q_CHECK_PTR(newbits);
- if (!newbits) // no memory
- return;
- int bppc = xi->bits_per_pixel;
-
- bool contig_bits = n_bits(red_mask) == rbits &&
- n_bits(green_mask) == gbits &&
- n_bits(blue_mask) == bbits;
- bool dither_tc =
- // Want it?
- (flags & Qt::Dither_Mask) != Qt::ThresholdDither &&
- (flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&
- // Need it?
- bppc < 24 && !d8 &&
- // Can do it? (Contiguous bits?)
- contig_bits;
-
- static bool init=false;
- static int D[16][16];
- if (dither_tc && !init) {
- // I also contributed this code to XV - WWA.
- /*
- The dither matrix, D, is obtained with this formula:
-
- D2 = [0 2]
- [3 1]
-
-
- D2*n = [4*Dn 4*Dn+2*Un]
- [4*Dn+3*Un 4*Dn+1*Un]
- */
- int n,i,j;
- init=1;
-
- /* Set D2 */
- D[0][0]=0;
- D[1][0]=2;
- D[0][1]=3;
- D[1][1]=1;
-
- /* Expand using recursive definition given above */
- for (n=2; n<16; n*=2) {
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) {
- D[i][j]*=4;
- D[i+n][j]=D[i][j]+2;
- D[i][j+n]=D[i][j]+3;
- D[i+n][j+n]=D[i][j]+1;
- }
- }
- }
- init=true;
- }
-
- enum { BPP8,
- BPP16_565, BPP16_555,
- BPP16_MSB, BPP16_LSB,
- BPP24_888,
- BPP24_MSB, BPP24_LSB,
- BPP32_8888,
- BPP32_MSB, BPP32_LSB
- } mode = BPP8;
-
- bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);
-
- if(bppc == 8) // 8 bit
- mode = BPP8;
- else if(bppc == 16) { // 16 bit MSB/LSB
- if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)
- mode = BPP16_565;
- else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)
- mode = BPP16_555;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;
- } else if(bppc == 24) { // 24 bit MSB/LSB
- if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
- mode = BPP24_888;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;
- } else if(bppc == 32) { // 32 bit MSB/LSB
- if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
- mode = BPP32_8888;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;
- } else
- qFatal("Logic error 3");
-
-#define GET_PIXEL \
- uint pixel; \
- if (d8) pixel = pix[*src++]; \
- else { \
- int r = qRed (*p); \
- int g = qGreen(*p); \
- int b = qBlue (*p++); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
- | ~(blue_mask | green_mask | red_mask); \
- }
-
-#define GET_PIXEL_DITHER_TC \
- int r = qRed (*p); \
- int g = qGreen(*p); \
- int b = qBlue (*p++); \
- const int thres = D[x%16][y%16]; \
- if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
-
-// again, optimized case
-// can't be optimized that much :(
-#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
- rbits,gbits,bbits) \
- const int thres = D[x%16][y%16]; \
- int r = qRed (*p); \
- if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- int g = qGreen(*p); \
- if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- int b = qBlue (*p++); \
- if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- uint pixel = ((r red_shift) & red_mask) \
- | ((g green_shift) & green_mask) \
- | ((b blue_shift) & blue_mask);
-
-#define CYCLE(body) \
- for (int y=0; y<h; y++) { \
- const uchar* src = cimage.scanLine(y); \
- uchar* dst = newbits + xi->bytes_per_line*y; \
- const QRgb* p = (const QRgb *)src; \
- body \
- }
-
- if (dither_tc) {
- switch (mode) {
- case BPP16_565:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_555:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- default:
- qFatal("Logic error");
- }
- } else {
- switch (mode) {
- case BPP8: // 8 bit
- CYCLE(
- Q_UNUSED(p);
- for (int x=0; x<w; x++)
- *dst++ = pix[*src++];
- )
- break;
- case BPP16_565:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x = 0; x < w; x++) {
- *dst16++ = ((*p >> 8) & 0xf800)
- | ((*p >> 5) & 0x7e0)
- | ((*p >> 3) & 0x1f);
- ++p;
- }
- )
- break;
- case BPP16_555:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- *dst16++ = ((*p >> 9) & 0x7c00)
- | ((*p >> 6) & 0x3e0)
- | ((*p >> 3) & 0x1f);
- ++p;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- case BPP24_888: // 24 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- *dst++ = qRed (*p);
- *dst++ = qGreen(*p);
- *dst++ = qBlue (*p++);
- }
- )
- break;
- case BPP24_MSB: // 24 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case BPP24_LSB: // 24 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- }
- )
- break;
- case BPP32_8888:
- CYCLE(
- memcpy(dst, p, w * 4);
- )
- break;
- case BPP32_MSB: // 32 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel >> 24;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case BPP32_LSB: // 32 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 24;
- }
- )
- break;
- default:
- qFatal("Logic error 2");
- }
- }
- xi->data = (char *)newbits;
- }
-
- if (d == 8 && !trucol) { // 8 bit pixmap
- int pop[256]; // pixel popularity
-
- if (image.colorCount() == 0)
- image.setColorCount(1);
-
- const QImage &cimage = image;
- memset(pop, 0, sizeof(int)*256); // reset popularity array
- for (int i = 0; i < h; i++) { // for each scanline...
- const uchar* p = cimage.scanLine(i);
- const uchar *end = p + w;
- while (p < end) // compute popularity
- pop[*p++]++;
- }
-
- newbits = (uchar *)malloc(nbytes); // copy image into newbits
- Q_CHECK_PTR(newbits);
- if (!newbits) // no memory
- return;
- uchar* p = newbits;
- memcpy(p, cimage.bits(), nbytes); // copy image data into newbits
-
- /*
- * The code below picks the most important colors. It is based on the
- * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
- */
-
- struct PIX { // pixel sort element
- uchar r,g,b,n; // color + pad
- int use; // popularity
- int index; // index in colormap
- int mindist;
- };
- int ncols = 0;
- for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors
- if (pop[i] > 0)
- ncols++;
- }
- for (int i = cimage.colorCount(); i < 256; i++) // ignore out-of-range pixels
- pop[i] = 0;
-
- // works since we make sure above to have at least
- // one color in the image
- if (ncols == 0)
- ncols = 1;
-
- PIX pixarr[256]; // pixel array
- PIX pixarr_sorted[256]; // pixel array (sorted)
- memset(pixarr, 0, ncols*sizeof(PIX));
- PIX *px = &pixarr[0];
- int maxpop = 0;
- int maxpix = 0;
- uint j = 0;
- QVector<QRgb> ctable = cimage.colorTable();
- for (int i = 0; i < 256; i++) { // init pixel array
- if (pop[i] > 0) {
- px->r = qRed (ctable[i]);
- px->g = qGreen(ctable[i]);
- px->b = qBlue (ctable[i]);
- px->n = 0;
- px->use = pop[i];
- if (pop[i] > maxpop) { // select most popular entry
- maxpop = pop[i];
- maxpix = j;
- }
- px->index = i;
- px->mindist = 1000000;
- px++;
- j++;
- }
- }
- pixarr_sorted[0] = pixarr[maxpix];
- pixarr[maxpix].use = 0;
-
- for (int i = 1; i < ncols; i++) { // sort pixels
- int minpix = -1, mindist = -1;
- px = &pixarr_sorted[i-1];
- int r = px->r;
- int g = px->g;
- int b = px->b;
- int dist;
- if ((i & 1) || i<10) { // sort on max distance
- for (int j=0; j<ncols; j++) {
- px = &pixarr[j];
- if (px->use) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if (px->mindist > dist)
- px->mindist = dist;
- if (px->mindist > mindist) {
- mindist = px->mindist;
- minpix = j;
- }
- }
- }
- } else { // sort on max popularity
- for (int j=0; j<ncols; j++) {
- px = &pixarr[j];
- if (px->use) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if (px->mindist > dist)
- px->mindist = dist;
- if (px->use > mindist) {
- mindist = px->use;
- minpix = j;
- }
- }
- }
- }
- pixarr_sorted[i] = pixarr[minpix];
- pixarr[minpix].use = 0;
- }
-
- QColormap cmap = QColormap::instance(xinfo.screen());
- uint pix[256]; // pixel translation table
- px = &pixarr_sorted[0];
- for (int i = 0; i < ncols; i++) { // allocate colors
- QColor c(px->r, px->g, px->b);
- pix[px->index] = cmap.pixel(c);
- px++;
- }
-
- p = newbits;
- for (int i = 0; i < nbytes; i++) { // translate pixels
- *p = pix[*p];
- p++;
- }
- }
-
- if (!xi) { // X image not created
- xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
- if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp
- ushort *p2;
- int p2inc = xi->bytes_per_line/sizeof(ushort);
- ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);
- Q_CHECK_PTR(newerbits);
- if (!newerbits) // no memory
- return;
- uchar* p = newbits;
- for (int y = 0; y < h; y++) { // OOPS: Do right byte order!!
- p2 = newerbits + p2inc*y;
- for (int x = 0; x < w; x++)
- *p2++ = *p++;
- }
- free(newbits);
- newbits = (uchar *)newerbits;
- } else if (xi->bits_per_pixel != 8) {
- qWarning("QPixmap::fromImage: Display not supported "
- "(bpp=%d)", xi->bits_per_pixel);
- }
- xi->data = (char *)newbits;
- }
-
- hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, xinfo.screen()),
- w, h, dd);
-
- GC gc = XCreateGC(dpy, hd, 0, 0);
- XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
- XFreeGC(dpy, gc);
-
- qSafeXDestroyImage(xi);
- d = dd;
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 1
- ? XRenderFindStandardFormat(X11->display, PictStandardA1)
- : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
- }
-#endif
-
- if (alphaCheck.hasAlpha()) {
- QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
- setMask(m);
- }
-}
-
-Qt::HANDLE QX11PlatformPixmap::createBitmapFromImage(const QImage &image)
-{
- QImage img = image.convertToFormat(QImage::Format_MonoLSB);
- const QRgb c0 = QColor(Qt::black).rgb();
- const QRgb c1 = QColor(Qt::white).rgb();
- if (img.color(0) == c0 && img.color(1) == c1) {
- img.invertPixels();
- img.setColor(0, c1);
- img.setColor(1, c0);
- }
-
- char *bits;
- uchar *tmp_bits;
- int w = img.width();
- int h = img.height();
- int bpl = (w + 7) / 8;
- int ibpl = img.bytesPerLine();
- if (bpl != ibpl) {
- tmp_bits = new uchar[bpl*h];
- bits = (char *)tmp_bits;
- uchar *p, *b;
- int y;
- b = tmp_bits;
- p = img.scanLine(0);
- for (y = 0; y < h; y++) {
- memcpy(b, p, bpl);
- b += bpl;
- p += ibpl;
- }
- } else {
- bits = (char *)img.bits();
- tmp_bits = 0;
- }
- Qt::HANDLE hd = (Qt::HANDLE)XCreateBitmapFromData(X11->display,
- QX11Info::appRootWindow(),
- bits, w, h);
- if (tmp_bits) // Avoid purify complaint
- delete [] tmp_bits;
- return hd;
-}
-
-void QX11PlatformPixmap::bitmapFromImage(const QImage &image)
-{
- w = image.width();
- h = image.height();
- d = 1;
- is_null = (w <= 0 || h <= 0);
- hd = createBitmapFromImage(image);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender)
- picture = XRenderCreatePicture(X11->display, hd,
- XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
-#endif // QT_NO_XRENDER
-}
-
-void QX11PlatformPixmap::fill(const QColor &fillColor)
-{
- if (fillColor.alpha() != 255) {
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- if (!picture || d != 32)
- convertToARGB32(/*preserveContents = */false);
-
- ::Picture src = X11->getSolidFill(xinfo.screen(), fillColor);
- XRenderComposite(X11->display, PictOpSrc, src, 0, picture,
- 0, 0, width(), height(),
- 0, 0, width(), height());
- } else
-#endif
- {
- QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
- im.fill(PREMUL(fillColor.rgba()));
- release();
- fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither);
- }
- return;
- }
-
- GC gc = XCreateGC(X11->display, hd, 0, 0);
- if (depth() == 1) {
- XSetForeground(X11->display, gc, qGray(fillColor.rgb()) > 127 ? 0 : 1);
- } else if (X11->use_xrender && d >= 24) {
- XSetForeground(X11->display, gc, fillColor.rgba());
- } else {
- XSetForeground(X11->display, gc,
- QColormap::instance(xinfo.screen()).pixel(fillColor));
- }
- XFillRectangle(X11->display, hd, gc, 0, 0, width(), height());
- XFreeGC(X11->display, gc);
-}
-
-QX11PlatformPixmap::~QX11PlatformPixmap()
-{
- // Cleanup hooks have to be called before the handles are freed
- if (is_cached) {
- QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(this);
- is_cached = false;
- }
-
- release();
-}
-
-void QX11PlatformPixmap::release()
-{
- delete pengine;
- pengine = 0;
-
- if (!X11) {
- // At this point, the X server will already have freed our resources,
- // so there is nothing to do.
- return;
- }
-
- if (x11_mask) {
-#ifndef QT_NO_XRENDER
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
- mask_picture = 0;
-#endif
- XFreePixmap(X11->display, x11_mask);
- x11_mask = 0;
- }
-
- if (hd) {
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderFreePicture(X11->display, picture);
- picture = 0;
- }
-#endif // QT_NO_XRENDER
-
- if (hd2) {
- XFreePixmap(xinfo.display(), hd2);
- hd2 = 0;
- }
- if (!(flags & Readonly))
- XFreePixmap(xinfo.display(), hd);
- hd = 0;
- }
-}
-
-QPixmap QX11PlatformPixmap::alphaChannel() const
-{
- if (!hasAlphaChannel()) {
- QPixmap pm(w, h);
- pm.fill(Qt::white);
- return pm;
- }
- QImage im(toImage());
- return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither);
-}
-
-void QX11PlatformPixmap::setAlphaChannel(const QPixmap &alpha)
-{
- QImage image(toImage());
- image.setAlphaChannel(alpha.toImage());
- release();
- fromImage(image, Qt::OrderedDither | Qt::OrderedAlphaDither);
-}
-
-
-QBitmap QX11PlatformPixmap::mask() const
-{
- QBitmap mask;
-#ifndef QT_NO_XRENDER
- if (picture && d == 32) {
- // #### slow - there must be a better way..
- mask = QBitmap::fromImage(toImage().createAlphaMask());
- } else
-#endif
- if (d == 1) {
- QX11PlatformPixmap *that = const_cast<QX11PlatformPixmap*>(this);
- mask = QPixmap(that);
- } else {
- mask = mask_to_bitmap(xinfo.screen());
- }
- return mask;
-}
-
-/*!
- Sets a mask bitmap.
-
- The \a newmask bitmap defines the clip mask for this pixmap. Every
- pixel in \a newmask corresponds to a pixel in this pixmap. Pixel
- value 1 means opaque and pixel value 0 means transparent. The mask
- must have the same size as this pixmap.
-
- \warning Setting the mask on a pixmap will cause any alpha channel
- data to be cleared. For example:
- \snippet doc/src/snippets/image/image.cpp 2
- Now, alpha and alphacopy are visually different.
-
- Setting a null mask resets the mask.
-
- The effect of this function is undefined when the pixmap is being
- painted on.
-
- \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap
- Transformations}, QBitmap
-*/
-void QX11PlatformPixmap::setMask(const QBitmap &newmask)
-{
- if (newmask.isNull()) { // clear mask
-#ifndef QT_NO_XRENDER
- if (picture && d == 32) {
- QX11PlatformPixmap newData(pixelType());
- newData.resize(w, h);
- newData.fill(Qt::black);
- XRenderComposite(X11->display, PictOpOver,
- picture, 0, newData.picture,
- 0, 0, 0, 0, 0, 0, w, h);
- release();
- *this = newData;
- // the new QX11PlatformPixmap object isn't referenced yet, so
- // ref it
- ref.ref();
-
- // the below is to make sure the QX11PlatformPixmap destructor
- // doesn't delete our newly created render picture
- newData.hd = 0;
- newData.x11_mask = 0;
- newData.picture = 0;
- newData.mask_picture = 0;
- newData.hd2 = 0;
- } else
-#endif
- if (x11_mask) {
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderPictureAttributes attrs;
- attrs.alpha_map = 0;
- XRenderChangePicture(X11->display, picture, CPAlphaMap,
- &attrs);
- }
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
- mask_picture = 0;
-#endif
- XFreePixmap(X11->display, x11_mask);
- x11_mask = 0;
- }
- return;
- }
-
-#ifndef QT_NO_XRENDER
- if (picture && d == 32) {
- XRenderComposite(X11->display, PictOpSrc,
- picture, newmask.x11PictureHandle(),
- picture, 0, 0, 0, 0, 0, 0, w, h);
- } else
-#endif
- if (depth() == 1) {
- XGCValues vals;
- vals.function = GXand;
- GC gc = XCreateGC(X11->display, hd, GCFunction, &vals);
- XCopyArea(X11->display, newmask.handle(), hd, gc, 0, 0,
- width(), height(), 0, 0);
- XFreeGC(X11->display, gc);
- } else {
- // ##### should or the masks together
- if (x11_mask) {
- XFreePixmap(X11->display, x11_mask);
-#ifndef QT_NO_XRENDER
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
-#endif
- }
- x11_mask = QX11PlatformPixmap::bitmap_to_mask(newmask, xinfo.screen());
-#ifndef QT_NO_XRENDER
- if (picture) {
- mask_picture = XRenderCreatePicture(X11->display, x11_mask,
- XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
- XRenderPictureAttributes attrs;
- attrs.alpha_map = mask_picture;
- XRenderChangePicture(X11->display, picture, CPAlphaMap, &attrs);
- }
-#endif
- }
-}
-
-int QX11PlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 1 << d;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM: {
- const int screen = xinfo.screen();
- const int mm = DisplayWidthMM(X11->display, screen) * w
- / DisplayWidth(X11->display, screen);
- return mm;
- }
- case QPaintDevice::PdmHeightMM: {
- const int screen = xinfo.screen();
- const int mm = (DisplayHeightMM(X11->display, screen) * h)
- / DisplayHeight(X11->display, screen);
- return mm;
- }
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return QX11Info::appDpiX(xinfo.screen());
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return QX11Info::appDpiY(xinfo.screen());
- default:
- qWarning("QX11PlatformPixmap::metric(): Invalid metric");
- return 0;
- }
-}
-
-struct QXImageWrapper
-{
- XImage *xi;
-};
-
-bool QX11PlatformPixmap::canTakeQImageFromXImage(const QXImageWrapper &xiWrapper) const
-{
- XImage *xi = xiWrapper.xi;
-
- // ARGB32_Premultiplied
- if (picture && depth() == 32)
- return true;
-
- Visual *visual = (Visual *)xinfo.visual();
-
- // RGB32
- if (depth() == 24 && xi->bits_per_pixel == 32 && visual->red_mask == 0xff0000
- && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
- return true;
-
- // RGB16
- if (depth() == 16 && xi->bits_per_pixel == 16 && visual->red_mask == 0xf800
- && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
- return true;
-
- return false;
-}
-
-QImage QX11PlatformPixmap::takeQImageFromXImage(const QXImageWrapper &xiWrapper) const
-{
- XImage *xi = xiWrapper.xi;
-
- QImage::Format format = QImage::Format_ARGB32_Premultiplied;
- if (depth() == 24)
- format = QImage::Format_RGB32;
- else if (depth() == 16)
- format = QImage::Format_RGB16;
-
- QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format);
- // take ownership
- image.data_ptr()->own_data = true;
- xi->data = 0;
-
- // we may have to swap the byte order
- if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
- || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
- {
- for (int i=0; i < image.height(); i++) {
- if (depth() == 16) {
- ushort *p = (ushort*)image.scanLine(i);
- ushort *end = p + image.width();
- while (p < end) {
- *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
- p++;
- }
- } else {
- uint *p = (uint*)image.scanLine(i);
- uint *end = p + image.width();
- while (p < end) {
- *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
- | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- }
- }
- }
-
- // fix-up alpha channel
- if (format == QImage::Format_RGB32) {
- QRgb *p = (QRgb *)image.bits();
- for (int y = 0; y < xi->height; ++y) {
- for (int x = 0; x < xi->width; ++x)
- p[x] |= 0xff000000;
- p += xi->bytes_per_line / 4;
- }
- }
-
- XDestroyImage(xi);
- return image;
-}
-
-QImage QX11PlatformPixmap::toImage(const QRect &rect) const
-{
- QXImageWrapper xiWrapper;
- xiWrapper.xi = XGetImage(X11->display, hd, rect.x(), rect.y(), rect.width(), rect.height(),
- AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap);
-
- Q_CHECK_PTR(xiWrapper.xi);
- if (!xiWrapper.xi)
- return QImage();
-
- if (!x11_mask && canTakeQImageFromXImage(xiWrapper))
- return takeQImageFromXImage(xiWrapper);
-
- QImage image = toImage(xiWrapper, rect);
- qSafeXDestroyImage(xiWrapper.xi);
- return image;
-}
-
-/*!
- Converts the pixmap to a QImage. Returns a null image if the
- conversion fails.
-
- If the pixmap has 1-bit depth, the returned image will also be 1
- bit deep. If the pixmap has 2- to 8-bit depth, the returned image
- has 8-bit depth. If the pixmap has greater than 8-bit depth, the
- returned image has 32-bit depth.
-
- Note that for the moment, alpha masks on monochrome images are
- ignored.
-
- \sa fromImage(), {QImage#Image Formats}{Image Formats}
-*/
-
-QImage QX11PlatformPixmap::toImage() const
-{
- return toImage(QRect(0, 0, w, h));
-}
-
-QImage QX11PlatformPixmap::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const
-{
- XImage *xi = xiWrapper.xi;
-
- int d = depth();
- Visual *visual = (Visual *)xinfo.visual();
- bool trucol = (visual->c_class >= TrueColor) && d > 1;
-
- QImage::Format format = QImage::Format_Mono;
- if (d > 1 && d <= 8) {
- d = 8;
- format = QImage::Format_Indexed8;
- }
- // we could run into the situation where d == 8 AND trucol is true, which can
- // cause problems when converting to and from images. in this case, always treat
- // the depth as 32...
- if (d > 8 || trucol) {
- d = 32;
- format = QImage::Format_RGB32;
- }
-
- if (d == 1 && xi->bitmap_bit_order == LSBFirst)
- format = QImage::Format_MonoLSB;
- if (x11_mask && format == QImage::Format_RGB32)
- format = QImage::Format_ARGB32;
-
- QImage image(xi->width, xi->height, format);
- if (image.isNull()) // could not create image
- return image;
-
- QImage alpha;
- if (x11_mask) {
- if (rect.contains(QRect(0, 0, w, h)))
- alpha = mask().toImage();
- else
- alpha = mask().toImage().copy(rect);
- }
- bool ale = alpha.format() == QImage::Format_MonoLSB;
-
- if (trucol) { // truecolor
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit(red_mask) - 7;
- const int green_shift = highest_bit(green_mask) - 7;
- const int blue_shift = highest_bit(blue_mask) - 7;
-
- const uint red_bits = n_bits(red_mask);
- const uint green_bits = n_bits(green_mask);
- const uint blue_bits = n_bits(blue_mask);
-
- static uint red_table_bits = 0;
- static uint green_table_bits = 0;
- static uint blue_table_bits = 0;
-
- if (red_bits < 8 && red_table_bits != red_bits) {
- build_scale_table(&red_scale_table, red_bits);
- red_table_bits = red_bits;
- }
- if (blue_bits < 8 && blue_table_bits != blue_bits) {
- build_scale_table(&blue_scale_table, blue_bits);
- blue_table_bits = blue_bits;
- }
- if (green_bits < 8 && green_table_bits != green_bits) {
- build_scale_table(&green_scale_table, green_bits);
- green_table_bits = green_bits;
- }
-
- int r, g, b;
-
- QRgb *dst;
- uchar *src;
- uint pixel;
- int bppc = xi->bits_per_pixel;
-
- if (bppc > 8 && xi->byte_order == LSBFirst)
- bppc++;
-
- for (int y = 0; y < xi->height; ++y) {
- uchar* asrc = x11_mask ? alpha.scanLine(y) : 0;
- dst = (QRgb *)image.scanLine(y);
- src = (uchar *)xi->data + xi->bytes_per_line*y;
- for (int x = 0; x < xi->width; x++) {
- switch (bppc) {
- case 8:
- pixel = *src++;
- break;
- case 16: // 16 bit MSB
- pixel = src[1] | (uint)src[0] << 8;
- src += 2;
- break;
- case 17: // 16 bit LSB
- pixel = src[0] | (uint)src[1] << 8;
- src += 2;
- break;
- case 24: // 24 bit MSB
- pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;
- src += 3;
- break;
- case 25: // 24 bit LSB
- pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;
- src += 3;
- break;
- case 32: // 32 bit MSB
- pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;
- src += 4;
- break;
- case 33: // 32 bit LSB
- pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;
- src += 4;
- break;
- default: // should not really happen
- x = xi->width; // leave loop
- y = xi->height;
- pixel = 0; // eliminate compiler warning
- qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
- }
- if (red_shift > 0)
- r = (pixel & red_mask) >> red_shift;
- else
- r = (pixel & red_mask) << -red_shift;
- if (green_shift > 0)
- g = (pixel & green_mask) >> green_shift;
- else
- g = (pixel & green_mask) << -green_shift;
- if (blue_shift > 0)
- b = (pixel & blue_mask) >> blue_shift;
- else
- b = (pixel & blue_mask) << -blue_shift;
-
- if (red_bits < 8)
- r = red_scale_table[r];
- if (green_bits < 8)
- g = green_scale_table[g];
- if (blue_bits < 8)
- b = blue_scale_table[b];
-
- if (x11_mask) {
- if (ale) {
- *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
- } else {
- *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
- }
- } else {
- *dst++ = qRgb(r, g, b);
- }
- }
- }
- } else if (xi->bits_per_pixel == d) { // compatible depth
- char *xidata = xi->data; // copy each scanline
- int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);
- for (int y=0; y<xi->height; y++) {
- memcpy(image.scanLine(y), xidata, bpl);
- xidata += xi->bytes_per_line;
- }
- } else {
- /* Typically 2 or 4 bits display depth */
- qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",
- xi->bits_per_pixel);
- return QImage();
- }
-
- if (d == 1) { // bitmap
- image.setColorCount(2);
- image.setColor(0, qRgb(255,255,255));
- image.setColor(1, qRgb(0,0,0));
- } else if (!trucol) { // pixmap with colormap
- register uchar *p;
- uchar *end;
- uchar use[256]; // pixel-in-use table
- uchar pix[256]; // pixel translation table
- int ncols, bpl;
- memset(use, 0, 256);
- memset(pix, 0, 256);
- bpl = image.bytesPerLine();
-
- if (x11_mask) { // which pixels are used?
- for (int i = 0; i < xi->height; i++) {
- uchar* asrc = alpha.scanLine(i);
- p = image.scanLine(i);
- if (ale) {
- for (int x = 0; x < xi->width; x++) {
- if (asrc[x >> 3] & (1 << (x & 7)))
- use[*p] = 1;
- ++p;
- }
- } else {
- for (int x = 0; x < xi->width; x++) {
- if (asrc[x >> 3] & (0x80 >> (x & 7)))
- use[*p] = 1;
- ++p;
- }
- }
- }
- } else {
- for (int i = 0; i < xi->height; i++) {
- p = image.scanLine(i);
- end = p + bpl;
- while (p < end)
- use[*p++] = 1;
- }
- }
- ncols = 0;
- for (int i = 0; i < 256; i++) { // build translation table
- if (use[i])
- pix[i] = ncols++;
- }
- for (int i = 0; i < xi->height; i++) { // translate pixels
- p = image.scanLine(i);
- end = p + bpl;
- while (p < end) {
- *p = pix[*p];
- p++;
- }
- }
- if (x11_mask) {
- int trans;
- if (ncols < 256) {
- trans = ncols++;
- image.setColorCount(ncols); // create color table
- image.setColor(trans, 0x00000000);
- } else {
- image.setColorCount(ncols); // create color table
- // oh dear... no spare "transparent" pixel.
- // use first pixel in image (as good as any).
- trans = image.scanLine(0)[0];
- }
- for (int i = 0; i < xi->height; i++) {
- uchar* asrc = alpha.scanLine(i);
- p = image.scanLine(i);
- if (ale) {
- for (int x = 0; x < xi->width; x++) {
- if (!(asrc[x >> 3] & (1 << (x & 7))))
- *p = trans;
- ++p;
- }
- } else {
- for (int x = 0; x < xi->width; x++) {
- if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
- *p = trans;
- ++p;
- }
- }
- }
- } else {
- image.setColorCount(ncols); // create color table
- }
- QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap();
- int j = 0;
- for (int i=0; i<colors.size(); i++) { // translate pixels
- if (use[i])
- image.setColor(j++, 0xff000000 | colors.at(i).rgb());
- }
- }
-
- return image;
-}
-
-/*!
- Returns a copy of the pixmap that is transformed using the given
- transformation \a matrix and transformation \a mode. The original
- pixmap is not changed.
-
- The transformation \a matrix is internally adjusted to compensate
- for unwanted translation; i.e. the pixmap produced is the smallest
- pixmap that contains all the transformed points of the original
- pixmap. Use the trueMatrix() function to retrieve the actual
- matrix used for transforming the pixmap.
-
- This function is slow because it involves transformation to a
- QImage, non-trivial computations and a transformation back to a
- QPixmap.
-
- \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
- Transformations}
-*/
-QPixmap QX11PlatformPixmap::transformed(const QTransform &transform,
- Qt::TransformationMode mode ) const
-{
- if (mode == Qt::SmoothTransformation || transform.type() >= QTransform::TxProject) {
- QImage image = toImage();
- return QPixmap::fromImage(image.transformed(transform, mode));
- }
-
- uint w = 0;
- uint h = 0; // size of target pixmap
- uint ws, hs; // size of source pixmap
- uchar *dptr; // data in target pixmap
- uint dbpl, dbytes; // bytes per line/bytes total
- uchar *sptr; // data in original pixmap
- int sbpl; // bytes per line in original
- int bpp; // bits per pixel
- bool depth1 = depth() == 1;
- Display *dpy = X11->display;
-
- ws = width();
- hs = height();
-
- QTransform mat(transform.m11(), transform.m12(), transform.m13(),
- transform.m21(), transform.m22(), transform.m23(),
- 0., 0., 1);
- bool complex_xform = false;
- qreal scaledWidth;
- qreal scaledHeight;
-
- if (mat.type() <= QTransform::TxScale) {
- scaledHeight = qAbs(mat.m22()) * hs + 0.9999;
- scaledWidth = qAbs(mat.m11()) * ws + 0.9999;
- h = qAbs(int(scaledHeight));
- w = qAbs(int(scaledWidth));
- } else { // rotation or shearing
- QPolygonF a(QRectF(0, 0, ws, hs));
- a = mat.map(a);
- QRect r = a.boundingRect().toAlignedRect();
- w = r.width();
- h = r.height();
- scaledWidth = w;
- scaledHeight = h;
- complex_xform = true;
- }
- mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix
-
- bool invertible;
- mat = mat.inverted(&invertible); // invert matrix
-
- if (h == 0 || w == 0 || !invertible
- || qAbs(scaledWidth) >= 32768 || qAbs(scaledHeight) >= 32768 )
- // error, return null pixmap
- return QPixmap();
-
-#if defined(QT_MITSHM)
- static bool try_once = true;
- if (try_once) {
- try_once = false;
- if (!xshminit)
- qt_create_mitshm_buffer(this, 800, 600);
- }
-
- bool use_mitshm = xshmimg && !depth1 &&
- xshmimg->width >= w && xshmimg->height >= h;
-#endif
- XImage *xi = XGetImage(X11->display, handle(), 0, 0, ws, hs, AllPlanes,
- depth1 ? XYPixmap : ZPixmap);
-
- if (!xi)
- return QPixmap();
-
- sbpl = xi->bytes_per_line;
- sptr = (uchar *)xi->data;
- bpp = xi->bits_per_pixel;
-
- if (depth1)
- dbpl = (w+7)/8;
- else
- dbpl = ((w*bpp+31)/32)*4;
- dbytes = dbpl*h;
-
-#if defined(QT_MITSHM)
- if (use_mitshm) {
- dptr = (uchar *)xshmimg->data;
- uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
- for (int y=0; y<h; y++)
- memset(dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl);
- } else {
-#endif
- dptr = (uchar *)malloc(dbytes); // create buffer for bits
- Q_CHECK_PTR(dptr);
- if (depth1) // fill with zeros
- memset(dptr, 0, dbytes);
- else if (bpp == 8) // fill with background color
- memset(dptr, WhitePixel(X11->display, xinfo.screen()), dbytes);
- else
- memset(dptr, 0, dbytes);
-#if defined(QT_MITSHM)
- }
-#endif
-
- // #define QT_DEBUG_XIMAGE
-#if defined(QT_DEBUG_XIMAGE)
- qDebug("----IMAGE--INFO--------------");
- qDebug("width............. %d", xi->width);
- qDebug("height............ %d", xi->height);
- qDebug("xoffset........... %d", xi->xoffset);
- qDebug("format............ %d", xi->format);
- qDebug("byte order........ %d", xi->byte_order);
- qDebug("bitmap unit....... %d", xi->bitmap_unit);
- qDebug("bitmap bit order.. %d", xi->bitmap_bit_order);
- qDebug("depth............. %d", xi->depth);
- qDebug("bytes per line.... %d", xi->bytes_per_line);
- qDebug("bits per pixel.... %d", xi->bits_per_pixel);
-#endif
-
- int type;
- if (xi->bitmap_bit_order == MSBFirst)
- type = QT_XFORM_TYPE_MSBFIRST;
- else
- type = QT_XFORM_TYPE_LSBFIRST;
- int xbpl, p_inc;
- if (depth1) {
- xbpl = (w+7)/8;
- p_inc = dbpl - xbpl;
- } else {
- xbpl = (w*bpp)/8;
- p_inc = dbpl - xbpl;
-#if defined(QT_MITSHM)
- if (use_mitshm)
- p_inc = xshmimg->bytes_per_line - xbpl;
-#endif
- }
-
- if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){
- qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp);
- QPixmap pm;
- return pm;
- }
-
- qSafeXDestroyImage(xi);
-
- if (depth1) { // mono bitmap
- QBitmap bm = QBitmap::fromData(QSize(w, h), dptr,
- BitmapBitOrder(X11->display) == MSBFirst
- ? QImage::Format_Mono
- : QImage::Format_MonoLSB);
- free(dptr);
- return bm;
- } else { // color pixmap
- QX11PlatformPixmap *x11Data = new QX11PlatformPixmap(QPlatformPixmap::PixmapType);
- QPixmap pm(x11Data);
- x11Data->flags &= ~QX11PlatformPixmap::Uninitialized;
- x11Data->xinfo = xinfo;
- x11Data->d = d;
- x11Data->w = w;
- x11Data->h = h;
- x11Data->is_null = (w <= 0 || h <= 0);
- x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, xinfo.screen()),
- w, h, d);
- x11Data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = x11Data->d == 32
- ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
- : XRenderFindVisualFormat(X11->display, (Visual *) x11Data->xinfo.visual());
- x11Data->picture = XRenderCreatePicture(X11->display, x11Data->hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-
- GC gc = XCreateGC(X11->display, x11Data->hd, 0, 0);
-#if defined(QT_MITSHM)
- if (use_mitshm) {
- XCopyArea(dpy, xshmpm, x11Data->hd, gc, 0, 0, w, h, 0, 0);
- } else
-#endif
- {
- xi = XCreateImage(dpy, (Visual*)x11Data->xinfo.visual(),
- x11Data->d,
- ZPixmap, 0, (char *)dptr, w, h, 32, 0);
- XPutImage(dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
- qSafeXDestroyImage(xi);
- }
- XFreeGC(X11->display, gc);
-
- if (x11_mask) { // xform mask, too
- pm.setMask(mask_to_bitmap(xinfo.screen()).transformed(transform));
- } else if (d != 32 && complex_xform) { // need a mask!
- QBitmap mask(ws, hs);
- mask.fill(Qt::color1);
- pm.setMask(mask.transformed(transform));
- }
- return pm;
- }
-}
-
-int QPixmap::x11SetDefaultScreen(int screen)
-{
- int old = defaultScreen;
- defaultScreen = screen;
- return old;
-}
-
-void QPixmap::x11SetScreen(int screen)
-{
- if (paintingActive()) {
- qWarning("QPixmap::x11SetScreen(): Cannot change screens during painting");
- return;
- }
-
- if (isNull())
- return;
-
- if (data->classId() != QPlatformPixmap::X11Class)
- return;
-
- if (screen < 0)
- screen = QX11Info::appScreen();
-
- QX11PlatformPixmap *x11Data = static_cast<QX11PlatformPixmap*>(data.data());
- if (screen == x11Data->xinfo.screen())
- return; // nothing to do
-
- if (isNull()) {
- QX11InfoData* xd = x11Data->xinfo.getX11Data(true);
- xd->screen = screen;
- xd->depth = QX11Info::appDepth(screen);
- xd->cells = QX11Info::appCells(screen);
- xd->colormap = QX11Info::appColormap(screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(screen);
- xd->visual = (Visual *)QX11Info::appVisual(screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(screen);
- x11Data->xinfo.setX11Data(xd);
- return;
- }
-#if 0
- qDebug("QPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", x11Data, x11Data->xinfo.screen(), screen, width(), height());
-#endif
-
- x11SetDefaultScreen(screen);
- *this = qt_toX11Pixmap(toImage());
-}
-
-QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
-{
- if (w == 0 || h == 0)
- return QPixmap();
-
- Display *dpy = X11->display;
- XWindowAttributes window_attr;
- if (!XGetWindowAttributes(dpy, window, &window_attr))
- return QPixmap();
-
- if (w < 0)
- w = window_attr.width - x;
- if (h < 0)
- h = window_attr.height - y;
-
- // determine the screen
- int scr;
- for (scr = 0; scr < ScreenCount(dpy); ++scr) {
- if (window_attr.root == RootWindow(dpy, scr)) // found it
- break;
- }
- if (scr >= ScreenCount(dpy)) // sanity check
- return QPixmap();
-
-
- // get the depth of the root window
- XWindowAttributes root_attr;
- if (!XGetWindowAttributes(dpy, window_attr.root, &root_attr))
- return QPixmap();
-
- if (window_attr.depth == root_attr.depth) {
- // if the depth of the specified window and the root window are the
- // same, grab pixels from the root window (so that we get the any
- // overlapping windows and window manager frames)
-
- // map x and y to the root window
- WId unused;
- if (!XTranslateCoordinates(dpy, window, window_attr.root, x, y,
- &x, &y, &unused))
- return QPixmap();
-
- window = window_attr.root;
- window_attr = root_attr;
- }
-
- QX11PlatformPixmap *data = new QX11PlatformPixmap(QPlatformPixmap::PixmapType);
-
- void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a);
- qt_x11_getX11InfoForWindow(&data->xinfo,window_attr);
-
- data->resize(w, h);
-
- QPixmap pm(data);
-
- data->flags &= ~QX11PlatformPixmap::Uninitialized;
- pm.x11SetScreen(scr);
-
- GC gc = XCreateGC(dpy, pm.handle(), 0, 0);
- XSetSubwindowMode(dpy, gc, IncludeInferiors);
- XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0);
- XFreeGC(dpy, gc);
-
- return pm;
-}
-
-bool QX11PlatformPixmap::hasAlphaChannel() const
-{
- return d == 32;
-}
-
-const QX11Info &QPixmap::x11Info() const
-{
- if (data && data->classId() == QPlatformPixmap::X11Class)
- return static_cast<QX11PlatformPixmap*>(data.data())->xinfo;
- else {
- static QX11Info nullX11Info;
- return nullX11Info;
- }
-}
-
-#if !defined(QT_NO_XRENDER)
-static XRenderPictFormat *qt_renderformat_for_depth(const QX11Info &xinfo, int depth)
-{
- if (depth == 1)
- return XRenderFindStandardFormat(X11->display, PictStandardA1);
- else if (depth == 32)
- return XRenderFindStandardFormat(X11->display, PictStandardARGB32);
- else
- return XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
-}
-#endif
-
-QPaintEngine* QX11PlatformPixmap::paintEngine() const
-{
- QX11PlatformPixmap *that = const_cast<QX11PlatformPixmap*>(this);
-
- if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) {
- // if someone wants to draw onto us, copy the shared contents
- // and turn it into a fully fledged QPixmap
- ::Pixmap hd_copy = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
- w, h, d);
-#if !defined(QT_NO_XRENDER)
- XRenderPictFormat *format = qt_renderformat_for_depth(xinfo, d);
- ::Picture picture_copy = XRenderCreatePicture(X11->display, hd_copy, format, 0, 0);
-
- if (picture && d == 32) {
- XRenderComposite(X11->display, PictOpSrc, picture, 0, picture_copy,
- 0, 0, 0, 0, 0, 0, w, h);
- XRenderFreePicture(X11->display, picture);
- that->picture = picture_copy;
- } else
-#endif
- {
- GC gc = XCreateGC(X11->display, hd_copy, 0, 0);
- XCopyArea(X11->display, hd, hd_copy, gc, 0, 0, w, h, 0, 0);
- XFreeGC(X11->display, gc);
- }
- that->hd = hd_copy;
- that->flags &= ~QX11PlatformPixmap::Readonly;
- }
-
- if (!that->pengine)
- that->pengine = new QX11PaintEngine;
- return that->pengine;
-}
-
-Qt::HANDLE QPixmap::x11PictureHandle() const
-{
-#ifndef QT_NO_XRENDER
- if (data && data->classId() == QPlatformPixmap::X11Class)
- return static_cast<const QX11PlatformPixmap*>(data.data())->picture;
- else
- return 0;
-#else
- return 0;
-#endif // QT_NO_XRENDER
-}
-
-Qt::HANDLE QX11PlatformPixmap::x11ConvertToDefaultDepth()
-{
-#ifndef QT_NO_XRENDER
- if (d == QX11Info::appDepth() || !X11->use_xrender)
- return hd;
- if (!hd2) {
- hd2 = XCreatePixmap(xinfo.display(), hd, w, h, QX11Info::appDepth());
- XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(),
- (Visual*) xinfo.visual());
- Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0);
- XRenderComposite(xinfo.display(), PictOpSrc, picture,
- XNone, pic, 0, 0, 0, 0, 0, 0, w, h);
- XRenderFreePicture(xinfo.display(), pic);
- }
- return hd2;
-#else
- return hd;
-#endif
-}
-
-void QX11PlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect)
-{
- if (data->pixelType() == BitmapType) {
- fromImage(data->toImage().copy(rect), Qt::AutoColor);
- return;
- }
-
- const QX11PlatformPixmap *x11Data = static_cast<const QX11PlatformPixmap*>(data);
-
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- flags &= ~Uninitialized;
- xinfo = x11Data->xinfo;
- d = x11Data->d;
- w = rect.width();
- h = rect.height();
- is_null = (w <= 0 || h <= 0);
- hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, x11Data->xinfo.screen()),
- w, h, d);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 32
- ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
- : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
- if (x11Data->x11_mask) {
- x11_mask = XCreatePixmap(X11->display, hd, w, h, 1);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- mask_picture = XRenderCreatePicture(X11->display, x11_mask,
- XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
- XRenderPictureAttributes attrs;
- attrs.alpha_map = x11Data->mask_picture;
- XRenderChangePicture(X11->display, x11Data->picture, CPAlphaMap, &attrs);
- }
-#endif
- }
-
-#if !defined(QT_NO_XRENDER)
- if (x11Data->picture && x11Data->d == 32) {
- XRenderComposite(X11->display, PictOpSrc,
- x11Data->picture, 0, picture,
- rect.x(), rect.y(), 0, 0, 0, 0, w, h);
- } else
-#endif
- {
- GC gc = XCreateGC(X11->display, hd, 0, 0);
- XCopyArea(X11->display, x11Data->hd, hd, gc,
- rect.x(), rect.y(), w, h, 0, 0);
- if (x11Data->x11_mask) {
- GC monogc = XCreateGC(X11->display, x11_mask, 0, 0);
- XCopyArea(X11->display, x11Data->x11_mask, x11_mask, monogc,
- rect.x(), rect.y(), w, h, 0, 0);
- XFreeGC(X11->display, monogc);
- }
- XFreeGC(X11->display, gc);
- }
-}
-
-bool QX11PlatformPixmap::scroll(int dx, int dy, const QRect &rect)
-{
- GC gc = XCreateGC(X11->display, hd, 0, 0);
- XCopyArea(X11->display, hd, hd, gc,
- rect.left(), rect.top(), rect.width(), rect.height(),
- rect.left() + dx, rect.top() + dy);
- XFreeGC(X11->display, gc);
- return true;
-}
-
-#if !defined(QT_NO_XRENDER)
-void QX11PlatformPixmap::convertToARGB32(bool preserveContents)
-{
- if (!X11->use_xrender)
- return;
-
- // Q_ASSERT(count == 1);
- if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared)
- return;
-
- Pixmap pm = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
- w, h, 32);
- Picture p = XRenderCreatePicture(X11->display, pm,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
- if (picture) {
- if (preserveContents)
- XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
- if (!(flags & Readonly))
- XRenderFreePicture(X11->display, picture);
- }
- if (hd && !(flags & Readonly))
- XFreePixmap(X11->display, hd);
- if (x11_mask) {
- XFreePixmap(X11->display, x11_mask);
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
- x11_mask = 0;
- mask_picture = 0;
- }
- hd = pm;
- picture = p;
- d = 32;
-}
-#endif
-
-QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
-{
- Window root;
- int x;
- int y;
- uint width;
- uint height;
- uint border_width;
- uint depth;
- XWindowAttributes win_attribs;
- int num_screens = ScreenCount(X11->display);
- int screen = 0;
-
- XGetGeometry(X11->display, pixmap, &root, &x, &y, &width, &height, &border_width, &depth);
- XGetWindowAttributes(X11->display, root, &win_attribs);
-
- for (; screen < num_screens; ++screen) {
- if (win_attribs.screen == ScreenOfDisplay(X11->display, screen))
- break;
- }
-
- QX11PlatformPixmap *data = new QX11PlatformPixmap(depth == 1 ? QPlatformPixmap::BitmapType : QPlatformPixmap::PixmapType);
- data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
- data->flags = QX11PlatformPixmap::Readonly;
- data->share_mode = mode;
- data->w = width;
- data->h = height;
- data->is_null = (width <= 0 || height <= 0);
- data->d = depth;
- data->hd = pixmap;
-
- if (defaultScreen >= 0 && defaultScreen != screen) {
- QX11InfoData* xd = data->xinfo.getX11Data(true);
- xd->screen = defaultScreen;
- xd->depth = QX11Info::appDepth(xd->screen);
- xd->cells = QX11Info::appCells(xd->screen);
- xd->colormap = QX11Info::appColormap(xd->screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
- xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
- data->xinfo.setX11Data(xd);
- }
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = qt_renderformat_for_depth(data->xinfo, depth);
- data->picture = XRenderCreatePicture(X11->display, data->hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-
- return QPixmap(data);
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qpixmap_x11_p.h b/src/widgets/platforms/x11/qpixmap_x11_p.h
deleted file mode 100644
index fce32cbe3e..0000000000
--- a/src/widgets/platforms/x11/qpixmap_x11_p.h
+++ /dev/null
@@ -1,156 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_X11_P_H
-#define QPIXMAPDATA_X11_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 <QtGui/qplatformpixmap_qpa.h>
-#include <QtGui/qplatformpixmapfactory_p.h>
-
-#include "QtGui/qx11info_x11.h"
-
-QT_BEGIN_NAMESPACE
-
-class QX11PaintEngine;
-
-struct QXImageWrapper;
-
-class Q_WIDGETS_EXPORT QX11PlatformPixmap : public QPlatformPixmap
-{
-public:
- QX11PlatformPixmap(PixelType type);
-// QX11PlatformPixmap(PixelType type, int width, int height);
-// QX11PlatformPixmap(PixelType type, const QImage &image,
-// Qt::ImageConversionFlags flags);
- ~QX11PlatformPixmap();
-
- QPlatformPixmap *createCompatiblePlatformPixmap() const;
-
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void copy(const QPlatformPixmap *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
-
- void fill(const QColor &color);
- QBitmap mask() const;
- void setMask(const QBitmap &mask);
- bool hasAlphaChannel() const;
- void setAlphaChannel(const QPixmap &alphaChannel);
- QPixmap alphaChannel() const;
- QPixmap transformed(const QTransform &transform,
- Qt::TransformationMode mode) const;
- QImage toImage() const;
- QImage toImage(const QRect &rect) const;
- QPaintEngine* paintEngine() const;
-
- Qt::HANDLE handle() const { return hd; }
- Qt::HANDLE x11ConvertToDefaultDepth();
-
- static Qt::HANDLE createBitmapFromImage(const QImage &image);
-
- void* gl_surface;
-#ifndef QT_NO_XRENDER
- void convertToARGB32(bool preserveContents = true);
-#endif
-
-protected:
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
-
-private:
- friend class QPixmap;
- friend class QBitmap;
- friend class QX11PaintEngine;
- friend class QX11WindowSurface;
- friend class QRasterWindowSurface;
- friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags
- friend class QEglContext; // Needs gl_surface
- friend class QGLContext; // Needs gl_surface
- friend class QX11GLPlatformPixmap; // Needs gl_surface
- friend class QMeeGoLivePlatformPixmap; // Needs gl_surface and flags
- friend bool qt_createEGLSurfaceForPixmap(QPlatformPixmap*, bool); // Needs gl_surface
-
- void release();
-
- QImage toImage(const QXImageWrapper &xi, const QRect &rect) const;
-
- QBitmap mask_to_bitmap(int screen) const;
- static Qt::HANDLE bitmap_to_mask(const QBitmap &, int screen);
- void bitmapFromImage(const QImage &image);
-
- bool canTakeQImageFromXImage(const QXImageWrapper &xi) const;
- QImage takeQImageFromXImage(const QXImageWrapper &xi) const;
-
- Qt::HANDLE hd;
-
- enum Flag {
- NoFlags = 0x0,
- Uninitialized = 0x1,
- Readonly = 0x2,
- InvertedWhenBoundToTexture = 0x4,
- GlSurfaceCreatedWithAlpha = 0x8
- };
- uint flags;
-
- QX11Info xinfo;
- Qt::HANDLE x11_mask;
- Qt::HANDLE picture;
- Qt::HANDLE mask_picture;
- Qt::HANDLE hd2; // sorted in the default display depth
- QPixmap::ShareMode share_mode;
-
- QX11PaintEngine *pengine;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_X11_P_H
-
diff --git a/src/widgets/platforms/x11/qregion_x11.cpp b/src/widgets/platforms/x11/qregion_x11.cpp
deleted file mode 100644
index a96ec6dc96..0000000000
--- a/src/widgets/platforms/x11/qregion_x11.cpp
+++ /dev/null
@@ -1,92 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qt_x11_p.h>
-
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-QRegion::QRegionData QRegion::shared_empty = {Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0};
-
-void QRegion::updateX11Region() const
-{
- d->rgn = XCreateRegion();
- if (!d->qt_rgn)
- return;
-
- int n = d->qt_rgn->numRects;
- const QRect *rect = (n == 1 ? &d->qt_rgn->extents : d->qt_rgn->rects.constData());
- while (n--) {
- XRectangle r;
- r.x = qMax(SHRT_MIN, rect->x());
- r.y = qMax(SHRT_MIN, rect->y());
- r.width = qMin((int)USHRT_MAX, rect->width());
- r.height = qMin((int)USHRT_MAX, rect->height());
- XUnionRectWithRegion(&r, d->rgn, d->rgn);
- ++rect;
- }
-}
-
-void *QRegion::clipRectangles(int &num) const
-{
- if (!d->xrectangles && !(d == &shared_empty || d->qt_rgn->numRects == 0)) {
- XRectangle *r = static_cast<XRectangle*>(malloc(d->qt_rgn->numRects * sizeof(XRectangle)));
- d->xrectangles = r;
- int n = d->qt_rgn->numRects;
- const QRect *rect = (n == 1 ? &d->qt_rgn->extents : d->qt_rgn->rects.constData());
- while (n--) {
- r->x = qMax(SHRT_MIN, rect->x());
- r->y = qMax(SHRT_MIN, rect->y());
- r->width = qMin((int)USHRT_MAX, rect->width());
- r->height = qMin((int)USHRT_MAX, rect->height());
- ++r;
- ++rect;
- }
- }
- if (d == &shared_empty || d->qt_rgn->numRects == 0)
- num = 0;
- else
- num = d->qt_rgn->numRects;
- return d->xrectangles;
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qsound_x11.cpp b/src/widgets/platforms/x11/qsound_x11.cpp
deleted file mode 100644
index c83c26a027..0000000000
--- a/src/widgets/platforms/x11/qsound_x11.cpp
+++ /dev/null
@@ -1,296 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsound.h"
-
-#ifndef QT_NO_SOUND
-
-#include "qhash.h"
-#include "qsocketnotifier.h"
-#include "qapplication.h"
-#include "qsound_p.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_NAS
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <audio/audiolib.h>
-#include <audio/soundlib.h>
-QT_END_INCLUDE_NAMESPACE
-
-static AuServer *nas=0;
-
-static AuBool eventPred(AuServer *, AuEvent *e, AuPointer p)
-{
- if (e && (e->type == AuEventTypeElementNotify)) {
- if (e->auelementnotify.flow == *((AuFlowID *)p))
- return true;
- }
- return false;
-}
-
-class QAuBucketNAS : public QAuBucket {
-public:
- QAuBucketNAS(AuBucketID b, AuFlowID f = 0) : id(b), flow(f), stopped(true), numplaying(0) { }
- ~QAuBucketNAS()
- {
- if (nas) {
- AuSync(nas, false);
- AuDestroyBucket(nas, id, NULL);
-
- AuEvent ev;
- while (AuScanEvents(nas, AuEventsQueuedAfterFlush, true, eventPred, &flow, &ev))
- ;
- }
- }
-
- AuBucketID id;
- AuFlowID flow;
- bool stopped;
- int numplaying;
-};
-
-class QAuServerNAS : public QAuServer {
- Q_OBJECT
-
- QSocketNotifier* sn;
-
-public:
- QAuServerNAS(QObject* parent);
- ~QAuServerNAS();
-
- void init(QSound*);
- void play(const QString& filename);
- void play(QSound*);
- void stop(QSound*);
- bool okay();
- void setDone(QSound*);
-
-public slots:
- void dataReceived();
- void soundDestroyed(QObject *o);
-
-private:
- QAuBucketNAS* bucket(QSound* s)
- {
- return (QAuBucketNAS*)QAuServer::bucket(s);
- }
-};
-
-QAuServerNAS::QAuServerNAS(QObject* parent) :
- QAuServer(parent)
-{
- setObjectName(QLatin1String("Network Audio System"));
- nas = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL);
- if (nas) {
- AuSetCloseDownMode(nas, AuCloseDownDestroy, NULL);
- // Ask Qt for async messages...
- sn=new QSocketNotifier(AuServerConnectionNumber(nas),
- QSocketNotifier::Read);
- QObject::connect(sn, SIGNAL(activated(int)),
- this, SLOT(dataReceived()));
- } else {
- sn = 0;
- }
-}
-
-QAuServerNAS::~QAuServerNAS()
-{
- if (nas)
- AuCloseServer(nas);
- delete sn;
- nas = 0;
-}
-
-typedef QHash<void*,QAuServerNAS*> AuServerHash;
-static AuServerHash *inprogress=0;
-
-void QAuServerNAS::soundDestroyed(QObject *o)
-{
- if (inprogress) {
- QSound *so = static_cast<QSound *>(o);
- while (inprogress->remove(so))
- ; // Loop while remove returns true
- }
-}
-
-void QAuServerNAS::play(const QString& filename)
-{
- if (nas) {
- int iv=100;
- AuFixedPoint volume=AuFixedPointFromFraction(iv,100);
- AuSoundPlayFromFile(nas, filename.toLocal8Bit().constData(), AuNone, volume,
- NULL, NULL, NULL, NULL, NULL, NULL);
- AuFlush(nas);
- dataReceived();
- AuFlush(nas);
- qApp->flush();
- }
-}
-
-static void callback(AuServer*, AuEventHandlerRec*, AuEvent* e, AuPointer p)
-{
- if (inprogress->contains(p) && e) {
- if (e->type==AuEventTypeElementNotify &&
- e->auelementnotify.kind==AuElementNotifyKindState) {
- if (e->auelementnotify.cur_state == AuStateStop) {
- AuServerHash::Iterator it = inprogress->find(p);
- if (it != inprogress->end())
- (*it)->setDone((QSound*)p);
- }
- }
- }
-}
-
-void QAuServerNAS::setDone(QSound* s)
-{
- if (nas) {
- decLoop(s);
- if (s->loopsRemaining() && !bucket(s)->stopped) {
- bucket(s)->stopped = true;
- play(s);
- } else {
- if (--(bucket(s)->numplaying) == 0)
- bucket(s)->stopped = true;
- inprogress->remove(s);
- }
- }
-}
-
-void QAuServerNAS::play(QSound* s)
-{
- if (nas) {
- ++(bucket(s)->numplaying);
- if (!bucket(s)->stopped) {
- stop(s);
- }
-
- bucket(s)->stopped = false;
- if (!inprogress)
- inprogress = new AuServerHash;
- inprogress->insert(s,this);
- int iv=100;
- AuFixedPoint volume=AuFixedPointFromFraction(iv,100);
- QAuBucketNAS *b = bucket(s);
- AuSoundPlayFromBucket(nas, b->id, AuNone, volume,
- callback, s, 0, &b->flow, NULL, NULL, NULL);
- AuFlush(nas);
- dataReceived();
- AuFlush(nas);
- qApp->flush();
- }
-}
-
-void QAuServerNAS::stop(QSound* s)
-{
- if (nas && !bucket(s)->stopped) {
- bucket(s)->stopped = true;
- AuStopFlow(nas, bucket(s)->flow, NULL);
- AuFlush(nas);
- dataReceived();
- AuFlush(nas);
- qApp->flush();
- }
-}
-
-void QAuServerNAS::init(QSound* s)
-{
- connect(s, SIGNAL(destroyed(QObject*)),
- this, SLOT(soundDestroyed(QObject*)));
-
- if (nas) {
- AuBucketID b_id =
- AuSoundCreateBucketFromFile(nas, s->fileName().toLocal8Bit().constData(),
- 0 /*AuAccessAllMasks*/, NULL, NULL);
- setBucket(s, new QAuBucketNAS(b_id));
- }
-}
-
-bool QAuServerNAS::okay()
-{
- return !!nas;
-}
-
-void QAuServerNAS::dataReceived()
-{
- AuHandleEvents(nas);
-}
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qsound_x11.moc"
-QT_END_INCLUDE_NAMESPACE
-
-#endif
-
-
-class QAuServerNull : public QAuServer
-{
-public:
- QAuServerNull(QObject* parent);
-
- void play(const QString&) { }
- void play(QSound*s) { while(decLoop(s) > 0) /* nothing */ ; }
- void stop(QSound*) { }
- bool okay() { return false; }
-};
-
-QAuServerNull::QAuServerNull(QObject* parent)
- : QAuServer(parent)
-{
-}
-
-
-QAuServer* qt_new_audio_server()
-{
-#ifndef QT_NO_NAS
- QAuServer* s = new QAuServerNAS(qApp);
- if (s->okay())
- return s;
- else
- delete s;
-#endif
- return new QAuServerNull(qApp);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SOUND
diff --git a/src/widgets/platforms/x11/qt_x11_p.h b/src/widgets/platforms/x11/qt_x11_p.h
deleted file mode 100644
index ea808fb8a2..0000000000
--- a/src/widgets/platforms/x11/qt_x11_p.h
+++ /dev/null
@@ -1,757 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_X11_P_H
-#define QT_X11_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 "QtGui/qwindowdefs.h"
-#include "QtCore/qlist.h"
-#include "QtCore/qvariant.h"
-
-// the following is necessary to work around breakage in many versions
-// of XFree86's Xlib.h still in use
-// ### which versions?
-#if defined(_XLIB_H_) // crude hack, but...
-#error "cannot include <X11/Xlib.h> before this file"
-#endif
-#define XRegisterIMInstantiateCallback qt_XRegisterIMInstantiateCallback
-#define XUnregisterIMInstantiateCallback qt_XUnregisterIMInstantiateCallback
-#define XSetIMValues qt_XSetIMValues
-#include <X11/Xlib.h>
-#undef XRegisterIMInstantiateCallback
-#undef XUnregisterIMInstantiateCallback
-#undef XSetIMValues
-
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#ifdef index
-# undef index
-#endif
-#ifdef rindex
-# undef rindex
-#endif
-#ifdef Q_OS_VXWORS
-# ifdef open
-# undef open
-# endif
-# ifdef getpid
-# undef getpid
-# endif
-#endif // Q_OS_VXWORKS
-#include <X11/Xatom.h>
-
-//#define QT_NO_SHAPE
-#ifdef QT_NO_SHAPE
-# define XShapeCombineRegion(a,b,c,d,e,f,g)
-# define XShapeCombineMask(a,b,c,d,e,f,g)
-#else
-# include <X11/extensions/shape.h>
-#endif // QT_NO_SHAPE
-
-
-#if !defined (QT_NO_TABLET)
-# include <X11/extensions/XInput.h>
-#if defined (Q_OS_IRIX)
-# include <X11/extensions/SGIMisc.h>
-# include <wacom.h>
-#endif
-#endif // QT_NO_TABLET
-
-
-// #define QT_NO_XINERAMA
-#ifndef QT_NO_XINERAMA
-# if 0 // ### Xsun, but how to detect it?
-// Xinerama is only supported in Solaris 7 with patches 107648/108376 and
-// Solaris 8 or above which introduce the X11R6.4 Xserver.
-// To switch the Xinerama functionality on, you need to add the "+xinerama"
-// argument to the Xsun start line.
-// At least Solaris 7 and 8 are missing Xinerama system headers and function
-// declarations (bug 4284701).
-// The Xinerama API is not documented. In theory it could change but it
-// probably won't because Sun are using it in at least dtlogin (bug 4221829).
-extern "C" Bool XPanoramiXQueryExtension(
- Display*,
- int*,
- int*
-);
-extern "C" Status XPanoramiXQueryVersion(
- Display*,
- int*,
- int*
-);
-extern "C" Status XPanoramiXGetState(
- Display*,
- Drawable,
- XPanoramiXInfo*
-);
-extern "C" Status XPanoramiXGetScreenCount(
- Display *,
- Drawable,
- XPanoramiXInfo*
-);
-extern "C" Status XPanoramiXGetScreenSize(
- Display*,
- Drawable,
- int,
- XPanoramiXInfo*
-);
-# else // XFree86
-// XFree86 does not C++ify Xinerama (at least up to XFree86 4.0.3).
-extern "C" {
-# include <X11/extensions/Xinerama.h>
-}
-# endif
-#endif // QT_NO_XINERAMA
-
-// #define QT_NO_XRANDR
-#ifndef QT_NO_XRANDR
-# include <X11/extensions/Xrandr.h>
-#endif // QT_NO_XRANDR
-
-// #define QT_NO_XRENDER
-#ifndef QT_NO_XRENDER
-# include <X11/extensions/Xrender.h>
-#endif // QT_NO_XRENDER
-
-#ifndef QT_NO_XSYNC
-extern "C" {
-# include "X11/extensions/sync.h"
-}
-#endif
-
-// #define QT_NO_XKB
-#ifndef QT_NO_XKB
-# include <X11/XKBlib.h>
-#endif // QT_NO_XKB
-
-
-#if !defined(XlibSpecificationRelease)
-# define X11R4
-typedef char *XPointer;
-#else
-# undef X11R4
-#endif
-
-// #define QT_NO_XIM
-#if defined(X11R4)
-// X11R4 does not have XIM
-#define QT_NO_XIM
-#elif defined(Q_OS_OSF) && (XlibSpecificationRelease < 6)
-// broken in Xlib up to OSF/1 3.2
-#define QT_NO_XIM
-#elif defined(Q_OS_AIX)
-// broken in Xlib up to what version of AIX?
-#define QT_NO_XIM
-#elif defined(QT_NO_DEBUG) && defined(Q_OS_IRIX)
-// XmbLookupString broken on IRIX
-// XCreateIC broken when compiling -64 on IRIX 6.5.2
-#define QT_NO_XIM
-#elif defined(Q_OS_HPUX) && defined(__LP64__)
-// XCreateIC broken when compiling 64-bit ELF on HP-UX 11.0
-#define QT_NO_XIM
-#elif defined(Q_OS_SCO)
-// ### suggested by user...
-// ### #define QT_NO_XIM
-#endif // QT_NO_XIM
-
-#ifndef QT_NO_XFIXES
-typedef Bool (*PtrXFixesQueryExtension)(Display *, int *, int *);
-typedef Status (*PtrXFixesQueryVersion)(Display *, int *, int *);
-typedef void (*PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name);
-typedef void (*PtrXFixesSelectSelectionInput)(Display *dpy, Window win, Atom selection, unsigned long eventMask);
-#endif // QT_NO_XFIXES
-
-#ifndef QT_NO_XCURSOR
-#include <X11/Xcursor/Xcursor.h>
-typedef Cursor (*PtrXcursorLibraryLoadCursor)(Display *, const char *);
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XINERAMA
-typedef Bool (*PtrXineramaQueryExtension)(Display *dpy, int *event_base, int *error_base);
-typedef Bool (*PtrXineramaIsActive)(Display *dpy);
-typedef XineramaScreenInfo *(*PtrXineramaQueryScreens)(Display *dpy, int *number);
-#endif // QT_NO_XINERAMA
-
-#ifndef QT_NO_XRANDR
-typedef void (*PtrXRRSelectInput)(Display *, Window, int);
-typedef int (*PtrXRRUpdateConfiguration)(XEvent *);
-typedef int (*PtrXRRRootToScreen)(Display *, Window);
-typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *);
-typedef XRRScreenSize *(*PtrXRRSizes)(Display *, int, int *);
-#endif // QT_NO_XRANDR
-
-#ifndef QT_NO_XINPUT
-typedef int (*PtrXCloseDevice)(Display *, XDevice *);
-typedef XDeviceInfo* (*PtrXListInputDevices)(Display *, int *);
-typedef XDevice* (*PtrXOpenDevice)(Display *, XID);
-typedef void (*PtrXFreeDeviceList)(XDeviceInfo *);
-typedef int (*PtrXSelectExtensionEvent)(Display *, Window, XEventClass *, int);
-#endif // QT_NO_XINPUT
-
-/*
- * Solaris patch 108652-47 and higher fixes crases in
- * XRegisterIMInstantiateCallback, but the function doesn't seem to
- * work.
- *
- * Instead, we disabled R6 input, and open the input method
- * immediately at application start.
- */
-#if !defined(QT_NO_XIM) && (XlibSpecificationRelease >= 6) && \
- !defined(Q_OS_SOLARIS)
-#define USE_X11R6_XIM
-
-//######### XFree86 has wrong declarations for XRegisterIMInstantiateCallback
-//######### and XUnregisterIMInstantiateCallback in at least version 3.3.2.
-//######### Many old X11R6 header files lack XSetIMValues.
-//######### Therefore, we have to declare these functions ourselves.
-
-extern "C" Bool XRegisterIMInstantiateCallback(
- Display*,
- struct _XrmHashBucketRec*,
- char*,
- char*,
- XIMProc, //XFree86 has XIDProc, which has to be wrong
- XPointer
-);
-
-extern "C" Bool XUnregisterIMInstantiateCallback(
- Display*,
- struct _XrmHashBucketRec*,
- char*,
- char*,
- XIMProc, //XFree86 has XIDProc, which has to be wrong
- XPointer
-);
-
-extern "C" char *XSetIMValues(XIM /* im */, ...);
-
-#endif
-
-#ifndef QT_NO_FONTCONFIG
-#include <fontconfig/fontconfig.h>
-#endif
-
-#ifndef QT_NO_XIM
-// some platforms (eg. Solaris 2.51) don't have these defines in Xlib.h
-#ifndef XNResetState
-#define XNResetState "resetState"
-#endif
-#ifndef XIMPreserveState
-#define XIMPreserveState (1L<<1)
-#endif
-#endif
-
-
-#ifndef X11R4
-# include <X11/Xlocale.h>
-#endif // X11R4
-
-
-#ifndef QT_NO_MITSHM
-# include <X11/extensions/XShm.h>
-#endif // QT_NO_MITSHM
-
-QT_BEGIN_NAMESPACE
-
-class QWidget;
-
-struct QX11InfoData {
- uint ref;
- int screen;
- int dpiX;
- int dpiY;
- int depth;
- int cells;
- Colormap colormap;
- Visual *visual;
- bool defaultColormap;
- bool defaultVisual;
- int subpixel;
-};
-
-class QDrag;
-struct QXdndDropTransaction
-{
- Time timestamp;
- Window target;
- Window proxy_target;
- QWidget *targetWidget;
- QWidget *embedding_widget;
- QDrag *object;
-};
-
-class QMimeData;
-
-struct QX11Data;
-extern Q_WIDGETS_EXPORT QX11Data *qt_x11Data;
-
-enum DesktopEnvironment {
- DE_UNKNOWN,
- DE_KDE,
- DE_GNOME,
- DE_CDE,
- DE_MEEGO_COMPOSITOR,
- DE_4DWM
-};
-
-struct QX11Data
-{
- static Qt::KeyboardModifiers translateModifiers(int s);
-
- Window findClientWindow(Window, Atom, bool);
-
- // from qclipboard_x11.cpp
- bool clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout);
- bool clipboardReadProperty(Window win, Atom property, bool deleteProperty,
- QByteArray *buffer, int *size, Atom *type, int *format);
- QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm);
-
- // from qdnd_x11.cpp
- bool dndEnable(QWidget* w, bool on);
- static void xdndSetup();
- void xdndHandleEnter(QWidget *, const XEvent *, bool);
- void xdndHandlePosition(QWidget *, const XEvent *, bool);
- void xdndHandleStatus(QWidget *, const XEvent *, bool);
- void xdndHandleLeave(QWidget *, const XEvent *, bool);
- void xdndHandleDrop(QWidget *, const XEvent *, bool);
- void xdndHandleFinished(QWidget *, const XEvent *, bool);
- void xdndHandleSelectionRequest(const XSelectionRequestEvent *);
- static bool xdndHandleBadwindow();
- QByteArray xdndAtomToString(Atom a);
- Atom xdndStringToAtom(const char *);
-
- QString xdndMimeAtomToString(Atom a);
- Atom xdndMimeStringToAtom(const QString &mimeType);
- QStringList xdndMimeFormatsForAtom(Atom a);
- bool xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat);
- QList<Atom> xdndMimeAtomsForFormat(const QString &format);
- QVariant xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding);
- Atom xdndMimeAtomForFormat(const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding);
-
- QList<QXdndDropTransaction> dndDropTransactions;
-
- // from qmotifdnd_x11.cpp
- void motifdndHandle(QWidget *, const XEvent *, bool);
- void motifdndEnable(QWidget *, bool);
- QVariant motifdndObtainData(const char *format);
- QByteArray motifdndFormat(int n);
- bool motifdnd_active;
-
- Display *display;
- char *displayName;
- bool foreignDisplay;
- // current focus model
- enum {
- FM_Unknown = -1,
- FM_Other = 0,
- FM_PointerRoot = 1
- };
- int focus_model;
-
- // true if Qt is compiled w/ RANDR support and RANDR is supported on the connected Display
- bool use_xrandr;
- int xrandr_major;
- int xrandr_eventbase;
- int xrandr_errorbase;
-
- // true if Qt is compiled w/ RENDER support and RENDER is supported on the connected Display
- bool use_xrender;
- int xrender_major;
- int xrender_version;
-
- // true if Qt is compiled w/ XFIXES support and XFIXES is supported on the connected Display
- bool use_xfixes;
- int xfixes_major;
- int xfixes_eventbase;
- int xfixes_errorbase;
-
-#ifndef QT_NO_XFIXES
- PtrXFixesQueryExtension ptrXFixesQueryExtension;
- PtrXFixesQueryVersion ptrXFixesQueryVersion;
- PtrXFixesSetCursorName ptrXFixesSetCursorName;
- PtrXFixesSelectSelectionInput ptrXFixesSelectSelectionInput;
-#endif
-
-#ifndef QT_NO_XINPUT
- PtrXCloseDevice ptrXCloseDevice;
- PtrXListInputDevices ptrXListInputDevices;
- PtrXOpenDevice ptrXOpenDevice;
- PtrXFreeDeviceList ptrXFreeDeviceList;
- PtrXSelectExtensionEvent ptrXSelectExtensionEvent;
-#endif // QT_NO_XINPUT
-
-
- // true if Qt is compiled w/ MIT-SHM support and MIT-SHM is supported on the connected Display
- bool use_mitshm;
- bool use_mitshm_pixmaps;
- int mitshm_major;
-
- // true if Qt is compiled w/ Tablet support and we have a tablet.
- bool use_xinput;
- int xinput_major;
- int xinput_eventbase;
- int xinput_errorbase;
-
- // for XKEYBOARD support
- bool use_xkb;
- int xkb_major;
- int xkb_eventbase;
- int xkb_errorbase;
-
- QList<QWidget *> deferred_map;
- struct ScrollInProgress {
- long id;
- QWidget* scrolled_widget;
- int dx, dy;
- };
- long sip_serial;
- QList<ScrollInProgress> sip_list;
-
- // window managers list of supported "stuff"
- Atom *net_supported_list;
- // list of virtual root windows
- Window *net_virtual_root_list;
- // client leader window
- Window wm_client_leader;
-
- QX11InfoData *screens;
- Visual **argbVisuals;
- Colormap *argbColormaps;
- int screenCount;
- int defaultScreen;
-
- Time time;
- Time userTime;
-
- QString default_im;
-
- // starts to ignore bad window errors from X
- static inline void ignoreBadwindow() {
- qt_x11Data->ignore_badwindow = true;
- qt_x11Data->seen_badwindow = false;
- }
-
- // ends ignoring bad window errors and returns whether an error had happened.
- static inline bool badwindow() {
- qt_x11Data->ignore_badwindow = false;
- return qt_x11Data->seen_badwindow;
- }
-
- bool ignore_badwindow;
- bool seen_badwindow;
-
- // options
- int visual_class;
- int visual_id;
- int color_count;
- bool custom_cmap;
-
- // outside visual/colormap
- Visual *visual;
- Colormap colormap;
-
-#ifndef QT_NO_XRENDER
- enum { solid_fill_count = 16 };
- struct SolidFills {
- XRenderColor color;
- int screen;
- Picture picture;
- } solid_fills[solid_fill_count];
- enum { pattern_fill_count = 16 };
- struct PatternFills {
- XRenderColor color;
- XRenderColor bg_color;
- int screen;
- int style;
- bool opaque;
- Picture picture;
- } pattern_fills[pattern_fill_count];
- Picture getSolidFill(int screen, const QColor &c);
- XRenderColor preMultiply(const QColor &c);
-#endif
-
- bool has_fontconfig;
- qreal fc_scale;
- bool fc_antialias;
- int fc_hint_style;
-
- char *startupId;
-
- DesktopEnvironment desktopEnvironment : 8;
- uint desktopVersion : 8; /* Used only for KDE */
-
- /* Warning: if you modify this list, modify the names of atoms in qapplication_x11.cpp as well! */
- enum X11Atom {
- // window-manager <-> client protocols
- WM_PROTOCOLS,
- WM_DELETE_WINDOW,
- WM_TAKE_FOCUS,
- _NET_WM_PING,
- _NET_WM_CONTEXT_HELP,
- _NET_WM_SYNC_REQUEST,
- _NET_WM_SYNC_REQUEST_COUNTER,
-
- // ICCCM window state
- WM_STATE,
- WM_CHANGE_STATE,
-
- // Session management
- WM_CLIENT_LEADER,
- WM_WINDOW_ROLE,
- SM_CLIENT_ID,
-
- // Clipboard
- CLIPBOARD,
- INCR,
- TARGETS,
- MULTIPLE,
- TIMESTAMP,
- SAVE_TARGETS,
- CLIP_TEMPORARY,
- _QT_SELECTION,
- _QT_CLIPBOARD_SENTINEL,
- _QT_SELECTION_SENTINEL,
- CLIPBOARD_MANAGER,
-
- RESOURCE_MANAGER,
-
- _XSETROOT_ID,
-
- _QT_SCROLL_DONE,
- _QT_INPUT_ENCODING,
-
- _MOTIF_WM_HINTS,
-
- DTWM_IS_RUNNING,
- ENLIGHTENMENT_DESKTOP,
- _DT_SAVE_MODE,
- _SGI_DESKS_MANAGER,
-
- // EWMH (aka NETWM)
- _NET_SUPPORTED,
- _NET_VIRTUAL_ROOTS,
- _NET_WORKAREA,
-
- _NET_MOVERESIZE_WINDOW,
- _NET_WM_MOVERESIZE,
-
- _NET_WM_NAME,
- _NET_WM_ICON_NAME,
- _NET_WM_ICON,
-
- _NET_WM_PID,
-
- _NET_WM_WINDOW_OPACITY,
-
- _NET_WM_STATE,
- _NET_WM_STATE_ABOVE,
- _NET_WM_STATE_BELOW,
- _NET_WM_STATE_FULLSCREEN,
- _NET_WM_STATE_MAXIMIZED_HORZ,
- _NET_WM_STATE_MAXIMIZED_VERT,
- _NET_WM_STATE_MODAL,
- _NET_WM_STATE_STAYS_ON_TOP,
- _NET_WM_STATE_DEMANDS_ATTENTION,
-
- _NET_WM_USER_TIME,
- _NET_WM_USER_TIME_WINDOW,
- _NET_WM_FULL_PLACEMENT,
-
- _NET_WM_WINDOW_TYPE,
- _NET_WM_WINDOW_TYPE_DESKTOP,
- _NET_WM_WINDOW_TYPE_DOCK,
- _NET_WM_WINDOW_TYPE_TOOLBAR,
- _NET_WM_WINDOW_TYPE_MENU,
- _NET_WM_WINDOW_TYPE_UTILITY,
- _NET_WM_WINDOW_TYPE_SPLASH,
- _NET_WM_WINDOW_TYPE_DIALOG,
- _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
- _NET_WM_WINDOW_TYPE_POPUP_MENU,
- _NET_WM_WINDOW_TYPE_TOOLTIP,
- _NET_WM_WINDOW_TYPE_NOTIFICATION,
- _NET_WM_WINDOW_TYPE_COMBO,
- _NET_WM_WINDOW_TYPE_DND,
- _NET_WM_WINDOW_TYPE_NORMAL,
- _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
-
- _KDE_NET_WM_FRAME_STRUT,
-
- _NET_STARTUP_INFO,
- _NET_STARTUP_INFO_BEGIN,
-
- _NET_SUPPORTING_WM_CHECK,
-
- _NET_WM_CM_S0,
-
- _NET_SYSTEM_TRAY_VISUAL,
-
- _NET_ACTIVE_WINDOW,
-
- // Property formats
- COMPOUND_TEXT,
- TEXT,
- UTF8_STRING,
-
- // Xdnd
- XdndEnter,
- XdndPosition,
- XdndStatus,
- XdndLeave,
- XdndDrop,
- XdndFinished,
- XdndTypelist,
- XdndActionList,
-
- XdndSelection,
-
- XdndAware,
- XdndProxy,
-
- XdndActionCopy,
- XdndActionLink,
- XdndActionMove,
- XdndActionPrivate,
-
- // Motif DND
- _MOTIF_DRAG_AND_DROP_MESSAGE,
- _MOTIF_DRAG_INITIATOR_INFO,
- _MOTIF_DRAG_RECEIVER_INFO,
- _MOTIF_DRAG_WINDOW,
- _MOTIF_DRAG_TARGETS,
-
- XmTRANSFER_SUCCESS,
- XmTRANSFER_FAILURE,
-
- // Xkb
- _XKB_RULES_NAMES,
-
- // XEMBED
- _XEMBED,
- _XEMBED_INFO,
-
- XWacomStylus,
- XWacomCursor,
- XWacomEraser,
-
- XTabletStylus,
- XTabletEraser,
-
- NPredefinedAtoms,
-
- _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
- NAtoms
- };
- Atom atoms[NAtoms];
-
- bool isSupportedByWM(Atom atom);
-
- bool compositingManagerRunning;
-
-#ifndef QT_NO_XCURSOR
- PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor;
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XINERAMA
- PtrXineramaQueryExtension ptrXineramaQueryExtension;
- PtrXineramaIsActive ptrXineramaIsActive;
- PtrXineramaQueryScreens ptrXineramaQueryScreens;
-#endif // QT_NO_XINERAMA
-
-#ifndef QT_NO_XRANDR
- PtrXRRSelectInput ptrXRRSelectInput;
- PtrXRRUpdateConfiguration ptrXRRUpdateConfiguration;
- PtrXRRRootToScreen ptrXRRRootToScreen;
- PtrXRRQueryExtension ptrXRRQueryExtension;
- PtrXRRSizes ptrXRRSizes;
-#endif // QT_NO_XRANDR
-};
-
-extern QX11Data *qt_x11Data;
-#define ATOM(x) qt_x11Data->atoms[QX11Data::x]
-#define X11 qt_x11Data
-
-// rename a couple of X defines to get rid of name clashes
-// resolve the conflict between X11's FocusIn and QEvent::FocusIn
-enum {
- XFocusOut = FocusOut,
- XFocusIn = FocusIn,
- XKeyPress = KeyPress,
- XKeyRelease = KeyRelease,
- XNone = None,
- XRevertToParent = RevertToParent,
- XGrayScale = GrayScale,
- XCursorShape = CursorShape
-};
-#undef FocusOut
-#undef FocusIn
-#undef KeyPress
-#undef KeyRelease
-#undef None
-#undef RevertToParent
-#undef GrayScale
-#undef CursorShape
-
-#ifdef FontChange
-#undef FontChange
-#endif
-
-Q_DECLARE_TYPEINFO(XPoint, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(XRectangle, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(XChar2b, Q_PRIMITIVE_TYPE);
-#ifndef QT_NO_XRENDER
-Q_DECLARE_TYPEINFO(XGlyphElt32, Q_PRIMITIVE_TYPE);
-#endif
-
-
-QT_END_NAMESPACE
-
-#endif // QT_X11_P_H
diff --git a/src/widgets/platforms/x11/qwidget_x11.cpp b/src/widgets/platforms/x11/qwidget_x11.cpp
deleted file mode 100644
index 5bb59b26c9..0000000000
--- a/src/widgets/platforms/x11/qwidget_x11.cpp
+++ /dev/null
@@ -1,3149 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qevent.h"
-#include "qwidget.h"
-#include "qdesktopwidget.h"
-#include "qapplication.h"
-#include "qapplication_p.h"
-#include "qnamespace.h"
-#include "qpainter.h"
-#include "qbitmap.h"
-#include "qlayout.h"
-#include "qtextcodec.h"
-#include "qelapsedtimer.h"
-#include "qcursor.h"
-#include "qstack.h"
-#include "qcolormap.h"
-#include "qdebug.h"
-#include "qmenu.h"
-#include "private/qmenu_p.h"
-#include "private/qbackingstore_p.h"
-#include "private/qwindowsurface_x11_p.h"
-
-//extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_x11.cpp
-
-#include <private/qpixmap_x11_p.h>
-#include <private/qpaintengine_x11_p.h>
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-
-#include <stdlib.h>
-
-//#define ALIEN_DEBUG
-
-// defined in qapplication_x11.cpp
-//bool qt_wstate_iconified(WId);
-//void qt_updated_rootinfo();
-
-
-#if !defined(QT_NO_IM)
-#include "qinputcontext.h"
-#include "qinputcontextfactory.h"
-#endif
-
-#include "qwidget_p.h"
-
-#define XCOORD_MAX 16383
-#define WRECT_MAX 8191
-
-QT_BEGIN_NAMESPACE
-
-extern bool qt_nograb();
-
-QWidget *QWidgetPrivate::mouseGrabber = 0;
-QWidget *QWidgetPrivate::keyboardGrabber = 0;
-
-void qt_net_remove_user_time(QWidget *tlw);
-void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
-
-int qt_x11_create_desktop_on_screen = -1;
-
-extern void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
-
-// MWM support
-struct QtMWMHints {
- ulong flags, functions, decorations;
- long input_mode;
- ulong status;
-};
-
-enum {
- MWM_HINTS_FUNCTIONS = (1L << 0),
-
- MWM_FUNC_ALL = (1L << 0),
- MWM_FUNC_RESIZE = (1L << 1),
- MWM_FUNC_MOVE = (1L << 2),
- MWM_FUNC_MINIMIZE = (1L << 3),
- MWM_FUNC_MAXIMIZE = (1L << 4),
- MWM_FUNC_CLOSE = (1L << 5),
-
- MWM_HINTS_DECORATIONS = (1L << 1),
-
- MWM_DECOR_ALL = (1L << 0),
- MWM_DECOR_BORDER = (1L << 1),
- MWM_DECOR_RESIZEH = (1L << 2),
- MWM_DECOR_TITLE = (1L << 3),
- MWM_DECOR_MENU = (1L << 4),
- MWM_DECOR_MINIMIZE = (1L << 5),
- MWM_DECOR_MAXIMIZE = (1L << 6),
-
- MWM_HINTS_INPUT_MODE = (1L << 2),
-
- MWM_INPUT_MODELESS = 0L,
- MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
- MWM_INPUT_FULL_APPLICATION_MODAL = 3L
-};
-
-
-static QtMWMHints getMWMHints(Display *display, Window window)
-{
- QtMWMHints mwmhints;
-
- Atom type;
- int format;
- ulong nitems, bytesLeft;
- uchar *data = 0;
- if ((XGetWindowProperty(display, window, ATOM(_MOTIF_WM_HINTS), 0, 5, false,
- ATOM(_MOTIF_WM_HINTS), &type, &format, &nitems, &bytesLeft,
- &data) == Success)
- && (type == ATOM(_MOTIF_WM_HINTS)
- && format == 32
- && nitems >= 5)) {
- mwmhints = *(reinterpret_cast<QtMWMHints *>(data));
- } else {
- mwmhints.flags = 0L;
- mwmhints.functions = MWM_FUNC_ALL;
- mwmhints.decorations = MWM_DECOR_ALL;
- mwmhints.input_mode = 0L;
- mwmhints.status = 0L;
- }
-
- if (data)
- XFree(data);
-
- return mwmhints;
-}
-
-static void SetMWMHints(Display *display, Window window, const QtMWMHints &mwmhints)
-{
- if (mwmhints.flags != 0l) {
- XChangeProperty(display, window, ATOM(_MOTIF_WM_HINTS), ATOM(_MOTIF_WM_HINTS), 32,
- PropModeReplace, (unsigned char *) &mwmhints, 5);
- } else {
- XDeleteProperty(display, window, ATOM(_MOTIF_WM_HINTS));
- }
-}
-
-// Returns true if we should set WM_TRANSIENT_FOR on \a w
-static inline bool isTransient(const QWidget *w)
-{
- return ((w->windowType() == Qt::Dialog
- || w->windowType() == Qt::Sheet
- || w->windowType() == Qt::Tool
- || w->windowType() == Qt::SplashScreen
- || w->windowType() == Qt::ToolTip
- || w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup)
- && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
-}
-
-static void do_size_hints(QWidget* widget, QWExtra *x);
-
-/*****************************************************************************
- QWidget member functions
- *****************************************************************************/
-
-const uint stdWidgetEventMask = // X event mask
- (uint)(
- KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask |
- KeymapStateMask |
- ButtonMotionMask | PointerMotionMask |
- EnterWindowMask | LeaveWindowMask |
- FocusChangeMask |
- ExposureMask |
- PropertyChangeMask |
- StructureNotifyMask
- );
-
-const uint stdDesktopEventMask = // X event mask
- (uint)(
- KeymapStateMask |
- EnterWindowMask | LeaveWindowMask |
- PropertyChangeMask
- );
-
-
-/*
- The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
-*/
-
-Window qt_XCreateWindow(const QWidget *creator,
- Display *display, Window parent,
- int x, int y, uint w, uint h,
- int borderwidth, int depth,
- uint windowclass, Visual *visual,
- ulong valuemask, XSetWindowAttributes *attributes);
-Window qt_XCreateSimpleWindow(const QWidget *creator,
- Display *display, Window parent,
- int x, int y, uint w, uint h, int borderwidth,
- ulong border, ulong background);
-void qt_XDestroyWindow(const QWidget *destroyer,
- Display *display, Window window);
-
-
-static void qt_insert_sip(QWidget* scrolled_widget, int dx, int dy)
-{
- if (!scrolled_widget->isWindow() && !scrolled_widget->internalWinId())
- return;
- QX11Data::ScrollInProgress sip = { X11->sip_serial++, scrolled_widget, dx, dy };
- X11->sip_list.append(sip);
-
- XClientMessageEvent client_message;
- client_message.type = ClientMessage;
- client_message.window = scrolled_widget->internalWinId();
- client_message.format = 32;
- client_message.message_type = ATOM(_QT_SCROLL_DONE);
- client_message.data.l[0] = sip.id;
-
- XSendEvent(X11->display, scrolled_widget->internalWinId(), False, NoEventMask,
- (XEvent*)&client_message);
-}
-
-static int qt_sip_count(QWidget* scrolled_widget)
-{
- int sips=0;
-
- for (int i = 0; i < X11->sip_list.size(); ++i) {
- const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
- if (sip.scrolled_widget == scrolled_widget)
- sips++;
- }
-
- return sips;
-}
-
-static void create_wm_client_leader()
-{
- if (X11->wm_client_leader) return;
-
- X11->wm_client_leader =
- XCreateSimpleWindow(X11->display,
- QX11Info::appRootWindow(),
- 0, 0, 1, 1, 0, 0, 0);
-
- // set client leader property to itself
- XChangeProperty(X11->display,
- X11->wm_client_leader, ATOM(WM_CLIENT_LEADER),
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&X11->wm_client_leader, 1);
-
-#ifndef QT_NO_SESSIONMANAGER
- // If we are session managed, inform the window manager about it
- QByteArray session = qApp->sessionId().toLatin1();
- if (!session.isEmpty()) {
- XChangeProperty(X11->display,
- X11->wm_client_leader, ATOM(SM_CLIENT_ID),
- XA_STRING, 8, PropModeReplace,
- (unsigned char *)session.data(), session.size());
- }
-#endif
-}
-
-/*!
- \internal
- Update the X11 cursor of the widget w.
- \a force is true if this function is called from dispatchEnterLeave, it means that the
- mouse is actually directly under this widget.
- */
-void qt_x11_enforce_cursor(QWidget * w, bool force)
-{
- if (!w->testAttribute(Qt::WA_WState_Created))
- return;
-
- static QPointer<QWidget> lastUnderMouse = 0;
- if (force) {
- lastUnderMouse = w;
- } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
- w = lastUnderMouse;
- } else if (!w->internalWinId()) {
- return; //the mouse is not under this widget, and it's not native, so don't change it
- }
-
- while (!w->internalWinId() && w->parentWidget() && !w->isWindow() && !w->testAttribute(Qt::WA_SetCursor))
- w = w->parentWidget();
-
- QWidget *nativeParent = w;
- if (!w->internalWinId())
- nativeParent = w->nativeParentWidget();
- // This does the same as effectiveWinId(), but since it is possible
- // to not have a native parent widget due to a special hack in
- // qwidget for reparenting widgets to a different X11 screen,
- // added additional check to make sure native parent widget exists.
- if (!nativeParent || !nativeParent->internalWinId())
- return;
- WId winid = nativeParent->internalWinId();
-
- if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
-#ifndef QT_NO_CURSOR
- QCursor *oc = QApplication::overrideCursor();
- if (oc) {
- XDefineCursor(X11->display, winid, oc->handle());
- } else if (w->isEnabled()) {
- XDefineCursor(X11->display, winid, w->cursor().handle());
- } else {
- // enforce the windows behavior of clearing the cursor on
- // disabled widgets
- XDefineCursor(X11->display, winid, XNone);
- }
-#endif
- } else {
- XDefineCursor(X11->display, winid, XNone);
- }
-}
-
-Q_WIDGETS_EXPORT void qt_x11_enforce_cursor(QWidget * w)
-{
- qt_x11_enforce_cursor(w, false);
-}
-
-void qt_x11_wait_for_window_manager(QWidget *w, bool sendPostedEvents)
-{
- if (!w || (!w->isWindow() && !w->internalWinId()))
- return;
- QApplication::flush();
- XEvent ev;
- QElapsedTimer t;
- t.start();
- static const int maximumWaitTime = 2000;
- if (!w->testAttribute(Qt::WA_WState_Created))
- return;
-
- WId winid = w->internalWinId();
-
- // first deliver events that are already in the local queue
- if (sendPostedEvents)
- QApplication::sendPostedEvents();
-
- // the normal sequence is:
- // ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
- // with X11BypassWindowManagerHint:
- // ConfigureNotify ... MapNotify ... Expose
-
- enum State {
- Initial, Mapped
- } state = Initial;
-
- do {
- if (XEventsQueued(X11->display, QueuedAlready)) {
- XNextEvent(X11->display, &ev);
- qApp->x11ProcessEvent(&ev);
-
- switch (state) {
- case Initial:
- if (ev.type == MapNotify && ev.xany.window == winid)
- state = Mapped;
- break;
- case Mapped:
- if (ev.type == Expose && ev.xany.window == winid)
- return;
- break;
- }
- } else {
- if (!XEventsQueued(X11->display, QueuedAfterFlush))
- qApp->syncX(); // non-busy wait
- }
- if (t.elapsed() > maximumWaitTime)
- return;
- } while(1);
-}
-
-Q_WIDGETS_EXPORT void qt_x11_wait_for_window_manager(QWidget *w)
-{
- qt_x11_wait_for_window_manager(w, true);
-}
-
-void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
-{
- if (!w->isVisible()) // not managed by the window manager
- return;
-
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(_NET_WM_STATE);
- e.xclient.display = X11->display;
- e.xclient.window = w->internalWinId();
- e.xclient.format = 32;
- e.xclient.data.l[0] = set ? 1 : 0;
- e.xclient.data.l[1] = one;
- e.xclient.data.l[2] = two;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
- XSendEvent(X11->display, RootWindow(X11->display, w->x11Info().screen()),
- false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
-}
-
-struct QX11WindowAttributes {
- const XWindowAttributes *att;
-};
-
-void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a)
-{
- QX11WindowAttributes att;
- att.att = &a;
- qt_x11_getX11InfoForWindow(xinfo,att);
-}
-
-
-static QVector<Atom> getNetWmState(QWidget *w)
-{
- QVector<Atom> returnValue;
-
- // Don't read anything, just get the size of the property data
- Atom actualType;
- int actualFormat;
- ulong propertyLength;
- ulong bytesLeft;
- uchar *propertyData = 0;
- if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0, 0,
- False, XA_ATOM, &actualType, &actualFormat,
- &propertyLength, &bytesLeft, &propertyData) == Success
- && actualType == XA_ATOM && actualFormat == 32) {
- returnValue.resize(bytesLeft / 4);
- XFree((char*) propertyData);
- propertyData = 0;
-
- // fetch all data
- if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0,
- returnValue.size(), False, XA_ATOM, &actualType, &actualFormat,
- &propertyLength, &bytesLeft, &propertyData) != Success) {
- returnValue.clear();
- } else if (propertyLength != (ulong)returnValue.size()) {
- returnValue.resize(propertyLength);
- }
-
- // put it into netWmState
- if (!returnValue.isEmpty()) {
- memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
- }
- if (propertyData)
- XFree((char*) propertyData);
- }
-
- return returnValue;
-}
-
-void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
-{
- Q_Q(QWidget);
- Qt::WindowType type = q->windowType();
- Qt::WindowFlags &flags = data.window_flags;
- QWidget *parentWidget = q->parentWidget();
-
- if (type == Qt::ToolTip)
- flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
- if (type == Qt::Popup)
- flags |= Qt::X11BypassWindowManagerHint;
-
- bool topLevel = (flags & Qt::Window);
- bool popup = (type == Qt::Popup);
- bool desktop = (type == Qt::Desktop);
- bool tool = (type == Qt::Tool || type == Qt::SplashScreen
- || type == Qt::ToolTip || type == Qt::Drawer);
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::create_sys START:" << q << "topLevel?" << topLevel << "WId:"
- << window << "initializeWindow:" << initializeWindow << "destroyOldWindow" << destroyOldWindow;
-#endif
- if (topLevel) {
- if (parentWidget) { // if our parent stays on top, so must we
- QWidget *ptl = parentWidget->window();
- if(ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
- flags |= Qt::WindowStaysOnTopHint;
- }
-
- if (type == Qt::SplashScreen) {
- if (X11->isSupportedByWM(ATOM(_NET_WM_WINDOW_TYPE_SPLASH))) {
- flags &= ~Qt::X11BypassWindowManagerHint;
- } else {
- flags |= Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint;
- }
- }
- // All these buttons depend on the system menu, so we enable it
- if (flags & (Qt::WindowMinimizeButtonHint
- | Qt::WindowMaximizeButtonHint
- | Qt::WindowContextHelpButtonHint))
- flags |= Qt::WindowSystemMenuHint;
- }
-
-
- Window parentw, destroyw = 0;
- WId id = 0;
-
- // always initialize
- if (!window)
- initializeWindow = true;
-
- QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0;
-
- if (desktop &&
- qt_x11_create_desktop_on_screen >= 0 &&
- qt_x11_create_desktop_on_screen != xinfo.screen()) {
- // desktop on a certain screen other than the default requested
- QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen];
- xinfo.setX11Data(xd);
- } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
- || (parentXinfo->visual() != xinfo.visual()
- && !q->inherits("QGLWidget"))))
- {
- // QGLWidgets have to be excluded here as they have a
- // specially crafted QX11Info structure which can't be swapped
- // out with the parent widgets QX11Info. The parent visual,
- // for instance, might not even be GL capable.
- xinfo = *parentXinfo;
- }
-
- //get display, screen number, root window and desktop geometry for
- //the current screen
- Display *dpy = X11->display;
- int scr = xinfo.screen();
- Window root_win = RootWindow(dpy, scr);
- int sw = DisplayWidth(dpy,scr);
- int sh = DisplayHeight(dpy,scr);
-
- if (desktop) { // desktop widget
- popup = false; // force these flags off
- data.crect.setRect(0, 0, sw, sh);
- } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
- QDesktopWidget *desktopWidget = qApp->desktop();
- if (desktopWidget->isVirtualDesktop()) {
- QRect r = desktopWidget->screenGeometry();
- sw = r.width();
- sh = r.height();
- }
-
- int width = sw / 2;
- int height = 4 * sh / 10;
- if (extra) {
- width = qMax(qMin(width, extra->maxw), extra->minw);
- height = qMax(qMin(height, extra->maxh), extra->minh);
- }
- data.crect.setSize(QSize(width, height));
- }
-
- parentw = topLevel ? root_win : parentWidget->effectiveWinId();
-
- XSetWindowAttributes wsa;
-
- if (window) { // override the old window
- if (destroyOldWindow) {
- if (topLevel)
- X11->dndEnable(q, false);
- destroyw = data.winid;
- }
- id = window;
- setWinId(window);
- XWindowAttributes a;
- XGetWindowAttributes(dpy, window, &a);
- data.crect.setRect(a.x, a.y, a.width, a.height);
-
- if (a.map_state == IsUnmapped)
- q->setAttribute(Qt::WA_WState_Visible, false);
- else
- q->setAttribute(Qt::WA_WState_Visible);
-
- qt_x11_getX11InfoForWindow(&xinfo,a);
-
- } else if (desktop) { // desktop widget
-#ifdef QWIDGET_EXTRA_DEBUG
- qDebug() << "create desktop";
-#endif
- id = (WId)parentw; // id = root window
-// QWidget *otherDesktop = find(id); // is there another desktop?
-// if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
-// otherDesktop->d->setWinId(0); // remove id from widget mapper
-// d->setWinId(id); // make sure otherDesktop is
-// otherDesktop->d->setWinId(id); // found first
-// } else {
- setWinId(id);
-// }
- } else if (topLevel || q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) {
-#ifdef QWIDGET_EXTRA_DEBUG
- static int topLevels = 0;
- static int children = 0;
- if (parentw == root_win)
- qDebug() << "create toplevel" << ++topLevels;
- else
- qDebug() << "create child" << ++children;
-#endif
- QRect safeRect = data.crect; //##### must handle huge sizes as well.... i.e. wrect
- if (safeRect.width() < 1|| safeRect.height() < 1) {
- if (topLevel) {
- // top-levels must be at least 1x1
- safeRect.setSize(safeRect.size().expandedTo(QSize(1, 1)));
- } else {
- // create it way off screen, and rely on
- // setWSGeometry() to do the right thing with it later
- safeRect = QRect(-1000,-1000,1,1);
- }
- }
-#ifndef QT_NO_XRENDER
- int screen = xinfo.screen();
- if (topLevel && X11->use_xrender
- && xinfo.depth() != 32 && X11->argbVisuals[screen]
- && q->testAttribute(Qt::WA_TranslucentBackground))
- {
- QX11InfoData *xd = xinfo.getX11Data(true);
-
- xd->screen = screen;
- xd->visual = X11->argbVisuals[screen];
- xd->colormap = X11->argbColormaps[screen];
- xd->depth = 32;
- xd->defaultVisual = false;
- xd->defaultColormap = false;
- xd->cells = xd->visual->map_entries;
- xinfo.setX11Data(xd);
- }
-#endif
- if (xinfo.defaultVisual() && xinfo.defaultColormap()) {
- id = (WId)qt_XCreateSimpleWindow(q, dpy, parentw,
- safeRect.left(), safeRect.top(),
- safeRect.width(), safeRect.height(),
- 0,
- BlackPixel(dpy, xinfo.screen()),
- WhitePixel(dpy, xinfo.screen()));
- } else {
- wsa.background_pixel = WhitePixel(dpy, xinfo.screen());
- wsa.border_pixel = BlackPixel(dpy, xinfo.screen());
- wsa.colormap = xinfo.colormap();
- id = (WId)qt_XCreateWindow(q, dpy, parentw,
- safeRect.left(), safeRect.top(),
- safeRect.width(), safeRect.height(),
- 0, xinfo.depth(), InputOutput,
- (Visual *) xinfo.visual(),
- CWBackPixel|CWBorderPixel|CWColormap,
- &wsa);
- }
-
- setWinId(id); // set widget id/handle + hd
- }
-
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderFreePicture(X11->display, picture);
- picture = 0;
- }
-
- if (X11->use_xrender && !desktop && q->internalWinId()) {
- XRenderPictFormat *format = XRenderFindVisualFormat(dpy, (Visual *) xinfo.visual());
- if (format)
- picture = XRenderCreatePicture(dpy, id, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-
- QtMWMHints mwmhints;
- mwmhints.flags = 0L;
- mwmhints.functions = 0L;
- mwmhints.decorations = 0;
- mwmhints.input_mode = 0L;
- mwmhints.status = 0L;
-
- if (topLevel) {
- ulong wsa_mask = 0;
- if (type != Qt::SplashScreen) { // && customize) {
- mwmhints.flags |= MWM_HINTS_DECORATIONS;
-
- bool customize = flags & Qt::CustomizeWindowHint;
- if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
- mwmhints.decorations |= MWM_DECOR_BORDER;
- mwmhints.decorations |= MWM_DECOR_RESIZEH;
-
- if (flags & Qt::WindowTitleHint)
- mwmhints.decorations |= MWM_DECOR_TITLE;
-
- if (flags & Qt::WindowSystemMenuHint)
- mwmhints.decorations |= MWM_DECOR_MENU;
-
- if (flags & Qt::WindowMinimizeButtonHint) {
- mwmhints.decorations |= MWM_DECOR_MINIMIZE;
- mwmhints.functions |= MWM_FUNC_MINIMIZE;
- }
-
- if (flags & Qt::WindowMaximizeButtonHint) {
- mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
- mwmhints.functions |= MWM_FUNC_MAXIMIZE;
- }
-
- if (flags & Qt::WindowCloseButtonHint)
- mwmhints.functions |= MWM_FUNC_CLOSE;
- }
- } else {
- // if type == Qt::SplashScreen
- mwmhints.decorations = MWM_DECOR_ALL;
- }
-
- if (tool) {
- wsa.save_under = True;
- wsa_mask |= CWSaveUnder;
- }
-
- if (flags & Qt::X11BypassWindowManagerHint) {
- wsa.override_redirect = True;
- wsa_mask |= CWOverrideRedirect;
- }
-
- if (wsa_mask && initializeWindow) {
- Q_ASSERT(id);
- XChangeWindowAttributes(dpy, id, wsa_mask, &wsa);
- }
-
- if (mwmhints.functions != 0) {
- mwmhints.flags |= MWM_HINTS_FUNCTIONS;
- mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
- } else {
- mwmhints.functions = MWM_FUNC_ALL;
- }
-
- if (!(flags & Qt::FramelessWindowHint)
- && flags & Qt::CustomizeWindowHint
- && flags & Qt::WindowTitleHint
- && !(flags &
- (Qt::WindowMinimizeButtonHint
- | Qt::WindowMaximizeButtonHint
- | Qt::WindowCloseButtonHint))) {
- // a special case - only the titlebar without any button
- mwmhints.flags = MWM_HINTS_FUNCTIONS;
- mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
- mwmhints.decorations = 0;
- }
- }
-
- if (!initializeWindow) {
- // do no initialization
- } else if (popup) { // popup widget
- // set EWMH window types
- setNetWmWindowTypes();
-
- wsa.override_redirect = True;
- wsa.save_under = True;
- Q_ASSERT(id);
- XChangeWindowAttributes(dpy, id, CWOverrideRedirect | CWSaveUnder,
- &wsa);
- } else if (topLevel && !desktop) { // top-level widget
- if (!X11->wm_client_leader)
- create_wm_client_leader();
-
- // note: WM_TRANSIENT_FOR is set in QWidgetPrivate::show_sys()
-
- XSizeHints size_hints;
- size_hints.flags = USSize | PSize | PWinGravity;
- size_hints.x = data.crect.left();
- size_hints.y = data.crect.top();
- size_hints.width = data.crect.width();
- size_hints.height = data.crect.height();
- size_hints.win_gravity =
- QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
-
- XWMHints wm_hints; // window manager hints
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- wm_hints.flags = InputHint | StateHint | WindowGroupHint;
- wm_hints.input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
- wm_hints.initial_state = NormalState;
- wm_hints.window_group = X11->wm_client_leader;
-
- XClassHint class_hint;
- QByteArray appName = qAppName().toLatin1();
- class_hint.res_name = appName.data(); // application name
- class_hint.res_class = const_cast<char *>(QX11Info::appClass()); // application class
-
- XSetWMProperties(dpy, id, 0, 0,
- qApp->d_func()->argv, qApp->d_func()->argc,
- &size_hints, &wm_hints, &class_hint);
-
- XResizeWindow(dpy, id,
- qBound(1, data.crect.width(), XCOORD_MAX),
- qBound(1, data.crect.height(), XCOORD_MAX));
- XStoreName(dpy, id, appName.data());
- Atom protocols[5];
- int n = 0;
- protocols[n++] = ATOM(WM_DELETE_WINDOW); // support del window protocol
- protocols[n++] = ATOM(WM_TAKE_FOCUS); // support take focus window protocol
- protocols[n++] = ATOM(_NET_WM_PING); // support _NET_WM_PING protocol
-#ifndef QT_NO_XSYNC
- protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol
-#endif // QT_NO_XSYNC
- if (flags & Qt::WindowContextHelpButtonHint)
- protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
- XSetWMProtocols(dpy, id, protocols, n);
-
- // set mwm hints
- SetMWMHints(dpy, id, mwmhints);
-
- // set EWMH window types
- setNetWmWindowTypes();
-
- // set _NET_WM_PID
- long curr_pid = getpid();
- XChangeProperty(dpy, id, ATOM(_NET_WM_PID), XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) &curr_pid, 1);
-
- // when we create a toplevel widget, the frame strut should be dirty
- data.fstrut_dirty = 1;
-
- // declare the widget's window role
- if (QTLWExtra *topData = maybeTopData()) {
- if (!topData->role.isEmpty()) {
- QByteArray windowRole = topData->role.toUtf8();
- XChangeProperty(dpy, id,
- ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
- (unsigned char *)windowRole.constData(), windowRole.length());
- }
- }
-
- // set client leader property
- XChangeProperty(dpy, id, ATOM(WM_CLIENT_LEADER),
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&X11->wm_client_leader, 1);
- } else {
- // non-toplevel widgets don't have a frame, so no need to
- // update the strut
- data.fstrut_dirty = 0;
- }
-
- if (initializeWindow && q->internalWinId()) {
- // don't erase when resizing
- wsa.bit_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
- Q_ASSERT(id);
- XChangeWindowAttributes(dpy, id, CWBitGravity, &wsa);
- }
-
- // set X11 event mask
- if (desktop) {
-// QWidget* main_desktop = find(id);
-// if (main_desktop->testWFlags(Qt::WPaintDesktop))
-// XSelectInput(dpy, id, stdDesktopEventMask | ExposureMask);
-// else
- XSelectInput(dpy, id, stdDesktopEventMask);
- } else if (q->internalWinId()) {
- XSelectInput(dpy, id, stdWidgetEventMask);
-#if !defined (QT_NO_TABLET)
- QTabletDeviceDataList *tablet_list = qt_tablet_devices();
- if (X11->ptrXSelectExtensionEvent) {
- for (int i = 0; i < tablet_list->size(); ++i) {
- QTabletDeviceData tablet = tablet_list->at(i);
- X11->ptrXSelectExtensionEvent(dpy, id, reinterpret_cast<XEventClass*>(tablet.eventList),
- tablet.eventCount);
- }
- }
-#endif
- }
-
- if (desktop) {
- q->setAttribute(Qt::WA_WState_Visible);
- } else if (topLevel) { // set X cursor
- if (initializeWindow) {
- qt_x11_enforce_cursor(q);
-
- if (QTLWExtra *topData = maybeTopData())
- if (!topData->caption.isEmpty())
- setWindowTitle_helper(topData->caption);
-
- //always enable dnd: it's not worth the effort to maintain the state
- // NOTE: this always creates topData()
- X11->dndEnable(q, true);
-
- if (maybeTopData() && maybeTopData()->opacity != 255)
- q->setWindowOpacity(maybeTopData()->opacity/255.);
-
- }
- } else if (q->internalWinId()) {
- qt_x11_enforce_cursor(q);
- if (QWidget *p = q->parentWidget()) // reset the cursor on the native parent
- qt_x11_enforce_cursor(p);
- }
-
- if (extra && !extra->mask.isEmpty() && q->internalWinId())
- XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
- extra->mask.handle(), ShapeSet);
-
- if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) {
- QInputContext *inputContext = q->inputContext();
- if (inputContext)
- inputContext->setFocusWidget(q);
- }
-
- if (destroyw) {
- qt_XDestroyWindow(q, dpy, destroyw);
- if (QTLWExtra *topData = maybeTopData()) {
-#ifndef QT_NO_XSYNC
- if (topData->syncUpdateCounter)
- XSyncDestroyCounter(dpy, topData->syncUpdateCounter);
-#endif
- // we destroyed our old window - reset the top-level state
- createTLSysExtra();
- }
- }
-
- // newly created windows are positioned at the window system's
- // (0,0) position. If the parent uses wrect mapping to expand the
- // coordinate system, we must also adjust this widget's window
- // system position
- if (!topLevel && !parentWidget->data->wrect.topLeft().isNull())
- setWSGeometry();
- else 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());
- XMapWindow(X11->display, q->internalWinId());
- // Ensure that mapped alien widgets are flushed immediately when re-created as native widgets.
- if (QWindowSurface *surface = q->windowSurface())
- surface->flush(q, q->rect(), q->mapTo(surface->window(), QPoint()));
- }
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::create_sys END:" << q;
-#endif
-}
-
-static void qt_x11_recreateWidget(QWidget *widget)
-{
- if (widget->inherits("QGLWidget")) {
- // We send QGLWidgets a ParentChange event which causes them to
- // recreate their GL context, which in turn causes them to choose
- // their visual again. Now that WA_TranslucentBackground is set,
- // QGLContext::chooseVisual will select an ARGB visual.
-
- // QGLWidget expects a ParentAboutToChange to be sent first
- QEvent aboutToChangeEvent(QEvent::ParentAboutToChange);
- QApplication::sendEvent(widget, &aboutToChangeEvent);
-
- QEvent parentChangeEvent(QEvent::ParentChange);
- QApplication::sendEvent(widget, &parentChangeEvent);
- } else {
- // For regular widgets, reparent them with their parent which
- // also triggers a recreation of the native window
- QPoint pos = widget->pos();
- bool visible = widget->isVisible();
- if (visible)
- widget->hide();
-
- widget->setParent(widget->parentWidget(), widget->windowFlags());
- widget->move(pos);
- if (visible)
- widget->show();
- }
-}
-
-static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
-{
- if (widget->internalWinId())
- qt_x11_recreateWidget(widget);
-
- const QObjectList &children = widget->children();
- for (int i = 0; i < children.size(); ++i) {
- QWidget *child = qobject_cast<QWidget*>(children.at(i));
- if (child)
- qt_x11_recreateNativeWidgetsRecursive(child);
- }
-}
-
-void QWidgetPrivate::x11UpdateIsOpaque()
-{
-#ifndef QT_NO_XRENDER
- Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
- return;
-
- bool topLevel = (data.window_flags & Qt::Window);
- int screen = xinfo.screen();
- if (topLevel && X11->use_xrender
- && X11->argbVisuals[screen] && xinfo.depth() != 32)
- {
- qt_x11_recreateNativeWidgetsRecursive(q);
- }
-#endif
-}
-
-/*
- Returns true if the background is inherited; otherwise returns
- false.
-
- Mainly used in the paintOnScreen case.
-*/
-bool QWidgetPrivate::isBackgroundInherited() const
-{
- Q_Q(const QWidget);
-
- // windows do not inherit their background
- if (q->isWindow() || q->windowType() == Qt::SubWindow)
- return false;
-
- if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
- return false;
-
- const QPalette &pal = q->palette();
- QPalette::ColorRole bg = q->backgroundRole();
- QBrush brush = pal.brush(bg);
-
- // non opaque brushes leaves us no choice, we must inherit
- if (!q->autoFillBackground() || !brush.isOpaque())
- return true;
-
- if (brush.style() == Qt::SolidPattern) {
- // the background is just a solid color. If there is no
- // propagated contents, then we claim as performance
- // optimization that it was not inheritet. This is the normal
- // case in standard Windows or Motif style.
- const QWidget *w = q->parentWidget();
- if (!w->d_func()->isBackgroundInherited())
- return false;
- }
-
- return true;
-}
-
-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);
- QObjectList childList = children();
- for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
- register QObject *obj = childList.at(i);
- if (obj->isWidgetType())
- static_cast<QWidget*>(obj)->destroy(destroySubWindows,
- destroySubWindows);
- }
- if (QWidgetPrivate::mouseGrabber == this)
- releaseMouse();
- if (QWidgetPrivate::keyboardGrabber == this)
- releaseKeyboard();
- if (isWindow())
- X11->deferred_map.removeAll(this);
- if (isModal()) {
- // just be sure we leave modal
- QApplicationPrivate::leaveModal(this);
- }
- else if ((windowType() == Qt::Popup))
- qApp->d_func()->closePopup(this);
-
-#ifndef QT_NO_XRENDER
- if (d->picture) {
- if (destroyWindow)
- XRenderFreePicture(X11->display, d->picture);
- d->picture = 0;
- }
-#endif // QT_NO_XRENDER
-
- // delete the _NET_WM_USER_TIME_WINDOW
- qt_net_remove_user_time(this);
-
- if ((windowType() == Qt::Desktop)) {
- if (acceptDrops())
- X11->dndEnable(this, false);
- } else {
- if (isWindow())
- X11->dndEnable(this, false);
- if (destroyWindow)
- qt_XDestroyWindow(this, X11->display, data->winid);
- }
- QT_TRY {
- d->setWinId(0);
- } QT_CATCH (const std::bad_alloc &) {
- // swallow - destructors must not throw
- }
-
- extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp
- if (testAttribute(Qt::WA_WState_Reparented))
- qPRCleanup(this);
-
- if(d->ic) {
- delete d->ic;
- } else {
- // release previous focus information participating with
- // preedit preservation of qic
- QInputContext *qic = QApplicationPrivate::inputContext;
- if (qic)
- qic->widgetDestroyed(this);
- }
- }
-}
-
-void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
-{
- Q_Q(QWidget);
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setParent_sys START" << q << "parent:" << parent;
-#endif
- QX11Info old_xinfo = xinfo;
- if (parent && parent->windowType() == Qt::Desktop) {
- // make sure the widget is created on the same screen as the
- // programmer specified desktop widget
- xinfo = parent->d_func()->xinfo;
- parent = 0;
- }
-
- QTLWExtra *topData = maybeTopData();
- bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
- if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
- q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- extern void qPRCreate(const QWidget *, Window);
-#ifndef QT_NO_CURSOR
- QCursor oldcurs;
-#endif
-
- // dnd unregister (we will register again below)
- if (q->testAttribute(Qt::WA_DropSiteRegistered))
- q->setAttribute(Qt::WA_DropSiteRegistered, false);
-
- // if we are a top then remove our dnd prop for now
- // it will get rest later
- if (q->isWindow() && wasCreated)
- X11->dndEnable(q, false);
-
- if (topData)
- qt_net_remove_user_time(q);
-
-// QWidget *oldparent = q->parentWidget();
- WId old_winid = wasCreated ? data.winid : 0;
- if ((q->windowType() == Qt::Desktop))
- old_winid = 0;
- setWinId(0);
-
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderFreePicture(X11->display, picture);
- picture = 0;
- }
-#endif
-
- // hide and reparent our own window away. Otherwise we might get
- // destroyed when emitting the child remove event below. See QWorkspace.
- if (wasCreated && old_winid) {
- XUnmapWindow(X11->display, old_winid);
- if (!old_xinfo.screen() != xinfo.screen())
- XReparentWindow(X11->display, old_winid, RootWindow(X11->display, xinfo.screen()), 0, 0);
- }
- if (topData) {
- topData->parentWinId = 0;
- // zero the frame strut and mark it dirty
- topData->frameStrut.setCoords(0, 0, 0, 0);
-
- // reparenting from top-level, make sure show() works again
- topData->waitingForMapNotify = 0;
- topData->validWMState = 0;
- }
- data.fstrut_dirty = (!parent || (f & Qt::Window)); // toplevels get a dirty framestrut
-
- QObjectPrivate::setParent_helper(parent);
- bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
-
- data.window_flags = f;
- 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)
- createWinId();
- if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
- q->setAttribute(Qt::WA_WState_Hidden);
- q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
-
- if (wasCreated) {
- 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->testAttribute(Qt::WA_WState_Created))
- continue;
- if (xinfo.screen() != w->d_func()->xinfo.screen()) {
- // ### force setParent() to not shortcut out (because
- // ### we're setting the parent to the current parent)
- // ### setParent will add child back to the list
- // ### of children so we need to make sure the
- // ### widget won't be added twice.
- w->d_func()->parent = 0;
- this->children.removeOne(w);
- w->setParent(q);
- } else if (!w->isWindow()) {
- w->d_func()->invalidateBuffer(w->rect());
- if (w->internalWinId()) {
- if (w->testAttribute(Qt::WA_NativeWindow)) {
- QWidget *nativeParentWidget = w->nativeParentWidget();
- // Qt::WA_NativeWindow ensures that we always have a nativeParentWidget
- Q_ASSERT(nativeParentWidget != 0);
- QPoint p = w->mapTo(nativeParentWidget, QPoint());
- XReparentWindow(X11->display,
- w->internalWinId(),
- nativeParentWidget->internalWinId(),
- p.x(), p.y());
- } else {
- w->d_func()->setParent_sys(q, w->data->window_flags);
- }
- }
- } else if (isTransient(w)) {
- /*
- when reparenting toplevel windows with toplevel-transient children,
- we need to make sure that the window manager gets the updated
- WM_TRANSIENT_FOR information... unfortunately, some window managers
- don't handle changing WM_TRANSIENT_FOR before the toplevel window is
- visible, so we unmap and remap all toplevel-transient children *after*
- the toplevel parent has been mapped. thankfully, this is easy in Qt :)
-
- note that the WM_TRANSIENT_FOR hint is actually updated in
- QWidgetPrivate::show_sys()
- */
- if (w->internalWinId())
- XUnmapWindow(X11->display, w->internalWinId());
- QApplication::postEvent(w, new QEvent(QEvent::ShowWindowRequest));
- }
- }
- }
- qPRCreate(q, old_winid);
- updateSystemBackground();
-
- if (old_winid) {
- Window *cmwret;
- int count;
- if (XGetWMColormapWindows(X11->display, old_winid, &cmwret, &count)) {
- Window *cmw;
- int cmw_size = sizeof(Window)*count;
- cmw = new Window[count];
- memcpy((char *)cmw, (char *)cmwret, cmw_size);
- XFree((char *)cmwret);
- int i;
- for (i=0; i<count; i++) {
- if (cmw[i] == old_winid) {
- cmw[i] = q->internalWinId();
- break;
- }
- }
- int top_count;
- if (XGetWMColormapWindows(X11->display, q->window()->internalWinId(),
- &cmwret, &top_count))
- {
- Window *merged_cmw = new Window[count + top_count];
- memcpy((char *)merged_cmw, (char *)cmw, cmw_size);
- memcpy((char *)merged_cmw + cmw_size, (char *)cmwret, sizeof(Window)*top_count);
- delete [] cmw;
- XFree((char *)cmwret);
- cmw = merged_cmw;
- count += top_count;
- }
-
- XSetWMColormapWindows(X11->display, q->window()->internalWinId(), cmw, count);
- delete [] cmw;
- }
-
- qt_XDestroyWindow(q, X11->display, old_winid);
- }
- }
-
- // check if we need to register our dropsite
- if (q->testAttribute(Qt::WA_AcceptDrops)
- || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) {
- q->setAttribute(Qt::WA_DropSiteRegistered, true);
- }
-#if !defined(QT_NO_IM)
- ic = 0;
-#endif
- invalidateBuffer(q->rect());
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setParent_sys END" << q;
-#endif
-}
-
-QPoint QWidgetPrivate::mapToGlobal(const QPoint &pos) const
-{
- Q_Q(const QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
- QPoint p = pos + q->data->crect.topLeft();
- //cannot trust that !isWindow() implies parentWidget() before create
- return (q->isWindow() || !q->parentWidget()) ? p : q->parentWidget()->d_func()->mapToGlobal(p);
- }
- int x, y;
- Window child;
- QPoint p = mapToWS(pos);
- XTranslateCoordinates(X11->display, q->internalWinId(),
- QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
- p.x(), p.y(), &x, &y, &child);
- return QPoint(x, y);
-}
-
-QPoint QWidgetPrivate::mapFromGlobal(const QPoint &pos) const
-{
- Q_Q(const QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
- //cannot trust that !isWindow() implies parentWidget() before create
- QPoint p = (q->isWindow() || !q->parentWidget()) ? pos : q->parentWidget()->d_func()->mapFromGlobal(pos);
- return p - q->data->crect.topLeft();
- }
- int x, y;
- Window child;
- XTranslateCoordinates(X11->display,
- QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
- q->internalWinId(), pos.x(), pos.y(), &x, &y, &child);
- return mapFromWS(QPoint(x, y));
-}
-
-QPoint QWidget::mapToGlobal(const QPoint &pos) const
-{
- Q_D(const QWidget);
- QPoint offset = data->crect.topLeft();
- const QWidget *w = this;
- const QWidget *p = w->parentWidget();
- while (!w->isWindow() && p) {
- w = p;
- p = p->parentWidget();
- offset += w->data->crect.topLeft();
- }
-
- const QWidgetPrivate *wd = w->d_func();
- QTLWExtra *tlw = wd->topData();
- if (!tlw->embedded)
- return pos + offset;
-
- return d->mapToGlobal(pos);
-}
-
-QPoint QWidget::mapFromGlobal(const QPoint &pos) const
-{
- Q_D(const QWidget);
- QPoint offset = data->crect.topLeft();
- const QWidget *w = this;
- const QWidget *p = w->parentWidget();
- while (!w->isWindow() && p) {
- w = p;
- p = p->parentWidget();
- offset += w->data->crect.topLeft();
- }
-
- const QWidgetPrivate *wd = w->d_func();
- QTLWExtra *tlw = wd->topData();
- if (!tlw->embedded)
- return pos - offset;
-
- return d->mapFromGlobal(pos);
-}
-
-void QWidgetPrivate::updateSystemBackground()
-{
- Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId())
- return;
- QBrush brush = q->palette().brush(QPalette::Active, q->backgroundRole());
- Qt::WindowType type = q->windowType();
- if (brush.style() == Qt::NoBrush
- || q->testAttribute(Qt::WA_NoSystemBackground)
- || q->testAttribute(Qt::WA_UpdatesDisabled)
- || type == Qt::Popup || type == Qt::ToolTip) {
- if (QX11Info::isCompositingManagerRunning()
- && q->testAttribute(Qt::WA_TranslucentBackground)
- && !(q->parent()))
- XSetWindowBackground(X11->display, q->internalWinId(),
- QColormap::instance(xinfo.screen()).pixel(Qt::transparent));
- else
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
- }
- else if (brush.style() == Qt::SolidPattern && brush.isOpaque())
- XSetWindowBackground(X11->display, q->internalWinId(),
- QColormap::instance(xinfo.screen()).pixel(brush.color()));
- else if (isBackgroundInherited())
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), ParentRelative);
- else if (brush.style() == Qt::TexturePattern) {
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(),
- static_cast<QX11PlatformPixmap*>(qt_toX11Pixmap(brush.texture()).data.data())->x11ConvertToDefaultDepth());
- } else
- XSetWindowBackground(X11->display, q->internalWinId(),
- QColormap::instance(xinfo.screen()).pixel(brush.color()));
-}
-
-#ifndef QT_NO_CURSOR
-void QWidgetPrivate::setCursor_sys(const QCursor &)
-{
- Q_Q(QWidget);
- qt_x11_enforce_cursor(q);
- XFlush(X11->display);
-}
-
-void QWidgetPrivate::unsetCursor_sys()
-{
- Q_Q(QWidget);
- qt_x11_enforce_cursor(q);
- XFlush(X11->display);
-}
-#endif
-
-static XTextProperty*
-qstring_to_xtp(const QString& s)
-{
- static XTextProperty tp = { 0, 0, 0, 0 };
- static bool free_prop = true; // we can't free tp.value in case it references
- // the data of the static QCString below.
- if (tp.value) {
- if (free_prop)
- XFree(tp.value);
- tp.value = 0;
- free_prop = true;
- }
-
- static const QTextCodec* mapper = QTextCodec::codecForLocale();
- int errCode = 0;
- if (mapper) {
- QByteArray mapped = mapper->fromUnicode(s);
- char* tl[2];
- tl[0] = mapped.data();
- tl[1] = 0;
- errCode = XmbTextListToTextProperty(X11->display, tl, 1, XStdICCTextStyle, &tp);
-#if defined(QT_DEBUG)
- if (errCode < 0)
- qDebug("qstring_to_xtp result code %d", errCode);
-#endif
- }
- if (!mapper || errCode < 0) {
- static QByteArray qcs;
- qcs = s.toAscii();
- tp.value = (uchar*)qcs.data();
- tp.encoding = XA_STRING;
- tp.format = 8;
- tp.nitems = qcs.length();
- free_prop = false;
- }
-
- // ### If we knew WM could understand unicode, we could use
- // ### a much simpler, cheaper encoding...
- /*
- tp.value = (XChar2b*)s.unicode();
- tp.encoding = XA_UNICODE; // wish
- tp.format = 16;
- tp.nitems = s.length();
- */
-
- return &tp;
-}
-
-void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (!q->internalWinId())
- return;
- XSetWMName(X11->display, q->internalWinId(), qstring_to_xtp(caption));
-
- QByteArray net_wm_name = caption.toUtf8();
- XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
- PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
-}
-
-void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
-{
- Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created))
- return;
- QTLWExtra *topData = this->topData();
- if (topData->iconPixmap && !forceReset)
- // already been set
- return;
-
- // preparing images to set the _NET_WM_ICON property
- QIcon icon = q->windowIcon();
- QVector<long> icon_data;
- Qt::HANDLE pixmap_handle = 0;
- if (!icon.isNull()) {
- QList<QSize> availableSizes = icon.availableSizes();
- if(availableSizes.isEmpty()) {
- // try to use default sizes since the icon can be a scalable image like svg.
- availableSizes.push_back(QSize(16,16));
- availableSizes.push_back(QSize(32,32));
- availableSizes.push_back(QSize(64,64));
- availableSizes.push_back(QSize(128,128));
- }
- for(int i = 0; i < availableSizes.size(); ++i) {
- QSize size = availableSizes.at(i);
- QPixmap pixmap = icon.pixmap(size);
- if (!pixmap.isNull()) {
- QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
- int pos = icon_data.size();
- icon_data.resize(pos + 2 + image.width()*image.height());
- icon_data[pos++] = image.width();
- icon_data[pos++] = image.height();
- if (sizeof(long) == sizeof(quint32)) {
- memcpy(icon_data.data() + pos, image.scanLine(0), image.byteCount());
- } else {
- for (int y = 0; y < image.height(); ++y) {
- uint *scanLine = reinterpret_cast<uint *>(image.scanLine(y));
- for (int x = 0; x < image.width(); ++x)
- icon_data[pos + y*image.width() + x] = scanLine[x];
- }
- }
- }
- }
- if (!icon_data.isEmpty()) {
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
- /*
- if the app is running on an unknown desktop, or it is not
- using the default visual, convert the icon to 1bpp as stated
- in the ICCCM section 4.1.2.4; otherwise, create the icon pixmap
- in the default depth (even though this violates the ICCCM)
- */
- if (X11->desktopEnvironment == DE_UNKNOWN
- || !QX11Info::appDefaultVisual(xinfo.screen())
- || !QX11Info::appDefaultColormap(xinfo.screen())) {
- // unknown DE or non-default visual/colormap, use 1bpp bitmap
- if (!forceReset || !topData->iconPixmap)
- topData->iconPixmap = new QPixmap(qt_toX11Pixmap(QBitmap(icon.pixmap(QSize(64,64)))));
- pixmap_handle = topData->iconPixmap->handle();
- } else {
- // default depth, use a normal pixmap (even though this
- // violates the ICCCM), since this works on all DEs known to Qt
- if (!forceReset || !topData->iconPixmap)
- topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
- pixmap_handle = static_cast<QX11PlatformPixmap*>(topData->iconPixmap->data.data())->x11ConvertToDefaultDepth();
- }
- }
- }
-
- if (!q->internalWinId())
- return;
-
- if (!icon_data.isEmpty()) {
- XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
- PropModeReplace, (unsigned char *) icon_data.data(),
- icon_data.size());
- } else {
- XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON));
- }
-
- XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
- XWMHints wm_hints;
- if (!h) {
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- h = &wm_hints;
- }
-
- if (pixmap_handle) {
- h->icon_pixmap = pixmap_handle;
- h->flags |= IconPixmapHint;
- } else {
- h->icon_pixmap = 0;
- h->flags &= ~(IconPixmapHint | IconMaskHint);
- }
-
- XSetWMHints(X11->display, q->internalWinId(), h);
- if (h != &wm_hints)
- XFree((char *)h);
-}
-
-void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
-{
- Q_Q(QWidget);
- if (!q->internalWinId())
- return;
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- XSetWMIconName(X11->display, q->internalWinId(), qstring_to_xtp(iconText));
-
- QByteArray icon_name = iconText.toUtf8();
- XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON_NAME), ATOM(UTF8_STRING), 8,
- PropModeReplace, (unsigned char *) icon_name.constData(), icon_name.size());
-}
-
-
-void QWidget::grabMouse()
-{
- if (isVisible() && !qt_nograb()) {
- if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
- QWidgetPrivate::mouseGrabber->releaseMouse();
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-#ifndef QT_NO_DEBUG
- int status =
-#endif
- XGrabPointer(X11->display, effectiveWinId(), False,
- (uint)(ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | EnterWindowMask |
- LeaveWindowMask),
- GrabModeAsync, GrabModeAsync,
- XNone, XNone, X11->time);
-#ifndef QT_NO_DEBUG
- if (status) {
- const char *s =
- status == GrabNotViewable ? "\"GrabNotViewable\"" :
- status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
- status == GrabFrozen ? "\"GrabFrozen\"" :
- status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
- "<?>";
- qWarning("QWidget::grabMouse: Failed with %s", s);
- }
-#endif
- QWidgetPrivate::mouseGrabber = this;
- }
-}
-
-
-#ifndef QT_NO_CURSOR
-void QWidget::grabMouse(const QCursor &cursor)
-{
- if (!qt_nograb()) {
- if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
- QWidgetPrivate::mouseGrabber->releaseMouse();
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-#ifndef QT_NO_DEBUG
- int status =
-#endif
- XGrabPointer(X11->display, effectiveWinId(), False,
- (uint)(ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | EnterWindowMask | LeaveWindowMask),
- GrabModeAsync, GrabModeAsync,
- XNone, cursor.handle(), X11->time);
-#ifndef QT_NO_DEBUG
- if (status) {
- const char *s =
- status == GrabNotViewable ? "\"GrabNotViewable\"" :
- status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
- status == GrabFrozen ? "\"GrabFrozen\"" :
- status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
- "<?>";
- qWarning("QWidget::grabMouse: Failed with %s", s);
- }
-#endif
- QWidgetPrivate::mouseGrabber = this;
- }
-}
-#endif
-
-
-void QWidget::releaseMouse()
-{
- if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
- XUngrabPointer(X11->display, X11->time);
- XFlush(X11->display);
- QWidgetPrivate::mouseGrabber = 0;
- }
-}
-
-
-void QWidget::grabKeyboard()
-{
- if (!qt_nograb()) {
- if (QWidgetPrivate::keyboardGrabber && QWidgetPrivate::keyboardGrabber != this)
- QWidgetPrivate::keyboardGrabber->releaseKeyboard();
- XGrabKeyboard(X11->display, effectiveWinId(), False, GrabModeAsync, GrabModeAsync,
- X11->time);
- QWidgetPrivate::keyboardGrabber = this;
- }
-}
-
-
-void QWidget::releaseKeyboard()
-{
- if (!qt_nograb() && QWidgetPrivate::keyboardGrabber == this) {
- XUngrabKeyboard(X11->display, X11->time);
- QWidgetPrivate::keyboardGrabber = 0;
- }
-}
-
-
-QWidget *QWidget::mouseGrabber()
-{
- return QWidgetPrivate::mouseGrabber;
-}
-
-
-QWidget *QWidget::keyboardGrabber()
-{
- return QWidgetPrivate::keyboardGrabber;
-}
-
-void QWidget::activateWindow()
-{
- QWidget *tlw = window();
- if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) {
- if (X11->userTime == 0)
- X11->userTime = X11->time;
- qt_net_update_user_time(tlw, X11->userTime);
-
- if (X11->isSupportedByWM(ATOM(_NET_ACTIVE_WINDOW))
- && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)) {
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(_NET_ACTIVE_WINDOW);
- e.xclient.display = X11->display;
- e.xclient.window = tlw->internalWinId();
- e.xclient.format = 32;
- e.xclient.data.l[0] = 1; // 1 == application
- e.xclient.data.l[1] = X11->userTime;
- if (QWidget *aw = QApplication::activeWindow())
- e.xclient.data.l[2] = aw->internalWinId();
- else
- e.xclient.data.l[2] = XNone;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
- XSendEvent(X11->display, RootWindow(X11->display, tlw->x11Info().screen()),
- false, SubstructureNotifyMask | SubstructureRedirectMask, &e);
- } else {
- if (!qt_widget_private(tlw)->topData()->waitingForMapNotify)
- XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
- }
- }
-}
-
-void QWidget::setWindowState(Qt::WindowStates newstate)
-{
- Q_D(QWidget);
- bool needShow = false;
- Qt::WindowStates oldstate = windowState();
- if (oldstate == newstate)
- return;
- if (isWindow()) {
- // Ensure the initial size is valid, since we store it as normalGeometry below.
- if (!testAttribute(Qt::WA_Resized) && !isVisible())
- adjustSize();
-
- QTLWExtra *top = d->topData();
-
- if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
- && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))) {
- if ((newstate & Qt::WindowMaximized) && !(oldstate & Qt::WindowFullScreen))
- top->normalGeometry = geometry();
- qt_change_net_wm_state(this, (newstate & Qt::WindowMaximized),
- ATOM(_NET_WM_STATE_MAXIMIZED_HORZ),
- ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
- } else if (! (newstate & Qt::WindowFullScreen)) {
- if (newstate & Qt::WindowMaximized) {
- // save original geometry
- const QRect normalGeometry = geometry();
-
- if (isVisible()) {
- data->fstrut_dirty = true;
- const QRect maxRect = QApplication::desktop()->availableGeometry(this);
- const QRect r = top->normalGeometry;
- const QRect fs = d->frameStrut();
- setGeometry(maxRect.x() + fs.left(),
- maxRect.y() + fs.top(),
- maxRect.width() - fs.left() - fs.right(),
- maxRect.height() - fs.top() - fs.bottom());
- top->normalGeometry = r;
- }
-
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- } else {
- // restore original geometry
- setGeometry(top->normalGeometry);
- }
- }
- }
-
- if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
- if (newstate & Qt::WindowFullScreen) {
- top->normalGeometry = geometry();
- top->fullScreenOffset = d->frameStrut().topLeft();
- }
- qt_change_net_wm_state(this, (newstate & Qt::WindowFullScreen),
- ATOM(_NET_WM_STATE_FULLSCREEN));
- } else {
- needShow = isVisible();
-
- if (newstate & Qt::WindowFullScreen) {
- data->fstrut_dirty = true;
- const QRect normalGeometry = geometry();
- const QPoint fullScreenOffset = d->frameStrut().topLeft();
-
- top->savedFlags = windowFlags();
- setParent(0, Qt::Window | Qt::FramelessWindowHint);
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->screenGeometry(this));
- top->normalGeometry = r;
-
- if (top->normalGeometry.width() < 0) {
- top->normalGeometry = normalGeometry;
- top->fullScreenOffset = fullScreenOffset;
- }
- } else {
- setParent(0, top->savedFlags);
-
- if (newstate & Qt::WindowMaximized) {
- // from fullscreen to maximized
- data->fstrut_dirty = true;
- const QRect maxRect = QApplication::desktop()->availableGeometry(this);
- const QRect r = top->normalGeometry;
- const QRect fs = d->frameStrut();
- setGeometry(maxRect.x() + fs.left(),
- maxRect.y() + fs.top(),
- maxRect.width() - fs.left() - fs.right(),
- maxRect.height() - fs.top() - fs.bottom());
- top->normalGeometry = r;
- } else {
- // restore original geometry
- setGeometry(top->normalGeometry.adjusted(-top->fullScreenOffset.x(),
- -top->fullScreenOffset.y(),
- -top->fullScreenOffset.x(),
- -top->fullScreenOffset.y()));
- }
- }
- }
- }
-
- createWinId();
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
- if (isVisible()) {
- if (newstate & Qt::WindowMinimized) {
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(WM_CHANGE_STATE);
- e.xclient.display = X11->display;
- e.xclient.window = data->winid;
- e.xclient.format = 32;
- e.xclient.data.l[0] = IconicState;
- e.xclient.data.l[1] = 0;
- e.xclient.data.l[2] = 0;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
- XSendEvent(X11->display,
- RootWindow(X11->display,d->xinfo.screen()),
- False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
- } else {
- setAttribute(Qt::WA_Mapped);
- XMapWindow(X11->display, effectiveWinId());
- }
- }
-
- needShow = false;
- }
- }
-
- data->window_state = newstate;
-
- if (needShow)
- show();
-
- if (newstate & Qt::WindowActive)
- activateWindow();
-
- QWindowStateChangeEvent e(oldstate);
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- \internal
- Platform-specific part of QWidget::show().
-*/
-
-void QWidgetPrivate::show_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
-
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- invalidateBuffer(q->rect());
- q->setAttribute(Qt::WA_Mapped);
- if (QTLWExtra *tlwExtra = maybeTopData())
- tlwExtra->waitingForMapNotify = 0;
- return;
- }
-
- if (q->isWindow()) {
- XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
- XWMHints wm_hints;
- bool got_hints = h != 0;
- if (!got_hints) {
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- h = &wm_hints;
- }
- h->initial_state = q->isMinimized() ? IconicState : NormalState;
- h->flags |= StateHint;
- XSetWMHints(X11->display, q->internalWinId(), h);
- if (got_hints)
- XFree((char *)h);
-
- // update WM_NORMAL_HINTS
- do_size_hints(q, extra);
-
- // udpate WM_TRANSIENT_FOR
- if (isTransient(q)) {
- QWidget *p = q->parentWidget();
-
-#ifndef QT_NO_MENU
- // hackish ... try to find the main window related to this QMenu
- if (qobject_cast<QMenu *>(q)) {
- p = static_cast<QMenuPrivate*>(this)->causedPopup.widget;
- if (!p)
- p = q->parentWidget();
- if (!p)
- p = QApplication::widgetAt(q->pos());
- if (!p)
- p = qApp->activeWindow();
- }
-#endif
- if (p)
- p = p->window();
- if (p) {
- // transient for window
- XSetTransientForHint(X11->display, q->internalWinId(), p->internalWinId());
- } else {
- // transient for group
- XSetTransientForHint(X11->display, q->internalWinId(), X11->wm_client_leader);
- }
- }
-
- // update _MOTIF_WM_HINTS
- QtMWMHints mwmhints = GetMWMHints(X11->display, q->internalWinId());
-
- if (data.window_modality != Qt::NonModal) {
- switch (data.window_modality) {
- case Qt::WindowModal:
- mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
- break;
- case Qt::ApplicationModal:
- default:
- mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
- break;
- }
- mwmhints.flags |= MWM_HINTS_INPUT_MODE;
- } else {
- mwmhints.input_mode = MWM_INPUT_MODELESS;
- mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
- }
-
- if (q->minimumSize() == q->maximumSize()) {
- // fixed size, remove the resize handle (since mwm/dtwm
- // isn't smart enough to do it itself)
- mwmhints.flags |= MWM_HINTS_FUNCTIONS;
- if (mwmhints.functions == MWM_FUNC_ALL) {
- mwmhints.functions = MWM_FUNC_MOVE;
- } else {
- mwmhints.functions &= ~MWM_FUNC_RESIZE;
- }
-
- if (mwmhints.decorations == MWM_DECOR_ALL) {
- mwmhints.flags |= MWM_HINTS_DECORATIONS;
- mwmhints.decorations = (MWM_DECOR_BORDER
- | MWM_DECOR_TITLE
- | MWM_DECOR_MENU);
- } else {
- mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
- }
-
- if (q->windowFlags() & Qt::WindowMinimizeButtonHint) {
- mwmhints.flags |= MWM_HINTS_DECORATIONS;
- mwmhints.decorations |= MWM_DECOR_MINIMIZE;
- mwmhints.functions |= MWM_FUNC_MINIMIZE;
- }
- if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
- mwmhints.flags |= MWM_HINTS_DECORATIONS;
- mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
- mwmhints.functions |= MWM_FUNC_MAXIMIZE;
- }
- if (q->windowFlags() & Qt::WindowCloseButtonHint)
- mwmhints.functions |= MWM_FUNC_CLOSE;
- }
-
- SetMWMHints(X11->display, q->internalWinId(), mwmhints);
-
- // update _NET_WM_STATE
- QVector<Atom> netWmState = getNetWmState(q);
-
- Qt::WindowFlags flags = q->windowFlags();
- if (flags & Qt::WindowStaysOnTopHint) {
- if (flags & Qt::WindowStaysOnBottomHint)
- qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
- if (!netWmState.contains(ATOM(_NET_WM_STATE_ABOVE)))
- netWmState.append(ATOM(_NET_WM_STATE_ABOVE));
- if (!netWmState.contains(ATOM(_NET_WM_STATE_STAYS_ON_TOP)))
- netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP));
- } else if (flags & Qt::WindowStaysOnBottomHint) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_BELOW)))
- netWmState.append(ATOM(_NET_WM_STATE_BELOW));
- }
- if (q->isFullScreen()) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_FULLSCREEN)))
- netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN));
- }
- if (q->isMaximized()) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
- netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ));
- if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))
- netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
- }
- if (data.window_modality != Qt::NonModal) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_MODAL)))
- netWmState.append(ATOM(_NET_WM_STATE_MODAL));
- }
-
- if (!netWmState.isEmpty()) {
- XChangeProperty(X11->display, q->internalWinId(),
- ATOM(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace,
- (unsigned char *) netWmState.data(), netWmState.size());
- } else {
- XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_STATE));
- }
-
- // set _NET_WM_USER_TIME
- Time userTime = X11->userTime;
- bool setUserTime = false;
- if (q->testAttribute(Qt::WA_ShowWithoutActivating)) {
- userTime = 0;
- setUserTime = true;
- } else if (userTime != CurrentTime) {
- setUserTime = true;
- }
- if (setUserTime)
- qt_net_update_user_time(q, userTime);
-
-#ifndef QT_NO_XSYNC
- if (!topData()->syncUpdateCounter) {
- XSyncValue value;
- XSyncIntToValue(&value, 0);
- topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);
-
- XChangeProperty(X11->display, q->internalWinId(),
- ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
- XA_CARDINAL,
- 32, PropModeReplace,
- (uchar *) &topData()->syncUpdateCounter, 1);
-
- topData()->newCounterValueHi = 0;
- topData()->newCounterValueLo = 0;
- }
-#endif
-
- if (!topData()->embedded
- && (topData()->validWMState || topData()->waitingForMapNotify)
- && !q->isMinimized()) {
- X11->deferred_map.append(q);
- return;
- }
-
- if (q->isMaximized() && !q->isFullScreen()
- && !(X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
- && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))) {
- XMapWindow(X11->display, q->internalWinId());
- data.fstrut_dirty = true;
- qt_x11_wait_for_window_manager(q);
-
- // if the wm was not smart enough to adjust our size, do that manually
- QRect maxRect = QApplication::desktop()->availableGeometry(q);
-
- QTLWExtra *top = topData();
- QRect normalRect = top->normalGeometry;
- const QRect fs = frameStrut();
-
- q->setGeometry(maxRect.x() + fs.left(),
- maxRect.y() + fs.top(),
- maxRect.width() - fs.left() - fs.right(),
- maxRect.height() - fs.top() - fs.bottom());
-
- // restore the original normalGeometry
- top->normalGeometry = normalRect;
- // internalSetGeometry() clears the maximized flag... make sure we set it back
- data.window_state = data.window_state | Qt::WindowMaximized;
- q->setAttribute(Qt::WA_Mapped);
- return;
- }
-
- if (q->isFullScreen() && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
- XMapWindow(X11->display, q->internalWinId());
- qt_x11_wait_for_window_manager(q);
- q->setAttribute(Qt::WA_Mapped);
- return;
- }
- }
-
- invalidateBuffer(q->rect());
-
- if (q->testAttribute(Qt::WA_OutsideWSRange))
- return;
- q->setAttribute(Qt::WA_Mapped);
- if (q->isWindow())
- topData()->waitingForMapNotify = 1;
-
- if (!q->isWindow()
- && (!q->autoFillBackground()
- || q->palette().brush(q->backgroundRole()).style() == Qt::LinearGradientPattern)) {
- if (q->internalWinId()) {
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
- XMapWindow(X11->display, q->internalWinId());
- updateSystemBackground();
- }
- return;
- }
-
- if (q->internalWinId())
- XMapWindow(X11->display, q->internalWinId());
-
- // Freedesktop.org Startup Notification
- if (X11->startupId && q->isWindow()) {
- QByteArray message("remove: ID=");
- message.append(X11->startupId);
- sendStartupMessage(message.constData());
- X11->startupId = 0;
- }
-}
-
-/*!
- \internal
- Platform-specific part of QWidget::show().
-*/
-
-void QWidgetPrivate::sendStartupMessage(const char *message) const
-{
- Q_Q(const QWidget);
-
- if (!message)
- return;
-
- XEvent xevent;
- xevent.xclient.type = ClientMessage;
- xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO_BEGIN);
- xevent.xclient.display = X11->display;
- xevent.xclient.window = q->internalWinId();
- xevent.xclient.format = 8;
-
- Window rootWindow = RootWindow(X11->display, DefaultScreen(X11->display));
- uint sent = 0;
- uint length = strlen(message) + 1;
- do {
- if (sent == 20)
- xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO);
-
- for (uint i = 0; i < 20 && i + sent <= length; i++)
- xevent.xclient.data.b[i] = message[i + sent++];
-
- XSendEvent(X11->display, rootWindow, false, PropertyChangeMask, &xevent);
- } while (sent <= length);
-}
-
-void QWidgetPrivate::setNetWmWindowTypes()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
-
- if (!q->isWindow()) {
- if (q->internalWinId())
- XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_WINDOW_TYPE));
- return;
- }
-
- QVector<long> windowTypes;
-
- // manual selection 1 (these are never set by Qt and take precedence)
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DESKTOP));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DOCK));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NOTIFICATION));
-
- // manual selection 2 (Qt uses these during auto selection);
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
-
- // manual selection 3 (these can be set by Qt, but don't have a
- // corresponding Qt::WindowType). note that order of the *MENU
- // atoms is important
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_MENU));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_POPUP_MENU));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_COMBO));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DND));
-
- // automatic selection
- switch (q->windowType()) {
- case Qt::Dialog:
- case Qt::Sheet:
- // dialog netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
- break;
-
- case Qt::Tool:
- case Qt::Drawer:
- // utility netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
- break;
-
- case Qt::ToolTip:
- // tooltip netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
- break;
-
- case Qt::SplashScreen:
- // splash netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
- break;
-
- default:
- break;
- }
-
- if (q->windowFlags() & Qt::FramelessWindowHint) {
- // override netwm type - quick and easy for KDE noborder
- windowTypes.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
- }
-
- // normal netwm type - default
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NORMAL));
-
- if (!windowTypes.isEmpty()) {
- XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE), XA_ATOM, 32,
- PropModeReplace, (unsigned char *) windowTypes.constData(),
- windowTypes.count());
- } else {
- XDeleteProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE));
- }
-}
-
-/*!
- \internal
- Platform-specific part of QWidget::hide().
-*/
-
-void QWidgetPrivate::hide_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- deactivateWidgetCleanup();
- if (q->isWindow()) {
- X11->deferred_map.removeAll(q);
- if (q->internalWinId()) // in nsplugin, may be 0
- XWithdrawWindow(X11->display, q->internalWinId(), xinfo.screen());
- XFlush(X11->display);
- } else {
- invalidateBuffer(q->rect());
- if (q->internalWinId()) // in nsplugin, may be 0
- XUnmapWindow(X11->display, q->internalWinId());
- }
- q->setAttribute(Qt::WA_Mapped, false);
-}
-
-void QWidgetPrivate::setFocus_sys()
-{
-
-}
-
-
-void QWidgetPrivate::raise_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (q->internalWinId())
- XRaiseWindow(X11->display, q->internalWinId());
-}
-
-void QWidgetPrivate::lower_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (q->internalWinId())
- XLowerWindow(X11->display, q->internalWinId());
- if(!q->isWindow())
- 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()) {
- Window stack[2];
- stack[0] = w->internalWinId();;
- stack[1] = q->internalWinId();
- XRestackWindows(X11->display, stack, 2);
- }
- if(!q->isWindow() || !w->internalWinId())
- invalidateBuffer(q->rect());
-}
-
-
-static void do_size_hints(QWidget* widget, QWExtra *x)
-{
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- XSizeHints s;
- s.flags = 0;
- if (x) {
- QRect g = widget->geometry();
- s.x = g.x();
- s.y = g.y();
- s.width = g.width();
- s.height = g.height();
- if (x->minw > 0 || x->minh > 0) {
- // add minimum size hints
- s.flags |= PMinSize;
- s.min_width = qMin(XCOORD_MAX, x->minw);
- s.min_height = qMin(XCOORD_MAX, x->minh);
- }
- if (x->maxw < QWIDGETSIZE_MAX || x->maxh < QWIDGETSIZE_MAX) {
- // add maximum size hints
- s.flags |= PMaxSize;
- s.max_width = qMin(XCOORD_MAX, x->maxw);
- s.max_height = qMin(XCOORD_MAX, x->maxh);
- }
- if (x->topextra &&
- (x->topextra->incw > 0 || x->topextra->inch > 0)) {
- // add resize increment hints
- s.flags |= PResizeInc | PBaseSize;
- s.width_inc = x->topextra->incw;
- s.height_inc = x->topextra->inch;
- s.base_width = x->topextra->basew;
- s.base_height = x->topextra->baseh;
- }
- }
- if (widget->testAttribute(Qt::WA_Moved)) {
- // user (i.e. command-line) specified position
- s.flags |= USPosition;
- s.flags |= PPosition;
- }
- if (widget->testAttribute(Qt::WA_Resized)) {
- // user (i.e. command-line) specified size
- s.flags |= USSize;
- s.flags |= PSize;
- }
- s.flags |= PWinGravity;
- if (widget->testAttribute(Qt::WA_Moved) && x && x->topextra && !x->topextra->posFromMove) {
- // position came from setGeometry(), tell the WM that we don't
- // want our window gravity-shifted
- s.win_gravity = StaticGravity;
- } else {
- // position came from move()
- s.x = widget->x();
- s.y = widget->y();
- s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
- }
- if (widget->internalWinId())
- XSetWMNormalHints(X11->display, widget->internalWinId(), &s);
-}
-
-
-/*
- Helper function for non-toplevel widgets. Helps to map Qt's 32bit
- coordinate system to X11's 16bit coordinate system.
-
- Sets the geometry of the widget to data.crect, but clipped to sizes
- that X can handle. Unmaps widgets that are completely outside the
- valid range.
-
- Maintains data.wrect, which is the geometry of the X widget,
- measured in this widget's coordinate system.
-
- if the parent is not clipped, parentWRect is empty, otherwise
- parentWRect is the geometry of the parent's X rect, measured in
- parent's coord sys
- */
-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).
- */
- Display *dpy = xinfo.display();
- 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 (data.winid)
- XMoveWindow(dpy, data.winid, xrect.x(), xrect.y());
- 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 (data.winid)
- XUnmapWindow(dpy, data.winid);
- 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...
- // ### can be optimized
- 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(jump);
- }
- }
-
- if (data.winid) {
- // 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 (jump) //avoid flicker when jumping
- XSetWindowBackgroundPixmap(dpy, data.winid, XNone);
- if (!parent->internalWinId())
- xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
- XMoveResizeWindow(dpy, data.winid, xrect.x(), xrect.y(), xrect.width(), xrect.height());
- }
-
- //to avoid flicker, we have to show children after the helper widget has moved
- if (jump) {
- for (int i = 0; i < children.size(); ++i) {
- QObject *object = children.at(i);
- if (object->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(object);
- if (!w->testAttribute(Qt::WA_OutsideWSRange) && !w->testAttribute(Qt::WA_Mapped) && !w->isHidden()) {
- w->setAttribute(Qt::WA_Mapped);
- if (w->internalWinId())
- XMapWindow(dpy, w->data->winid);
- }
- }
- }
- }
-
-
- if (jump && data.winid)
- XClearArea(dpy, data.winid, 0, 0, wrect.width(), wrect.height(), True);
-
- if (mapWindow && !dontShow) {
- q->setAttribute(Qt::WA_Mapped);
- if (data.winid)
- XMapWindow(dpy, data.winid);
- }
-}
-
-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));
- Display *dpy = X11->display;
-
- if ((q->windowType() == Qt::Desktop))
- return;
- if (q->isWindow()) {
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
- data.window_state &= ~Qt::WindowMaximized;
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
- data.window_state &= ~Qt::WindowFullScreen;
- if (QTLWExtra *topData = maybeTopData())
- topData->normalGeometry = QRect(0,0,-1,-1);
- } else {
- uint s = data.window_state;
- s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen);
- data.window_state = s;
- }
- 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);
- }
- QPoint oldPos(q->pos());
- QSize oldSize(q->size());
- QRect oldGeom(data.crect);
- QRect r(x, y, w, h);
-
- // We only care about stuff that changes the geometry, or may
- // cause the window manager to change its state
- if (!q->isWindow() && oldGeom == r)
- return;
-
- data.crect = r;
- bool isResize = q->size() != oldSize;
-
- if (q->isWindow()) {
- if (w == 0 || h == 0) {
- q->setAttribute(Qt::WA_OutsideWSRange, true);
- if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
- hide_sys();
- } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
- q->setAttribute(Qt::WA_OutsideWSRange, false);
-
- // put the window in its place and show it
- if (data.winid)
- XMoveResizeWindow(dpy, data.winid, x, y, w, h);
- topData()->posFromMove = false; // force StaticGravity
- do_size_hints(q, extra);
- show_sys();
- } else {
- q->setAttribute(Qt::WA_OutsideWSRange, false);
- if (!q->isVisible())
- do_size_hints(q, extra);
- if (isMove) {
- if ((data.window_flags & Qt::X11BypassWindowManagerHint) == Qt::X11BypassWindowManagerHint
- // work around 4Dwm's incompliance with ICCCM 4.1.5
- || X11->desktopEnvironment == DE_4DWM) {
- if (data.winid)
- XMoveResizeWindow(dpy, data.winid, x, y, w, h);
- } else if (q->isVisible()
- && topData()->validWMState
- && X11->isSupportedByWM(ATOM(_NET_MOVERESIZE_WINDOW))) {
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(_NET_MOVERESIZE_WINDOW);
- e.xclient.display = X11->display;
- e.xclient.window = q->internalWinId();
- e.xclient.format = 32;
- e.xclient.data.l[0] = StaticGravity | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12;
- e.xclient.data.l[1] = x;
- e.xclient.data.l[2] = y;
- e.xclient.data.l[3] = w;
- e.xclient.data.l[4] = h;
- XSendEvent(X11->display, RootWindow(X11->display, q->x11Info().screen()),
- false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
- } else if (data.winid) {
- // pos() is right according to ICCCM 4.1.5
- XMoveResizeWindow(dpy, data.winid, q->pos().x(), q->pos().y(), w, h);
- }
- } else if (isResize && data.winid) {
- if (!q->isVisible()
- && topData()->validWMState
- && !q->testAttribute(Qt::WA_PendingMoveEvent)) {
- /*
- even though we've not visible, we could be in a
- race w/ the window manager, and it may ignore
- our ConfigureRequest. setting posFromMove to
- false makes sure that doDeferredMap() in
- qapplication_x11.cpp keeps the window in the
- right place
- */
- topData()->posFromMove = false;
- }
- XResizeWindow(dpy, data.winid, w, h);
- }
- }
- if (isResize && !q->testAttribute(Qt::WA_DontShowOnScreen)) // set config pending only on resize, see qapplication_x11.cpp, translateConfigEvent()
- q->setAttribute(Qt::WA_WState_ConfigPending);
-
- } else {
- QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
- const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
- const bool disableInTopLevelResize = inTopLevelResize && q->internalWinId();
- if (disableInTopLevelResize) {
- // Top-level resize optimization does not work for native child widgets;
- // disable it for this particular widget.
- tlwExtra->inTopLevelResize = false;
- }
-
- if (!isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible()) {
- moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
- }
- if (q->testAttribute(Qt::WA_WState_Created))
- setWSGeometry();
-
- if (isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible())
- invalidateBuffer_resizeHelper(oldPos, oldSize);
-
- if (disableInTopLevelResize)
- tlwExtra->inTopLevelResize = true;
- }
-
- if (q->isVisible()) {
- if (isMove && q->pos() != oldPos) {
- if (X11->desktopEnvironment != DE_4DWM) {
- // pos() is right according to ICCCM 4.1.5
- QMoveEvent e(q->pos(), oldPos);
- QApplication::sendEvent(q, &e);
- } else {
- // work around 4Dwm's incompliance with ICCCM 4.1.5
- QMoveEvent e(data.crect.topLeft(), oldGeom.topLeft());
- 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);
- }
-}
-
-void QWidgetPrivate::setConstraints_sys()
-{
- Q_Q(QWidget);
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setConstraints_sys START" << q;
-#endif
- if (q->testAttribute(Qt::WA_WState_Created))
- do_size_hints(q, extra);
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setConstraints_sys END" << q;
-#endif
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy)
-{
- Q_Q(QWidget);
-
- scrollChildren(dx, dy);
- if (!paintOnScreen()) {
- scrollRect(q->rect(), dx, dy);
- } else {
- scroll_sys(dx, dy, QRect());
- }
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
-{
- Q_Q(QWidget);
-
- if (!paintOnScreen()) {
- scrollRect(r, dx, dy);
- return;
- }
- bool valid_rect = r.isValid();
- bool just_update = qAbs(dx) > q->width() || qAbs(dy) > q->height();
- QRect sr = valid_rect ? r : clipRect();
- if (just_update)
- q->update();
- else if (!valid_rect)
- dirty.translate(dx, dy);
-
- int x1, y1, x2, y2, w = sr.width(), h = sr.height();
- if (dx > 0) {
- x1 = sr.x();
- x2 = x1+dx;
- w -= dx;
- } else {
- x2 = sr.x();
- x1 = x2-dx;
- w += dx;
- }
- if (dy > 0) {
- y1 = sr.y();
- y2 = y1+dy;
- h -= dy;
- } else {
- y2 = sr.y();
- y1 = y2-dy;
- h += dy;
- }
-
- if (dx == 0 && dy == 0)
- return;
-
- Display *dpy = X11->display;
- // Want expose events
- if (w > 0 && h > 0 && !just_update && q->internalWinId()) {
- GC gc = XCreateGC(dpy, q->internalWinId(), 0, 0);
- XSetGraphicsExposures(dpy, gc, True);
- XCopyArea(dpy, q->internalWinId(), q->internalWinId(), gc, x1, y1, w, h, x2, y2);
- XFreeGC(dpy, gc);
- }
-
- if (!valid_rect && !children.isEmpty()) { // scroll children
- QPoint pd(dx, dy);
- for (int i = 0; i < children.size(); ++i) { // move all children
- register QObject *object = children.at(i);
- if (object->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(object);
- if (!w->isWindow())
- w->move(w->pos() + pd);
- }
- }
- }
-
- if (just_update)
- return;
-
- // Don't let the server be bogged-down with repaint events
- bool repaint_immediately = (qt_sip_count(q) < 3 && !q->testAttribute(Qt::WA_WState_InPaintEvent));
-
- if (dx) {
- int x = x2 == sr.x() ? sr.x()+w : sr.x();
- if (repaint_immediately)
- q->repaint(x, sr.y(), qAbs(dx), sr.height());
- else if (q->internalWinId())
- XClearArea(dpy, data.winid, x, sr.y(), qAbs(dx), sr.height(), True);
- }
- if (dy) {
- int y = y2 == sr.y() ? sr.y()+h : sr.y();
- if (repaint_immediately)
- q->repaint(sr.x(), y, sr.width(), qAbs(dy));
- else if (q->internalWinId())
- XClearArea(dpy, data.winid, sr.x(), y, sr.width(), qAbs(dy), True);
- }
-
- qt_insert_sip(q, dx, dy); // #### ignores r
-}
-
-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 {
- Display *dpy = X11->display;
- int scr = d->xinfo.screen();
- 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 = QX11Info::appDpiX(scr);
- 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 = QX11Info::appDpiY(scr);
- break;
- case PdmWidthMM:
- val = (DisplayWidthMM(dpy,scr)*data->crect.width())/
- DisplayWidth(dpy,scr);
- break;
- case PdmHeightMM:
- val = (DisplayHeightMM(dpy,scr)*data->crect.height())/
- DisplayHeight(dpy,scr);
- break;
- case PdmNumColors:
- val = d->xinfo.cells();
- break;
- case PdmDepth:
- val = d->xinfo.depth();
- break;
- default:
- val = 0;
- qWarning("QWidget::metric: Invalid metric command");
- }
- }
- return val;
-}
-
-void QWidgetPrivate::createSysExtra()
-{
- extra->compress_events = true;
- extra->xDndProxy = 0;
-}
-
-void QWidgetPrivate::deleteSysExtra()
-{
-}
-
-void QWidgetPrivate::createTLSysExtra()
-{
- extra->topextra->spont_unmapped = 0;
- extra->topextra->dnd = 0;
- extra->topextra->validWMState = 0;
- extra->topextra->waitingForMapNotify = 0;
- extra->topextra->parentWinId = 0;
- extra->topextra->userTimeWindow = 0;
-#ifndef QT_NO_XSYNC
- extra->topextra->syncUpdateCounter = 0;
- extra->topextra->syncRequestTimestamp = 0;
- extra->topextra->newCounterValueHi = 0;
- extra->topextra->newCounterValueLo = 0;
-#endif
-}
-
-void QWidgetPrivate::deleteTLSysExtra()
-{
- // don't destroy input context here. it will be destroyed in
- // QWidget::destroy() destroyInputContext();
-}
-
-void QWidgetPrivate::registerDropSite(bool on)
-{
- Q_UNUSED(on);
-}
-
-void QWidgetPrivate::setMask_sys(const QRegion &region)
-{
- Q_Q(QWidget);
- if (!q->internalWinId())
- return;
-
- if (region.isEmpty()) {
- XShapeCombineMask(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
- XNone, ShapeSet);
- } else {
- XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
- region.handle(), ShapeSet);
- }
-}
-
-/*!
- \internal
-
- Computes the frame rectangle when needed. This is an internal function, you
- should never call this.
-*/
-
-void QWidgetPrivate::updateFrameStrut()
-{
- Q_Q(QWidget);
-
- QTLWExtra *top = topData();
- if (!top->validWMState) {
- return;
- }
- if (!q->isWindow() && !q->internalWinId()) {
- data.fstrut_dirty = false;
- return;
- }
-
- Atom type_ret;
- Window l = q->effectiveWinId(), w = l, p, r; // target window, its parent, root
- Window *c;
- int i_unused;
- unsigned int nc;
- unsigned char *data_ret;
- unsigned long l_unused;
-
- while (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
- if (c && nc > 0)
- XFree(c);
-
- if (! p) {
- qWarning("QWidget::updateFrameStrut: No parent");
- return;
- }
-
- // if the parent window is the root window, an Enlightenment virtual root or
- // a NET WM virtual root window, stop here
- data_ret = 0;
- if (p == r ||
- (XGetWindowProperty(X11->display, p,
- ATOM(ENLIGHTENMENT_DESKTOP), 0, 1, False, XA_CARDINAL,
- &type_ret, &i_unused, &l_unused, &l_unused,
- &data_ret) == Success &&
- type_ret == XA_CARDINAL)) {
- if (data_ret)
- XFree(data_ret);
-
- break;
- } else if (X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)) && X11->net_virtual_root_list) {
- int i = 0;
- while (X11->net_virtual_root_list[i] != 0) {
- if (X11->net_virtual_root_list[i++] == p)
- break;
- }
- }
-
- l = w;
- w = p;
- }
-
- // we have our window
- int transx, transy;
- XWindowAttributes wattr;
- if (XTranslateCoordinates(X11->display, l, w,
- 0, 0, &transx, &transy, &p) &&
- XGetWindowAttributes(X11->display, w, &wattr)) {
- top->frameStrut.setCoords(transx,
- transy,
- wattr.width - data.crect.width() - transx,
- wattr.height - data.crect.height() - transy);
-
- // add the border_width for the window managers frame... some window managers
- // do not use a border_width of zero for their frames, and if we the left and
- // top strut, we ensure that pos() is absolutely correct. frameGeometry()
- // will still be incorrect though... perhaps i should have foffset as well, to
- // indicate the frame offset (equal to the border_width on X).
- // - Brad
- top->frameStrut.adjust(wattr.border_width,
- wattr.border_width,
- wattr.border_width,
- wattr.border_width);
- }
-
- data.fstrut_dirty = false;
-}
-
-void QWidgetPrivate::setWindowOpacity_sys(qreal opacity)
-{
- Q_Q(QWidget);
- ulong value = ulong(opacity * 0xffffffff);
- XChangeProperty(QX11Info::display(), q->internalWinId(), ATOM(_NET_WM_WINDOW_OPACITY), XA_CARDINAL,
- 32, PropModeReplace, (uchar*)&value, 1);
-}
-
-const QX11Info &QWidget::x11Info() const
-{
- Q_D(const QWidget);
- return d->xinfo;
-}
-
-void QWidgetPrivate::setWindowRole()
-{
- Q_Q(QWidget);
- if (!q->internalWinId())
- return;
- QByteArray windowRole = topData()->role.toUtf8();
- XChangeProperty(X11->display, q->internalWinId(),
- ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
- (unsigned char *)windowRole.constData(), windowRole.length());
-}
-
-Q_GLOBAL_STATIC(QX11PaintEngine, qt_widget_paintengine)
-QPaintEngine *QWidget::paintEngine() const
-{
- Q_D(const QWidget);
- if (qt_widget_paintengine()->isActive()) {
- if (d->extraPaintEngine)
- return d->extraPaintEngine;
- QWidget *self = const_cast<QWidget *>(this);
- self->d_func()->extraPaintEngine = new QX11PaintEngine();
- return d->extraPaintEngine;
- }
- return qt_widget_paintengine();
-}
-
-QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
-{
- return new QX11WindowSurface(q_func());
-}
-
-Qt::HANDLE QWidget::x11PictureHandle() const
-{
-#ifndef QT_NO_XRENDER
- Q_D(const QWidget);
- if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
- (void)winId(); // enforce native window
- return d->picture;
-#else
- return 0;
-#endif // QT_NO_XRENDER
-}
-
-#ifndef QT_NO_XRENDER
-XRenderColor QX11Data::preMultiply(const QColor &c)
-{
- XRenderColor color;
- const uint A = c.alpha(),
- R = c.red(),
- G = c.green(),
- B = c.blue();
- color.alpha = (A | A << 8);
- color.red = (R | R << 8) * color.alpha / 0x10000;
- color.green = (G | G << 8) * color.alpha / 0x10000;
- color.blue = (B | B << 8) * color.alpha / 0x10000;
- return color;
-}
-Picture QX11Data::getSolidFill(int screen, const QColor &c)
-{
- if (!X11->use_xrender)
- return XNone;
-
- XRenderColor color = preMultiply(c);
- for (int i = 0; i < X11->solid_fill_count; ++i) {
- if (X11->solid_fills[i].screen == screen
- && X11->solid_fills[i].color.alpha == color.alpha
- && X11->solid_fills[i].color.red == color.red
- && X11->solid_fills[i].color.green == color.green
- && X11->solid_fills[i].color.blue == color.blue)
- return X11->solid_fills[i].picture;
- }
- // none found, replace one
- int i = qrand() % 16;
-
- if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
- XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
- X11->solid_fills[i].picture = 0;
- }
-
- if (!X11->solid_fills[i].picture) {
- Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
- XRenderPictureAttributes attrs;
- attrs.repeat = True;
- X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32),
- CPRepeat, &attrs);
- XFreePixmap (X11->display, pixmap);
- }
-
- X11->solid_fills[i].color = color;
- X11->solid_fills[i].screen = screen;
- XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
- return X11->solid_fills[i].picture;
-}
-#endif
-
-void QWidgetPrivate::setModal_sys()
-{
-}
-
-void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &att)
-{
- QX11InfoData* xd = xinfo->getX11Data(true);
- const XWindowAttributes &a = *(att.att);
- // find which screen the window is on...
- xd->screen = QX11Info::appScreen(); // by default, use the default :)
- int i;
- for (i = 0; i < ScreenCount(X11->display); i++) {
- if (RootWindow(X11->display, i) == a.root) {
- xd->screen = i;
- break;
- }
- }
-
- xd->depth = a.depth;
- xd->cells = DisplayCells(X11->display, xd->screen);
- xd->visual = a.visual;
- xd->defaultVisual = (XVisualIDFromVisual((Visual *) a.visual) ==
- XVisualIDFromVisual((Visual *) QX11Info::appVisual(xinfo->screen())));
- xd->colormap = a.colormap;
- xd->defaultColormap = (a.colormap == QX11Info::appColormap(xinfo->screen()));
- xinfo->setX11Data(xd);
-}
-
-void QWidgetPrivate::updateX11AcceptFocus()
-{
- Q_Q(QWidget);
- if (!q->isWindow() || !q->internalWinId())
- return;
-
- XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
- XWMHints wm_hints;
- if (!h) {
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- h = &wm_hints;
- }
- h->flags |= InputHint;
- h->input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
-
- XSetWMHints(X11->display, q->internalWinId(), h);
- if (h != &wm_hints)
- XFree((char *)h);
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qwidgetcreate_x11.cpp b/src/widgets/platforms/x11/qwidgetcreate_x11.cpp
deleted file mode 100644
index 0a0656dd2b..0000000000
--- a/src/widgets/platforms/x11/qwidgetcreate_x11.cpp
+++ /dev/null
@@ -1,79 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwidget.h"
-#include "qt_x11_p.h"
-
-/*
- Internal Qt functions to create X windows. We have put them in
- separate functions to allow the programmer to reimplement them by
- custom versions.
-*/
-
-QT_BEGIN_NAMESPACE
-
-Window qt_XCreateWindow(const QWidget *, Display *display, Window parent,
- int x, int y, uint w, uint h,
- int borderwidth, int depth,
- uint windowclass, Visual *visual,
- ulong valuemask, XSetWindowAttributes *attributes)
-{
- return XCreateWindow(display, parent, x, y, w, h, borderwidth, depth,
- windowclass, visual, valuemask, attributes);
-}
-
-
-Window qt_XCreateSimpleWindow(const QWidget *, Display *display, Window parent,
- int x, int y, uint w, uint h, int borderwidth,
- ulong border, ulong background)
-{
- return XCreateSimpleWindow(display, parent, x, y, w, h, borderwidth,
- border, background);
-}
-
-
-void qt_XDestroyWindow(const QWidget *, Display *display, Window window)
-{
- if (window)
- XDestroyWindow(display, window);
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qx11embed_x11.cpp b/src/widgets/platforms/x11/qx11embed_x11.cpp
deleted file mode 100644
index 3213b97629..0000000000
--- a/src/widgets/platforms/x11/qx11embed_x11.cpp
+++ /dev/null
@@ -1,1810 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qx11embed_x11.h"
-#include <qapplication.h>
-#include <qevent.h>
-#include <qpainter.h>
-#include <qlayout.h>
-#include <qstyle.h>
-#include <qstyleoption.h>
-#include <qelapsedtimer.h>
-#include <qpointer.h>
-#include <qdebug.h>
-#include <qx11info_x11.h>
-#include <private/qt_x11_p.h>
-#include <private/qwidget_p.h>
-
-#define XK_MISCELLANY
-#define XK_LATIN1
-#define None 0
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/keysymdef.h>
-#include <X11/X.h>
-
-#ifndef XK_ISO_Left_Tab
-#define XK_ISO_Left_Tab 0xFE20
-#endif
-
-//#define QX11EMBED_DEBUG
-#ifdef QX11EMBED_DEBUG
-#include <qdebug.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QX11EmbedWidget
- \ingroup advanced
- \inmodule QtWidgets
-
- \brief The QX11EmbedWidget class provides an XEmbed client widget.
-
- XEmbed is an X11 protocol that supports the embedding of a widget
- from one application into another application.
-
- An XEmbed \e{client widget} is a window that is embedded into a
- \e container. A container is the graphical location that embeds
- (or \e swallows) an external application.
-
- QX11EmbedWidget is a widget used for writing XEmbed applets or
- plugins. When it has been embedded and the container receives tab
- focus, focus is passed on to the widget. When the widget reaches
- the end of its focus chain, focus is passed back to the
- container. Window activation, accelerator support, modality and
- drag and drop (XDND) are also handled.
-
- The widget and container can both initiate the embedding. If the
- widget is the initiator, the X11 window ID of the container that
- it wants to embed itself into must be passed to embedInto().
-
- If the container initiates the embedding, the window ID of the
- embedded widget must be known. The container calls embed(),
- passing the window ID.
-
- This example shows an application that embeds a QX11EmbedWidget
- subclass into the window whose ID is passed as a command-line
- argument:
-
- \snippet doc/src/snippets/qx11embedwidget/main.cpp 0
-
- The problem of obtaining the window IDs is often solved by the
- container invoking the application that provides the widget as a
- separate process (as a panel invokes a docked applet), passing
- its window ID to the new process as a command-line argument. The
- new process can then call embedInto() with the container's window
- ID, as shown in the example code above. Similarly, the new
- process can report its window ID to the container through IPC, in
- which case the container can embed the widget.
-
- When the widget has been embedded, it emits the signal
- embedded(). If it is closed by the container, the widget emits
- containerClosed(). If an error occurs when embedding, error() is
- emitted.
-
- There are XEmbed widgets available for KDE and GTK+. The GTK+
- equivalent of QX11EmbedWidget is GtkPlug. The corresponding KDE 3
- widget is called QXEmbed.
-
- \sa QX11EmbedContainer, {XEmbed Specification}
-*/
-
-/*!
- \class QX11EmbedContainer
- \ingroup advanced
- \inmodule QtWidgets
-
- \brief The QX11EmbedContainer class provides an XEmbed container
- widget.
-
- XEmbed is an X11 protocol that supports the embedding of a widget
- from one application into another application.
-
- An XEmbed \e container is the graphical location that embeds an
- external \e {client widget}. A client widget is a window that is
- embedded into a container.
-
- When a widget has been embedded and the container receives tab
- focus, focus is passed on to the widget. When the widget reaches
- the end of its focus chain, focus is passed back to the
- container. Window activation, accelerator support, modality and
- drag and drop (XDND) are also handled.
-
- QX11EmbedContainer is commonly used for writing panels or
- toolbars that hold applets, or for \e swallowing X11
- applications. When writing a panel application, one container
- widget is created on the toolbar, and it can then either swallow
- another widget using embed(), or allow an XEmbed widget to be
- embedded into itself. The container's X11 window ID, which is
- retrieved with winId(), must then be known to the client widget.
- After embedding, the client's window ID can be retrieved with
- clientWinId().
-
- In the following example, a container widget is created as the
- main widget. It then invokes an application called "playmovie",
- passing its window ID as a command line argument. The "playmovie"
- program is an XEmbed client widget. The widget embeds itself into
- the container using the container's window ID.
-
- \snippet doc/src/snippets/qx11embedcontainer/main.cpp 0
-
- When the client widget is embedded, the container emits the
- signal clientIsEmbedded(). The signal clientClosed() is emitted
- when a widget is closed.
-
- It is possible for QX11EmbedContainer to embed XEmbed widgets
- from toolkits other than Qt, such as GTK+. Arbitrary (non-XEmbed)
- X11 widgets can also be embedded, but the XEmbed-specific
- features such as window activation and focus handling are then
- lost.
-
- The GTK+ equivalent of QX11EmbedContainer is GtkSocket. The
- corresponding KDE 3 widget is called QXEmbed.
-
- \sa QX11EmbedWidget, {XEmbed Specification}
-*/
-
-/*! \fn void QX11EmbedWidget::embedded()
-
- This signal is emitted by the widget that has been embedded by an
- XEmbed container.
-*/
-
-/*! \fn void QX11EmbedWidget::containerClosed()
-
- This signal is emitted by the client widget when the container
- closes the widget. This can happen if the container itself
- closes, or if the widget is rejected.
-
- The container can reject a widget for any reason, but the most
- common cause of a rejection is when an attempt is made to embed a
- widget into a container that already has an embedded widget.
-*/
-
-/*! \fn void QX11EmbedContainer::clientIsEmbedded()
-
- This signal is emitted by the container when a client widget has
- been embedded.
-*/
-
-/*! \fn void QX11EmbedContainer::clientClosed()
-
- This signal is emitted by the container when the client widget
- closes.
-*/
-
-/*!
- \fn void QX11EmbedWidget::error(QX11EmbedWidget::Error error)
-
- This signal is emitted if an error occurred as a result of
- embedding into or communicating with a container. The specified
- \a error describes the problem that occurred.
-
- \sa QX11EmbedWidget::Error
-*/
-
-/*!
- \fn QX11EmbedContainer::Error QX11EmbedContainer::error() const
-
- Returns the last error that occurred.
-*/
-
-/*! \fn void QX11EmbedContainer::error(QX11EmbedContainer::Error error)
-
- This signal is emitted if an error occurred when embedding or
- communicating with a client. The specified \a error describes the
- problem that occurred.
-
- \sa QX11EmbedContainer::Error
-*/
-
-/*!
- \enum QX11EmbedWidget::Error
-
- \value Unknown An unrecognized error occurred.
-
- \value InvalidWindowID The X11 window ID of the container was
- invalid. This error is usually triggered by passing an invalid
- window ID to embedInto().
-
- \omitvalue Internal
-*/
-
-/*!
- \enum QX11EmbedContainer::Error
-
- \value Unknown An unrecognized error occurred.
-
- \value InvalidWindowID The X11 window ID of the container was
- invalid. This error is usually triggered by passing an invalid
- window ID to embed().
-
- \omitvalue Internal
-*/
-
-const int XButtonPress = ButtonPress;
-const int XButtonRelease = ButtonRelease;
-#undef ButtonPress
-#undef ButtonRelease
-
-// This is a hack to move topData() out from QWidgetPrivate to public. We
-// need to to inspect window()'s embedded state.
-class QHackWidget : public QWidget
-{
- Q_DECLARE_PRIVATE(QWidget)
-public:
- QTLWExtra* topData() { return d_func()->topData(); }
-};
-
-static unsigned int XEMBED_VERSION = 0;
-
-enum QX11EmbedMessageType {
- XEMBED_EMBEDDED_NOTIFY = 0,
- XEMBED_WINDOW_ACTIVATE = 1,
- XEMBED_WINDOW_DEACTIVATE = 2,
- XEMBED_REQUEST_FOCUS = 3,
- XEMBED_FOCUS_IN = 4,
- XEMBED_FOCUS_OUT = 5,
- XEMBED_FOCUS_NEXT = 6,
- XEMBED_FOCUS_PREV = 7,
- XEMBED_MODALITY_ON = 10,
- XEMBED_MODALITY_OFF = 11,
- XEMBED_REGISTER_ACCELERATOR = 12,
- XEMBED_UNREGISTER_ACCELERATOR = 13,
- XEMBED_ACTIVATE_ACCELERATOR = 14
-};
-
-enum QX11EmbedFocusInDetail {
- XEMBED_FOCUS_CURRENT = 0,
- XEMBED_FOCUS_FIRST = 1,
- XEMBED_FOCUS_LAST = 2
-};
-
-enum QX11EmbedFocusInFlags {
- XEMBED_FOCUS_OTHER = (0 << 0),
- XEMBED_FOCUS_WRAPAROUND = (1 << 0)
-};
-
-enum QX11EmbedInfoFlags {
- XEMBED_MAPPED = (1 << 0)
-};
-
-enum QX11EmbedAccelModifiers {
- XEMBED_MODIFIER_SHIFT = (1 << 0),
- XEMBED_MODIFIER_CONTROL = (1 << 1),
- XEMBED_MODIFIER_ALT = (1 << 2),
- XEMBED_MODIFIER_SUPER = (1 << 3),
- XEMBED_MODIFIER_HYPER = (1 << 4)
-};
-
-enum QX11EmbedAccelFlags {
- XEMBED_ACCELERATOR_OVERLOADED = (1 << 0)
-};
-
-// Silence the default X11 error handler.
-static int x11ErrorHandler(Display *, XErrorEvent *)
-{
- return 0;
-}
-
-// Returns the X11 timestamp. Maintained mainly by qapplication
-// internals, but also updated by the XEmbed widgets.
-static Time x11Time()
-{
- return qt_x11Data->time;
-}
-
-// Gives the version and flags of the supported XEmbed protocol.
-static unsigned int XEmbedVersion()
-{
- return 0;
-}
-
-// Sends an XEmbed message.
-static void sendXEmbedMessage(WId window, Display *display, long message,
- long detail = 0, long data1 = 0, long data2 = 0)
-{
- XClientMessageEvent c;
- memset(&c, 0, sizeof(c));
- c.type = ClientMessage;
- c.message_type = ATOM(_XEMBED);
- c.format = 32;
- c.display = display;
- c.window = window;
-
- c.data.l[0] = x11Time();
- c.data.l[1] = message;
- c.data.l[2] = detail;
- c.data.l[3] = data1;
- c.data.l[4] = data2;
-
- XSendEvent(display, window, false, NoEventMask, (XEvent *) &c);
-}
-
-// From qapplication_x11.cpp
-static XKeyEvent lastKeyEvent;
-
-static QCoreApplication::EventFilter oldX11EventFilter;
-
-// The purpose of this global x11 filter is for one to capture the key
-// events in their original state, but most importantly this is the
-// only way to get the WM_TAKE_FOCUS message from WM_PROTOCOLS.
-static bool x11EventFilter(void *message, long *result)
-{
- XEvent *event = reinterpret_cast<XEvent *>(message);
- if (event->type == XKeyPress || event->type == XKeyRelease)
- lastKeyEvent = event->xkey;
-
- if (oldX11EventFilter && oldX11EventFilter != &x11EventFilter)
- return oldX11EventFilter(message, result);
- else
- return false;
-}
-
-//
-struct functorData
-{
- Window id, rootWindow;
- bool clearedWmState;
- bool reparentedToRoot;
-};
-
-static Bool functor(Display *display, XEvent *event, XPointer arg)
-{
- functorData *data = (functorData *) arg;
-
- if (!data->reparentedToRoot && event->type == ReparentNotify
- && event->xreparent.window == data->id
- && event->xreparent.parent == data->rootWindow) {
- data->reparentedToRoot = true;
- return true;
- }
-
- if (!data->clearedWmState
- && event->type == PropertyNotify
- && event->xproperty.window == data->id
- && event->xproperty.atom == ATOM(WM_STATE)) {
- if (event->xproperty.state == PropertyDelete) {
- data->clearedWmState = true;
- return true;
- }
-
- Atom ret;
- int format, status;
- unsigned char *retval;
- unsigned long nitems, after;
- status = XGetWindowProperty(display, data->id, ATOM(WM_STATE), 0, 2, False, ATOM(WM_STATE),
- &ret, &format, &nitems, &after, &retval );
- if (status == Success && ret == ATOM(WM_STATE) && format == 32 && nitems > 0) {
- long state = *(long *)retval;
- XFree(retval);
- if (state == WithdrawnState) {
- data->clearedWmState = true;
- return true;
- }
- }
- }
-
- return false;
-}
-
-class QX11EmbedWidgetPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QX11EmbedWidget)
-public:
- inline QX11EmbedWidgetPrivate()
- {
- lastError = QX11EmbedWidget::Unknown;
- container = 0;
- }
-
- void setEmbedded();
-
- void emitError(QX11EmbedWidget::Error error) {
- Q_Q(QX11EmbedWidget);
-
- lastError = error;
- emit q->error(error);
- }
-
- enum FocusWidgets {
- FirstFocusWidget,
- LastFocusWidget
- };
-
- int focusOriginator;
- QWidget *getFocusWidget(FocusWidgets fw);
- void checkActivateWindow(QObject *o);
- QX11EmbedWidget *xEmbedWidget(QObject *o) const;
- void clearFocus();
-
- WId container;
- QPointer<QWidget> currentFocus;
-
- QX11EmbedWidget::Error lastError;
-
-};
-
-/*!
- Constructs a QX11EmbedWidget object with the given \a parent.
-*/
-QX11EmbedWidget::QX11EmbedWidget(QWidget *parent)
- : QWidget(*new QX11EmbedWidgetPrivate, parent, 0)
-{
- XSetErrorHandler(x11ErrorHandler);
-
- setAttribute(Qt::WA_NativeWindow);
- setAttribute(Qt::WA_DontCreateNativeAncestors);
- createWinId();
- XSelectInput(x11Info().display(), internalWinId(),
- KeyPressMask | KeyReleaseMask | ButtonPressMask
- | ButtonReleaseMask
- | KeymapStateMask | ButtonMotionMask | PointerMotionMask
- | FocusChangeMask
- | ExposureMask | StructureNotifyMask
- | SubstructureNotifyMask | PropertyChangeMask);
-
- long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
- XChangeProperty(x11Info().display(), internalWinId(), ATOM(_XEMBED_INFO),
- ATOM(_XEMBED_INFO), 32, PropModeReplace,
- (unsigned char*) data, 2);
-
- setFocusPolicy(Qt::StrongFocus);
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- QApplication::instance()->installEventFilter(this);
-
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedWidget::QX11EmbedWidget: constructed client"
- << (void *)this << "with winId" << winId();
-#endif
-}
-
-/*!
- Destructs the QX11EmbedWidget object. If the widget is embedded
- when deleted, it is hidden and then detached from its container,
- so that the container is free to embed a new widget.
-*/
-QX11EmbedWidget::~QX11EmbedWidget()
-{
- Q_D(QX11EmbedWidget);
- if (d->container) {
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedWidget::~QX11EmbedWidget: unmapping"
- << (void *)this << "with winId" << winId()
- << "from container with winId" << d->container;
-#endif
- XUnmapWindow(x11Info().display(), internalWinId());
- XReparentWindow(x11Info().display(), internalWinId(), x11Info().appRootWindow(x11Info().screen()), 0, 0);
- }
-
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedWidget::~QX11EmbedWidget: destructed client"
- << (void *)this << "with winId" << winId();
-#endif
-}
-
-/*!
- Returns the type of error that occurred last. This is the same error code
- that is emitted by the error() signal.
-
- \sa Error
-*/
-QX11EmbedWidget::Error QX11EmbedWidget::error() const
-{
- return d_func()->lastError;
-}
-
-/*!
- When this function is called, the widget embeds itself into the
- container whose window ID is \a id.
-
- If \a id is \e not the window ID of a container this function will
- behave unpredictably.
-*/
-void QX11EmbedWidget::embedInto(WId id)
-{
- Q_D(QX11EmbedWidget);
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedWidget::embedInto: embedding client"
- << (void *)this << "with winId" << winId() << "into container"
- << id;
-#endif
-
- d->container = id;
- switch (XReparentWindow(x11Info().display(), internalWinId(), d->container, 0, 0)) {
- case BadWindow:
- d->emitError(InvalidWindowID);
- break;
- case BadMatch:
- d->emitError(Internal);
- break;
- case Success:
- default:
- break;
- }
- QTLWExtra* x = d->extra ? d->extra->topextra : 0;
- if (x)
- x->frameStrut.setCoords(0, 0, 0, 0);
- d->data.fstrut_dirty = false;
-}
-
-/*! \internal
-
- Gets the first or last child widget that can get focus.
-*/
-QWidget *QX11EmbedWidgetPrivate::getFocusWidget(FocusWidgets fw)
-{
- Q_Q(QX11EmbedWidget);
- QWidget *tlw = q;
- QWidget *w = tlw->nextInFocusChain();
-
- QWidget *last = tlw;
-
- extern bool qt_tab_all_widgets;
- uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
-
- while (w != tlw)
- {
- if (((w->focusPolicy() & focus_flag) == focus_flag)
- && w->isVisibleTo(q) && w->isEnabled())
- {
- last = w;
- if (fw == FirstFocusWidget)
- break;
- }
- w = w->nextInFocusChain();
- }
-
- return last;
-}
-
-/*! \internal
-
- Returns the xembed widget that the widget is a child of
-*/
-QX11EmbedWidget *QX11EmbedWidgetPrivate::xEmbedWidget(QObject *o) const
-{
- QX11EmbedWidget *xec = 0;
-
- // Check the widget itself, then its parents, and find the first
- // QX11EmbedWidget.
- do {
- if ((xec = qobject_cast<QX11EmbedWidget *>(o)))
- return xec;
- } while ((o = o->parent()));
- return 0;
-}
-
-/*! \internal
-
- Checks the active window.
-*/
-void QX11EmbedWidgetPrivate::checkActivateWindow(QObject *o)
-{
- Q_Q(QX11EmbedWidget);
- QX11EmbedWidget *xec = xEmbedWidget(o);
-
- // check if we are in the right xembed client
- if (q != xec)
- return;
-
- QWidget *w = qobject_cast<QWidget *>(o);
-
- // if it is no active window, then don't do the change
- if (!(w && qApp->activeWindow()))
- return;
-
- // if it already is the active window, don't do anything
- if (w->window() != qApp->activeWindow())
- {
- qApp->setActiveWindow(w->window());
- currentFocus = w;
-
- sendXEmbedMessage(xec->containerWinId(), q->x11Info().display(), XEMBED_REQUEST_FOCUS);
- }
-}
-
-/*! \internal
-
- Clears the focus
-*/
-void QX11EmbedWidgetPrivate::clearFocus()
-{
- Q_Q(QX11EmbedWidget);
- // Setting focus on the client itself removes Qt's
- // logical focus rectangle. We can't just do a
- // clearFocus here, because when we send the synthetic
- // FocusIn to ourselves on activation, Qt will set
- // focus on focusWidget() again. This way, we "hide"
- // focus rather than clearing it.
-
- if (!q->window()->hasFocus())
- q->window()->setFocus(Qt::OtherFocusReason);
-
- currentFocus = 0;
-}
-
-/*! \internal
-
- Sets the embedded flag on the client.
-*/
-void QX11EmbedWidgetPrivate::setEmbedded()
-{
- Q_Q(QX11EmbedWidget);
- ((QHackWidget *)q->window())->topData()->embedded = 1;
-}
-
-/*! \internal
-
- Handles WindowActivate and FocusIn events for the client.
-*/
-bool QX11EmbedWidget::eventFilter(QObject *o, QEvent *event)
-{
- Q_D(QX11EmbedWidget);
- switch (event->type()) {
- case QEvent::FocusIn:
- switch (((QFocusEvent *)event)->reason()) {
- case Qt::MouseFocusReason:
- // If the user clicks into one of the client widget's
- // children and we didn't have focus already, we request
- // focus from our container.
- if (d->xEmbedWidget(o) == this) {
- if (d->currentFocus.isNull())
- sendXEmbedMessage(d->container, x11Info().display(), XEMBED_REQUEST_FOCUS);
-
- d->currentFocus = qobject_cast<QWidget *>(o);
- }
- break;
- case Qt::TabFocusReason:
- // If the xembed client receives a focus event because of
- // a Tab, then we are at the end of our focus chain and we
- // ask the container to move to its next focus widget.
- if (o == this) {
- d->clearFocus();
- sendXEmbedMessage(d->container, x11Info().display(), XEMBED_FOCUS_NEXT);
- return true;
- } else {
- // We're listening on events from qApp, so in order
- // for us to know who to set focus on if we receive an
- // activation event, we note the widget that got the
- // focusin last.
- if (d->xEmbedWidget(o) == this)
- d->currentFocus = qobject_cast<QWidget *>(o);
- }
- break;
- case Qt::BacktabFocusReason:
- // If the window receives a focus event because of
- // a Backtab, then we are at the start of our focus chain
- // and we ask the container to move to its previous focus
- // widget.
- if (o == this) {
- // See comment for Tab.
- // If we receive a XEMBED_FOCUS_IN
- // XEMBED_FOCUS_CURRENT, we will set focus in
- // currentFocus. To avoid that in this case, we reset
- // currentFocus.
- d->clearFocus();
- sendXEmbedMessage(d->container, x11Info().display(), XEMBED_FOCUS_PREV);
- return true;
- } else {
- if (d->xEmbedWidget(o) == this)
- d->currentFocus = qobject_cast<QWidget *>(o);
- }
- break;
- case Qt::ActiveWindowFocusReason:
- if (isActiveWindow()) {
- if (!d->currentFocus.isNull()) {
- if (!d->currentFocus->hasFocus())
- d->currentFocus->setFocus(Qt::OtherFocusReason);
- } else {
- d->clearFocus();
- return true;
- }
- }
-
- break;
- case Qt::PopupFocusReason:
- case Qt::ShortcutFocusReason:
- case Qt::OtherFocusReason:
- // If focus is received to any child widget because of any
- // other reason, remember the widget so that we can give
- // it focus again if we're activated.
- if (d->xEmbedWidget(o) == this) {
- d->currentFocus = qobject_cast<QWidget *>(o);
- }
- break;
- default:
- break;
- }
- break;
- case QEvent::MouseButtonPress:
- // If we get a mouse button press event inside a embedded widget
- // make sure this is the active window in qapp.
- d->checkActivateWindow(o);
- break;
- default:
- break;
- }
-
- return QWidget::eventFilter(o, event);
-}
-
-/*! \internal
-
- Handles some notification events and client messages. Client side
- XEmbed message receiving is also handled here.
-*/
-bool QX11EmbedWidget::x11Event(XEvent *event)
-{
- Q_D(QX11EmbedWidget);
- switch (event->type) {
- case DestroyNotify:
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedWidget::x11Event: client"
- << (void *)this << "with winId" << winId()
- << "received a DestroyNotify";
-#endif
- // If the container window is destroyed, we signal this to the user.
- d->container = 0;
- emit containerClosed();
- break;
- case ReparentNotify:
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedWidget::x11Event: client"
- << (void *)this << "with winId" << winId()
- << "received a ReparentNotify to"
- << ((event->xreparent.parent == x11Info().appRootWindow(x11Info().screen()))
- ? QString::fromLatin1("root") : QString::number(event->xreparent.parent));
-#endif
- // If the container shuts down, we will be reparented to the
- // root window. We must also consider the case that we may be
- // reparented from one container to another.
- if (event->xreparent.parent == x11Info().appRootWindow(x11Info().screen())) {
- if (((QHackWidget *)this)->topData()->embedded) {
- d->container = 0;
- emit containerClosed();
- }
- return true;
- } else {
- d->container = event->xreparent.parent;
- }
- break;
- case UnmapNotify:
- // Mapping and unmapping are handled by changes to the
- // _XEMBED_INFO property. Any default map/unmap requests are
- // ignored.
- return true;
- case PropertyNotify:
- // The container sends us map/unmap messages through the
- // _XEMBED_INFO property. We adhere to the XEMBED_MAPPED bit in
- // data2.
- if (event->xproperty.atom == ATOM(_XEMBED_INFO)) {
- Atom actual_type_return;
- int actual_format_return;
- unsigned long nitems_return;
- unsigned long bytes_after_return;
- unsigned char *prop_return = 0;
- if (XGetWindowProperty(x11Info().display(), internalWinId(), ATOM(_XEMBED_INFO), 0, 2,
- false, ATOM(_XEMBED_INFO), &actual_type_return,
- &actual_format_return, &nitems_return,
- &bytes_after_return, &prop_return) == Success) {
- if (nitems_return > 1) {
- if (((long * )prop_return)[1] & XEMBED_MAPPED) {
- XMapWindow(x11Info().display(), internalWinId());
- } else {
- XUnmapWindow(x11Info().display(), internalWinId());
- }
- }
- if (prop_return)
- XFree(prop_return);
- }
- }
-
- break;
- case ClientMessage:
- // XEMBED messages have message_type _XEMBED
- if (event->xclient.message_type == ATOM(_XEMBED)) {
- // Discard XEMBED messages not to ourselves. (### dead code?)
- if (event->xclient.window != internalWinId())
- break;
-
- // Update qt_x_time if necessary
- Time msgtime = (Time) event->xclient.data.l[0];
- if (msgtime > X11->time)
- X11->time = msgtime;
-
- switch (event->xclient.data.l[1]) {
- case XEMBED_WINDOW_ACTIVATE: {
- // When we receive an XEMBED_WINDOW_ACTIVATE, we simply send
- // ourselves a WindowActivate event. Real activation happens
- // when receive XEMBED_FOCUS_IN.
- if (!isActiveWindow()) {
- QEvent ev(QEvent::WindowActivate);
- QApplication::sendEvent(this, &ev);
- }
- }
- break;
- case XEMBED_WINDOW_DEACTIVATE: {
- // When we receive an XEMBED_WINDOW_DEACTIVATE, we simply send
- // ourselves a WindowDeactivate event. Real activation happens
- // when receive XEMBED_FOCUS_IN.
- if (isActiveWindow()) {
- if (!qApp->activePopupWidget())
- QApplication::setActiveWindow(0);
- } else {
- QEvent ev(QEvent::WindowDeactivate);
- QApplication::sendEvent(this, &ev);
- }
- }
- break;
- case XEMBED_EMBEDDED_NOTIFY: {
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedWidget::x11Event: client"
- << (void *)this << "with winId" << winId()
- << "received an XEMBED EMBEDDED NOTIFY message";
-#endif
- // In this message's l[2] we have the max version
- // supported by both the client and the
- // container. QX11EmbedWidget does not use this field.
-
- // We have been embedded, so we set our
- // client's embedded flag.
- d->setEmbedded();
- emit embedded();
- }
- break;
- case XEMBED_FOCUS_IN:
- // don't set the focus if a modal dialog is open
- if (qApp->activeModalWidget())
- break;
-
- // in case we embed more than one topLevel window inside the same
- // host window.
- if (window() != qApp->activeWindow())
- qApp->setActiveWindow(this);
-
- switch (event->xclient.data.l[2]) {
- case XEMBED_FOCUS_CURRENT:
- // The container sends us this message if it wants
- // us to focus on the widget that last had focus.
- // This is the reply when XEMBED_REQUEST_FOCUS is
- // sent to the container.
- if (!d->currentFocus.isNull()) {
- if (!d->currentFocus->hasFocus())
- d->currentFocus->setFocus(Qt::OtherFocusReason);
- } else {
- // No widget currently has focus. We set focus
- // on the first widget next to the
- // client widget. Since the setFocus will not work
- // if the window is disabled, set the currentFocus
- // directly so that it's set on window activate.
- d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::FirstFocusWidget);
- d->currentFocus->setFocus(Qt::OtherFocusReason);
- }
- break;
- case XEMBED_FOCUS_FIRST:
- // The container sends this message when it wants
- // us to focus on the first widget in our focus
- // chain (typically because of a tab).
- d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::FirstFocusWidget);
- d->currentFocus->setFocus(Qt::TabFocusReason);
- break;
- case XEMBED_FOCUS_LAST:
- // The container sends this message when it wants
- // us to focus on the last widget in our focus
- // chain (typically because of a backtab).
- d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::LastFocusWidget);
- d->currentFocus->setFocus(Qt::BacktabFocusReason);
- break;
- default:
- // Ignore any other XEMBED_FOCUS_IN details.
- break;
- }
- break;
- case XEMBED_FOCUS_OUT:
- // The container sends us this message when it wants us
- // to lose focus and forget about the widget that last
- // had focus. Typically sent by the container when it
- // loses focus because of mouse or tab activity. We do
- // then not want to set focus on anything if we're
- // activated.
- if (isActiveWindow())
- d->clearFocus();
-
- break;
- default:
- // Ignore any other XEMBED messages.
- break;
- };
- } else {
- // Non-XEMBED client messages are not interesting.
- }
-
- break;
- default:
- // Ignore all other x11 events.
- break;
- }
-
- // Allow default handling.
- return QWidget::x11Event(event);
-}
-
-/*!
- \reimp
-*/
-bool QX11EmbedWidget::event(QEvent *event)
-{
- if (event->type() == QEvent::ParentChange) {
- XSelectInput(x11Info().display(), internalWinId(),
- KeyPressMask | KeyReleaseMask | ButtonPressMask
- | ButtonReleaseMask
- | KeymapStateMask | ButtonMotionMask | PointerMotionMask
- | FocusChangeMask
- | ExposureMask | StructureNotifyMask
- | SubstructureNotifyMask | PropertyChangeMask);
- }
- return QWidget::event(event);
-}
-
-/*!
- \reimp
-*/
-void QX11EmbedWidget::resizeEvent(QResizeEvent *event)
-{
- if (layout())
- layout()->update();
- QWidget::resizeEvent(event);
-}
-
-/*!
- If the widget is embedded, returns the window ID of the
- container; otherwize returns 0.
-*/
-WId QX11EmbedWidget::containerWinId() const
-{
- Q_D(const QX11EmbedWidget);
- return d->container;
-}
-
-class QX11EmbedContainerPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QX11EmbedContainer)
-public:
- inline QX11EmbedContainerPrivate()
- {
- lastError = QX11EmbedContainer::Unknown;
- client = 0;
- focusProxy = 0;
- clientIsXEmbed = false;
- xgrab = false;
- }
-
- bool isEmbedded() const;
- void moveInputToProxy();
-
- void acceptClient(WId window);
- void rejectClient(WId window);
-
- void checkGrab();
-
- WId topLevelParentWinId() const;
-
- void emitError(QX11EmbedContainer::Error error) {
- Q_Q(QX11EmbedContainer);
- lastError = error;
- emit q->error(error);
- }
-
- WId client;
- QWidget *focusProxy;
- bool clientIsXEmbed;
- bool xgrab;
- QRect clientOriginalRect;
- QSize wmMinimumSizeHint;
-
- QX11EmbedContainer::Error lastError;
-
- static QX11EmbedContainer *activeContainer;
-};
-
-QX11EmbedContainer *QX11EmbedContainerPrivate::activeContainer = 0;
-
-/*!
- Creates a QX11EmbedContainer object with the given \a parent.
-*/
-QX11EmbedContainer::QX11EmbedContainer(QWidget *parent)
- : QWidget(*new QX11EmbedContainerPrivate, parent, 0)
-{
- Q_D(QX11EmbedContainer);
- XSetErrorHandler(x11ErrorHandler);
-
- setAttribute(Qt::WA_NativeWindow);
- setAttribute(Qt::WA_DontCreateNativeAncestors);
- createWinId();
-
- setFocusPolicy(Qt::StrongFocus);
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- // ### PORT setKeyCompression(false);
- setAcceptDrops(true);
- setEnabled(false);
-
- // Everybody gets a focus proxy, but only one toplevel container's
- // focus proxy is actually in use.
- d->focusProxy = new QWidget(this);
- d->focusProxy->setAttribute(Qt::WA_NativeWindow);
- d->focusProxy->setAttribute(Qt::WA_DontCreateNativeAncestors);
- d->focusProxy->createWinId();
- d->focusProxy->setGeometry(-1, -1, 1, 1);
-
- // We need events from the window (activation status) and
- // from qApp (keypress/release).
- qApp->installEventFilter(this);
-
- // Install X11 event filter.
- if (!oldX11EventFilter)
- oldX11EventFilter = QCoreApplication::instance()->setEventFilter(x11EventFilter);
-
- XSelectInput(x11Info().display(), internalWinId(),
- KeyPressMask | KeyReleaseMask
- | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | KeymapStateMask
- | PointerMotionMask
- | EnterWindowMask | LeaveWindowMask
- | FocusChangeMask
- | ExposureMask
- | StructureNotifyMask
- | SubstructureNotifyMask);
-
- // Make sure our new event mask takes effect as soon as possible.
- XFlush(x11Info().display());
-
- // Move input to our focusProxy if this widget is active, and not
- // shaded by a modal dialog (in which case isActiveWindow() would
- // still return true, but where we must not move input focus).
- if (qApp->activeWindow() == window() && !d->isEmbedded())
- d->moveInputToProxy();
-
-#ifdef QX11EMBED_DEBUG
- qDebug() << "QX11EmbedContainer::QX11EmbedContainer: constructed container"
- << (void *)this << "with winId" << winId();
-#endif
-}
-
-/*!
- Destructs a QX11EmbedContainer.
-*/
-QX11EmbedContainer::~QX11EmbedContainer()
-{
- Q_D(QX11EmbedContainer);
- if (d->client) {
- XUnmapWindow(x11Info().display(), d->client);
- XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(x11Info().screen()), 0, 0);
- }
-
- if (d->xgrab)
- XUngrabButton(x11Info().display(), AnyButton, AnyModifier, internalWinId());
-}
-
-
-QX11EmbedContainer::Error QX11EmbedContainer::error() const {
- return d_func()->lastError;
-}
-
-
-/*! \reimp
-*/
-void QX11EmbedContainer::paintEvent(QPaintEvent *)
-{
-}
-
-/*! \internal
-
- Returns whether or not the windows' embedded flag is set.
-*/
-bool QX11EmbedContainerPrivate::isEmbedded() const
-{
- Q_Q(const QX11EmbedContainer);
- return ((QHackWidget *)q->window())->topData()->embedded == 1;
-}
-
-/*! \internal
-
- Returns the parentWinId of the window.
-*/
-WId QX11EmbedContainerPrivate::topLevelParentWinId() const
-{
- Q_Q(const QX11EmbedContainer);
- return ((QHackWidget *)q->window())->topData()->parentWinId;
-}
-
-/*!
- If the container has an embedded widget, this function returns
- the X11 window ID of the client; otherwise it returns 0.
-*/
-WId QX11EmbedContainer::clientWinId() const
-{
- Q_D(const QX11EmbedContainer);
- return d->client;
-}
-
-/*!
- Instructs the container to embed the X11 window with window ID \a
- id. The client widget will then move on top of the container
- window and be resized to fit into the container.
-
- The \a id should be the ID of a window controlled by an XEmbed
- enabled application, but this is not mandatory. If \a id does not
- belong to an XEmbed client widget, then focus handling,
- activation, accelerators and other features will not work
- properly.
-*/
-void QX11EmbedContainer::embedClient(WId id)
-{
- Q_D(QX11EmbedContainer);
-
- if (id == 0) {
- d->emitError(InvalidWindowID);
- return;
- }
-
- // Walk up the tree of parent windows to prevent embedding of ancestors.
- WId thisId = internalWinId();
- Window rootReturn;
- Window parentReturn;
- Window *childrenReturn = 0;
- unsigned int nchildrenReturn;
- do {
- if (XQueryTree(x11Info().display(), thisId, &rootReturn,
- &parentReturn, &childrenReturn, &nchildrenReturn) == 0) {
- d->emitError(InvalidWindowID);
- return;
- }
- if (childrenReturn) {
- XFree(childrenReturn);
- childrenReturn = 0;
- }
-
- thisId = parentReturn;
- if (id == thisId) {
- d->emitError(InvalidWindowID);
- return;
- }
- } while (thisId != rootReturn);
-
- // watch for property notify events (see below)
- XGrabServer(x11Info().display());
- XWindowAttributes attrib;
- if (!XGetWindowAttributes(x11Info().display(), id, &attrib)) {
- XUngrabServer(x11Info().display());
- d->emitError(InvalidWindowID);
- return;
- }
- XSelectInput(x11Info().display(), id, attrib.your_event_mask | PropertyChangeMask | StructureNotifyMask);
- XUngrabServer(x11Info().display());
-
- // Put the window into WithdrawnState
- XUnmapWindow(x11Info().display(), id);
- XSync(x11Info().display(), False); // make sure the window is hidden
-
- /*
- Wait for notification from the window manager that the window is
- in withdrawn state. According to the ICCCM section 4.1.3.1,
- we should wait for the WM_STATE property to either be deleted or
- set to WithdrawnState.
-
- For safety, we will not wait more than 500 ms, so that we can
- preemptively workaround buggy window managers.
- */
- QElapsedTimer t;
- t.start();
-
- functorData data;
- data.id = id;
- data.rootWindow = attrib.root;
- data.clearedWmState = false;
- data.reparentedToRoot = false;
-
- do {
- if (t.elapsed() > 500) // time-out after 500 ms
- break;
-
- XEvent event;
- if (!XCheckIfEvent(x11Info().display(), &event, functor, (XPointer) &data)) {
- XSync(x11Info().display(), False);
- usleep(50000);
- continue;
- }
-
- qApp->x11ProcessEvent(&event);
- } while (!data.clearedWmState || !data.reparentedToRoot);
-
- // restore the event mask
- XSelectInput(x11Info().display(), id, attrib.your_event_mask);
-
- switch (XReparentWindow(x11Info().display(), id, internalWinId(), 0, 0)) {
- case BadWindow:
- case BadMatch:
- d->emitError(InvalidWindowID);
- break;
- default:
- break;
- }
-}
-
-/*! \internal
-
- Handles key, activation and focus events for the container.
-*/
-bool QX11EmbedContainer::eventFilter(QObject *o, QEvent *event)
-{
- Q_D(QX11EmbedContainer);
- switch (event->type()) {
- case QEvent::KeyPress:
- // Forward any keypresses to our client.
- if (o == this && d->client) {
- lastKeyEvent.window = d->client;
- XSendEvent(x11Info().display(), d->client, false, KeyPressMask, (XEvent *) &lastKeyEvent);
- return true;
- }
- break;
- case QEvent::KeyRelease:
- // Forward any keyreleases to our client.
- if (o == this && d->client) {
- lastKeyEvent.window = d->client;
- XSendEvent(x11Info().display(), d->client, false, KeyReleaseMask, (XEvent *) &lastKeyEvent);
- return true;
- }
- break;
-
- case QEvent::WindowActivate:
- // When our container window is activated, we pass the
- // activation message on to our client. Note that X input
- // focus is set to our focus proxy. We want to intercept all
- // keypresses.
- if (o == window() && d->client) {
- if (d->clientIsXEmbed) {
- sendXEmbedMessage(d->client, x11Info().display(), XEMBED_WINDOW_ACTIVATE);
- } else {
- d->checkGrab();
- if (hasFocus())
- XSetInputFocus(x11Info().display(), d->client, XRevertToParent, x11Time());
- }
- if (!d->isEmbedded())
- d->moveInputToProxy();
- }
- break;
- case QEvent::WindowDeactivate:
- // When our container window is deactivated, we pass the
- // deactivation message to our client.
- if (o == window() && d->client) {
- if (d->clientIsXEmbed)
- sendXEmbedMessage(d->client, x11Info().display(), XEMBED_WINDOW_DEACTIVATE);
- else
- d->checkGrab();
- }
- break;
- case QEvent::FocusIn:
- // When receiving FocusIn events generated by Tab or Backtab,
- // we pass focus on to our client. Any mouse activity is sent
- // directly to the client, and it will ask us for focus with
- // XEMBED_REQUEST_FOCUS.
- if (o == this && d->client) {
- if (!d->isEmbedded())
- d->activeContainer = this;
-
- if (d->clientIsXEmbed) {
- if (!d->isEmbedded())
- d->moveInputToProxy();
-
- QFocusEvent *fe = (QFocusEvent *)event;
- switch (fe->reason()) {
- case Qt::TabFocusReason:
- sendXEmbedMessage(d->client, x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_FIRST);
- break;
- case Qt::BacktabFocusReason:
- sendXEmbedMessage(d->client, x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_LAST);
- break;
- default:
- sendXEmbedMessage(d->client, x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT);
- break;
- }
- } else {
- d->checkGrab();
- XSetInputFocus(x11Info().display(), d->client, XRevertToParent, x11Time());
- }
- }
-
- break;
- case QEvent::FocusOut: {
- // When receiving a FocusOut, we ask our client to remove its
- // focus.
- if (o == this && d->client) {
- if (!d->isEmbedded()) {
- d->activeContainer = 0;
- if (isActiveWindow())
- d->moveInputToProxy();
- }
-
- if (d->clientIsXEmbed) {
- QFocusEvent *fe = (QFocusEvent *)event;
- if (o == this && d->client && fe->reason() != Qt::ActiveWindowFocusReason)
- sendXEmbedMessage(d->client, x11Info().display(), XEMBED_FOCUS_OUT);
- } else {
- d->checkGrab();
- }
- }
- }
- break;
-
- case QEvent::Close: {
- if (o == this && d->client) {
- // Unmap the client and reparent it to the root window.
- // Wait until the messages have been processed. Then ask
- // the window manager to delete the window.
- XUnmapWindow(x11Info().display(), d->client);
- XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(x11Info().screen()), 0, 0);
- XSync(x11Info().display(), false);
-
- XEvent ev;
- memset(&ev, 0, sizeof(ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.window = d->client;
- ev.xclient.message_type = ATOM(WM_PROTOCOLS);
- ev.xclient.format = 32;
- ev.xclient.data.s[0] = ATOM(WM_DELETE_WINDOW);
- XSendEvent(x11Info().display(), d->client, false, NoEventMask, &ev);
-
- XFlush(x11Info().display());
- d->client = 0;
- d->clientIsXEmbed = false;
- d->wmMinimumSizeHint = QSize();
- updateGeometry();
- setEnabled(false);
- update();
-
- emit clientClosed();
- }
- }
- default:
- break;
- }
-
- return QWidget::eventFilter(o, event);
-}
-
-/*! \internal
-
- Handles X11 events for the container.
-*/
-bool QX11EmbedContainer::x11Event(XEvent *event)
-{
- Q_D(QX11EmbedContainer);
-
- switch (event->type) {
- case CreateNotify:
- // The client created an embedded window.
- if (d->client)
- d->rejectClient(event->xcreatewindow.window);
- else
- d->acceptClient(event->xcreatewindow.window);
- break;
- case DestroyNotify:
- if (event->xdestroywindow.window == d->client) {
- // The client died.
- d->client = 0;
- d->clientIsXEmbed = false;
- d->wmMinimumSizeHint = QSize();
- updateGeometry();
- update();
- setEnabled(false);
- emit clientClosed();
- }
- break;
- case ReparentNotify:
- // The client sends us this if it reparents itself out of our
- // widget.
- if (event->xreparent.window == d->client && event->xreparent.parent != internalWinId()) {
- d->client = 0;
- d->clientIsXEmbed = false;
- d->wmMinimumSizeHint = QSize();
- updateGeometry();
- update();
- setEnabled(false);
- emit clientClosed();
- } else if (event->xreparent.parent == internalWinId()) {
- // The client reparented itself into this window.
- if (d->client)
- d->rejectClient(event->xreparent.window);
- else
- d->acceptClient(event->xreparent.window);
- }
- break;
- case ClientMessage: {
- if (event->xclient.message_type == ATOM(_XEMBED)) {
- // Ignore XEMBED messages not to ourselves
- if (event->xclient.window != internalWinId())
- break;
-
- // Receiving an XEmbed message means the client
- // is an XEmbed client.
- d->clientIsXEmbed = true;
-
- Time msgtime = (Time) event->xclient.data.l[0];
- if (msgtime > X11->time)
- X11->time = msgtime;
-
- switch (event->xclient.data.l[1]) {
- case XEMBED_REQUEST_FOCUS: {
- // This typically happens when the client gets focus
- // because of a mouse click.
- if (!hasFocus())
- setFocus(Qt::OtherFocusReason);
-
- // The message is passed along to the topmost container
- // that eventually responds with a XEMBED_FOCUS_IN
- // message. The focus in message is passed all the way
- // back until it reaches the original focus
- // requestor. In the end, not only the original client
- // has focus, but also all its ancestor containers.
- if (d->isEmbedded()) {
- // If our window's embedded flag is set, then
- // that suggests that we are part of a client. The
- // parentWinId will then point to an container to whom
- // we must pass this message.
- sendXEmbedMessage(d->topLevelParentWinId(), x11Info().display(), XEMBED_REQUEST_FOCUS);
- } else {
- // Our window's embedded flag is not set,
- // so we are the topmost container. We respond to
- // the focus request message with a focus in
- // message. This message will pass on from client
- // to container to client until it reaches the
- // originator of the XEMBED_REQUEST_FOCUS message.
- sendXEmbedMessage(d->client, x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT);
- }
-
- break;
- }
- case XEMBED_FOCUS_NEXT:
- // Client sends this event when it received a tab
- // forward and was at the end of its focus chain. If
- // we are the only widget in the focus chain, we send
- // ourselves a FocusIn event.
- if (d->focus_next != this) {
- focusNextPrevChild(true);
- } else {
- QFocusEvent event(QEvent::FocusIn, Qt::TabFocusReason);
- qApp->sendEvent(this, &event);
- }
-
- break;
- case XEMBED_FOCUS_PREV:
- // Client sends this event when it received a backtab
- // and was at the start of its focus chain. If we are
- // the only widget in the focus chain, we send
- // ourselves a FocusIn event.
- if (d->focus_next != this) {
- focusNextPrevChild(false);
- } else {
- QFocusEvent event(QEvent::FocusIn, Qt::BacktabFocusReason);
- qApp->sendEvent(this, &event);
- }
-
- break;
- default:
- break;
- }
- }
- }
- break;
- case XButtonPress:
- if (!d->clientIsXEmbed) {
- setFocus(Qt::MouseFocusReason);
- XAllowEvents(x11Info().display(), ReplayPointer, CurrentTime);
- return true;
- }
- break;
- case XButtonRelease:
- if (!d->clientIsXEmbed)
- XAllowEvents(x11Info().display(), SyncPointer, CurrentTime);
- break;
- default:
- break;
- }
-
- return QWidget::x11Event(event);
-}
-
-/*! \internal
-
- Whenever the container is resized, we need to resize our client.
-*/
-void QX11EmbedContainer::resizeEvent(QResizeEvent *)
-{
- Q_D(QX11EmbedContainer);
- if (d->client)
- XResizeWindow(x11Info().display(), d->client, width(), height());
-}
-
-/*! \internal
-
- We use the QShowEvent to signal to our client that we want it to
- map itself. We do this by changing its window property
- XEMBED_INFO. The client will get an X11 PropertyNotify.
-*/
-void QX11EmbedContainer::showEvent(QShowEvent *)
-{
- Q_D(QX11EmbedContainer);
- if (d->client) {
- long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
- XChangeProperty(x11Info().display(), d->client, ATOM(_XEMBED_INFO), ATOM(_XEMBED_INFO), 32,
- PropModeReplace, (unsigned char *) data, 2);
- }
-}
-
-/*! \internal
-
- We use the QHideEvent to signal to our client that we want it to
- unmap itself. We do this by changing its window property
- XEMBED_INFO. The client will get an X11 PropertyNotify.
-*/
-void QX11EmbedContainer::hideEvent(QHideEvent *)
-{
- Q_D(QX11EmbedContainer);
- if (d->client) {
- long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
- XChangeProperty(x11Info().display(), d->client, ATOM(_XEMBED_INFO), ATOM(_XEMBED_INFO), 32,
- PropModeReplace, (unsigned char *) data, 2);
- }
-}
-
-/*!
- \reimp
-*/
-bool QX11EmbedContainer::event(QEvent *event)
-{
- if (event->type() == QEvent::ParentChange) {
- XSelectInput(x11Info().display(), internalWinId(),
- KeyPressMask | KeyReleaseMask
- | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | KeymapStateMask
- | PointerMotionMask
- | EnterWindowMask | LeaveWindowMask
- | FocusChangeMask
- | ExposureMask
- | StructureNotifyMask
- | SubstructureNotifyMask);
- }
- return QWidget::event(event);
-}
-
-/*! \internal
-
- Rejects a client window by reparenting it to the root window. The
- client will receive a reparentnotify, and will most likely assume
- that the container has shut down. The XEmbed protocol does not
- define any way to reject a client window, but this is a clean way
- to do it.
-*/
-void QX11EmbedContainerPrivate::rejectClient(WId window)
-{
- Q_Q(QX11EmbedContainer);
- q->setEnabled(false);
- XRemoveFromSaveSet(q->x11Info().display(), client);
- XReparentWindow(q->x11Info().display(), window, q->x11Info().appRootWindow(q->x11Info().screen()), 0, 0);
-}
-
-/*! \internal
-
- Accepts a client by mapping it, resizing it and optionally
- activating and giving it logical focusing through XEMBED messages.
-*/
-void QX11EmbedContainerPrivate::acceptClient(WId window)
-{
- Q_Q(QX11EmbedContainer);
- client = window;
- q->setEnabled(true);
-
- // This tells Qt that we wish to forward DnD messages to
- // our client.
- if (!extra)
- createExtra();
- extraData()->xDndProxy = client;
-
- unsigned int version = XEmbedVersion();
-
- Atom actual_type_return;
- int actual_format_return;
- unsigned long nitems_return = 0;
- unsigned long bytes_after_return;
- unsigned char *prop_return = 0;
- unsigned int clientversion = 0;
-
- // Add this client to our saveset, so if we crash, the client window
- // doesn't get destroyed. This is useful for containers that restart
- // automatically after a crash, because it can simply reembed its clients
- // without having to restart them (KDE panel).
- XAddToSaveSet(q->x11Info().display(), client);
-
- // XEmbed clients have an _XEMBED_INFO property in which we can
- // fetch the version
- if (XGetWindowProperty(q->x11Info().display(), client, ATOM(_XEMBED_INFO), 0, 2, false,
- ATOM(_XEMBED_INFO), &actual_type_return, &actual_format_return,
- &nitems_return, &bytes_after_return, &prop_return) == Success) {
-
- if (actual_type_return != None && actual_format_return != 0) {
- // Clients with the _XEMBED_INFO property are XEMBED clients.
- clientIsXEmbed = true;
-
- long *p = (long *)prop_return;
- if (nitems_return >= 2)
- clientversion = (unsigned int)p[0];
- }
-
- XFree(prop_return);
- }
-
- // Store client window's original size and placement.
- Window root;
- int x_return, y_return;
- unsigned int width_return, height_return, border_width_return, depth_return;
- XGetGeometry(q->x11Info().display(), client, &root, &x_return, &y_return,
- &width_return, &height_return, &border_width_return, &depth_return);
- clientOriginalRect.setCoords(x_return, y_return,
- x_return + width_return - 1,
- y_return + height_return - 1);
-
- // Ask the client for its minimum size.
- XSizeHints size;
- long msize;
- if (XGetWMNormalHints(q->x11Info().display(), client, &size, &msize) && (size.flags & PMinSize)) {
- wmMinimumSizeHint = QSize(size.min_width, size.min_height);
- q->updateGeometry();
- }
-
- // The container should set the data2 field to the lowest of its
- // supported version number and that of the client (from
- // _XEMBED_INFO property).
- unsigned int minversion = version > clientversion ? clientversion : version;
- sendXEmbedMessage(client, q->x11Info().display(), XEMBED_EMBEDDED_NOTIFY, q->internalWinId(), minversion);
- XMapWindow(q->x11Info().display(), client);
-
- // Resize it, but no smaller than its minimum size hint.
- XResizeWindow(q->x11Info().display(),
- client,
- qMax(q->width(), wmMinimumSizeHint.width()),
- qMax(q->height(), wmMinimumSizeHint.height()));
- q->update();
-
- // Not mentioned in the protocol is that if the container
- // is already active, the client must be activated to work
- // properly.
- if (q->window()->isActiveWindow())
- sendXEmbedMessage(client, q->x11Info().display(), XEMBED_WINDOW_ACTIVATE);
-
- // Also, if the container already has focus, then it must
- // send a focus in message to its new client; otherwise we ask
- // it to remove focus.
- if (q->focusWidget() == q && q->hasFocus())
- sendXEmbedMessage(client, q->x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_FIRST);
- else
- sendXEmbedMessage(client, q->x11Info().display(), XEMBED_FOCUS_OUT);
-
- if (!clientIsXEmbed) {
- checkGrab();
- if (q->hasFocus()) {
- XSetInputFocus(q->x11Info().display(), client, XRevertToParent, x11Time());
- }
- } else {
- if (!isEmbedded())
- moveInputToProxy();
- }
-
- emit q->clientIsEmbedded();
-}
-
-/*! \internal
-
- Moves X11 keyboard input focus to the focusProxy, unless the focus
- is there already. When X11 keyboard input focus is on the
- focusProxy, which is a child of the container and a sibling of the
- client, X11 keypresses and keyreleases will always go to the proxy
- and not to the client.
-*/
-void QX11EmbedContainerPrivate::moveInputToProxy()
-{
- Q_Q(QX11EmbedContainer);
- // Following Owen Taylor's advice from the XEmbed specification to
- // always use CurrentTime when no explicit user action is involved.
- XSetInputFocus(q->x11Info().display(), focusProxy->internalWinId(), XRevertToParent, CurrentTime);
-}
-
-/*! \internal
-
- Ask the window manager to give us a default minimum size.
-*/
-QSize QX11EmbedContainer::minimumSizeHint() const
-{
- Q_D(const QX11EmbedContainer);
- if (!d->client || !d->wmMinimumSizeHint.isValid())
- return QWidget::minimumSizeHint();
- return d->wmMinimumSizeHint;
-}
-
-/*! \internal
-
-*/
-void QX11EmbedContainerPrivate::checkGrab()
-{
- Q_Q(QX11EmbedContainer);
- if (!clientIsXEmbed && q->isActiveWindow() && !q->hasFocus()) {
- if (!xgrab) {
- XGrabButton(q->x11Info().display(), AnyButton, AnyModifier, q->internalWinId(),
- true, ButtonPressMask, GrabModeSync, GrabModeAsync,
- None, None);
- }
- xgrab = true;
- } else {
- if (xgrab)
- XUngrabButton(q->x11Info().display(), AnyButton, AnyModifier, q->internalWinId());
- xgrab = false;
- }
-}
-
-/*!
- Detaches the client from the embedder. The client will appear as a
- standalone window on the desktop.
-*/
-void QX11EmbedContainer::discardClient()
-{
- Q_D(QX11EmbedContainer);
- if (d->client) {
- XResizeWindow(x11Info().display(), d->client, d->clientOriginalRect.width(),
- d->clientOriginalRect.height());
-
- d->rejectClient(d->client);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qx11embed_x11.h b/src/widgets/platforms/x11/qx11embed_x11.h
deleted file mode 100644
index fcf94b60a2..0000000000
--- a/src/widgets/platforms/x11/qx11embed_x11.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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QX11EMBED_X11_H
-#define QX11EMBED_X11_H
-
-#include <QtWidgets/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QX11EmbedWidgetPrivate;
-class Q_WIDGETS_EXPORT QX11EmbedWidget : public QWidget
-{
- Q_OBJECT
-public:
- QX11EmbedWidget(QWidget *parent = 0);
- ~QX11EmbedWidget();
-
- void embedInto(WId id);
- WId containerWinId() const;
-
- enum Error {
- Unknown,
- Internal,
- InvalidWindowID
- };
- Error error() const;
-
-Q_SIGNALS:
- void embedded();
- void containerClosed();
- void error(QX11EmbedWidget::Error error);
-
-protected:
- bool x11Event(XEvent *);
- bool eventFilter(QObject *, QEvent *);
- bool event(QEvent *);
- void resizeEvent(QResizeEvent *);
-
-private:
- Q_DECLARE_PRIVATE(QX11EmbedWidget)
- Q_DISABLE_COPY(QX11EmbedWidget)
-};
-
-class QX11EmbedContainerPrivate;
-class Q_WIDGETS_EXPORT QX11EmbedContainer : public QWidget
-{
- Q_OBJECT
-public:
- QX11EmbedContainer(QWidget *parent = 0);
- ~QX11EmbedContainer();
-
- void embedClient(WId id);
- void discardClient();
-
- WId clientWinId() const;
-
- QSize minimumSizeHint() const;
-
- enum Error {
- Unknown,
- Internal,
- InvalidWindowID
- };
- Error error() const;
-
-Q_SIGNALS:
- void clientIsEmbedded();
- void clientClosed();
- void error(QX11EmbedContainer::Error);
-
-protected:
- bool x11Event(XEvent *);
- bool eventFilter(QObject *, QEvent *);
- void paintEvent(QPaintEvent *e);
- void resizeEvent(QResizeEvent *);
- void showEvent(QShowEvent *);
- void hideEvent(QHideEvent *);
- bool event(QEvent *);
-
-private:
- Q_DECLARE_PRIVATE(QX11EmbedContainer)
- Q_DISABLE_COPY(QX11EmbedContainer)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QX11EMBED_X11_H
diff --git a/src/widgets/platforms/x11/qx11info_x11.cpp b/src/widgets/platforms/x11/qx11info_x11.cpp
deleted file mode 100644
index 88092b3bac..0000000000
--- a/src/widgets/platforms/x11/qx11info_x11.cpp
+++ /dev/null
@@ -1,544 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwidget.h"
-#include "qpixmap.h"
-#include "qx11info_x11.h"
-#include "qt_x11_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QX11Info
- \brief The QX11Info class provides information about the X display
- configuration.
-
- \ingroup shared
- \inmodule QtWidgets
-
- The class provides two APIs: a set of non-static functions that
- provide information about a specific widget or pixmap, and a set
- of static functions that provide the default information for the
- application.
-
- \warning This class is only available on X11. For querying
- per-screen information in a portable way, use QDesktopWidget.
-
- \sa QWidget::x11Info(), QPixmap::x11Info(), QDesktopWidget
-*/
-
-/*!
- Constructs an empty QX11Info object.
-*/
-QX11Info::QX11Info()
- : x11data(0)
-{
-}
-
-/*!
- Constructs a copy of \a other.
-*/
-QX11Info::QX11Info(const QX11Info &other)
-{
- x11data = other.x11data;
- if (x11data)
- ++x11data->ref;
-}
-
-/*!
- Assigns \a other to this object and returns a reference to this
- object.
-*/
-QX11Info &QX11Info::operator=(const QX11Info &other)
-{
- if (other.x11data)
- ++other.x11data->ref;
- if (x11data && !--x11data->ref)
- delete x11data;
- x11data = other.x11data;
- return *this;
-}
-
-/*!
- Destroys the QX11Info object.
-*/
-QX11Info::~QX11Info()
-{
- if (x11data && !--x11data->ref)
- delete x11data;
-}
-
-/*!
- \internal
- Makes a shallow copy of the X11-specific data of \a fromDevice, if it is not
- null. Otherwise this function sets it to null.
-*/
-
-void QX11Info::copyX11Data(const QPaintDevice *fromDevice)
-{
- QX11InfoData *xd = 0;
- if (fromDevice) {
- if (fromDevice->devType() == QInternal::Widget)
- xd = static_cast<const QWidget *>(fromDevice)->x11Info().x11data;
- else if (fromDevice->devType() == QInternal::Pixmap)
- xd = static_cast<const QPixmap *>(fromDevice)->x11Info().x11data;
- }
- setX11Data(xd);
-}
-
-/*!
- \internal
- Makes a deep copy of the X11-specific data of \a fromDevice, if it is not
- null. Otherwise this function sets it to null.
-*/
-
-void QX11Info::cloneX11Data(const QPaintDevice *fromDevice)
-{
- QX11InfoData *d = 0;
- if (fromDevice) {
- QX11InfoData *xd;
- if (fromDevice->devType() == QInternal::Widget) {
- xd = static_cast<const QWidget *>(fromDevice)->x11Info().x11data;
- } else {
- Q_ASSERT(fromDevice->devType() == QInternal::Pixmap);
- xd = static_cast<const QPixmap *>(fromDevice)->x11Info().x11data;
- }
- d = new QX11InfoData(*xd);
- d->ref = 0;
- }
- setX11Data(d);
-}
-
-/*!
- \internal
- Makes a shallow copy of the X11-specific data \a d and assigns it to this
- class. This function increments the reference code of \a d.
-*/
-
-void QX11Info::setX11Data(const QX11InfoData* d)
-{
- if (x11data && !--x11data->ref)
- delete x11data;
- x11data = (QX11InfoData *)d;
- if (x11data)
- ++x11data->ref;
-}
-
-
-/*!
- \internal
- If \a def is false, returns a deep copy of the x11Data, or 0 if x11Data is 0.
- If \a def is true, makes a QX11Data struct filled with the default
- values.
-
- In either case the caller is responsible for deleting the returned
- struct. But notice that the struct is a shared class, so other
- classes might also have a reference to it. The reference count of
- the returned QX11Data* is 0.
-*/
-
-QX11InfoData* QX11Info::getX11Data(bool def) const
-{
- QX11InfoData* res = 0;
- if (def) {
- res = new QX11InfoData;
- res->ref = 0;
- res->screen = appScreen();
- res->depth = appDepth();
- res->cells = appCells();
- res->colormap = colormap();
- res->defaultColormap = appDefaultColormap();
- res->visual = (Visual*) appVisual();
- res->defaultVisual = appDefaultVisual();
- } else if (x11data) {
- res = new QX11InfoData;
- *res = *x11data;
- res->ref = 0;
- }
- return res;
-}
-
-/*!
- Returns the horizontal resolution of the given \a screen in terms of the
- number of dots per inch.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa setAppDpiX(), appDpiY()
-*/
-int QX11Info::appDpiX(int screen)
-{
- if (!X11)
- return 75;
- if (screen < 0)
- screen = X11->defaultScreen;
- if (screen > X11->screenCount)
- return 0;
- return X11->screens[screen].dpiX;
-}
-
-/*!
- Sets the horizontal resolution of the given \a screen to the number of
- dots per inch specified by \a xdpi.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa appDpiX(), setAppDpiY()
-*/
-
-void QX11Info::setAppDpiX(int screen, int xdpi)
-{
- if (!X11)
- return;
- if (screen < 0)
- screen = X11->defaultScreen;
- if (screen > X11->screenCount)
- return;
- X11->screens[screen].dpiX = xdpi;
-}
-
-/*!
- Returns the vertical resolution of the given \a screen in terms of the
- number of dots per inch.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa setAppDpiY(), appDpiX()
-*/
-
-int QX11Info::appDpiY(int screen)
-{
- if (!X11)
- return 75;
- if (screen < 0)
- screen = X11->defaultScreen;
- if (screen > X11->screenCount)
- return 0;
- return X11->screens[screen].dpiY;
-}
-
-/*!
- Sets the vertical resolution of the given \a screen to the number of
- dots per inch specified by \a ydpi.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa appDpiY(), setAppDpiX()
-*/
-void QX11Info::setAppDpiY(int screen, int ydpi)
-{
- if (!X11)
- return;
- if (screen < 0)
- screen = X11->defaultScreen;
- if (screen > X11->screenCount)
- return;
- X11->screens[screen].dpiY = ydpi;
-}
-
-/*!
- Returns the X11 time.
-
- \sa setAppTime(), appUserTime()
-*/
-unsigned long QX11Info::appTime()
-{
- return X11 ? X11->time : 0;
-}
-
-/*!
- Sets the X11 time to the value specified by \a time.
-
- \sa appTime(), setAppUserTime()
-*/
-void QX11Info::setAppTime(unsigned long time)
-{
- if (X11) {
- X11->time = time;
- }
-}
-
-/*!
- Returns the X11 user time.
-
- \sa setAppUserTime(), appTime()
-*/
-unsigned long QX11Info::appUserTime()
-{
- return X11 ? X11->userTime : 0;
-}
-
-/*!
- Sets the X11 user time as specified by \a time.
-
- \sa appUserTime(), setAppTime()
-*/
-void QX11Info::setAppUserTime(unsigned long time)
-{
- if (X11) {
- X11->userTime = time;
- }
-}
-
-
-/*!
- \fn const char *QX11Info::appClass()
-
- Returns the X11 application class.
-
- \sa display()
-*/
-
-/*!
- Returns the default display for the application.
-
- \sa appScreen()
-*/
-
-Display *QX11Info::display()
-{
- return X11 ? X11->display : 0;
-}
-
-/*!
- Returns the number of the screen where the application is being
- displayed.
-
- \sa display(), screen()
-*/
-int QX11Info::appScreen()
-{
- return X11 ? X11->defaultScreen : 0;
-}
-
-/*!
- Returns a handle for the application's color map on the given \a screen.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa colormap(), defaultColormap()
-*/
-Qt::HANDLE QX11Info::appColormap(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].colormap : 0;
-}
-
-/*!
- Returns the current visual used by the application on the given
- \a screen.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa visual(), defaultVisual()
-*/
-
-void *QX11Info::appVisual(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].visual : 0;
-}
-
-/*!
- Returns a handle for the applications root window on the given \a screen.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa QApplication::desktop()
-*/
-Qt::HANDLE QX11Info::appRootWindow(int screen)
-{
- return X11 ? RootWindow(X11->display, screen == -1 ? X11->defaultScreen : screen) : 0;
-}
-
-/*!
- Returns the color depth (bits per pixel) used by the application on the
- given \a screen.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa depth()
-*/
-
-int QX11Info::appDepth(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].depth : 32;
-}
-
-/*!
- Returns the number of cells used by the application on the given \a screen.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa cells()
-*/
-
-int QX11Info::appCells(int screen)
-{ return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].cells : 0; }
-
-/*!
- Returns true if the application has a default color map on the given
- \a screen; otherwise returns false.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-*/
-bool QX11Info::appDefaultColormap(int screen)
-{ return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].defaultColormap : true; }
-
-/*!
- Returns true if the application has a default visual on the given \a screen;
- otherwise returns false.
-
- The \a screen argument is an X screen number. Be aware that if
- the user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-*/
-bool QX11Info::appDefaultVisual(int screen)
-{ return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].defaultVisual : true; }
-
-/*!
- Returns the number of the screen currently in use.
-
- The return value is an X screen number. Be aware that if the
- user's system uses Xinerama (as opposed to traditional X11
- multiscreen), there is only one X screen. Use QDesktopWidget to
- query for information about Xinerama screens.
-
- \sa appScreen()
-*/
-int QX11Info::screen() const
-{ return x11data ? x11data->screen : QX11Info::appScreen(); }
-
-/*!
- Returns the color depth (bits per pixel) of the X display.
-
- \sa appDepth()
-*/
-
-int QX11Info::depth() const
-{ return x11data ? x11data->depth : QX11Info::appDepth(); }
-
-/*!
- Returns the number of cells.
-
- \sa appCells()
-*/
-
-int QX11Info::cells() const
-{ return x11data ? x11data->cells : QX11Info::appCells(); }
-
-/*!
- Returns a handle for the color map.
-
- \sa defaultColormap()
-*/
-
-Qt::HANDLE QX11Info::colormap() const
-{ return x11data ? x11data->colormap : QX11Info::appColormap(); }
-
-/*!
- Returns true if there is a default color map; otherwise returns false.
-
- \sa colormap()
-*/
-
-bool QX11Info::defaultColormap() const
-{ return x11data ? x11data->defaultColormap : QX11Info::appDefaultColormap(); }
-
-/*!
- Returns the current visual.
-
- \sa appVisual(), defaultVisual()
-*/
-
-void *QX11Info::visual() const
-{ return x11data ? x11data->visual : QX11Info::appVisual(); }
-
-/*!
- Returns true if there is a default visual; otherwise returns false.
-
- \sa visual(), appVisual()
-*/
-
-bool QX11Info::defaultVisual() const
-{ return x11data ? x11data->defaultVisual : QX11Info::appDefaultVisual(); }
-
-
-/*!
- \since 4.4
-
- Returns true if there is a compositing manager running.
-*/
-bool QX11Info::isCompositingManagerRunning()
-{
- return X11 ? X11->compositingManagerRunning : false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qx11info_x11.h b/src/widgets/platforms/x11/qx11info_x11.h
deleted file mode 100644
index 60cd0e9e92..0000000000
--- a/src/widgets/platforms/x11/qx11info_x11.h
+++ /dev/null
@@ -1,123 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QX11INFO_X11_H
-#define QX11INFO_X11_H
-
-#include <QtCore/qnamespace.h>
-
-typedef struct _XDisplay Display;
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-struct QX11InfoData;
-class QX11Info;
-class QPaintDevice;
-class QApplicationPrivate;
-class QX11InfoPrivate;
-struct QX11WindowAttributes;
-
-void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &a);
-class Q_WIDGETS_EXPORT QX11Info
-{
-public:
- QX11Info();
- ~QX11Info();
- QX11Info(const QX11Info &other);
- QX11Info &operator=(const QX11Info &other);
-
- static Display *display();
- static const char *appClass();
- int screen() const;
- int depth() const;
- int cells() const;
- Qt::HANDLE colormap() const;
- bool defaultColormap() const;
- void *visual() const;
- bool defaultVisual() const;
-
- static int appScreen();
- static int appDepth(int screen = -1);
- static int appCells(int screen = -1);
- static Qt::HANDLE appColormap(int screen = -1);
- static void *appVisual(int screen = -1);
- static Qt::HANDLE appRootWindow(int screen = -1);
- static bool appDefaultColormap(int screen = -1);
- static bool appDefaultVisual(int screen = -1);
- static int appDpiX(int screen = -1);
- static int appDpiY(int screen = -1);
- static void setAppDpiX(int screen, int dpi);
- static void setAppDpiY(int screen, int dpi);
- static unsigned long appTime();
- static unsigned long appUserTime();
- static void setAppTime(unsigned long time);
- static void setAppUserTime(unsigned long time);
- static bool isCompositingManagerRunning();
-
-protected:
- void copyX11Data(const QPaintDevice *);
- void cloneX11Data(const QPaintDevice *);
- void setX11Data(const QX11InfoData *);
- QX11InfoData* getX11Data(bool def = false) const;
-
- QX11InfoData *x11data;
-
- friend class QX11PaintEngine;
- friend class QPixmap;
- friend class QX11PlatformPixmap;
- friend class QWidget;
- friend class QWidgetPrivate;
- friend class QGLWidget;
- friend void qt_init(QApplicationPrivate *priv, int, Display *display, Qt::HANDLE visual,
- Qt::HANDLE colormap);
- friend void qt_cleanup();
- friend void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &a);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QX11INFO_X11_H
diff --git a/src/widgets/platforms/x11/qximinputcontext_p.h b/src/widgets/platforms/x11/qximinputcontext_p.h
deleted file mode 100644
index 47c6f78ff9..0000000000
--- a/src/widgets/platforms/x11/qximinputcontext_p.h
+++ /dev/null
@@ -1,142 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QXIMInputContext class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QXIMINPUTCONTEXT_P_H
-#define QXIMINPUTCONTEXT_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.
-//
-
-#if !defined(Q_NO_IM)
-
-#include "QtCore/qglobal.h"
-#include "QtWidgets/qinputcontext.h"
-#include "QtGui/qfont.h"
-#include "QtCore/qhash.h"
-#ifdef Q_WS_X11
-#include "QtCore/qlist.h"
-#include "QtCore/qbitarray.h"
-#include "QtGui/qwindowdefs.h"
-#include "private/qt_x11_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QKeyEvent;
-class QWidget;
-class QFont;
-class QString;
-
-class QXIMInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- struct ICData {
- XIC ic;
- XFontSet fontset;
- QWidget *widget;
- QString text;
- QBitArray selectedChars;
- bool composing;
- bool preeditEmpty;
- void clear();
- };
-
- QXIMInputContext();
- ~QXIMInputContext();
-
- QString identifierName();
- QString language();
-
- void reset();
-
- void mouseHandler( int x, QMouseEvent *event);
- bool isComposing() const;
-
- void setFocusWidget( QWidget *w );
- void widgetDestroyed(QWidget *w);
-
- void create_xim();
- void close_xim();
-
- void update();
-
- ICData *icData() const;
-protected:
- bool x11FilterEvent( QWidget *keywidget, XEvent *event );
-
-private:
- static XIMStyle xim_style;
-
- QString _language;
- XIM xim;
- QHash<WId, ICData *> ximData;
-
- ICData *createICData(QWidget *w);
-};
-
-QT_END_NAMESPACE
-
-#endif // Q_NO_IM
-
-#endif // QXIMINPUTCONTEXT_P_H
diff --git a/src/widgets/platforms/x11/qximinputcontext_x11.cpp b/src/widgets/platforms/x11/qximinputcontext_x11.cpp
deleted file mode 100644
index de1212c556..0000000000
--- a/src/widgets/platforms/x11/qximinputcontext_x11.cpp
+++ /dev/null
@@ -1,885 +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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QXIMInputContext class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qdebug.h"
-#include "qximinputcontext_p.h"
-
-#if !defined(QT_NO_IM)
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_NO_XIM)
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qplatformdefs.h"
-
-#include "qapplication.h"
-#include "qwidget.h"
-#include "qstring.h"
-#include "qlist.h"
-#include "qtextcodec.h"
-#include "qevent.h"
-#include "qtextformat.h"
-
-#include "qx11info_x11.h"
-
-#include <stdlib.h>
-#include <limits.h>
-QT_END_INCLUDE_NAMESPACE
-
-// #define QT_XIM_DEBUG
-#ifdef QT_XIM_DEBUG
-#define XIM_DEBUG qDebug
-#else
-#define XIM_DEBUG if (0) qDebug
-#endif
-
-// from qapplication_x11.cpp
-// #### move to X11 struct
-extern XIMStyle qt_xim_preferred_style;
-extern char *qt_ximServer;
-extern int qt_ximComposingKeycode;
-extern QTextCodec * qt_input_mapper;
-
-XIMStyle QXIMInputContext::xim_style = 0;
-// moved from qapplication_x11.cpp
-static const XIMStyle xim_default_style = XIMPreeditCallbacks | XIMStatusNothing;
-
-
-extern "C" {
-#ifdef USE_X11R6_XIM
- static void xim_create_callback(XIM /*im*/,
- XPointer client_data,
- XPointer /*call_data*/)
- {
- QXIMInputContext *qic = reinterpret_cast<QXIMInputContext *>(client_data);
- // qDebug("xim_create_callback");
- qic->create_xim();
- }
-
- static void xim_destroy_callback(XIM /*im*/,
- XPointer client_data,
- XPointer /*call_data*/)
- {
- QXIMInputContext *qic = reinterpret_cast<QXIMInputContext *>(client_data);
- // qDebug("xim_destroy_callback");
- qic->close_xim();
- XRegisterIMInstantiateCallback(X11->display, 0, 0, 0,
- (XIMProc) xim_create_callback, reinterpret_cast<char *>(qic));
- }
-#endif // USE_X11R6_XIM
-
- static int xic_start_callback(XIC, XPointer client_data, XPointer) {
- QXIMInputContext *qic = (QXIMInputContext *) client_data;
- if (!qic) {
- XIM_DEBUG("xic_start_callback: no qic");
- return 0;
- }
- QXIMInputContext::ICData *data = qic->icData();
- if (!data) {
- XIM_DEBUG("xic_start_callback: no ic data");
- return 0;
- }
- XIM_DEBUG("xic_start_callback");
-
- data->clear();
- data->composing = true;
-
- return 0;
- }
-
- static int xic_draw_callback(XIC, XPointer client_data, XPointer call_data) {
- QXIMInputContext *qic = (QXIMInputContext *) client_data;
- if (!qic) {
- XIM_DEBUG("xic_draw_callback: no qic");
- return 0;
- }
- QXIMInputContext::ICData *data = qic->icData();
- if (!data) {
- XIM_DEBUG("xic_draw_callback: no ic data");
- return 0;
- }
- XIM_DEBUG("xic_draw_callback");
-
-
- if(!data->composing) {
- data->clear();
- data->composing = true;
- }
-
- XIMPreeditDrawCallbackStruct *drawstruct = (XIMPreeditDrawCallbackStruct *) call_data;
- XIMText *text = (XIMText *) drawstruct->text;
- int cursor = drawstruct->caret, sellen = 0, selstart = 0;
-
- if (!drawstruct->caret && !drawstruct->chg_first && !drawstruct->chg_length && !text) {
- if(data->text.isEmpty()) {
- XIM_DEBUG("compose emptied");
- // if the composition string has been emptied, we need
- // to send an InputMethodEnd event
- QInputMethodEvent e;
- qic->sendEvent(e);
- data->clear();
-
- // if the commit string has coming after here, InputMethodStart
- // will be sent dynamically
- }
- return 0;
- }
-
- if (text) {
- char *str = 0;
- if (text->encoding_is_wchar) {
- int l = wcstombs(NULL, text->string.wide_char, text->length);
- if (l != -1) {
- str = new char[l + 1];
- wcstombs(str, text->string.wide_char, l);
- str[l] = 0;
- }
- } else
- str = text->string.multi_byte;
-
- if (!str)
- return 0;
-
- QString s = QString::fromLocal8Bit(str);
-
- if (text->encoding_is_wchar)
- delete [] str;
-
- if (drawstruct->chg_length < 0)
- data->text.replace(drawstruct->chg_first, INT_MAX, s);
- else
- data->text.replace(drawstruct->chg_first, drawstruct->chg_length, s);
-
- if (data->selectedChars.size() < data->text.length()) {
- // expand the selectedChars array if the compose string is longer
- int from = data->selectedChars.size();
- data->selectedChars.resize(data->text.length());
- for (int x = from; x < data->selectedChars.size(); ++x)
- data->selectedChars.clearBit(x);
- }
-
- // determine if the changed chars are selected based on text->feedback
- for (int x = 0; x < text->length; ++x)
- data->selectedChars.setBit(x + drawstruct->chg_first,
- (text->feedback ? (text->feedback[x] & XIMReverse) : 0));
-
- // figure out where the selection starts, and how long it is
- bool started = false;
- for (int x = 0; x < qMin(data->selectedChars.size(), data->text.length()); ++x) {
- if (started) {
- if (data->selectedChars.testBit(x)) ++sellen;
- else break;
- } else {
- if (data->selectedChars.testBit(x)) {
- selstart = x;
- started = true;
- sellen = 1;
- }
- }
- }
- } else {
- if (drawstruct->chg_length == 0)
- drawstruct->chg_length = -1;
-
- data->text.remove(drawstruct->chg_first, drawstruct->chg_length);
- bool qt_compose_emptied = data->text.isEmpty();
- if (qt_compose_emptied) {
- XIM_DEBUG("compose emptied 2 text=%s", data->text.toUtf8().constData());
- // if the composition string has been emptied, we need
- // to send an InputMethodEnd event
- QInputMethodEvent e;
- qic->sendEvent(e);
- data->clear();
- // if the commit string has coming after here, InputMethodStart
- // will be sent dynamically
- return 0;
- }
- }
-
- XIM_DEBUG("sending compose: '%s', cursor=%d, sellen=%d",
- data->text.toUtf8().constData(), cursor, sellen);
- QList<QInputMethodEvent::Attribute> attrs;
- if (selstart > 0)
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selstart,
- qic->standardFormat(QInputContext::PreeditFormat));
- if (sellen)
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selstart, sellen,
- qic->standardFormat(QInputContext::SelectionFormat));
- if (selstart + sellen < data->text.length())
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- selstart + sellen, data->text.length() - selstart - sellen,
- qic->standardFormat(QInputContext::PreeditFormat));
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, sellen ? 0 : 1, QVariant());
- QInputMethodEvent e(data->text, attrs);
- data->preeditEmpty = data->text.isEmpty();
- qic->sendEvent(e);
-
- return 0;
- }
-
- static int xic_done_callback(XIC, XPointer client_data, XPointer) {
- QXIMInputContext *qic = (QXIMInputContext *) client_data;
- if (!qic)
- return 0;
-
- XIM_DEBUG("xic_done_callback");
- // Don't send InputMethodEnd here. QXIMInputContext::x11FilterEvent()
- // handles InputMethodEnd with commit string.
- return 0;
- }
-}
-
-void QXIMInputContext::ICData::clear()
-{
- text = QString();
- selectedChars.clear();
- composing = false;
- preeditEmpty = true;
-}
-
-QXIMInputContext::ICData *QXIMInputContext::icData() const
-{
- if (QWidget *w = focusWidget())
- return ximData.value(w->effectiveWinId());
- return 0;
-}
-/* The cache here is needed, as X11 leaks a few kb for every
- XFreeFontSet call, so we avoid creating and deletion of fontsets as
- much as possible
-*/
-static XFontSet fontsetCache[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-static int fontsetRefCount = 0;
-
-static const char * const fontsetnames[] = {
- "-*-fixed-medium-r-*-*-16-*,-*-*-medium-r-*-*-16-*",
- "-*-fixed-medium-i-*-*-16-*,-*-*-medium-i-*-*-16-*",
- "-*-fixed-bold-r-*-*-16-*,-*-*-bold-r-*-*-16-*",
- "-*-fixed-bold-i-*-*-16-*,-*-*-bold-i-*-*-16-*",
- "-*-fixed-medium-r-*-*-24-*,-*-*-medium-r-*-*-24-*",
- "-*-fixed-medium-i-*-*-24-*,-*-*-medium-i-*-*-24-*",
- "-*-fixed-bold-r-*-*-24-*,-*-*-bold-r-*-*-24-*",
- "-*-fixed-bold-i-*-*-24-*,-*-*-bold-i-*-*-24-*"
-};
-
-static XFontSet getFontSet(const QFont &f)
-{
- int i = 0;
- if (f.italic())
- i |= 1;
- if (f.bold())
- i |= 2;
-
- if (f.pointSize() > 20)
- i += 4;
-
- if (!fontsetCache[i]) {
- Display* dpy = X11->display;
- int missCount;
- char** missList;
- fontsetCache[i] = XCreateFontSet(dpy, fontsetnames[i], &missList, &missCount, 0);
- if(missCount > 0)
- XFreeStringList(missList);
- if (!fontsetCache[i]) {
- fontsetCache[i] = XCreateFontSet(dpy, "-*-fixed-*-*-*-*-16-*", &missList, &missCount, 0);
- if(missCount > 0)
- XFreeStringList(missList);
- if (!fontsetCache[i])
- fontsetCache[i] = (XFontSet)-1;
- }
- }
- return (fontsetCache[i] == (XFontSet)-1) ? 0 : fontsetCache[i];
-}
-
-extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp
-#ifndef QT_NO_XKB
-extern QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName);
-#endif
-
-QXIMInputContext::QXIMInputContext()
-{
- if (!qt_xim_preferred_style) // no configured input style, use the default
- qt_xim_preferred_style = xim_default_style;
-
- xim = 0;
- QByteArray ximServerName(qt_ximServer);
- if (qt_ximServer)
- ximServerName.prepend("@im=");
- else
- ximServerName = "";
-
- if (!XSupportsLocale())
-#ifndef QT_NO_DEBUG
- qWarning("Qt: Locale not supported on X server")
-#endif
- ;
-#ifdef USE_X11R6_XIM
- else if (XSetLocaleModifiers (ximServerName.constData()) == 0)
- qWarning("Qt: Cannot set locale modifiers: %s", ximServerName.constData());
- else
- XRegisterIMInstantiateCallback(X11->display, 0, 0, 0,
- (XIMProc) xim_create_callback, reinterpret_cast<char *>(this));
-#else // !USE_X11R6_XIM
- else if (XSetLocaleModifiers ("") == 0)
- qWarning("Qt: Cannot set locale modifiers");
- else
- QXIMInputContext::create_xim();
-#endif // USE_X11R6_XIM
-
-#ifndef QT_NO_XKB
- if (X11->use_xkb) {
- QByteArray layoutName;
- QByteArray variantName;
-
- Atom type = XNone;
- int format = 0;
- ulong nitems = 0;
- ulong bytesAfter = 0;
- uchar *data = 0;
- if (XGetWindowProperty(X11->display, RootWindow(X11->display, 0), ATOM(_XKB_RULES_NAMES), 0, 1024,
- false, XA_STRING, &type, &format, &nitems, &bytesAfter, &data) == Success
- && type == XA_STRING && format == 8 && nitems > 2) {
-
- char *names[5] = { 0, 0, 0, 0, 0 };
- char *p = reinterpret_cast<char *>(data), *end = p + nitems;
- int i = 0;
- do {
- names[i++] = p;
- p += qstrlen(p) + 1;
- } while (p < end);
-
- QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(',');
- QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(',');
- for (int i = 0; i < qMin(layoutNames.count(), variantNames.count()); ++i ) {
- QByteArray variantName = variantNames.at(i);
- const int dashPos = variantName.indexOf("-");
- if (dashPos >= 0)
- variantName.truncate(dashPos);
- QLocale keyboardInputLocale = q_getKeyboardLocale(layoutNames.at(i), variantName);
- if (keyboardInputLocale.textDirection() == Qt::RightToLeft)
- qt_use_rtl_extensions = true;
- }
- }
-
- if (data)
- XFree(data);
- }
-#endif // QT_NO_XKB
-
-}
-
-
-/*!\internal
- Creates the application input method.
-*/
-void QXIMInputContext::create_xim()
-{
- ++fontsetRefCount;
-#ifndef QT_NO_XIM
- xim = XOpenIM(X11->display, 0, 0, 0);
- if (xim) {
-
-#ifdef USE_X11R6_XIM
- XIMCallback destroy;
- destroy.callback = (XIMProc) xim_destroy_callback;
- destroy.client_data = XPointer(this);
- if (XSetIMValues(xim, XNDestroyCallback, &destroy, (char *) 0) != 0)
- qWarning("Xlib doesn't support destroy callback");
-#endif // USE_X11R6_XIM
-
- XIMStyles *styles = 0;
- XGetIMValues(xim, XNQueryInputStyle, &styles, (char *) 0, (char *) 0);
- if (styles) {
- int i;
- for (i = 0; !xim_style && i < styles->count_styles; i++) {
- if (styles->supported_styles[i] == qt_xim_preferred_style) {
- xim_style = qt_xim_preferred_style;
- break;
- }
- }
- // if the preferred input style couldn't be found, look for
- // Nothing
- for (i = 0; !xim_style && i < styles->count_styles; i++) {
- if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) {
- xim_style = XIMPreeditNothing | XIMStatusNothing;
- break;
- }
- }
- // ... and failing that, None.
- for (i = 0; !xim_style && i < styles->count_styles; i++) {
- if (styles->supported_styles[i] == (XIMPreeditNone |
- XIMStatusNone)) {
- xim_style = XIMPreeditNone | XIMStatusNone;
- break;
- }
- }
-
- // qDebug("QApplication: using im style %lx", xim_style);
- XFree((char *)styles);
- }
-
- if (xim_style) {
-
-#ifdef USE_X11R6_XIM
- XUnregisterIMInstantiateCallback(X11->display, 0, 0, 0,
- (XIMProc) xim_create_callback, reinterpret_cast<char *>(this));
-#endif // USE_X11R6_XIM
-
- if (QWidget *focusWidget = QApplication::focusWidget()) {
- // reinitialize input context after the input method
- // server (like SCIM) has been launched without
- // requiring the user to manually switch focus.
- if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled)
- && focusWidget->testAttribute(Qt::WA_WState_Created)
- && focusWidget->isEnabled())
- setFocusWidget(focusWidget);
- }
- // following code fragment is not required for immodule
- // version of XIM
-#if 0
- QWidgetList list = qApp->topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- w->d->createTLSysExtra();
- }
-#endif
- } else {
- // Give up
- qWarning("No supported input style found."
- " See InputMethod documentation.");
- close_xim();
- }
- }
-#endif // QT_NO_XIM
-}
-
-/*!\internal
- Closes the application input method.
-*/
-void QXIMInputContext::close_xim()
-{
- for(QHash<WId, ICData *>::const_iterator i = ximData.constBegin(),
- e = ximData.constEnd(); i != e; ++i) {
- ICData *data = i.value();
- if (data->ic)
- XDestroyIC(data->ic);
- delete data;
- }
- ximData.clear();
-
- if ( --fontsetRefCount == 0 ) {
- Display *dpy = X11->display;
- for ( int i = 0; i < 8; i++ ) {
- if ( fontsetCache[i] && fontsetCache[i] != (XFontSet)-1 ) {
- XFreeFontSet(dpy, fontsetCache[i]);
- fontsetCache[i] = 0;
- }
- }
- }
-
- setFocusWidget(0);
- xim = 0;
-}
-
-
-
-QXIMInputContext::~QXIMInputContext()
-{
- XIM old_xim = xim; // close_xim clears xim pointer.
- close_xim();
- if (old_xim)
- XCloseIM(old_xim);
-}
-
-
-QString QXIMInputContext::identifierName()
-{
- // the name should be "xim" rather than "XIM" to be consistent
- // with corresponding immodule of GTK+
- return QLatin1String("xim");
-}
-
-
-QString QXIMInputContext::language()
-{
- QString language;
- if (xim) {
- QByteArray locale(XLocaleOfIM(xim));
-
- if (locale.startsWith("zh")) {
- // Chinese language should be formed as "zh_CN", "zh_TW", "zh_HK"
- language = QLatin1String(locale.left(5));
- } else {
- // other languages should be two-letter ISO 639 language code
- language = QLatin1String(locale.left(2));
- }
- }
- return language;
-}
-
-void QXIMInputContext::reset()
-{
- QWidget *w = focusWidget();
- if (!w)
- return;
-
- ICData *data = ximData.value(w->effectiveWinId());
- if (!data)
- return;
-
- if (data->ic) {
- char *mb = XmbResetIC(data->ic);
- QInputMethodEvent e;
- if (mb) {
- e.setCommitString(QString::fromLocal8Bit(mb));
- XFree(mb);
- data->preeditEmpty = false; // force sending an event
- }
- if (!data->preeditEmpty) {
- sendEvent(e);
- update();
- }
- }
- data->clear();
-}
-
-void QXIMInputContext::widgetDestroyed(QWidget *w)
-{
- QInputContext::widgetDestroyed(w);
- ICData *data = ximData.take(w->effectiveWinId());
- if (!data)
- return;
-
- data->clear();
- if (data->ic)
- XDestroyIC(data->ic);
- delete data;
-}
-
-void QXIMInputContext::mouseHandler(int pos, QMouseEvent *e)
-{
- if(e->type() != QEvent::MouseButtonPress)
- return;
-
- XIM_DEBUG("QXIMInputContext::mouseHandler pos=%d", pos);
- if (QWidget *w = focusWidget()) {
- ICData *data = ximData.value(w->effectiveWinId());
- if (!data)
- return;
- if (pos < 0 || pos > data->text.length())
- reset();
- // ##### handle mouse position
- }
-}
-
-bool QXIMInputContext::isComposing() const
-{
- QWidget *w = focusWidget();
- if (!w)
- return false;
-
- ICData *data = ximData.value(w->effectiveWinId());
- if (!data)
- return false;
- return data->composing;
-}
-
-void QXIMInputContext::setFocusWidget(QWidget *w)
-{
- if (!xim)
- return;
- QWidget *oldFocus = focusWidget();
- if (oldFocus == w)
- return;
-
- if (language() != QLatin1String("ja"))
- reset();
-
- if (oldFocus) {
- ICData *data = ximData.value(oldFocus->effectiveWinId());
- if (data && data->ic)
- XUnsetICFocus(data->ic);
- }
-
- QInputContext::setFocusWidget(w);
-
- if (!w || w->inputMethodHints() & (Qt::ImhExclusiveInputMask | Qt::ImhHiddenText))
- return;
-
- ICData *data = ximData.value(w->effectiveWinId());
- if (!data)
- data = createICData(w);
-
- if (data->ic)
- XSetICFocus(data->ic);
-
- update();
-}
-
-
-bool QXIMInputContext::x11FilterEvent(QWidget *keywidget, XEvent *event)
-{
- int xkey_keycode = event->xkey.keycode;
- if (!keywidget->testAttribute(Qt::WA_WState_Created))
- return false;
- if (XFilterEvent(event, keywidget->effectiveWinId())) {
- qt_ximComposingKeycode = xkey_keycode; // ### not documented in xlib
-
- update();
-
- return true;
- }
- if (event->type != XKeyPress || event->xkey.keycode != 0)
- return false;
-
- QWidget *w = focusWidget();
- if (keywidget != w)
- return false;
- ICData *data = ximData.value(w->effectiveWinId());
- if (!data)
- return false;
-
- // input method has sent us a commit string
- QByteArray string;
- string.resize(513);
- KeySym key; // unused
- Status status; // unused
- QString text;
- int count = XmbLookupString(data->ic, &event->xkey, string.data(), string.size(),
- &key, &status);
-
- if (status == XBufferOverflow) {
- string.resize(count + 1);
- count = XmbLookupString(data->ic, &event->xkey, string.data(), string.size(),
- &key, &status);
- }
- if (count > 0) {
- // XmbLookupString() gave us some text, convert it to unicode
- text = qt_input_mapper->toUnicode(string.constData() , count);
- if (text.isEmpty()) {
- // codec couldn't convert to unicode? this can happen when running in the
- // C locale (or with no LANG set). try converting from latin-1
- text = QString::fromLatin1(string.constData(), count);
- }
- }
-
-#if 0
- if (!(xim_style & XIMPreeditCallbacks) || !isComposing()) {
- // ############### send a regular key event here!
- ;
- }
-#endif
-
- QInputMethodEvent e;
- e.setCommitString(text);
- sendEvent(e);
- data->clear();
-
- update();
-
- return true;
-}
-
-
-QXIMInputContext::ICData *QXIMInputContext::createICData(QWidget *w)
-{
- ICData *data = new ICData;
- data->widget = w;
- data->preeditEmpty = true;
-
- XVaNestedList preedit_attr = 0;
- XIMCallback startcallback, drawcallback, donecallback;
-
- QFont font = w->font();
- data->fontset = getFontSet(font);
-
- if (xim_style & XIMPreeditArea) {
- XRectangle rect;
- rect.x = 0;
- rect.y = 0;
- rect.width = w->width();
- rect.height = w->height();
-
- preedit_attr = XVaCreateNestedList(0,
- XNArea, &rect,
- XNFontSet, data->fontset,
- (char *) 0);
- } else if (xim_style & XIMPreeditPosition) {
- XPoint spot;
- spot.x = 1;
- spot.y = 1;
-
- preedit_attr = XVaCreateNestedList(0,
- XNSpotLocation, &spot,
- XNFontSet, data->fontset,
- (char *) 0);
- } else if (xim_style & XIMPreeditCallbacks) {
- startcallback.client_data = (XPointer) this;
- startcallback.callback = (XIMProc) xic_start_callback;
- drawcallback.client_data = (XPointer) this;
- drawcallback.callback = (XIMProc)xic_draw_callback;
- donecallback.client_data = (XPointer) this;
- donecallback.callback = (XIMProc) xic_done_callback;
-
- preedit_attr = XVaCreateNestedList(0,
- XNPreeditStartCallback, &startcallback,
- XNPreeditDrawCallback, &drawcallback,
- XNPreeditDoneCallback, &donecallback,
- (char *) 0);
- }
-
- if (preedit_attr) {
- data->ic = XCreateIC(xim,
- XNInputStyle, xim_style,
- XNClientWindow, w->effectiveWinId(),
- XNPreeditAttributes, preedit_attr,
- (char *) 0);
- XFree(preedit_attr);
- } else {
- data->ic = XCreateIC(xim,
- XNInputStyle, xim_style,
- XNClientWindow, w->effectiveWinId(),
- (char *) 0);
- }
-
- if (data->ic) {
- // when resetting the input context, preserve the input state
- (void) XSetICValues(data->ic, XNResetState, XIMPreserveState, (char *) 0);
- } else {
- qWarning("Failed to create XIC");
- }
-
- ximData[w->effectiveWinId()] = data;
- return data;
-}
-
-void QXIMInputContext::update()
-{
- QWidget *w = focusWidget();
- if (!w)
- return;
-
- ICData *data = ximData.value(w->effectiveWinId());
- if (!data || !data->ic)
- return;
-
- QRect r = w->inputMethodQuery(Qt::ImMicroFocus).toRect();
- QPoint p;
- if (w->nativeParentWidget())
- p = w->mapTo(w->nativeParentWidget(), QPoint((r.left() + r.right() + 1)/2, r.bottom()));
- else
- p = QPoint((r.left() + r.right() + 1)/2, r.bottom());
- XPoint spot;
- spot.x = p.x();
- spot.y = p.y();
-
- r = w->rect();
- XRectangle area;
- area.x = r.x();
- area.y = r.y();
- area.width = r.width();
- area.height = r.height();
-
- XFontSet fontset = getFontSet(qvariant_cast<QFont>(w->inputMethodQuery(Qt::ImFont)));
- if (data->fontset == fontset)
- fontset = 0;
- else
- data->fontset = fontset;
-
- XVaNestedList preedit_attr;
- if (fontset)
- preedit_attr = XVaCreateNestedList(0,
- XNSpotLocation, &spot,
- XNArea, &area,
- XNFontSet, fontset,
- (char *) 0);
- else
- preedit_attr = XVaCreateNestedList(0,
- XNSpotLocation, &spot,
- XNArea, &area,
- (char *) 0);
-
- XSetICValues(data->ic, XNPreeditAttributes, preedit_attr, (char *) 0);
- XFree(preedit_attr);
-}
-
-
-#else
-/*
- When QT_NO_XIM is defined, we provide a dummy implementation for
- this class. The reason for this is that the header file is moc'ed
- regardless of QT_NO_XIM. The best would be to remove the file
- completely from the pri file is QT_NO_XIM was defined, or for moc
- to understand this preprocessor directive. Since the header does
- not declare this class when QT_NO_XIM is defined, this is dead
- code.
-*/
-bool QXIMInputContext::isComposing() const { return false; }
-QString QXIMInputContext::identifierName() { return QString(); }
-void QXIMInputContext::mouseHandler(int, QMouseEvent *) {}
-void QXIMInputContext::setFocusWidget(QWidget *) {}
-void QXIMInputContext::reset() {}
-void QXIMInputContext::update() {}
-QXIMInputContext::~QXIMInputContext() {}
-void QXIMInputContext::widgetDestroyed(QWidget *) {}
-QString QXIMInputContext::language() { return QString(); }
-bool QXIMInputContext::x11FilterEvent(QWidget *, XEvent *) { return true; }
-
-#endif //QT_NO_XIM
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_IM