1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <o3tl/char16_t2wchar_t.hxx>
23 #include <sal/log.hxx>
24 #include <vcl/window.hxx>
26 #include <win/salsys.h>
27 #include <win/salframe.h>
28 #include <win/salinst.h>
29 #include <win/saldata.hxx>
33 #include <unordered_map>
35 SalSystem
* WinSalInstance::CreateSalSystem()
37 return new WinSalSystem();
40 WinSalSystem::~WinSalSystem()
44 static BOOL CALLBACK
ImplEnumMonitorProc( HMONITOR hMonitor
,
49 WinSalSystem
* pSys
= reinterpret_cast<WinSalSystem
*>(dwData
);
50 return pSys
->handleMonitorCallback( reinterpret_cast<sal_IntPtr
>(hMonitor
),
51 reinterpret_cast<sal_IntPtr
>(hDC
),
52 reinterpret_cast<sal_IntPtr
>(lpRect
) );
55 bool WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor
, sal_IntPtr
, sal_IntPtr
)
58 aInfo
.cbSize
= sizeof( aInfo
);
59 if( GetMonitorInfoW( reinterpret_cast<HMONITOR
>(hMonitor
), &aInfo
) )
61 aInfo
.szDevice
[CCHDEVICENAME
-1] = 0;
62 OUString
aDeviceName( o3tl::toU(aInfo
.szDevice
) );
63 std::map
< OUString
, unsigned int >::const_iterator it
=
64 m_aDeviceNameToMonitor
.find( aDeviceName
);
65 if( it
!= m_aDeviceNameToMonitor
.end() )
67 DisplayMonitor
& rMon( m_aMonitors
[ it
->second
] );
68 rMon
.m_aArea
= tools::Rectangle( Point( aInfo
.rcMonitor
.left
,
69 aInfo
.rcMonitor
.top
),
70 Size( aInfo
.rcMonitor
.right
- aInfo
.rcMonitor
.left
,
71 aInfo
.rcMonitor
.bottom
- aInfo
.rcMonitor
.top
) );
72 if( (aInfo
.dwFlags
& MONITORINFOF_PRIMARY
) != 0 )
73 m_nPrimary
= it
->second
;
79 void WinSalSystem::clearMonitors()
85 bool WinSalSystem::initMonitors()
87 if( m_aMonitors
.size() > 0 )
90 int nMonitors
= GetSystemMetrics( SM_CMONITORS
);
93 int w
= GetSystemMetrics( SM_CXSCREEN
);
94 int h
= GetSystemMetrics( SM_CYSCREEN
);
95 m_aMonitors
.push_back( DisplayMonitor( OUString(),
96 tools::Rectangle( Point(), Size( w
, h
) ) ) );
97 m_aDeviceNameToMonitor
[ OUString() ] = 0;
102 DISPLAY_DEVICEW aDev
;
103 aDev
.cb
= sizeof( aDev
);
105 std::unordered_map
< OUString
, int > aDeviceStringCount
;
106 while( EnumDisplayDevicesW( nullptr, nDevice
++, &aDev
, 0 ) )
108 if( (aDev
.StateFlags
& DISPLAY_DEVICE_ACTIVE
)
109 && !(aDev
.StateFlags
& DISPLAY_DEVICE_MIRRORING_DRIVER
) ) // sort out non/disabled monitors
111 aDev
.DeviceName
[31] = 0;
112 aDev
.DeviceString
[127] = 0;
113 OUString
aDeviceName( o3tl::toU(aDev
.DeviceName
) );
114 OUString
aDeviceString( o3tl::toU(aDev
.DeviceString
) );
115 aDeviceStringCount
[ aDeviceString
]++;
116 m_aDeviceNameToMonitor
[ aDeviceName
] = m_aMonitors
.size();
117 m_aMonitors
.push_back( DisplayMonitor( aDeviceString
,
118 tools::Rectangle() ) );
121 HDC aDesktopRC
= GetDC( nullptr );
122 EnumDisplayMonitors( aDesktopRC
, nullptr, ImplEnumMonitorProc
, reinterpret_cast<LPARAM
>(this) );
124 // append monitor numbers to name strings
125 std::unordered_map
< OUString
, int > aDevCount( aDeviceStringCount
);
126 unsigned int nMonitorCount
= m_aMonitors
.size();
127 for( unsigned int i
= 0; i
< nMonitorCount
; i
++ )
129 const OUString
& rDev( m_aMonitors
[i
].m_aName
);
130 if( aDeviceStringCount
[ rDev
] > 1 )
132 int nInstance
= aDeviceStringCount
[ rDev
] - (-- aDevCount
[ rDev
] );
133 m_aMonitors
[ i
].m_aName
= rDev
+ " (" + OUString::number( nInstance
) + ")";
136 ReleaseDC(nullptr, aDesktopRC
);
139 return m_aMonitors
.size() > 0;
142 unsigned int WinSalSystem::GetDisplayScreenCount()
145 return m_aMonitors
.size();
148 unsigned int WinSalSystem::GetDisplayBuiltInScreen()
154 tools::Rectangle
WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen
)
157 if (nScreen
>= m_aMonitors
.size())
159 SAL_WARN("vcl", "Requested screen size/pos for screen #"
160 << nScreen
<< ", but only " << m_aMonitors
.size() << " screens found.");
162 return tools::Rectangle();
164 return m_aMonitors
[nScreen
].m_aArea
;
167 int WinSalSystem::ShowNativeMessageBox(const OUString
& rTitle
, const OUString
& rMessage
)
172 o3tl::toW(rMessage
.getStr()),
173 o3tl::toW(rTitle
.getStr()),
174 MB_TASKMODAL
| MB_SETFOREGROUND
| MB_ICONWARNING
| MB_DEFBUTTON1
);
177 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */