xref: /aoo42x/main/vcl/win/source/app/salinfo.cxx (revision 79aad27f)
1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9f62ea84SAndrew Rist  * distributed with this work for additional information
6*9f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9f62ea84SAndrew Rist  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9f62ea84SAndrew Rist  *
13*9f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist  * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9f62ea84SAndrew Rist  * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist  * under the License.
19*9f62ea84SAndrew Rist  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "svsys.h"
28cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "tools/debug.hxx"
31cdf0e10cSrcweir #include "tools/string.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include "vcl/window.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include "win/salsys.h"
36cdf0e10cSrcweir #include "win/salframe.h"
37cdf0e10cSrcweir #include "win/salinst.h"
38cdf0e10cSrcweir #include "win/saldata.hxx"
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include "svdata.hxx"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <hash_map>
43cdf0e10cSrcweir 
CreateSalSystem()44cdf0e10cSrcweir SalSystem* WinSalInstance::CreateSalSystem()
45cdf0e10cSrcweir {
46cdf0e10cSrcweir     return new WinSalSystem();
47cdf0e10cSrcweir }
48cdf0e10cSrcweir 
~WinSalSystem()49cdf0e10cSrcweir WinSalSystem::~WinSalSystem()
50cdf0e10cSrcweir {
51cdf0e10cSrcweir }
52cdf0e10cSrcweir 
53cdf0e10cSrcweir // -----------------------------------------------------------------------
54cdf0e10cSrcweir 
ImplEnumMonitorProc(HMONITOR hMonitor,HDC hDC,LPRECT lpRect,LPARAM dwData)55cdf0e10cSrcweir static BOOL CALLBACK ImplEnumMonitorProc( HMONITOR hMonitor,
56cdf0e10cSrcweir                                           HDC hDC,
57cdf0e10cSrcweir                                           LPRECT lpRect,
58cdf0e10cSrcweir                                           LPARAM dwData )
59cdf0e10cSrcweir {
60cdf0e10cSrcweir 	WinSalSystem* pSys = reinterpret_cast<WinSalSystem*>(dwData);
61cdf0e10cSrcweir 	return pSys->handleMonitorCallback( reinterpret_cast<sal_IntPtr>(hMonitor),
62cdf0e10cSrcweir 									    reinterpret_cast<sal_IntPtr>(hDC),
63cdf0e10cSrcweir 										reinterpret_cast<sal_IntPtr>(lpRect) );
64cdf0e10cSrcweir }
65cdf0e10cSrcweir 
handleMonitorCallback(sal_IntPtr hMonitor,sal_IntPtr,sal_IntPtr)66cdf0e10cSrcweir sal_Bool WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor, sal_IntPtr, sal_IntPtr )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir     MONITORINFOEXW aInfo;
69cdf0e10cSrcweir     aInfo.cbSize = sizeof( aInfo );
70cdf0e10cSrcweir     if( GetMonitorInfoW( reinterpret_cast<HMONITOR>(hMonitor), &aInfo ) )
71cdf0e10cSrcweir     {
72cdf0e10cSrcweir         aInfo.szDevice[CCHDEVICENAME-1] = 0;
73cdf0e10cSrcweir         rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aInfo.szDevice) );
74cdf0e10cSrcweir         std::map< rtl::OUString, unsigned int >::const_iterator it =
75cdf0e10cSrcweir             m_aDeviceNameToMonitor.find( aDeviceName );
76cdf0e10cSrcweir         if( it != m_aDeviceNameToMonitor.end() )
77cdf0e10cSrcweir         {
78cdf0e10cSrcweir             DisplayMonitor& rMon( m_aMonitors[ it->second ] );
79cdf0e10cSrcweir             rMon.m_aArea = Rectangle( Point( aInfo.rcMonitor.left,
80cdf0e10cSrcweir                                              aInfo.rcMonitor.top ),
81cdf0e10cSrcweir                                       Size( aInfo.rcMonitor.right - aInfo.rcMonitor.left,
82cdf0e10cSrcweir                                             aInfo.rcMonitor.bottom - aInfo.rcMonitor.top ) );
83cdf0e10cSrcweir             rMon.m_aWorkArea = Rectangle( Point( aInfo.rcWork.left,
84cdf0e10cSrcweir                                                  aInfo.rcWork.top ),
85cdf0e10cSrcweir                                           Size( aInfo.rcWork.right - aInfo.rcWork.left,
86cdf0e10cSrcweir                                                 aInfo.rcWork.bottom - aInfo.rcWork.top ) );
87cdf0e10cSrcweir             if( (aInfo.dwFlags & MONITORINFOF_PRIMARY) != 0 )
88cdf0e10cSrcweir 				m_nPrimary = it->second;
89cdf0e10cSrcweir         }
90cdf0e10cSrcweir     }
91cdf0e10cSrcweir     return sal_True;
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
clearMonitors()94cdf0e10cSrcweir void WinSalSystem::clearMonitors()
95cdf0e10cSrcweir {
96cdf0e10cSrcweir 	m_aMonitors.clear();
97cdf0e10cSrcweir 	m_nPrimary = 0;
98cdf0e10cSrcweir }
99cdf0e10cSrcweir 
initMonitors()100cdf0e10cSrcweir bool WinSalSystem::initMonitors()
101cdf0e10cSrcweir {
102cdf0e10cSrcweir     if( m_aMonitors.size() > 0 )
103cdf0e10cSrcweir         return true;
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     bool winVerOk = true;
106cdf0e10cSrcweir 
107cdf0e10cSrcweir     // multi monitor calls not available on Win95/NT
108cdf0e10cSrcweir     if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
109cdf0e10cSrcweir     {
110cdf0e10cSrcweir         if ( aSalShlData.maVersionInfo.dwMajorVersion <= 4 )
111cdf0e10cSrcweir             winVerOk = false;	// NT
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir     else if( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
114cdf0e10cSrcweir     {
115cdf0e10cSrcweir         if ( aSalShlData.maVersionInfo.dwMajorVersion == 4 && aSalShlData.maVersionInfo.dwMinorVersion == 0 )
116cdf0e10cSrcweir             winVerOk = false;	// Win95
117cdf0e10cSrcweir     }
118cdf0e10cSrcweir     if( winVerOk )
119cdf0e10cSrcweir     {
120cdf0e10cSrcweir         int nMonitors = GetSystemMetrics( SM_CMONITORS );
121cdf0e10cSrcweir         if( nMonitors == 1 )
122cdf0e10cSrcweir         {
123cdf0e10cSrcweir             int w = GetSystemMetrics( SM_CXSCREEN );
124cdf0e10cSrcweir             int h = GetSystemMetrics( SM_CYSCREEN );
125cdf0e10cSrcweir             m_aMonitors.push_back( DisplayMonitor( rtl::OUString(),
126cdf0e10cSrcweir                                                    rtl::OUString(),
127cdf0e10cSrcweir                                                    Rectangle( Point(), Size( w, h ) ),
128cdf0e10cSrcweir                                                    Rectangle( Point(), Size( w, h ) ),
129cdf0e10cSrcweir                                                    0 ) );
130cdf0e10cSrcweir             m_aDeviceNameToMonitor[ rtl::OUString() ] = 0;
131cdf0e10cSrcweir             m_nPrimary = 0;
132cdf0e10cSrcweir             RECT aWorkRect;
133cdf0e10cSrcweir             if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) )
134cdf0e10cSrcweir                 m_aMonitors.back().m_aWorkArea =  Rectangle( aWorkRect.left, aWorkRect.top,
135cdf0e10cSrcweir                                                              aWorkRect.right, aWorkRect.bottom );
136cdf0e10cSrcweir         }
137cdf0e10cSrcweir         else
138cdf0e10cSrcweir         {
139cdf0e10cSrcweir             DISPLAY_DEVICEW aDev;
140cdf0e10cSrcweir             aDev.cb = sizeof( aDev );
141cdf0e10cSrcweir             DWORD nDevice = 0;
142cdf0e10cSrcweir 			std::hash_map< rtl::OUString, int, rtl::OUStringHash > aDeviceStringCount;
143cdf0e10cSrcweir             while( EnumDisplayDevicesW( NULL, nDevice++, &aDev, 0 ) )
144cdf0e10cSrcweir             {
145cdf0e10cSrcweir                 if( (aDev.StateFlags & DISPLAY_DEVICE_ACTIVE)
146cdf0e10cSrcweir                     && !(aDev.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ) // sort out non/disabled monitors
147cdf0e10cSrcweir                 {
148cdf0e10cSrcweir                     aDev.DeviceName[31] = 0;
149cdf0e10cSrcweir                     aDev.DeviceString[127] = 0;
150cdf0e10cSrcweir                     rtl::OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aDev.DeviceName) );
151cdf0e10cSrcweir                     rtl::OUString aDeviceString( reinterpret_cast<const sal_Unicode *>(aDev.DeviceString) );
152cdf0e10cSrcweir 					if( aDeviceStringCount.find( aDeviceString ) == aDeviceStringCount.end() )
153cdf0e10cSrcweir 						aDeviceStringCount[ aDeviceString ] = 1;
154cdf0e10cSrcweir 					else
155cdf0e10cSrcweir 						aDeviceStringCount[ aDeviceString ]++;
156cdf0e10cSrcweir                     m_aDeviceNameToMonitor[ aDeviceName ] = m_aMonitors.size();
157cdf0e10cSrcweir                     m_aMonitors.push_back( DisplayMonitor( aDeviceString,
158cdf0e10cSrcweir                                                            aDeviceName,
159cdf0e10cSrcweir                                                            Rectangle(),
160cdf0e10cSrcweir                                                            Rectangle(),
161cdf0e10cSrcweir                                                            aDev.StateFlags ) );
162cdf0e10cSrcweir                 }
163cdf0e10cSrcweir             }
164cdf0e10cSrcweir             HDC aDesktopRC = GetDC( NULL );
165cdf0e10cSrcweir             EnumDisplayMonitors( aDesktopRC, NULL, ImplEnumMonitorProc, reinterpret_cast<LPARAM>(this) );
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 			// append monitor numbers to name strings
168cdf0e10cSrcweir 			std::hash_map< rtl::OUString, int, rtl::OUStringHash > aDevCount( aDeviceStringCount );
169cdf0e10cSrcweir 			unsigned int nMonitors = m_aMonitors.size();
170cdf0e10cSrcweir 			for( unsigned int i = 0; i < nMonitors; i++ )
171cdf0e10cSrcweir 			{
172cdf0e10cSrcweir 				const rtl::OUString& rDev( m_aMonitors[i].m_aName );
173cdf0e10cSrcweir 				if( aDeviceStringCount[ rDev ] > 1 )
174cdf0e10cSrcweir 				{
175cdf0e10cSrcweir 					int nInstance = aDeviceStringCount[ rDev ] - (-- aDevCount[ rDev ] );
176cdf0e10cSrcweir 					rtl::OUStringBuffer aBuf( rDev.getLength() + 8 );
177cdf0e10cSrcweir 					aBuf.append( rDev );
178cdf0e10cSrcweir 					aBuf.appendAscii( " (" );
179cdf0e10cSrcweir 					aBuf.append( sal_Int32( nInstance ) );
180cdf0e10cSrcweir 					aBuf.append( sal_Unicode(')') );
181cdf0e10cSrcweir 					m_aMonitors[ i ].m_aName = aBuf.makeStringAndClear();
182cdf0e10cSrcweir 				}
183cdf0e10cSrcweir 			}
184cdf0e10cSrcweir         }
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir     else
187cdf0e10cSrcweir     {
188cdf0e10cSrcweir         int w = GetSystemMetrics( SM_CXSCREEN );
189cdf0e10cSrcweir         int h = GetSystemMetrics( SM_CYSCREEN );
190cdf0e10cSrcweir         m_aMonitors.push_back( DisplayMonitor( rtl::OUString(),
191cdf0e10cSrcweir                                                rtl::OUString(),
192cdf0e10cSrcweir                                                Rectangle( Point(), Size( w, h ) ),
193cdf0e10cSrcweir                                                Rectangle( Point(), Size( w, h ) ),
194cdf0e10cSrcweir                                                0 ) );
195cdf0e10cSrcweir         m_aDeviceNameToMonitor[ rtl::OUString() ] = 0;
196cdf0e10cSrcweir         m_nPrimary = 0;
197cdf0e10cSrcweir         RECT aWorkRect;
198cdf0e10cSrcweir         if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) )
199cdf0e10cSrcweir             m_aMonitors.back().m_aWorkArea =  Rectangle( aWorkRect.left, aWorkRect.top,
200cdf0e10cSrcweir                                                          aWorkRect.right, aWorkRect.bottom );
201cdf0e10cSrcweir     }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     return m_aMonitors.size() > 0;
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
GetDisplayScreenCount()206cdf0e10cSrcweir unsigned int WinSalSystem::GetDisplayScreenCount()
207cdf0e10cSrcweir {
208cdf0e10cSrcweir     initMonitors();
209cdf0e10cSrcweir     return m_aMonitors.size();
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
IsMultiDisplay()212cdf0e10cSrcweir bool WinSalSystem::IsMultiDisplay()
213cdf0e10cSrcweir {
214cdf0e10cSrcweir     return false;
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
GetDefaultDisplayNumber()217cdf0e10cSrcweir unsigned int WinSalSystem::GetDefaultDisplayNumber()
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     initMonitors();
220cdf0e10cSrcweir     return m_nPrimary;
221cdf0e10cSrcweir }
222cdf0e10cSrcweir 
GetDisplayScreenPosSizePixel(unsigned int nScreen)223cdf0e10cSrcweir Rectangle WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen )
224cdf0e10cSrcweir {
225cdf0e10cSrcweir     initMonitors();
226cdf0e10cSrcweir     return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aArea : Rectangle();
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
GetDisplayWorkAreaPosSizePixel(unsigned int nScreen)229cdf0e10cSrcweir Rectangle WinSalSystem::GetDisplayWorkAreaPosSizePixel( unsigned int nScreen )
230cdf0e10cSrcweir {
231cdf0e10cSrcweir     initMonitors();
232cdf0e10cSrcweir     return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aWorkArea : Rectangle();
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
GetScreenName(unsigned int nScreen)235cdf0e10cSrcweir rtl::OUString WinSalSystem::GetScreenName( unsigned int nScreen )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir 	initMonitors();
238cdf0e10cSrcweir 	return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aName : rtl::OUString();
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir // -----------------------------------------------------------------------
242cdf0e10cSrcweir /* We have to map the button identifier to the identifier used by the Win32
243cdf0e10cSrcweir    Platform SDK to specify the default button for the MessageBox API.
244cdf0e10cSrcweir    The first dimension is the button combination, the second dimension
245cdf0e10cSrcweir    is the button identifier.
246cdf0e10cSrcweir */
247cdf0e10cSrcweir static int DEFAULT_BTN_MAPPING_TABLE[][8] =
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     //  Undefined        OK             CANCEL         ABORT          RETRY          IGNORE         YES             NO
250cdf0e10cSrcweir     { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK
251cdf0e10cSrcweir     { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK_CANCEL
252cdf0e10cSrcweir     { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //ABORT_RETRY_IGNO
253cdf0e10cSrcweir     { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO_CANCEL
254cdf0e10cSrcweir     { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO
255cdf0e10cSrcweir     { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }  //RETRY_CANCEL
256cdf0e10cSrcweir };
257cdf0e10cSrcweir 
ShowNativeMessageBox(const String & rTitle,const String & rMessage,int nButtonCombination,int nDefaultButton)258cdf0e10cSrcweir int WinSalSystem::ShowNativeMessageBox(const String& rTitle, const String& rMessage, int nButtonCombination, int nDefaultButton)
259cdf0e10cSrcweir {
260cdf0e10cSrcweir     DBG_ASSERT( nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
261cdf0e10cSrcweir                 nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
262cdf0e10cSrcweir                 nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
263cdf0e10cSrcweir                 nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, "Invalid arguments!" );
264cdf0e10cSrcweir 
265cdf0e10cSrcweir     int nFlags = MB_TASKMODAL | MB_SETFOREGROUND | MB_ICONWARNING | nButtonCombination;
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     if (nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
268cdf0e10cSrcweir         nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
269cdf0e10cSrcweir         nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
270cdf0e10cSrcweir         nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO)
271cdf0e10cSrcweir         nFlags |= DEFAULT_BTN_MAPPING_TABLE[nButtonCombination][nDefaultButton];
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     //#107209 hide the splash screen if active
274cdf0e10cSrcweir     ImplSVData* pSVData = ImplGetSVData();
275cdf0e10cSrcweir     if (pSVData->mpIntroWindow)
276cdf0e10cSrcweir         pSVData->mpIntroWindow->Hide();
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     return MessageBoxW(
279cdf0e10cSrcweir         0,
280cdf0e10cSrcweir         reinterpret_cast<LPCWSTR>(rMessage.GetBuffer()),
281cdf0e10cSrcweir         reinterpret_cast<LPCWSTR>(rTitle.GetBuffer()),
282cdf0e10cSrcweir         nFlags);
283cdf0e10cSrcweir }
284