diff options
Diffstat (limited to 'vcl/win/source/app/salinfo.cxx')
-rw-r--r-- | vcl/win/source/app/salinfo.cxx | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/vcl/win/source/app/salinfo.cxx b/vcl/win/source/app/salinfo.cxx new file mode 100644 index 000000000000..020e555d8498 --- /dev/null +++ b/vcl/win/source/app/salinfo.cxx @@ -0,0 +1,272 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +// rely on unicows on for multimon functions for older versions +#if WINVER < 0x0500 +#undef WINVER +#define WINVER 0x0500 +#endif + +#define VCL_NEED_BASETSD +#include "tools/presys.h" +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <winuser.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include "tools/postsys.h" + +#include "tools/string.hxx" +#include "salsys.h" +#include "salframe.h" +#include "salinst.h" +#include "saldata.hxx" +#include "tools/debug.hxx" +#include "vcl/svdata.hxx" +#include "vcl/window.hxx" + +#include "rtl/ustrbuf.hxx" + +#include <boost/unordered_map.hpp> + +SalSystem* WinSalInstance::CreateSalSystem() +{ + return new WinSalSystem(); +} + +WinSalSystem::~WinSalSystem() +{ +} + +// ----------------------------------------------------------------------- + +static BOOL CALLBACK ImplEnumMonitorProc( HMONITOR hMonitor, + HDC hDC, + LPRECT lpRect, + LPARAM dwData ) +{ + WinSalSystem* pSys = reinterpret_cast<WinSalSystem*>(dwData); + return pSys->handleMonitorCallback( reinterpret_cast<sal_IntPtr>(hMonitor), + reinterpret_cast<sal_IntPtr>(hDC), + reinterpret_cast<sal_IntPtr>(lpRect) ); +} + +sal_Bool WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor, sal_IntPtr, sal_IntPtr ) +{ + MONITORINFOEXW aInfo; + aInfo.cbSize = sizeof( aInfo ); + if( GetMonitorInfoW( reinterpret_cast<HMONITOR>(hMonitor), &aInfo ) ) + { + aInfo.szDevice[CCHDEVICENAME-1] = 0; + rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aInfo.szDevice) ); + std::map< rtl::OUString, unsigned int >::const_iterator it = + m_aDeviceNameToMonitor.find( aDeviceName ); + if( it != m_aDeviceNameToMonitor.end() ) + { + DisplayMonitor& rMon( m_aMonitors[ it->second ] ); + rMon.m_aArea = Rectangle( Point( aInfo.rcMonitor.left, + aInfo.rcMonitor.top ), + Size( aInfo.rcMonitor.right - aInfo.rcMonitor.left, + aInfo.rcMonitor.bottom - aInfo.rcMonitor.top ) ); + rMon.m_aWorkArea = Rectangle( Point( aInfo.rcWork.left, + aInfo.rcWork.top ), + Size( aInfo.rcWork.right - aInfo.rcWork.left, + aInfo.rcWork.bottom - aInfo.rcWork.top ) ); + if( (aInfo.dwFlags & MONITORINFOF_PRIMARY) != 0 ) + m_nPrimary = it->second; + } + } + return sal_True; +} + +void WinSalSystem::clearMonitors() +{ + m_aMonitors.clear(); + m_nPrimary = 0; +} + +bool WinSalSystem::initMonitors() +{ + if( m_aMonitors.size() > 0 ) + return true; + + int nMonitors = GetSystemMetrics( SM_CMONITORS ); + if( nMonitors == 1 ) + { + int w = GetSystemMetrics( SM_CXSCREEN ); + int h = GetSystemMetrics( SM_CYSCREEN ); + m_aMonitors.push_back( DisplayMonitor( rtl::OUString(), + rtl::OUString(), + Rectangle( Point(), Size( w, h ) ), + Rectangle( Point(), Size( w, h ) ), + 0 ) ); + m_aDeviceNameToMonitor[ rtl::OUString() ] = 0; + m_nPrimary = 0; + RECT aWorkRect; + if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) ) + m_aMonitors.back().m_aWorkArea = Rectangle( aWorkRect.left, aWorkRect.top, + aWorkRect.right, aWorkRect.bottom ); + } + else + { + DISPLAY_DEVICEW aDev; + aDev.cb = sizeof( aDev ); + DWORD nDevice = 0; + boost::unordered_map< rtl::OUString, int, rtl::OUStringHash > aDeviceStringCount; + while( EnumDisplayDevicesW( NULL, nDevice++, &aDev, 0 ) ) + { + if( (aDev.StateFlags & DISPLAY_DEVICE_ACTIVE) + && !(aDev.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ) // sort out non/disabled monitors + { + aDev.DeviceName[31] = 0; + aDev.DeviceString[127] = 0; + rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aDev.DeviceName) ); + rtl::OUString aDeviceString( reinterpret_cast<const sal_Unicode *>(aDev.DeviceString) ); + if( aDeviceStringCount.find( aDeviceString ) == aDeviceStringCount.end() ) + aDeviceStringCount[ aDeviceString ] = 1; + else + aDeviceStringCount[ aDeviceString ]++; + m_aDeviceNameToMonitor[ aDeviceName ] = m_aMonitors.size(); + m_aMonitors.push_back( DisplayMonitor( aDeviceString, + aDeviceName, + Rectangle(), + Rectangle(), + aDev.StateFlags ) ); + } + } + HDC aDesktopRC = GetDC( NULL ); + EnumDisplayMonitors( aDesktopRC, NULL, ImplEnumMonitorProc, reinterpret_cast<LPARAM>(this) ); + + // append monitor numbers to name strings + boost::unordered_map< rtl::OUString, int, rtl::OUStringHash > aDevCount( aDeviceStringCount ); + unsigned int nMonitors = m_aMonitors.size(); + for( unsigned int i = 0; i < nMonitors; i++ ) + { + const rtl::OUString& rDev( m_aMonitors[i].m_aName ); + if( aDeviceStringCount[ rDev ] > 1 ) + { + int nInstance = aDeviceStringCount[ rDev ] - (-- aDevCount[ rDev ] ); + rtl::OUStringBuffer aBuf( rDev.getLength() + 8 ); + aBuf.append( rDev ); + aBuf.appendAscii( " (" ); + aBuf.append( sal_Int32( nInstance ) ); + aBuf.append( sal_Unicode(')') ); + m_aMonitors[ i ].m_aName = aBuf.makeStringAndClear(); + } + } + } + + return m_aMonitors.size() > 0; +} + +unsigned int WinSalSystem::GetDisplayScreenCount() +{ + initMonitors(); + return m_aMonitors.size(); +} + +bool WinSalSystem::IsMultiDisplay() +{ + return false; +} + +unsigned int WinSalSystem::GetDefaultDisplayNumber() +{ + initMonitors(); + return m_nPrimary; +} + +Rectangle WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen ) +{ + initMonitors(); + return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aArea : Rectangle(); +} + +Rectangle WinSalSystem::GetDisplayWorkAreaPosSizePixel( unsigned int nScreen ) +{ + initMonitors(); + return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aWorkArea : Rectangle(); +} + +rtl::OUString WinSalSystem::GetScreenName( unsigned int nScreen ) +{ + initMonitors(); + return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aName : rtl::OUString(); +} + +// ----------------------------------------------------------------------- +/* We have to map the button identifier to the identifier used by the Win32 + Platform SDK to specify the default button for the MessageBox API. + The first dimension is the button combination, the second dimension + is the button identifier. +*/ +static int DEFAULT_BTN_MAPPING_TABLE[][8] = +{ + // Undefined OK CANCEL ABORT RETRY IGNORE YES NO + { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK + { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK_CANCEL + { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //ABORT_RETRY_IGNO + { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO_CANCEL + { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO + { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 } //RETRY_CANCEL +}; + +int WinSalSystem::ShowNativeMessageBox(const String& rTitle, const String& rMessage, int nButtonCombination, int nDefaultButton) +{ + DBG_ASSERT( nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK && + nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL && + nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK && + nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, "Invalid arguments!" ); + + int nFlags = MB_TASKMODAL | MB_SETFOREGROUND | MB_ICONWARNING | nButtonCombination; + + if (nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK && + nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL && + nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK && + nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO) + nFlags |= DEFAULT_BTN_MAPPING_TABLE[nButtonCombination][nDefaultButton]; + + //#107209 hide the splash screen if active + ImplSVData* pSVData = ImplGetSVData(); + if (pSVData->mpIntroWindow) + pSVData->mpIntroWindow->Hide(); + + return MessageBoxW( + 0, + reinterpret_cast<LPCWSTR>(rMessage.GetBuffer()), + reinterpret_cast<LPCWSTR>(rTitle.GetBuffer()), + nFlags); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |