summarylogtreecommitdiffstats
path: root/external-rotation.patch
blob: 004831d5fbdcb5c95b5681cdbe6b63064eea8bd9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
diff --git a/src/drm.cpp b/src/drm.cpp
index 42c67b9..628bfc9 100644
--- a/src/drm.cpp
+++ b/src/drm.cpp
@@ -521,6 +521,7 @@ bool g_bSupportsSyncObjs = false;
 
 extern gamescope::GamescopeModeGeneration g_eGamescopeModeGeneration;
 extern GamescopePanelOrientation g_DesiredInternalOrientation;
+extern GamescopePanelOrientation g_DesiredExternalOrientation;
 
 extern bool g_bForceDisableColorMgmt;
 
@@ -2008,6 +2009,10 @@ namespace gamescope
 		{
 			m_ChosenOrientation = g_DesiredInternalOrientation;
 		}
+		else if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO )
+		{
+			m_ChosenOrientation = g_DesiredExternalOrientation;
+		}
 		else
 		{
 			if ( this->GetProperties().panel_orientation )
diff --git a/src/main.cpp b/src/main.cpp
index 88c4c7c..2f5fc0a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -121,6 +121,7 @@ const struct option *gamescope_options = (struct option[]){
 	{ "disable-xres", no_argument, nullptr, 'x' },
 	{ "fade-out-duration", required_argument, nullptr, 0 },
 	{ "force-orientation", required_argument, nullptr, 0 },
+	{ "force-external-orientation", required_argument, nullptr, 0 },
 	{ "force-windows-fullscreen", no_argument, nullptr, 0 },
 
 	{ "disable-color-management", no_argument, nullptr, 0 },
@@ -171,6 +172,7 @@ const char usage[] =
 	"  --xwayland-count               create N xwayland servers\n"
 	"  --prefer-vk-device             prefer Vulkan device for compositing (ex: 1002:7300)\n"
 	"  --force-orientation            rotate the internal display (left, right, normal, upsidedown)\n"
+	"  --force-external-orientation   rotate the external display (left, right, normal, upsidedown)\n"
 	"  --force-windows-fullscreen     force windows inside of gamescope to be the size of the nested display (fullscreen)\n"
 	"  --cursor-scale-height          if specified, sets a base output height to linearly scale the cursor against.\n"
 	"  --hdr-enabled                  enable HDR output (needs Gamescope WSI layer enabled for support from clients)\n"
@@ -267,6 +269,8 @@ bool g_bOutputHDREnabled = false;
 bool g_bFullscreen = false;
 bool g_bForceRelativeMouse = false;
 
+bool g_bExternalForced = false;
+
 bool g_bGrabbed = false;
 
 float g_mouseSensitivity = 1.0;
@@ -353,6 +357,27 @@ static GamescopePanelOrientation force_orientation(const char *str)
 	}
 }
 
+GamescopePanelOrientation g_DesiredExternalOrientation = GAMESCOPE_PANEL_ORIENTATION_AUTO;
+static GamescopePanelOrientation force_external_orientation(const char *str)
+{
+	if (strcmp(str, "normal") == 0) {
+		g_bExternalForced = true;
+		return GAMESCOPE_PANEL_ORIENTATION_0;
+	} else if (strcmp(str, "right") == 0) {
+		g_bExternalForced = true;
+		return GAMESCOPE_PANEL_ORIENTATION_270;
+	} else if (strcmp(str, "left") == 0) {
+		g_bExternalForced = true;
+		return GAMESCOPE_PANEL_ORIENTATION_90;
+	} else if (strcmp(str, "upsidedown") == 0) {
+		g_bExternalForced = true;
+		return GAMESCOPE_PANEL_ORIENTATION_180;
+	} else {
+		fprintf( stderr, "gamescope: invalid value for --force-external-orientation\n" );
+		exit(1);
+	}
+}
+
 static enum GamescopeUpscaleScaler parse_upscaler_scaler(const char *str)
 {
 	if (strcmp(str, "auto") == 0) {
@@ -648,6 +673,8 @@ int main(int argc, char **argv)
 					g_eGamescopeModeGeneration = parse_gamescope_mode_generation( optarg );
 				} else if (strcmp(opt_name, "force-orientation") == 0) {
 					g_DesiredInternalOrientation = force_orientation( optarg );
+				} else if (strcmp(opt_name, "force-external-orientation") == 0) {
+					g_DesiredExternalOrientation = force_external_orientation( optarg );
 				} else if (strcmp(opt_name, "sharpness") == 0 ||
 						   strcmp(opt_name, "fsr-sharpness") == 0) {
 					g_upscaleFilterSharpness = atoi( optarg );
diff --git a/src/main.hpp b/src/main.hpp
index 4e4e9a7..be9a9dd 100644
--- a/src/main.hpp
+++ b/src/main.hpp
@@ -28,6 +28,7 @@ extern bool g_bGrabbed;
 
 extern float g_mouseSensitivity;
 extern const char *g_sOutputName;
+extern bool g_bExternalForced;
 
 enum class GamescopeUpscaleFilter : uint32_t
 {
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
index 9afaab7..b3f9f31 100644
--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -2130,6 +2130,32 @@ static void apply_touchscreen_orientation(double *x, double *y )
 			break;
 	}
 
+	// Rotate screen if it's forced with --force-external-orientation
+	if ( g_bExternalForced == true )
+	{
+		switch ( GetBackend()->GetConnector( gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL )->GetCurrentOrientation() )
+		{
+			default:
+			case GAMESCOPE_PANEL_ORIENTATION_AUTO:
+			case GAMESCOPE_PANEL_ORIENTATION_0:
+				tx = *x;
+				ty = *y;
+				break;
+			case GAMESCOPE_PANEL_ORIENTATION_90:
+				tx = 1.0 - *y;
+				ty = *x;
+				break;
+			case GAMESCOPE_PANEL_ORIENTATION_180:
+				tx = 1.0 - *x;
+				ty = 1.0 - *y;
+				break;
+			case GAMESCOPE_PANEL_ORIENTATION_270:
+				tx = *y;
+				ty = 1.0 - *x;
+				break;
+		}
+	}
+
 	*x = tx;
 	*y = ty;
 }