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 "rtl/ustrbuf.hxx"
23 #include "tools/debug.hxx"
25 #include <vcl/window.hxx>
27 #include "win/salsys.h"
28 #include "win/salframe.h"
29 #include "win/salinst.h"
30 #include "win/saldata.hxx"
34 #include <unordered_map>
36 SalSystem
* WinSalInstance::CreateSalSystem()
38 return new WinSalSystem();
41 WinSalSystem::~WinSalSystem()
45 static BOOL CALLBACK
ImplEnumMonitorProc( HMONITOR hMonitor
,
50 WinSalSystem
* pSys
= reinterpret_cast<WinSalSystem
*>(dwData
);
51 return pSys
->handleMonitorCallback( reinterpret_cast<sal_IntPtr
>(hMonitor
),
52 reinterpret_cast<sal_IntPtr
>(hDC
),
53 reinterpret_cast<sal_IntPtr
>(lpRect
) );
56 bool WinSalSystem::handleMonitorCallback( sal_IntPtr hMonitor
, sal_IntPtr
, sal_IntPtr
)
59 aInfo
.cbSize
= sizeof( aInfo
);
60 if( GetMonitorInfoW( reinterpret_cast<HMONITOR
>(hMonitor
), &aInfo
) )
62 aInfo
.szDevice
[CCHDEVICENAME
-1] = 0;
63 OUString
aDeviceName( reinterpret_cast<const sal_Unicode
*>(aInfo
.szDevice
) );
64 std::map
< OUString
, unsigned int >::const_iterator it
=
65 m_aDeviceNameToMonitor
.find( aDeviceName
);
66 if( it
!= m_aDeviceNameToMonitor
.end() )
68 DisplayMonitor
& rMon( m_aMonitors
[ it
->second
] );
69 rMon
.m_aArea
= Rectangle( Point( aInfo
.rcMonitor
.left
,
70 aInfo
.rcMonitor
.top
),
71 Size( aInfo
.rcMonitor
.right
- aInfo
.rcMonitor
.left
,
72 aInfo
.rcMonitor
.bottom
- aInfo
.rcMonitor
.top
) );
73 if( (aInfo
.dwFlags
& MONITORINFOF_PRIMARY
) != 0 )
74 m_nPrimary
= it
->second
;
80 void WinSalSystem::clearMonitors()
86 bool WinSalSystem::initMonitors()
88 if( m_aMonitors
.size() > 0 )
91 int nMonitors
= GetSystemMetrics( SM_CMONITORS
);
94 int w
= GetSystemMetrics( SM_CXSCREEN
);
95 int h
= GetSystemMetrics( SM_CYSCREEN
);
96 m_aMonitors
.push_back( DisplayMonitor( OUString(),
97 Rectangle( Point(), Size( w
, h
) ) ) );
98 m_aDeviceNameToMonitor
[ OUString() ] = 0;
103 DISPLAY_DEVICEW aDev
;
104 aDev
.cb
= sizeof( aDev
);
106 std::unordered_map
< OUString
, int, OUStringHash
> aDeviceStringCount
;
107 while( EnumDisplayDevicesW( nullptr, nDevice
++, &aDev
, 0 ) )
109 if( (aDev
.StateFlags
& DISPLAY_DEVICE_ACTIVE
)
110 && !(aDev
.StateFlags
& DISPLAY_DEVICE_MIRRORING_DRIVER
) ) // sort out non/disabled monitors
112 aDev
.DeviceName
[31] = 0;
113 aDev
.DeviceString
[127] = 0;
114 OUString
aDeviceName( reinterpret_cast<const sal_Unicode
*>(aDev
.DeviceName
) );
115 OUString
aDeviceString( reinterpret_cast<const sal_Unicode
*>(aDev
.DeviceString
) );
116 if( aDeviceStringCount
.find( aDeviceString
) == aDeviceStringCount
.end() )
117 aDeviceStringCount
[ aDeviceString
] = 1;
119 aDeviceStringCount
[ aDeviceString
]++;
120 m_aDeviceNameToMonitor
[ aDeviceName
] = m_aMonitors
.size();
121 m_aMonitors
.push_back( DisplayMonitor( aDeviceString
,
125 HDC aDesktopRC
= GetDC( nullptr );
126 EnumDisplayMonitors( aDesktopRC
, nullptr, ImplEnumMonitorProc
, reinterpret_cast<LPARAM
>(this) );
128 // append monitor numbers to name strings
129 std::unordered_map
< OUString
, int, OUStringHash
> aDevCount( aDeviceStringCount
);
130 unsigned int nMonitorCount
= m_aMonitors
.size();
131 for( unsigned int i
= 0; i
< nMonitorCount
; i
++ )
133 const OUString
& rDev( m_aMonitors
[i
].m_aName
);
134 if( aDeviceStringCount
[ rDev
] > 1 )
136 int nInstance
= aDeviceStringCount
[ rDev
] - (-- aDevCount
[ rDev
] );
137 OUStringBuffer
aBuf( rDev
.getLength() + 8 );
140 aBuf
.append( sal_Int32( nInstance
) );
142 m_aMonitors
[ i
].m_aName
= aBuf
.makeStringAndClear();
147 return m_aMonitors
.size() > 0;
150 unsigned int WinSalSystem::GetDisplayScreenCount()
153 return m_aMonitors
.size();
156 unsigned int WinSalSystem::GetDisplayBuiltInScreen()
162 Rectangle
WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen
)
165 return (nScreen
< m_aMonitors
.size()) ? m_aMonitors
[nScreen
].m_aArea
: Rectangle();
168 int WinSalSystem::ShowNativeMessageBox(const OUString
& rTitle
, const OUString
& rMessage
)
170 int nFlags
= MB_TASKMODAL
| MB_SETFOREGROUND
| MB_ICONWARNING
| MB_DEFBUTTON1
;
175 reinterpret_cast<LPCWSTR
>(rMessage
.getStr()),
176 reinterpret_cast<LPCWSTR
>(rTitle
.getStr()),
180 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */