Bump version to 4.1-6
[LibreOffice.git] / vcl / win / source / app / salinfo.cxx
blob3262ce31ab7256990e4123073c36a964967af6bc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "svsys.h"
22 #include "rtl/ustrbuf.hxx"
24 #include "tools/debug.hxx"
26 #include "vcl/window.hxx"
28 #include "win/salsys.h"
29 #include "win/salframe.h"
30 #include "win/salinst.h"
31 #include "win/saldata.hxx"
33 #include "svdata.hxx"
35 #include <boost/unordered_map.hpp>
37 SalSystem* WinSalInstance::CreateSalSystem()
39 return new WinSalSystem();
42 WinSalSystem::~WinSalSystem()
46 // -----------------------------------------------------------------------
48 static BOOL CALLBACK ImplEnumMonitorProc( HMONITOR hMonitor,
49 HDC hDC,
50 LPRECT lpRect,
51 LPARAM dwData )
53 WinSalSystem* pSys = reinterpret_cast<WinSalSystem*>(dwData);
54 return pSys->handleMonitorCallback( reinterpret_cast<sal_IntPtr>(hMonitor),
55 reinterpret_cast<sal_IntPtr>(hDC),
56 reinterpret_cast<sal_IntPtr>(lpRect) );
59 sal_Bool WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor, sal_IntPtr, sal_IntPtr )
61 MONITORINFOEXW aInfo;
62 aInfo.cbSize = sizeof( aInfo );
63 if( GetMonitorInfoW( reinterpret_cast<HMONITOR>(hMonitor), &aInfo ) )
65 aInfo.szDevice[CCHDEVICENAME-1] = 0;
66 OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aInfo.szDevice) );
67 std::map< OUString, unsigned int >::const_iterator it =
68 m_aDeviceNameToMonitor.find( aDeviceName );
69 if( it != m_aDeviceNameToMonitor.end() )
71 DisplayMonitor& rMon( m_aMonitors[ it->second ] );
72 rMon.m_aArea = Rectangle( Point( aInfo.rcMonitor.left,
73 aInfo.rcMonitor.top ),
74 Size( aInfo.rcMonitor.right - aInfo.rcMonitor.left,
75 aInfo.rcMonitor.bottom - aInfo.rcMonitor.top ) );
76 rMon.m_aWorkArea = Rectangle( Point( aInfo.rcWork.left,
77 aInfo.rcWork.top ),
78 Size( aInfo.rcWork.right - aInfo.rcWork.left,
79 aInfo.rcWork.bottom - aInfo.rcWork.top ) );
80 if( (aInfo.dwFlags & MONITORINFOF_PRIMARY) != 0 )
81 m_nPrimary = it->second;
84 return sal_True;
87 void WinSalSystem::clearMonitors()
89 m_aMonitors.clear();
90 m_nPrimary = 0;
93 bool WinSalSystem::initMonitors()
95 if( m_aMonitors.size() > 0 )
96 return true;
98 int nMonitors = GetSystemMetrics( SM_CMONITORS );
99 if( nMonitors == 1 )
101 int w = GetSystemMetrics( SM_CXSCREEN );
102 int h = GetSystemMetrics( SM_CYSCREEN );
103 m_aMonitors.push_back( DisplayMonitor( OUString(),
104 OUString(),
105 Rectangle( Point(), Size( w, h ) ),
106 Rectangle( Point(), Size( w, h ) ),
107 0 ) );
108 m_aDeviceNameToMonitor[ OUString() ] = 0;
109 m_nPrimary = 0;
110 RECT aWorkRect;
111 if( SystemParametersInfo( SPI_GETWORKAREA, 0, &aWorkRect, 0 ) )
112 m_aMonitors.back().m_aWorkArea = Rectangle( aWorkRect.left, aWorkRect.top,
113 aWorkRect.right, aWorkRect.bottom );
115 else
117 DISPLAY_DEVICEW aDev;
118 aDev.cb = sizeof( aDev );
119 DWORD nDevice = 0;
120 boost::unordered_map< OUString, int, OUStringHash > aDeviceStringCount;
121 while( EnumDisplayDevicesW( NULL, nDevice++, &aDev, 0 ) )
123 if( (aDev.StateFlags & DISPLAY_DEVICE_ACTIVE)
124 && !(aDev.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ) // sort out non/disabled monitors
126 aDev.DeviceName[31] = 0;
127 aDev.DeviceString[127] = 0;
128 OUString aDeviceName( reinterpret_cast<const sal_Unicode *>(aDev.DeviceName) );
129 OUString aDeviceString( reinterpret_cast<const sal_Unicode *>(aDev.DeviceString) );
130 if( aDeviceStringCount.find( aDeviceString ) == aDeviceStringCount.end() )
131 aDeviceStringCount[ aDeviceString ] = 1;
132 else
133 aDeviceStringCount[ aDeviceString ]++;
134 m_aDeviceNameToMonitor[ aDeviceName ] = m_aMonitors.size();
135 m_aMonitors.push_back( DisplayMonitor( aDeviceString,
136 aDeviceName,
137 Rectangle(),
138 Rectangle(),
139 aDev.StateFlags ) );
142 HDC aDesktopRC = GetDC( NULL );
143 EnumDisplayMonitors( aDesktopRC, NULL, ImplEnumMonitorProc, reinterpret_cast<LPARAM>(this) );
145 // append monitor numbers to name strings
146 boost::unordered_map< OUString, int, OUStringHash > aDevCount( aDeviceStringCount );
147 unsigned int nMonitorCount = m_aMonitors.size();
148 for( unsigned int i = 0; i < nMonitorCount; i++ )
150 const OUString& rDev( m_aMonitors[i].m_aName );
151 if( aDeviceStringCount[ rDev ] > 1 )
153 int nInstance = aDeviceStringCount[ rDev ] - (-- aDevCount[ rDev ] );
154 OUStringBuffer aBuf( rDev.getLength() + 8 );
155 aBuf.append( rDev );
156 aBuf.appendAscii( " (" );
157 aBuf.append( sal_Int32( nInstance ) );
158 aBuf.append( sal_Unicode(')') );
159 m_aMonitors[ i ].m_aName = aBuf.makeStringAndClear();
164 return m_aMonitors.size() > 0;
167 unsigned int WinSalSystem::GetDisplayScreenCount()
169 initMonitors();
170 return m_aMonitors.size();
173 unsigned int WinSalSystem::GetDisplayBuiltInScreen()
175 initMonitors();
176 return m_nPrimary;
179 Rectangle WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen )
181 initMonitors();
182 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aArea : Rectangle();
185 Rectangle WinSalSystem::GetDisplayScreenWorkAreaPosSizePixel( unsigned int nScreen )
187 initMonitors();
188 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aWorkArea : Rectangle();
191 OUString WinSalSystem::GetDisplayScreenName( unsigned int nScreen )
193 initMonitors();
194 return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen].m_aName : OUString();
197 // -----------------------------------------------------------------------
198 /* We have to map the button identifier to the identifier used by the Win32
199 Platform SDK to specify the default button for the MessageBox API.
200 The first dimension is the button combination, the second dimension
201 is the button identifier.
203 static int DEFAULT_BTN_MAPPING_TABLE[][8] =
205 // Undefined OK CANCEL ABORT RETRY IGNORE YES NO
206 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK
207 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK_CANCEL
208 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //ABORT_RETRY_IGNO
209 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO_CANCEL
210 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO
211 { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 } //RETRY_CANCEL
214 int WinSalSystem::ShowNativeMessageBox(const OUString& rTitle, const OUString& rMessage, int nButtonCombination, int nDefaultButton, SAL_UNUSED_PARAMETER bool)
216 DBG_ASSERT( nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
217 nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
218 nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
219 nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, "Invalid arguments!" );
221 int nFlags = MB_TASKMODAL | MB_SETFOREGROUND | MB_ICONWARNING | nButtonCombination;
223 if (nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
224 nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
225 nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
226 nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO)
227 nFlags |= DEFAULT_BTN_MAPPING_TABLE[nButtonCombination][nDefaultButton];
229 ImplHideSplash();
230 return MessageBoxW(
232 reinterpret_cast<LPCWSTR>(rMessage.getStr()),
233 reinterpret_cast<LPCWSTR>(rTitle.getStr()),
234 nFlags);
237 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */