merge the formfield patch from ooo-build
[ooovba.git] / vcl / win / source / app / salinfo.cxx
blob1450739368b8cbd057bb4f97d5be085d2585386c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salinfo.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 // rely on unicows on for multimon functions for older versions
35 #if WINVER < 0x0500
36 #undef WINVER
37 #define WINVER 0x0500
38 #endif
40 #define VCL_NEED_BASETSD
41 #include "tools/presys.h"
42 #if defined _MSC_VER
43 #pragma warning(push, 1)
44 #endif
45 #include <windows.h>
46 #include <winuser.h>
47 #if defined _MSC_VER
48 #pragma warning(pop)
49 #endif
50 #include "tools/postsys.h"
52 #include "tools/string.hxx"
53 #include "salsys.h"
54 #include "salframe.h"
55 #include "salinst.h"
56 #include "saldata.hxx"
57 #include "tools/debug.hxx"
58 #include "vcl/svdata.hxx"
59 #include "vcl/window.hxx"
61 #include "rtl/ustrbuf.hxx"
63 #include <hash_map>
65 SalSystem* WinSalInstance::CreateSalSystem()
67 return new WinSalSystem();
70 WinSalSystem::~WinSalSystem()
74 // -----------------------------------------------------------------------
76 static WIN_BOOL CALLBACK ImplEnumMonitorProc( HMONITOR hMonitor,
77 HDC hDC,
78 LPRECT lpRect,
79 LPARAM dwData )
81 WinSalSystem* pSys = reinterpret_cast<WinSalSystem*>(dwData);
82 return pSys->handleMonitorCallback( reinterpret_cast<sal_IntPtr>(hMonitor),
83 reinterpret_cast<sal_IntPtr>(hDC),
84 reinterpret_cast<sal_IntPtr>(lpRect) );
87 BOOL WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor, sal_IntPtr, sal_IntPtr )
89 MONITORINFOEXW aInfo;
90 aInfo.cbSize = sizeof( aInfo );
91 if( GetMonitorInfoW( reinterpret_cast<HMONITOR>(hMonitor), &aInfo ) )
93 aInfo.szDevice[CCHDEVICENAME-1] = 0;
94 rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aInfo.szDevice) );
95 std::map< rtl::OUString, unsigned int >::const_iterator it =
96 m_aDeviceNameToMonitor.find( aDeviceName );
97 if( it != m_aDeviceNameToMonitor.end() )
99 DisplayMonitor& rMon( m_aMonitors[ it->second ] );
100 rMon.m_aArea = Rectangle( Point( aInfo.rcMonitor.left,
101 aInfo.rcMonitor.top ),
102 Size( aInfo.rcMonitor.right - aInfo.rcMonitor.left,
103 aInfo.rcMonitor.bottom - aInfo.rcMonitor.top ) );
104 rMon.m_aWorkArea = Rectangle( Point( aInfo.rcWork.left,
105 aInfo.rcWork.top ),
106 Size( aInfo.rcWork.right - aInfo.rcWork.left,
107 aInfo.rcWork.bottom - aInfo.rcWork.top ) );
108 if( (aInfo.dwFlags & MONITORINFOF_PRIMARY) != 0 )
109 m_nPrimary = it->second;
112 return TRUE;
115 void WinSalSystem::clearMonitors()
117 m_aMonitors.clear();
118 m_nPrimary = 0;
121 bool WinSalSystem::initMonitors()
123 if( m_aMonitors.size() > 0 )
124 return true;
126 bool winVerOk = true;
128 // multi monitor calls not available on Win95/NT
129 if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
131 if ( aSalShlData.maVersionInfo.dwMajorVersion <= 4 )
132 winVerOk = false; // NT
134 else if( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
136 if ( aSalShlData.maVersionInfo.dwMajorVersion == 4 && aSalShlData.maVersionInfo.dwMinorVersion == 0 )
137 winVerOk = false; // Win95
139 if( winVerOk )
141 int nMonitors = GetSystemMetrics( SM_CMONITORS );
142 if( nMonitors == 1 )
144 int w = GetSystemMetrics( SM_CXSCREEN );
145 int h = GetSystemMetrics( SM_CYSCREEN );
146 m_aMonitors.push_back( DisplayMonitor( rtl::OUString(),
147 rtl::OUString(),
148 Rectangle( Point(), Size( w, h ) ),
149 Rectangle( Point(), Size( w, h ) ),
150 0 ) );
151 m_aDeviceNameToMonitor[ rtl::OUString() ] = 0;
152 m_nPrimary = 0;
153 RECT aWorkRect;
154 if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) )
155 m_aMonitors.back().m_aWorkArea = Rectangle( aWorkRect.left, aWorkRect.top,
156 aWorkRect.right, aWorkRect.bottom );
158 else
160 DISPLAY_DEVICEW aDev;
161 aDev.cb = sizeof( aDev );
162 DWORD nDevice = 0;
163 std::hash_map< rtl::OUString, int, rtl::OUStringHash > aDeviceStringCount;
164 while( EnumDisplayDevicesW( NULL, nDevice++, &aDev, 0 ) )
166 if( (aDev.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) == 0 ) // sort out non monitors
168 aDev.DeviceName[31] = 0;
169 aDev.DeviceString[127] = 0;
170 rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aDev.DeviceName) );
171 rtl::OUString aDeviceString( reinterpret_cast<const sal_Unicode *>(aDev.DeviceString) );
172 if( aDeviceStringCount.find( aDeviceString ) == aDeviceStringCount.end() )
173 aDeviceStringCount[ aDeviceString ] = 1;
174 else
175 aDeviceStringCount[ aDeviceString ]++;
176 m_aDeviceNameToMonitor[ aDeviceName ] = m_aMonitors.size();
177 m_aMonitors.push_back( DisplayMonitor( aDeviceString,
178 aDeviceName,
179 Rectangle(),
180 Rectangle(),
181 aDev.StateFlags ) );
184 HDC aDesktopRC = GetDC( NULL );
185 EnumDisplayMonitors( aDesktopRC, NULL, ImplEnumMonitorProc, reinterpret_cast<LPARAM>(this) );
187 // append monitor numbers to name strings
188 std::hash_map< rtl::OUString, int, rtl::OUStringHash > aDevCount( aDeviceStringCount );
189 unsigned int nMonitors = m_aMonitors.size();
190 for( unsigned int i = 0; i < nMonitors; i++ )
192 const rtl::OUString& rDev( m_aMonitors[i].m_aName );
193 if( aDeviceStringCount[ rDev ] > 1 )
195 int nInstance = aDeviceStringCount[ rDev ] - (-- aDevCount[ rDev ] );
196 rtl::OUStringBuffer aBuf( rDev.getLength() + 8 );
197 aBuf.append( rDev );
198 aBuf.appendAscii( " (" );
199 aBuf.append( sal_Int32( nInstance ) );
200 aBuf.append( sal_Unicode(')') );
201 m_aMonitors[ i ].m_aName = aBuf.makeStringAndClear();
206 else
208 int w = GetSystemMetrics( SM_CXSCREEN );
209 int h = GetSystemMetrics( SM_CYSCREEN );
210 m_aMonitors.push_back( DisplayMonitor( rtl::OUString(),
211 rtl::OUString(),
212 Rectangle( Point(), Size( w, h ) ),
213 Rectangle( Point(), Size( w, h ) ),
214 0 ) );
215 m_aDeviceNameToMonitor[ rtl::OUString() ] = 0;
216 m_nPrimary = 0;
217 RECT aWorkRect;
218 if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) )
219 m_aMonitors.back().m_aWorkArea = Rectangle( aWorkRect.left, aWorkRect.top,
220 aWorkRect.right, aWorkRect.bottom );
223 return m_aMonitors.size() > 0;
226 unsigned int WinSalSystem::GetDisplayScreenCount()
228 initMonitors();
229 return m_aMonitors.size();
232 bool WinSalSystem::IsMultiDisplay()
234 return false;
237 unsigned int WinSalSystem::GetDefaultDisplayNumber()
239 initMonitors();
240 return m_nPrimary;
243 Rectangle WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen )
245 initMonitors();
246 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aArea : Rectangle();
249 Rectangle WinSalSystem::GetDisplayWorkAreaPosSizePixel( unsigned int nScreen )
251 initMonitors();
252 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aWorkArea : Rectangle();
255 rtl::OUString WinSalSystem::GetScreenName( unsigned int nScreen )
257 initMonitors();
258 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aName : rtl::OUString();
261 // -----------------------------------------------------------------------
262 /* We have to map the button identifier to the identifier used by the Win32
263 Platform SDK to specify the default button for the MessageBox API.
264 The first dimension is the button combination, the second dimension
265 is the button identifier.
267 static int DEFAULT_BTN_MAPPING_TABLE[][8] =
269 // Undefined OK CANCEL ABORT RETRY IGNORE YES NO
270 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK
271 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK_CANCEL
272 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //ABORT_RETRY_IGNO
273 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO_CANCEL
274 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO
275 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 } //RETRY_CANCEL
278 int WinSalSystem::ShowNativeMessageBox(const String& rTitle, const String& rMessage, int nButtonCombination, int nDefaultButton)
280 DBG_ASSERT( nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
281 nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
282 nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
283 nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, "Invalid arguments!" );
285 int nFlags = MB_TASKMODAL | MB_SETFOREGROUND | MB_ICONWARNING | nButtonCombination;
287 if (nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
288 nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
289 nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
290 nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO)
291 nFlags |= DEFAULT_BTN_MAPPING_TABLE[nButtonCombination][nDefaultButton];
293 //#107209 hide the splash screen if active
294 ImplSVData* pSVData = ImplGetSVData();
295 if (pSVData->mpIntroWindow)
296 pSVData->mpIntroWindow->Hide();
298 return MessageBoxW(
300 reinterpret_cast<LPCWSTR>(rMessage.GetBuffer()),
301 reinterpret_cast<LPCWSTR>(rTitle.GetBuffer()),
302 nFlags);