Skip to content

Commit e4fcaa8

Browse files
committed
WIP: X11 (and Wayland) display helpers
1 parent 2f7187b commit e4fcaa8

File tree

8 files changed

+376
-2
lines changed

8 files changed

+376
-2
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ jobs:
206206
libcairo2 \
207207
libsecret-1-dev \
208208
libtool \
209+
libx11-dev \
210+
libxfixes-dev \
211+
libxrandr-dev \
209212
nasm \
210213
ninja-build \
211214
qtbase5-dev

CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,10 @@ if(APPLE)
132132
find_package(LibArchive REQUIRED)
133133
elseif(UNIX)
134134
find_package(LIBSECRET)
135-
find_package(Uuid REQUIRED)
136135
find_package(Fontconfig REQUIRED)
136+
find_package(Uuid REQUIRED)
137+
find_package(Wayland)
138+
find_package(X11 COMPONENTS X11 Xrandr)
137139
elseif(WIN32)
138140
if(PLASMA_BUILD_MAX_PLUGIN STREQUAL "REQUIRED")
139141
set(_3dsm_FIND_ARG "REQUIRED")
@@ -183,6 +185,8 @@ cmake_dependent_option(USE_SPEEX "Use Speex audio for voice chat" ON "TARGET Spe
183185
cmake_dependent_option(USE_VPX "Use VPX for movie support" ON "TARGET VPX::VPX" OFF)
184186
cmake_dependent_option(USE_WEBM "Use WebM movie player" ON "TARGET Opus::opus AND TARGET libwebm::libwebm AND USE_VPX" OFF)
185187
cmake_dependent_option(USE_VLD "Build and link with Visual Leak Detector" OFF "TARGET VLD::VLD" OFF)
188+
cmake_dependent_option(USE_WAYLAND "Build with Wayland compositor support" ON "TARGET Wayland::Client" OFF)
189+
cmake_dependent_option(USE_X11 "Build with X11 support" ON "TARGET X11::X11" OFF)
186190

187191
# Configure compile-time compiler-specific flags and other config files
188192
include(cmake/CompilerChecks.cmake)

Sources/Tools/hsG3DDeviceDumper/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ plasma_executable(hsG3DDeviceDumper TOOL
1010

1111
# Hack hack hack
1212
$<$<PLATFORM_ID:Darwin>:../../Plasma/Apps/plClient/Mac-Cocoa/plMacDisplayHelper.mm>
13+
$<$<PLATFORM_ID:Windows>:../../Plasma/Apps/plClient/win32/plWinDisplayHelper.cpp>
14+
$<$<BOOL:${USE_X11}>:plX11DisplayHelper.cpp>
15+
)
16+
17+
target_include_directories(
18+
hsG3DDeviceDumper
19+
PRIVATE
20+
$<$<AND:$<BOOL:${USE_X11}>,$<TARGET_EXISTS:X11::X11>>:$<TARGET_PROPERTY:X11::X11,INCLUDE_DIRECTORIES>>
21+
$<$<AND:$<BOOL:${USE_X11}>,$<TARGET_EXISTS:X11::Xrandr>>:$<TARGET_PROPERTY:X11::Xrandr,INCLUDE_DIRECTORIES>>
1322
)
1423

1524
target_link_libraries(

Sources/Tools/hsG3DDeviceDumper/main.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
4040
4141
*==LICENSE==*/
4242

43+
#include <cstdlib>
4344
#include <string_theory/stdio>
4445

4546
#include "HeadSpin.h"
@@ -50,6 +51,13 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
5051
#ifdef HS_BUILD_FOR_MACOS
5152
# include "../../Plasma/Apps/plClient/Mac-Cocoa/plMacDisplayHelper.h"
5253
#endif
54+
#ifdef HS_BUILD_FOR_WIN32
55+
# include "../../Plasma/Apps/plClient/win32/plWinDisplayHelper.h"
56+
#endif
57+
58+
#ifdef USE_X11
59+
# include "plX11DisplayHelper.h"
60+
#endif
5361

5462
#ifdef PLASMA_PIPELINE_GL
5563
# include "pfGLPipeline/plGLPipeline.h"
@@ -65,8 +73,33 @@ int main(int argc, const char* argv[]) {
6573
hsG3DDeviceSelector devSel;
6674
plDisplayHelper* helper = nullptr;
6775

76+
#ifdef USE_WAYLAND
77+
# ifdef USE_X11
78+
// In a perfect world, this would always be set to tell us if we're running
79+
// X11 or Wayland, but the world is far from perfect so we'll try this and
80+
// then guess based on other variables.
81+
// We only need to do the runtime detection if both are available,
82+
// otherwise you get what you get
83+
const char* sessionType = getenv("XDG_SESSION_TYPE");
84+
if (strcmp(sessionType, "wayland") == 0 || !sessionType && getenv("WAYLAND_DISPLAY"))
85+
// Fallthrough
86+
# endif
87+
ST::printf(" ...running Wayland\n");
88+
#endif
89+
90+
#ifdef USE_X11
91+
if (!helper && getenv("DISPLAY"))
92+
helper = new plX11DisplayHelper();
93+
#endif
94+
6895
#ifdef HS_BUILD_FOR_MACOS
69-
helper = new plMacDisplayHelper();
96+
if (!helper)
97+
helper = new plMacDisplayHelper();
98+
#endif
99+
100+
#ifdef HS_BUILD_FOR_WIN32
101+
if (!helper)
102+
helper = new plWinDisplayHelper();
70103
#endif
71104

72105
plDisplayHelper::SetInstance(helper);
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*==LICENSE==*
2+
3+
CyanWorlds.com Engine - MMOG client, server and tools
4+
Copyright (C) 2011 Cyan Worlds, Inc.
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
Additional permissions under GNU GPL version 3 section 7
20+
21+
If you modify this Program, or any covered work, by linking or
22+
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
23+
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
24+
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
25+
(or a modified version of those libraries),
26+
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
27+
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
28+
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
29+
licensors of this Program grant you additional
30+
permission to convey the resulting work. Corresponding Source for a
31+
non-source form of such a combination shall include the source code for
32+
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
33+
work.
34+
35+
You can contact Cyan Worlds, Inc. by email legal@cyan.com
36+
or by snail mail at:
37+
Cyan Worlds, Inc.
38+
14617 N Newport Hwy
39+
Mead, WA 99021
40+
41+
*==LICENSE==*/
42+
43+
#include "hsOptionalCall.h"
44+
#include "plX11DisplayHelper.h"
45+
46+
// X11 includes MUST be after everything else to avoid contamination!
47+
#include <X11/Xlib.h>
48+
hsOptionalCallDecl("libX11", XCloseDisplay);
49+
hsOptionalCallDecl("libX11", XOpenDisplay);
50+
51+
#if __has_include(<X11/extensions/Xrandr.h>)
52+
# define HAS_XRANDR
53+
# include <X11/extensions/Xrandr.h>
54+
hsOptionalCallDecl("libXrandr", XRRSizes);
55+
#endif
56+
57+
plX11DisplayHelper::plX11DisplayHelper() : fCurrentDisplay()
58+
{
59+
}
60+
61+
plX11DisplayHelper::~plX11DisplayHelper()
62+
{
63+
if (fCurrentDisplay)
64+
__XCloseDisplay(fCurrentDisplay);
65+
}
66+
67+
void plX11DisplayHelper::SetCurrentScreen(hsDisplayHndl display) const
68+
{
69+
if (fCurrentDisplay == display)
70+
return;
71+
else if (fCurrentDisplay)
72+
__XCloseDisplay(fCurrentDisplay);
73+
74+
fCurrentDisplay = reinterpret_cast<Display*>(display);
75+
int screen = DefaultScreen(fCurrentDisplay);
76+
77+
fDisplayModes.clear();
78+
79+
#ifdef HAS_XRANDR
80+
if ((bool)__XRRSizes) {
81+
// We can use the X RandR extension to get resolutions
82+
int num_sizes;
83+
XRRScreenSize* xrrs;
84+
85+
xrrs = *__XRRSizes(fCurrentDisplay, 0, &num_sizes);
86+
for (int i = 0; i < num_sizes; i++) {
87+
// Don't include unreasonably small sizes
88+
if (xrrs[i].width < 800 || xrrs[i].height < 600)
89+
continue;
90+
91+
fDisplayModes.emplace_back(plDisplayMode {
92+
xrrs[i].width,
93+
xrrs[i].height,
94+
DefaultDepth(fCurrentDisplay, screen)
95+
});
96+
}
97+
}
98+
else
99+
#endif
100+
{
101+
fDisplayModes.emplace_back(plDisplayMode {
102+
DisplayWidth(fCurrentDisplay, screen),
103+
DisplayHeight(fCurrentDisplay, screen),
104+
DefaultDepth(fCurrentDisplay, screen)
105+
});
106+
}
107+
108+
std::sort(fDisplayModes.begin(), fDisplayModes.end(),
109+
[](plDisplayMode a, plDisplayMode b) {
110+
int resolutionA = a.Width * a.Height;
111+
int resolutionB = b.Width * b.Height;
112+
return resolutionA > resolutionB;
113+
});
114+
}
115+
116+
std::vector<plDisplayMode> plX11DisplayHelper::GetSupportedDisplayModes(hsDisplayHndl display, int ColorDepth) const
117+
{
118+
// Cache the current display so we can answer repeat requests quickly.
119+
// SetCurrentScreen will catch redundant sets.
120+
SetCurrentScreen(display);
121+
return fDisplayModes;
122+
}
123+
124+
hsDisplayHndl plX11DisplayHelper::DefaultDisplay() const
125+
{
126+
if (!fCurrentDisplay) {
127+
Display* display = *__XOpenDisplay(nullptr);
128+
SetCurrentScreen(reinterpret_cast<hsDisplayHndl>(display));
129+
}
130+
131+
return reinterpret_cast<hsDisplayHndl>(fCurrentDisplay);
132+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*==LICENSE==*
2+
3+
CyanWorlds.com Engine - MMOG client, server and tools
4+
Copyright (C) 2011 Cyan Worlds, Inc.
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
Additional permissions under GNU GPL version 3 section 7
20+
21+
If you modify this Program, or any covered work, by linking or
22+
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
23+
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
24+
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
25+
(or a modified version of those libraries),
26+
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
27+
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
28+
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
29+
licensors of this Program grant you additional
30+
permission to convey the resulting work. Corresponding Source for a
31+
non-source form of such a combination shall include the source code for
32+
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
33+
work.
34+
35+
You can contact Cyan Worlds, Inc. by email legal@cyan.com
36+
or by snail mail at:
37+
Cyan Worlds, Inc.
38+
14617 N Newport Hwy
39+
Mead, WA 99021
40+
41+
*==LICENSE==*/
42+
43+
#ifndef plX11DisplayHelper_h
44+
#define plX11DisplayHelper_h
45+
46+
#include "plPipeline/hsG3DDeviceSelector.h"
47+
#include "plPipeline/pl3DPipeline.h"
48+
49+
class plX11DisplayHelper : public plDisplayHelper
50+
{
51+
public:
52+
plX11DisplayHelper();
53+
~plX11DisplayHelper();
54+
55+
plDisplayMode DesktopDisplayMode() override { return fDesktopDisplayMode; };
56+
std::vector<plDisplayMode> GetSupportedDisplayModes(hsDisplayHndl display, int ColorDepth = 32) const override;
57+
hsDisplayHndl DefaultDisplay() const override;
58+
59+
private:
60+
mutable struct _XDisplay* fCurrentDisplay;
61+
mutable plDisplayMode fDesktopDisplayMode;
62+
mutable std::vector<plDisplayMode> fDisplayModes;
63+
64+
void SetCurrentScreen(hsDisplayHndl screen) const;
65+
};
66+
67+
#endif /* plX11DisplayHelper_h */
68+

0 commit comments

Comments
 (0)