|
47 | 47 |
|
48 | 48 | #include "svnrev.h" |
49 | 49 |
|
| 50 | +// Down here because X11 has a lot of defines that can conflict |
| 51 | +#if defined(__linux__) |
| 52 | +#include <SDL2/SDL.h> |
| 53 | +#include <X11/Xlib.h> |
| 54 | +#include <X11/Xutil.h> |
| 55 | +#include <sys/select.h> |
| 56 | +#include <unistd.h> |
| 57 | +#endif |
| 58 | + |
50 | 59 | namespace GSRunner |
51 | 60 | { |
52 | 61 | static void InitializeConsole(); |
@@ -1086,4 +1095,118 @@ void GSRunner::StopPlatformMessagePump() |
1086 | 1095 | CocoaTools::StopMainThreadEventLoop(); |
1087 | 1096 | } |
1088 | 1097 |
|
| 1098 | +#elif defined(__linux__) |
| 1099 | +static Display* s_display = nullptr; |
| 1100 | +static Window s_window = None; |
| 1101 | +static WindowInfo s_wi; |
| 1102 | +static std::atomic<bool> s_shutdown_requested{false}; |
| 1103 | + |
| 1104 | +bool GSRunner::CreatePlatformWindow() |
| 1105 | +{ |
| 1106 | + pxAssertRel(!s_display && s_window == None, "Tried to create window when there already was one!"); |
| 1107 | + |
| 1108 | + s_display = XOpenDisplay(nullptr); |
| 1109 | + if (!s_display) |
| 1110 | + { |
| 1111 | + Console.Error("Failed to open X11 display"); |
| 1112 | + return false; |
| 1113 | + } |
| 1114 | + |
| 1115 | + int screen = DefaultScreen(s_display); |
| 1116 | + Window root = RootWindow(s_display, screen); |
| 1117 | + |
| 1118 | + s_window = XCreateSimpleWindow(s_display, root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 1, |
| 1119 | + BlackPixel(s_display, screen), WhitePixel(s_display, screen)); |
| 1120 | + |
| 1121 | + if (s_window == None) |
| 1122 | + { |
| 1123 | + Console.Error("Failed to create X11 window"); |
| 1124 | + XCloseDisplay(s_display); |
| 1125 | + s_display = nullptr; |
| 1126 | + return false; |
| 1127 | + } |
| 1128 | + |
| 1129 | + XStoreName(s_display, s_window, "PCSX2 GS Runner"); |
| 1130 | + XSelectInput(s_display, s_window, StructureNotifyMask); |
| 1131 | + XMapWindow(s_display, s_window); |
| 1132 | + |
| 1133 | + s_wi.type = WindowInfo::Type::X11; |
| 1134 | + s_wi.display_connection = s_display; |
| 1135 | + s_wi.window_handle = reinterpret_cast<void*>(s_window); |
| 1136 | + s_wi.surface_width = WINDOW_WIDTH; |
| 1137 | + s_wi.surface_height = WINDOW_HEIGHT; |
| 1138 | + s_wi.surface_scale = 1.0f; |
| 1139 | + |
| 1140 | + XFlush(s_display); |
| 1141 | + PumpPlatformMessages(); |
| 1142 | + return true; |
| 1143 | +} |
| 1144 | + |
| 1145 | +void GSRunner::DestroyPlatformWindow() |
| 1146 | +{ |
| 1147 | + if (s_display && s_window != None) |
| 1148 | + { |
| 1149 | + XDestroyWindow(s_display, s_window); |
| 1150 | + s_window = None; |
| 1151 | + } |
| 1152 | + |
| 1153 | + if (s_display) |
| 1154 | + { |
| 1155 | + XCloseDisplay(s_display); |
| 1156 | + s_display = nullptr; |
| 1157 | + } |
| 1158 | +} |
| 1159 | + |
| 1160 | +std::optional<WindowInfo> GSRunner::GetPlatformWindowInfo() |
| 1161 | +{ |
| 1162 | + WindowInfo wi; |
| 1163 | + if (s_display && s_window != None) |
| 1164 | + wi = s_wi; |
| 1165 | + else |
| 1166 | + wi.type = WindowInfo::Type::Surfaceless; |
| 1167 | + return wi; |
| 1168 | +} |
| 1169 | + |
| 1170 | +void GSRunner::PumpPlatformMessages(bool forever) |
| 1171 | +{ |
| 1172 | + if (!s_display) |
| 1173 | + return; |
| 1174 | + |
| 1175 | + do |
| 1176 | + { |
| 1177 | + while (XPending(s_display) > 0) |
| 1178 | + { |
| 1179 | + XEvent event; |
| 1180 | + XNextEvent(s_display, &event); |
| 1181 | + |
| 1182 | + switch (event.type) |
| 1183 | + { |
| 1184 | + case ConfigureNotify: |
| 1185 | + { |
| 1186 | + const XConfigureEvent& configure = event.xconfigure; |
| 1187 | + s_wi.surface_width = static_cast<u32>(configure.width); |
| 1188 | + s_wi.surface_height = static_cast<u32>(configure.height); |
| 1189 | + break; |
| 1190 | + } |
| 1191 | + case DestroyNotify: |
| 1192 | + return; |
| 1193 | + default: |
| 1194 | + break; |
| 1195 | + } |
| 1196 | + } |
| 1197 | + |
| 1198 | + if (s_shutdown_requested.load()) |
| 1199 | + return; |
| 1200 | + |
| 1201 | + if (forever) |
| 1202 | + { |
| 1203 | + std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 1204 | + } |
| 1205 | + } while (forever && !s_shutdown_requested.load()); |
| 1206 | +} |
| 1207 | + |
| 1208 | +void GSRunner::StopPlatformMessagePump() |
| 1209 | +{ |
| 1210 | + s_shutdown_requested.store(true); |
| 1211 | +} |
1089 | 1212 | #endif // _WIN32 / __APPLE__ |
0 commit comments