src/gui/kernel/qguifunctions_wince.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/kernel/qguifunctions_wince.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qguifunctions_wince.h"
+#include <shellapi.h>
+#include <QtCore/qlibrary.h>
+
+QT_USE_NAMESPACE
+
+struct AygSHINITDLGINFO
+{
+    DWORD dwMask;
+    HWND  hDlg;
+    DWORD dwFlags;
+};
+
+struct AygSIPINFO
+{
+    DWORD   cbSize;
+    DWORD   fdwFlags;
+    RECT    rcVisibleDesktop;
+    RECT    rcSipRect;
+    DWORD   dwImDataSize;
+    void   *pvImData;
+};
+
+#ifndef SHIDIF_CANCELBUTTON
+#define SHIDIF_CANCELBUTTON 0x0080
+#endif
+
+#ifndef SHIDIM_FLAGS
+#define SHIDIM_FLAGS 0x0001
+#endif
+
+#ifndef SHIDIF_DONEBUTTON
+#define SHIDIF_DONEBUTTON 0x0001
+#endif
+#ifndef SHIDIF_SIZEDLGFULLSCREEN
+#define SHIDIF_SIZEDLGFULLSCREEN 0x0004
+#endif
+
+#ifndef 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
+
+typedef BOOL (*AygInitDialog)(AygSHINITDLGINFO*);
+typedef BOOL (*AygFullScreen)(HWND, DWORD);
+typedef BOOL (*AygSHSipInfo)(UINT, UINT, PVOID, UINT);
+
+static AygInitDialog ptrAygInitDialog = 0;
+static AygFullScreen ptrAygFullScreen = 0;
+static AygSHSipInfo  ptrAygSHSipInfo  = 0;
+static bool aygResolved = false;
+
+static void resolveAygLibs()
+{
+    if (!aygResolved) {
+        aygResolved = true;
+        QLibrary ayglib(QLatin1String("aygshell"));
+        if (!ayglib.load())
+            return;
+        ptrAygInitDialog = (AygInitDialog) ayglib.resolve("SHInitDialog");
+        ptrAygFullScreen = (AygFullScreen) ayglib.resolve("SHFullScreen");
+        ptrAygSHSipInfo  = (AygSHSipInfo)  ayglib.resolve("SHSipInfo");
+    }
+}
+
+struct DIBINFO : public BITMAPINFO
+{
+    RGBQUAD arColors[255];
+
+    operator LPBITMAPINFO() { return (LPBITMAPINFO) this; }
+    operator LPBITMAPINFOHEADER() { return &bmiHeader; }
+    RGBQUAD* ColorTable() { return bmiColors; }
+};
+
+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()
+{
+    return ((qt_wince_get_version() == 52) && (qt_wince_get_build() > 2000));
+}
+
+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;
+        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_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);
+}