diff -r 000000000000 -r 1918ee327afb src/gui/kernel/qguifunctions_wince.cpp --- /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 +#include + +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 (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); +}