merged tag ooo/DEV300_m102
[LibreOffice.git] / vcl / win / source / app / salinfo.cxx
blobc635fdfc984513a2aa6a30131a275ffe6be36b67
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
31 // rely on unicows on for multimon functions for older versions
32 #if WINVER < 0x0500
33 #undef WINVER
34 #define WINVER 0x0500
35 #endif
37 #define VCL_NEED_BASETSD
38 #include "tools/presys.h"
39 #if defined _MSC_VER
40 #pragma warning(push, 1)
41 #endif
42 #include <windows.h>
43 #include <winuser.h>
44 #if defined _MSC_VER
45 #pragma warning(pop)
46 #endif
47 #include "tools/postsys.h"
49 #include "tools/string.hxx"
50 #include "salsys.h"
51 #include "salframe.h"
52 #include "salinst.h"
53 #include "saldata.hxx"
54 #include "tools/debug.hxx"
55 #include "vcl/svdata.hxx"
56 #include "vcl/window.hxx"
58 #include "rtl/ustrbuf.hxx"
60 #include <hash_map>
62 SalSystem* WinSalInstance::CreateSalSystem()
64 return new WinSalSystem();
67 WinSalSystem::~WinSalSystem()
71 // -----------------------------------------------------------------------
73 static BOOL CALLBACK ImplEnumMonitorProc( HMONITOR hMonitor,
74 HDC hDC,
75 LPRECT lpRect,
76 LPARAM dwData )
78 WinSalSystem* pSys = reinterpret_cast<WinSalSystem*>(dwData);
79 return pSys->handleMonitorCallback( reinterpret_cast<sal_IntPtr>(hMonitor),
80 reinterpret_cast<sal_IntPtr>(hDC),
81 reinterpret_cast<sal_IntPtr>(lpRect) );
84 sal_Bool WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor, sal_IntPtr, sal_IntPtr )
86 MONITORINFOEXW aInfo;
87 aInfo.cbSize = sizeof( aInfo );
88 if( GetMonitorInfoW( reinterpret_cast<HMONITOR>(hMonitor), &aInfo ) )
90 aInfo.szDevice[CCHDEVICENAME-1] = 0;
91 rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aInfo.szDevice) );
92 std::map< rtl::OUString, unsigned int >::const_iterator it =
93 m_aDeviceNameToMonitor.find( aDeviceName );
94 if( it != m_aDeviceNameToMonitor.end() )
96 DisplayMonitor& rMon( m_aMonitors[ it->second ] );
97 rMon.m_aArea = Rectangle( Point( aInfo.rcMonitor.left,
98 aInfo.rcMonitor.top ),
99 Size( aInfo.rcMonitor.right - aInfo.rcMonitor.left,
100 aInfo.rcMonitor.bottom - aInfo.rcMonitor.top ) );
101 rMon.m_aWorkArea = Rectangle( Point( aInfo.rcWork.left,
102 aInfo.rcWork.top ),
103 Size( aInfo.rcWork.right - aInfo.rcWork.left,
104 aInfo.rcWork.bottom - aInfo.rcWork.top ) );
105 if( (aInfo.dwFlags & MONITORINFOF_PRIMARY) != 0 )
106 m_nPrimary = it->second;
109 return sal_True;
112 void WinSalSystem::clearMonitors()
114 m_aMonitors.clear();
115 m_nPrimary = 0;
118 bool WinSalSystem::initMonitors()
120 if( m_aMonitors.size() > 0 )
121 return true;
123 bool winVerOk = true;
125 // multi monitor calls not available on Win95/NT
126 if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
128 if ( aSalShlData.maVersionInfo.dwMajorVersion <= 4 )
129 winVerOk = false; // NT
131 else if( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
133 if ( aSalShlData.maVersionInfo.dwMajorVersion == 4 && aSalShlData.maVersionInfo.dwMinorVersion == 0 )
134 winVerOk = false; // Win95
136 if( winVerOk )
138 int nMonitors = GetSystemMetrics( SM_CMONITORS );
139 if( nMonitors == 1 )
141 int w = GetSystemMetrics( SM_CXSCREEN );
142 int h = GetSystemMetrics( SM_CYSCREEN );
143 m_aMonitors.push_back( DisplayMonitor( rtl::OUString(),
144 rtl::OUString(),
145 Rectangle( Point(), Size( w, h ) ),
146 Rectangle( Point(), Size( w, h ) ),
147 0 ) );
148 m_aDeviceNameToMonitor[ rtl::OUString() ] = 0;
149 m_nPrimary = 0;
150 RECT aWorkRect;
151 if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) )
152 m_aMonitors.back().m_aWorkArea = Rectangle( aWorkRect.left, aWorkRect.top,
153 aWorkRect.right, aWorkRect.bottom );
155 else
157 DISPLAY_DEVICEW aDev;
158 aDev.cb = sizeof( aDev );
159 DWORD nDevice = 0;
160 std::hash_map< rtl::OUString, int, rtl::OUStringHash > aDeviceStringCount;
161 while( EnumDisplayDevicesW( NULL, nDevice++, &aDev, 0 ) )
163 if( (aDev.StateFlags & DISPLAY_DEVICE_ACTIVE)
164 && !(aDev.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ) // sort out non/disabled monitors
166 aDev.DeviceName[31] = 0;
167 aDev.DeviceString[127] = 0;
168 rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aDev.DeviceName) );
169 rtl::OUString aDeviceString( reinterpret_cast<const sal_Unicode *>(aDev.DeviceString) );
170 if( aDeviceStringCount.find( aDeviceString ) == aDeviceStringCount.end() )
171 aDeviceStringCount[ aDeviceString ] = 1;
172 else
173 aDeviceStringCount[ aDeviceString ]++;
174 m_aDeviceNameToMonitor[ aDeviceName ] = m_aMonitors.size();
175 m_aMonitors.push_back( DisplayMonitor( aDeviceString,
176 aDeviceName,
177 Rectangle(),
178 Rectangle(),
179 aDev.StateFlags ) );
182 HDC aDesktopRC = GetDC( NULL );
183 EnumDisplayMonitors( aDesktopRC, NULL, ImplEnumMonitorProc, reinterpret_cast<LPARAM>(this) );
185 // append monitor numbers to name strings
186 std::hash_map< rtl::OUString, int, rtl::OUStringHash > aDevCount( aDeviceStringCount );
187 unsigned int nMonitors = m_aMonitors.size();
188 for( unsigned int i = 0; i < nMonitors; i++ )
190 const rtl::OUString& rDev( m_aMonitors[i].m_aName );
191 if( aDeviceStringCount[ rDev ] > 1 )
193 int nInstance = aDeviceStringCount[ rDev ] - (-- aDevCount[ rDev ] );
194 rtl::OUStringBuffer aBuf( rDev.getLength() + 8 );
195 aBuf.append( rDev );
196 aBuf.appendAscii( " (" );
197 aBuf.append( sal_Int32( nInstance ) );
198 aBuf.append( sal_Unicode(')') );
199 m_aMonitors[ i ].m_aName = aBuf.makeStringAndClear();
204 else
206 int w = GetSystemMetrics( SM_CXSCREEN );
207 int h = GetSystemMetrics( SM_CYSCREEN );
208 m_aMonitors.push_back( DisplayMonitor( rtl::OUString(),
209 rtl::OUString(),
210 Rectangle( Point(), Size( w, h ) ),
211 Rectangle( Point(), Size( w, h ) ),
212 0 ) );
213 m_aDeviceNameToMonitor[ rtl::OUString() ] = 0;
214 m_nPrimary = 0;
215 RECT aWorkRect;
216 if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) )
217 m_aMonitors.back().m_aWorkArea = Rectangle( aWorkRect.left, aWorkRect.top,
218 aWorkRect.right, aWorkRect.bottom );
221 return m_aMonitors.size() > 0;
224 unsigned int WinSalSystem::GetDisplayScreenCount()
226 initMonitors();
227 return m_aMonitors.size();
230 bool WinSalSystem::IsMultiDisplay()
232 return false;
235 unsigned int WinSalSystem::GetDefaultDisplayNumber()
237 initMonitors();
238 return m_nPrimary;
241 Rectangle WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen )
243 initMonitors();
244 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aArea : Rectangle();
247 Rectangle WinSalSystem::GetDisplayWorkAreaPosSizePixel( unsigned int nScreen )
249 initMonitors();
250 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aWorkArea : Rectangle();
253 rtl::OUString WinSalSystem::GetScreenName( unsigned int nScreen )
255 initMonitors();
256 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aName : rtl::OUString();
259 // -----------------------------------------------------------------------
260 /* We have to map the button identifier to the identifier used by the Win32
261 Platform SDK to specify the default button for the MessageBox API.
262 The first dimension is the button combination, the second dimension
263 is the button identifier.
265 static int DEFAULT_BTN_MAPPING_TABLE[][8] =
267 // Undefined OK CANCEL ABORT RETRY IGNORE YES NO
268 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK
269 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK_CANCEL
270 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //ABORT_RETRY_IGNO
271 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO_CANCEL
272 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO
273 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 } //RETRY_CANCEL
276 int WinSalSystem::ShowNativeMessageBox(const String& rTitle, const String& rMessage, int nButtonCombination, int nDefaultButton)
278 DBG_ASSERT( nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
279 nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
280 nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
281 nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, "Invalid arguments!" );
283 int nFlags = MB_TASKMODAL | MB_SETFOREGROUND | MB_ICONWARNING | nButtonCombination;
285 if (nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
286 nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
287 nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
288 nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO)
289 nFlags |= DEFAULT_BTN_MAPPING_TABLE[nButtonCombination][nDefaultButton];
291 //#107209 hide the splash screen if active
292 ImplSVData* pSVData = ImplGetSVData();
293 if (pSVData->mpIntroWindow)
294 pSVData->mpIntroWindow->Hide();
296 return MessageBoxW(
298 reinterpret_cast<LPCWSTR>(rMessage.GetBuffer()),
299 reinterpret_cast<LPCWSTR>(rTitle.GetBuffer()),
300 nFlags);