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 <vcl/window.hxx>
25 #include <win/salsys.h>
26 #include <win/salframe.h>
27 #include <win/salinst.h>
28 #include <win/saldata.hxx>
32 #include <unordered_map>
34 SalSystem
* WinSalInstance::CreateSalSystem()
36 return new WinSalSystem();
39 WinSalSystem::~WinSalSystem()
43 static BOOL CALLBACK
ImplEnumMonitorProc( HMONITOR hMonitor
,
48 WinSalSystem
* pSys
= reinterpret_cast<WinSalSystem
*>(dwData
);
49 return pSys
->handleMonitorCallback( reinterpret_cast<sal_IntPtr
>(hMonitor
),
50 reinterpret_cast<sal_IntPtr
>(hDC
),
51 reinterpret_cast<sal_IntPtr
>(lpRect
) );
54 bool WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor
, sal_IntPtr
, sal_IntPtr
)
57 aInfo
.cbSize
= sizeof( aInfo
);
58 if( GetMonitorInfoW( reinterpret_cast<HMONITOR
>(hMonitor
), &aInfo
) )
60 aInfo
.szDevice
[CCHDEVICENAME
-1] = 0;
61 OUString
aDeviceName( o3tl::toU(aInfo
.szDevice
) );
62 std::map
< OUString
, unsigned int >::const_iterator it
=
63 m_aDeviceNameToMonitor
.find( aDeviceName
);
64 if( it
!= m_aDeviceNameToMonitor
.end() )
66 DisplayMonitor
& rMon( m_aMonitors
[ it
->second
] );
67 rMon
.m_aArea
= tools::Rectangle( Point( aInfo
.rcMonitor
.left
,
68 aInfo
.rcMonitor
.top
),
69 Size( aInfo
.rcMonitor
.right
- aInfo
.rcMonitor
.left
,
70 aInfo
.rcMonitor
.bottom
- aInfo
.rcMonitor
.top
) );
71 if( (aInfo
.dwFlags
& MONITORINFOF_PRIMARY
) != 0 )
72 m_nPrimary
= it
->second
;
78 void WinSalSystem::clearMonitors()
84 bool WinSalSystem::initMonitors()
86 if( m_aMonitors
.size() > 0 )
89 int nMonitors
= GetSystemMetrics( SM_CMONITORS
);
92 int w
= GetSystemMetrics( SM_CXSCREEN
);
93 int h
= GetSystemMetrics( SM_CYSCREEN
);
94 m_aMonitors
.push_back( DisplayMonitor( OUString(),
95 tools::Rectangle( Point(), Size( w
, h
) ) ) );
96 m_aDeviceNameToMonitor
[ OUString() ] = 0;
101 DISPLAY_DEVICEW aDev
;
102 aDev
.cb
= sizeof( aDev
);
104 std::unordered_map
< OUString
, int > aDeviceStringCount
;
105 while( EnumDisplayDevicesW( nullptr, nDevice
++, &aDev
, 0 ) )
107 if( (aDev
.StateFlags
& DISPLAY_DEVICE_ACTIVE
)
108 && !(aDev
.StateFlags
& DISPLAY_DEVICE_MIRRORING_DRIVER
) ) // sort out non/disabled monitors
110 aDev
.DeviceName
[31] = 0;
111 aDev
.DeviceString
[127] = 0;
112 OUString
aDeviceName( o3tl::toU(aDev
.DeviceName
) );
113 OUString
aDeviceString( o3tl::toU(aDev
.DeviceString
) );
114 if( aDeviceStringCount
.find( aDeviceString
) == aDeviceStringCount
.end() )
115 aDeviceStringCount
[ aDeviceString
] = 1;
117 aDeviceStringCount
[ aDeviceString
]++;
118 m_aDeviceNameToMonitor
[ aDeviceName
] = m_aMonitors
.size();
119 m_aMonitors
.push_back( DisplayMonitor( aDeviceString
,
120 tools::Rectangle() ) );
123 HDC aDesktopRC
= GetDC( nullptr );
124 EnumDisplayMonitors( aDesktopRC
, nullptr, ImplEnumMonitorProc
, reinterpret_cast<LPARAM
>(this) );
126 // append monitor numbers to name strings
127 std::unordered_map
< OUString
, int > aDevCount( aDeviceStringCount
);
128 unsigned int nMonitorCount
= m_aMonitors
.size();
129 for( unsigned int i
= 0; i
< nMonitorCount
; i
++ )
131 const OUString
& rDev( m_aMonitors
[i
].m_aName
);
132 if( aDeviceStringCount
[ rDev
] > 1 )
134 int nInstance
= aDeviceStringCount
[ rDev
] - (-- aDevCount
[ rDev
] );
135 m_aMonitors
[ i
].m_aName
= rDev
+ " (" + OUString::number( nInstance
) + ")";
140 return m_aMonitors
.size() > 0;
143 unsigned int WinSalSystem::GetDisplayScreenCount()
146 return m_aMonitors
.size();
149 unsigned int WinSalSystem::GetDisplayBuiltInScreen()
155 tools::Rectangle
WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen
)
158 return (nScreen
< m_aMonitors
.size()) ? m_aMonitors
[nScreen
].m_aArea
: tools::Rectangle();
161 int WinSalSystem::ShowNativeMessageBox(const OUString
& rTitle
, const OUString
& rMessage
)
166 o3tl::toW(rMessage
.getStr()),
167 o3tl::toW(rTitle
.getStr()),
168 MB_TASKMODAL
| MB_SETFOREGROUND
| MB_ICONWARNING
| MB_DEFBUTTON1
);
171 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */