mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-29 00:59:44 -06:00
Merge pull request #1467 from waddlesplash/dolphin-qt
DolphinQt: Games now boot!
This commit is contained in:
@ -8,10 +8,6 @@ set(LIBS core
|
||||
${GTK2_LIBRARIES})
|
||||
|
||||
if(NOT ANDROID)
|
||||
if(USE_X11)
|
||||
set(LIBS ${LIBS} ${XRANDR_LIBRARIES})
|
||||
endif()
|
||||
|
||||
link_directories(${CMAKE_PREFIX_PATH}/lib)
|
||||
else()
|
||||
set(LIBS ${LIBS} png iconv)
|
||||
@ -76,31 +72,6 @@ set(WXLIBS ${wxWidgets_LIBRARIES} dl)
|
||||
set(ANDROID_SRCS Android/ButtonManager.cpp
|
||||
MainAndroid.cpp)
|
||||
|
||||
if(USE_EGL)
|
||||
set(SRCS ${SRCS} GLInterface/EGL.cpp)
|
||||
if(ANDROID)
|
||||
set(SRCS ${SRCS} GLInterface/EGLAndroid.cpp)
|
||||
elseif(USE_X11)
|
||||
set(SRCS ${SRCS} GLInterface/EGLX11.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(SRCS ${SRCS} GLInterface/WGL.cpp)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(SRCS ${SRCS} GLInterface/AGL.cpp)
|
||||
elseif(USE_X11)
|
||||
if (NOT USE_EGL)
|
||||
set(SRCS ${SRCS} GLInterface/GLX.cpp)
|
||||
# GLX has a hard dependency on libGL.
|
||||
# Make sure to link to it if using GLX.
|
||||
set(LIBS ${LIBS} ${OPENGL_LIBRARIES})
|
||||
endif()
|
||||
set(SRCS ${SRCS} GLInterface/X11_Util.cpp)
|
||||
endif()
|
||||
|
||||
set(SRCS ${SRCS} GLInterface/GLInterface.cpp)
|
||||
|
||||
set(NOGUI_SRCS MainNoGUI.cpp)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
@ -125,8 +96,6 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
list(APPEND SRCS ${RESOURCES})
|
||||
set_source_files_properties(${RESOURCES} PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources)
|
||||
elseif(USE_X11)
|
||||
set(SRCS ${SRCS} X11Utils.cpp)
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR
|
||||
@ -156,7 +125,7 @@ endif()
|
||||
if(ANDROID)
|
||||
set(DOLPHIN_EXE main)
|
||||
add_library(${DOLPHIN_EXE} SHARED ${SRCS} ${ANDROID_SRCS})
|
||||
target_link_libraries(${DOLPHIN_EXE}
|
||||
target_link_libraries(${DOLPHIN_EXE}
|
||||
log
|
||||
android
|
||||
"-Wl,--no-warn-mismatch"
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||
#include "DolphinWX/X11Utils.h"
|
||||
#include "VideoBackends/OGL/GLInterface/X11Utils.h"
|
||||
#endif
|
||||
|
||||
class wxBoxSizer;
|
||||
|
@ -78,8 +78,6 @@
|
||||
<ClCompile Include="FrameAui.cpp" />
|
||||
<ClCompile Include="FrameTools.cpp" />
|
||||
<ClCompile Include="GameListCtrl.cpp" />
|
||||
<ClCompile Include="GLInterface\GLInterface.cpp" />
|
||||
<ClCompile Include="GLInterface\WGL.cpp" />
|
||||
<ClCompile Include="HotkeyDlg.cpp" />
|
||||
<ClCompile Include="InputConfigDiag.cpp" />
|
||||
<ClCompile Include="InputConfigDiagBitmaps.cpp" />
|
||||
@ -131,7 +129,6 @@
|
||||
<ClInclude Include="FifoPlayerDlg.h" />
|
||||
<ClInclude Include="Frame.h" />
|
||||
<ClInclude Include="GameListCtrl.h" />
|
||||
<ClInclude Include="GLInterface\WGL.h" />
|
||||
<ClInclude Include="Globals.h" />
|
||||
<ClInclude Include="HotkeyDlg.h" />
|
||||
<ClInclude Include="InputConfigDiag.h" />
|
||||
|
@ -27,8 +27,6 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GLInterface\GLInterface.cpp" />
|
||||
<ClCompile Include="GLInterface\WGL.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="MainNoGUI.cpp" />
|
||||
<ClCompile Include="WXInputBase.cpp" />
|
||||
@ -170,7 +168,6 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GLInterface\WGL.h" />
|
||||
<ClInclude Include="Main.h" />
|
||||
<ClInclude Include="WXInputBase.h" />
|
||||
<ClInclude Include="WxUtils.h" />
|
||||
|
@ -72,6 +72,23 @@ extern "C" {
|
||||
|
||||
int g_saveSlot = 1;
|
||||
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
// X11Utils nastiness that's only used here
|
||||
namespace X11Utils {
|
||||
|
||||
Window XWindowFromHandle(void *Handle)
|
||||
{
|
||||
return GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(Handle)));
|
||||
}
|
||||
|
||||
Display *XDisplayFromHandle(void *Handle)
|
||||
{
|
||||
return GDK_WINDOW_XDISPLAY(gtk_widget_get_window(GTK_WIDGET(Handle)));
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
CRenderFrame::CRenderFrame(wxFrame* parent, wxWindowID id, const wxString& title,
|
||||
const wxPoint& pos, const wxSize& size, long style)
|
||||
: wxFrame(parent, id, title, pos, size, style)
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "InputCommon/GCPadStatus.h"
|
||||
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
#include "DolphinWX/X11Utils.h"
|
||||
#include "VideoBackends/OGL/GLInterface/X11Utils.h"
|
||||
#endif
|
||||
|
||||
// Class declarations
|
||||
|
@ -1,109 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinWX/GLInterface/AGL.h"
|
||||
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
void cInterfaceAGL::Swap()
|
||||
{
|
||||
[cocoaCtx flushBuffer];
|
||||
}
|
||||
|
||||
// Create rendering window.
|
||||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||
bool cInterfaceAGL::Create(void *window_handle)
|
||||
{
|
||||
cocoaWin = reinterpret_cast<NSView*>(window_handle);
|
||||
NSSize size = [cocoaWin frame].size;
|
||||
|
||||
// Enable high-resolution display support.
|
||||
[cocoaWin setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
NSWindow *window = [cocoaWin window];
|
||||
|
||||
float scale = [window backingScaleFactor];
|
||||
size.width *= scale;
|
||||
size.height *= scale;
|
||||
|
||||
// Control window size and picture scaling
|
||||
s_backbuffer_width = size.width;
|
||||
s_backbuffer_height = size.height;
|
||||
|
||||
NSOpenGLPixelFormatAttribute attr[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, NSOpenGLPFAAccelerated, 0 };
|
||||
NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc]
|
||||
initWithAttributes: attr];
|
||||
if (fmt == nil)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "failed to create pixel format");
|
||||
return false;
|
||||
}
|
||||
|
||||
cocoaCtx = [[NSOpenGLContext alloc] initWithFormat: fmt shareContext: nil];
|
||||
[fmt release];
|
||||
if (cocoaCtx == nil)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "failed to create context");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cocoaWin == nil)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "failed to create window");
|
||||
return false;
|
||||
}
|
||||
|
||||
[window makeFirstResponder:cocoaWin];
|
||||
[cocoaCtx setView: cocoaWin];
|
||||
[window makeKeyAndOrderFront: nil];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cInterfaceAGL::MakeCurrent()
|
||||
{
|
||||
[cocoaCtx makeCurrentContext];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cInterfaceAGL::ClearCurrent()
|
||||
{
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
return true;
|
||||
}
|
||||
|
||||
// Close backend
|
||||
void cInterfaceAGL::Shutdown()
|
||||
{
|
||||
[cocoaCtx clearDrawable];
|
||||
[cocoaCtx release];
|
||||
cocoaCtx = nil;
|
||||
}
|
||||
|
||||
void cInterfaceAGL::Update()
|
||||
{
|
||||
NSWindow *window = [cocoaWin window];
|
||||
NSSize size = [cocoaWin frame].size;
|
||||
|
||||
float scale = [window backingScaleFactor];
|
||||
size.width *= scale;
|
||||
size.height *= scale;
|
||||
|
||||
if (s_backbuffer_width == size.width &&
|
||||
s_backbuffer_height == size.height)
|
||||
return;
|
||||
|
||||
s_backbuffer_width = size.width;
|
||||
s_backbuffer_height = size.height;
|
||||
|
||||
[cocoaCtx update];
|
||||
}
|
||||
|
||||
void cInterfaceAGL::SwapInterval(int interval)
|
||||
{
|
||||
[cocoaCtx setValues:(GLint *)&interval forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __APPLE__
|
||||
#import <AppKit/AppKit.h>
|
||||
#endif
|
||||
|
||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||
|
||||
class cInterfaceAGL : public cInterfaceBase
|
||||
{
|
||||
private:
|
||||
NSView *cocoaWin;
|
||||
NSOpenGLContext *cocoaCtx;
|
||||
public:
|
||||
void Swap();
|
||||
bool Create(void *window_handle);
|
||||
bool MakeCurrent();
|
||||
bool ClearCurrent();
|
||||
void Shutdown();
|
||||
void Update();
|
||||
void SwapInterval(int interval);
|
||||
|
||||
};
|
@ -1,209 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinWX/GLInterface/EGL.h"
|
||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
|
||||
// Show the current FPS
|
||||
void cInterfaceEGL::Swap()
|
||||
{
|
||||
eglSwapBuffers(egl_dpy, egl_surf);
|
||||
}
|
||||
void cInterfaceEGL::SwapInterval(int Interval)
|
||||
{
|
||||
eglSwapInterval(egl_dpy, Interval);
|
||||
}
|
||||
|
||||
void* cInterfaceEGL::GetFuncAddress(const std::string& name)
|
||||
{
|
||||
return (void*)eglGetProcAddress(name.c_str());
|
||||
}
|
||||
|
||||
void cInterfaceEGL::DetectMode()
|
||||
{
|
||||
if (s_opengl_mode != MODE_DETECT)
|
||||
return;
|
||||
|
||||
EGLint num_configs;
|
||||
EGLConfig *config = nullptr;
|
||||
bool supportsGL = false, supportsGLES2 = false, supportsGLES3 = false;
|
||||
|
||||
// attributes for a visual in RGBA format with at least
|
||||
// 8 bits per color
|
||||
int attribs[] = {
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_NONE };
|
||||
|
||||
// Get how many configs there are
|
||||
if (!eglChooseConfig( egl_dpy, attribs, nullptr, 0, &num_configs))
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
config = new EGLConfig[num_configs];
|
||||
|
||||
// Get all the configurations
|
||||
if (!eglChooseConfig(egl_dpy, attribs, config, num_configs, &num_configs))
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_configs; ++i)
|
||||
{
|
||||
EGLint attribVal;
|
||||
bool ret;
|
||||
ret = eglGetConfigAttrib(egl_dpy, config[i], EGL_RENDERABLE_TYPE, &attribVal);
|
||||
if (ret)
|
||||
{
|
||||
if (attribVal & EGL_OPENGL_BIT)
|
||||
supportsGL = true;
|
||||
if (attribVal & (1 << 6)) /* EGL_OPENGL_ES3_BIT_KHR */
|
||||
supportsGLES3 = true;
|
||||
if (attribVal & EGL_OPENGL_ES2_BIT)
|
||||
supportsGLES2 = true;
|
||||
}
|
||||
}
|
||||
if (supportsGL)
|
||||
s_opengl_mode = GLInterfaceMode::MODE_OPENGL;
|
||||
else if (supportsGLES3)
|
||||
s_opengl_mode = GLInterfaceMode::MODE_OPENGLES3;
|
||||
else if (supportsGLES2)
|
||||
s_opengl_mode = GLInterfaceMode::MODE_OPENGLES2;
|
||||
err_exit:
|
||||
if (s_opengl_mode == GLInterfaceMode::MODE_DETECT) // Errored before we found a mode
|
||||
s_opengl_mode = GLInterfaceMode::MODE_OPENGL; // Fall back to OpenGL
|
||||
if (config)
|
||||
delete[] config;
|
||||
}
|
||||
|
||||
// Create rendering window.
|
||||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||
bool cInterfaceEGL::Create(void *window_handle)
|
||||
{
|
||||
const char *s;
|
||||
EGLint egl_major, egl_minor;
|
||||
|
||||
egl_dpy = OpenDisplay();
|
||||
|
||||
if (!egl_dpy)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglGetDisplay() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor))
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglInitialize() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Detection code */
|
||||
EGLConfig config;
|
||||
EGLint num_configs;
|
||||
|
||||
DetectMode();
|
||||
|
||||
// attributes for a visual in RGBA format with at least
|
||||
// 8 bits per color
|
||||
int attribs[] = {
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_NONE };
|
||||
|
||||
EGLint ctx_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
switch (s_opengl_mode)
|
||||
{
|
||||
case MODE_OPENGL:
|
||||
attribs[1] = EGL_OPENGL_BIT;
|
||||
ctx_attribs[0] = EGL_NONE;
|
||||
break;
|
||||
case MODE_OPENGLES2:
|
||||
attribs[1] = EGL_OPENGL_ES2_BIT;
|
||||
ctx_attribs[1] = 2;
|
||||
break;
|
||||
case MODE_OPENGLES3:
|
||||
attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
|
||||
ctx_attribs[1] = 3;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(VIDEO, "Unknown opengl mode set\n");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs))
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (s_opengl_mode == MODE_OPENGL)
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
else
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
EGLNativeWindowType host_window = (EGLNativeWindowType) window_handle;
|
||||
EGLNativeWindowType native_window = InitializePlatform(host_window, config);
|
||||
|
||||
s = eglQueryString(egl_dpy, EGL_VERSION);
|
||||
INFO_LOG(VIDEO, "EGL_VERSION = %s\n", s);
|
||||
|
||||
s = eglQueryString(egl_dpy, EGL_VENDOR);
|
||||
INFO_LOG(VIDEO, "EGL_VENDOR = %s\n", s);
|
||||
|
||||
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
|
||||
INFO_LOG(VIDEO, "EGL_EXTENSIONS = %s\n", s);
|
||||
|
||||
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
|
||||
INFO_LOG(VIDEO, "EGL_CLIENT_APIS = %s\n", s);
|
||||
|
||||
egl_ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
|
||||
if (!egl_ctx)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
egl_surf = eglCreateWindowSurface(egl_dpy, config, native_window, nullptr);
|
||||
if (!egl_surf)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cInterfaceEGL::MakeCurrent()
|
||||
{
|
||||
return eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx);
|
||||
}
|
||||
// Close backend
|
||||
void cInterfaceEGL::Shutdown()
|
||||
{
|
||||
ShutdownPlatform();
|
||||
if (egl_ctx && !eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx))
|
||||
NOTICE_LOG(VIDEO, "Could not release drawing context.");
|
||||
if (egl_ctx)
|
||||
{
|
||||
eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (!eglDestroyContext(egl_dpy, egl_ctx))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
|
||||
if (!eglDestroySurface(egl_dpy, egl_surf))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy window surface.");
|
||||
if (!eglTerminate(egl_dpy))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
|
||||
egl_ctx = nullptr;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||
|
||||
class cInterfaceEGL : public cInterfaceBase
|
||||
{
|
||||
protected:
|
||||
void DetectMode();
|
||||
EGLSurface egl_surf;
|
||||
EGLContext egl_ctx;
|
||||
EGLDisplay egl_dpy;
|
||||
|
||||
virtual EGLDisplay OpenDisplay() = 0;
|
||||
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) = 0;
|
||||
virtual void ShutdownPlatform() = 0;
|
||||
public:
|
||||
void SwapInterval(int Interval);
|
||||
void Swap();
|
||||
void SetMode(u32 mode) { s_opengl_mode = mode; }
|
||||
void* GetFuncAddress(const std::string& name);
|
||||
bool Create(void *window_handle);
|
||||
bool MakeCurrent();
|
||||
void Shutdown();
|
||||
};
|
@ -1,29 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/Host.h"
|
||||
#include "DolphinWX/GLInterface/EGLAndroid.h"
|
||||
|
||||
EGLDisplay cInterfaceEGLAndroid::OpenDisplay()
|
||||
{
|
||||
return eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
EGLNativeWindowType cInterfaceEGLAndroid::InitializePlatform(EGLNativeWindowType host_window, EGLConfig config)
|
||||
{
|
||||
EGLint format;
|
||||
eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &format);
|
||||
ANativeWindow_setBuffersGeometry(host_window, 0, 0, format);
|
||||
|
||||
int none, width, height;
|
||||
Host_GetRenderWindowSize(none, none, width, height);
|
||||
GLInterface->SetBackBufferDimensions(width, height);
|
||||
|
||||
return host_window;
|
||||
}
|
||||
|
||||
void cInterfaceEGLAndroid::ShutdownPlatform()
|
||||
{
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DolphinWX/GLInterface/EGL.h"
|
||||
|
||||
class cInterfaceEGLAndroid : public cInterfaceEGL
|
||||
{
|
||||
protected:
|
||||
EGLDisplay OpenDisplay() override;
|
||||
EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) override;
|
||||
void ShutdownPlatform() override;
|
||||
};
|
@ -1,44 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinWX/GLInterface/EGLX11.h"
|
||||
|
||||
EGLDisplay cInterfaceEGLX11::OpenDisplay()
|
||||
{
|
||||
dpy = XOpenDisplay(nullptr);
|
||||
XWindow.Initialize(dpy);
|
||||
return eglGetDisplay(dpy);
|
||||
}
|
||||
|
||||
EGLNativeWindowType cInterfaceEGLX11::InitializePlatform(EGLNativeWindowType host_window, EGLConfig config)
|
||||
{
|
||||
EGLint vid;
|
||||
eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid);
|
||||
|
||||
XVisualInfo visTemplate;
|
||||
visTemplate.visualid = vid;
|
||||
|
||||
XVisualInfo *vi;
|
||||
int nVisuals;
|
||||
vi = XGetVisualInfo(dpy, VisualIDMask, &visTemplate, &nVisuals);
|
||||
|
||||
XWindowAttributes attribs;
|
||||
if (!XGetWindowAttributes(dpy, (Window)host_window, &attribs))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Window attribute retrieval failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_backbuffer_width = attribs.width;
|
||||
s_backbuffer_height = attribs.height;
|
||||
|
||||
return (EGLNativeWindowType) XWindow.CreateXWindow((Window) host_window, vi);
|
||||
}
|
||||
|
||||
void cInterfaceEGLX11::ShutdownPlatform()
|
||||
{
|
||||
XWindow.DestroyXWindow();
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "DolphinWX/GLInterface/EGL.h"
|
||||
#include "DolphinWX/GLInterface/X11_Util.h"
|
||||
|
||||
class cInterfaceEGLX11 : public cInterfaceEGL
|
||||
{
|
||||
private:
|
||||
cX11Window XWindow;
|
||||
Display *dpy;
|
||||
protected:
|
||||
EGLDisplay OpenDisplay() override;
|
||||
EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) override;
|
||||
void ShutdownPlatform() override;
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "DolphinWX/GLInterface/EGLAndroid.h"
|
||||
#elif defined(__APPLE__)
|
||||
#include "DolphinWX/GLInterface/AGL.h"
|
||||
#elif defined(_WIN32)
|
||||
#include "DolphinWX/GLInterface/WGL.h"
|
||||
#elif HAVE_X11
|
||||
#if defined(USE_EGL) && USE_EGL
|
||||
#include "DolphinWX/GLInterface/EGLX11.h"
|
||||
#else
|
||||
#include "DolphinWX/GLInterface/GLX.h"
|
||||
#endif
|
||||
#else
|
||||
#error Platform doesnt have a GLInterface
|
||||
#endif
|
||||
|
||||
cInterfaceBase* HostGL_CreateGLInterface()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
return new cInterfaceEGLAndroid;
|
||||
#elif defined(__APPLE__)
|
||||
return new cInterfaceAGL;
|
||||
#elif defined(_WIN32)
|
||||
return new cInterfaceWGL;
|
||||
#elif defined(HAVE_X11) && HAVE_X11
|
||||
#if defined(USE_EGL) && USE_EGL
|
||||
return new cInterfaceEGLX11;
|
||||
#else
|
||||
return new cInterfaceGLX;
|
||||
#endif
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "DolphinWX/GLInterface/GLX.h"
|
||||
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
|
||||
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr;
|
||||
|
||||
void cInterfaceGLX::SwapInterval(int Interval)
|
||||
{
|
||||
if (glXSwapIntervalSGI)
|
||||
glXSwapIntervalSGI(Interval);
|
||||
else
|
||||
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
||||
}
|
||||
void* cInterfaceGLX::GetFuncAddress(const std::string& name)
|
||||
{
|
||||
return (void*)glXGetProcAddress((const GLubyte*)name.c_str());
|
||||
}
|
||||
|
||||
void cInterfaceGLX::Swap()
|
||||
{
|
||||
glXSwapBuffers(dpy, win);
|
||||
}
|
||||
|
||||
// Create rendering window.
|
||||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||
bool cInterfaceGLX::Create(void *window_handle)
|
||||
{
|
||||
int glxMajorVersion, glxMinorVersion;
|
||||
|
||||
// attributes for a single buffered visual in RGBA format with at least
|
||||
// 8 bits per color
|
||||
int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
None};
|
||||
|
||||
// attributes for a double buffered visual in RGBA format with at least
|
||||
// 8 bits per color
|
||||
int attrListDbl[] = {GLX_RGBA, GLX_DOUBLEBUFFER,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
None };
|
||||
|
||||
int attrListDefault[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None };
|
||||
|
||||
dpy = XOpenDisplay(nullptr);
|
||||
int screen = DefaultScreen(dpy);
|
||||
|
||||
glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion);
|
||||
NOTICE_LOG(VIDEO, "glX-Version %d.%d", glxMajorVersion, glxMinorVersion);
|
||||
|
||||
// Get an appropriate visual
|
||||
vi = glXChooseVisual(dpy, screen, attrListDbl);
|
||||
if (vi == nullptr)
|
||||
{
|
||||
vi = glXChooseVisual(dpy, screen, attrListSgl);
|
||||
if (vi != nullptr)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Only single buffered visual!");
|
||||
}
|
||||
else
|
||||
{
|
||||
vi = glXChooseVisual(dpy, screen, attrListDefault);
|
||||
if (vi == nullptr)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Could not choose visual (glXChooseVisual)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NOTICE_LOG(VIDEO, "Got double buffered visual!");
|
||||
}
|
||||
|
||||
// Create a GLX context.
|
||||
ctx = glXCreateContext(dpy, vi, nullptr, GL_TRUE);
|
||||
if (!ctx)
|
||||
{
|
||||
PanicAlert("Unable to create GLX context.");
|
||||
return false;
|
||||
}
|
||||
|
||||
XWindow.Initialize(dpy);
|
||||
|
||||
Window parent = (Window)window_handle;
|
||||
|
||||
XWindowAttributes attribs;
|
||||
if (!XGetWindowAttributes(dpy, parent, &attribs))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Window attribute retrieval failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_backbuffer_width = attribs.width;
|
||||
s_backbuffer_height = attribs.height;
|
||||
|
||||
win = XWindow.CreateXWindow(parent, vi);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cInterfaceGLX::MakeCurrent()
|
||||
{
|
||||
bool success = glXMakeCurrent(dpy, win, ctx);
|
||||
if (success)
|
||||
{
|
||||
// load this function based on the current bound context
|
||||
glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)GLInterface->GetFuncAddress("glXSwapIntervalSGI");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool cInterfaceGLX::ClearCurrent()
|
||||
{
|
||||
return glXMakeCurrent(dpy, None, nullptr);
|
||||
}
|
||||
|
||||
|
||||
// Close backend
|
||||
void cInterfaceGLX::Shutdown()
|
||||
{
|
||||
XWindow.DestroyXWindow();
|
||||
if (ctx)
|
||||
{
|
||||
glXDestroyContext(dpy, ctx);
|
||||
XCloseDisplay(dpy);
|
||||
ctx = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include "DolphinWX/GLInterface/X11_Util.h"
|
||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||
|
||||
class cInterfaceGLX : public cInterfaceBase
|
||||
{
|
||||
private:
|
||||
cX11Window XWindow;
|
||||
Display *dpy;
|
||||
Window win;
|
||||
GLXContext ctx;
|
||||
XVisualInfo *vi;
|
||||
public:
|
||||
friend class cX11Window;
|
||||
void SwapInterval(int Interval) override;
|
||||
void Swap() override;
|
||||
void* GetFuncAddress(const std::string& name) override;
|
||||
bool Create(void *window_handle);
|
||||
bool MakeCurrent() override;
|
||||
bool ClearCurrent() override;
|
||||
void Shutdown() override;
|
||||
};
|
@ -1,182 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Core/Host.h"
|
||||
|
||||
#include "DolphinWX/GLInterface/WGL.h"
|
||||
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
static HDC hDC = nullptr; // Private GDI Device Context
|
||||
static HGLRC hRC = nullptr; // Permanent Rendering Context
|
||||
static HINSTANCE dllHandle = nullptr; // Handle to OpenGL32.dll
|
||||
|
||||
// typedef from wglext.h
|
||||
typedef BOOL(WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
|
||||
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr;
|
||||
|
||||
void cInterfaceWGL::SwapInterval(int Interval)
|
||||
{
|
||||
if (wglSwapIntervalEXT)
|
||||
wglSwapIntervalEXT(Interval);
|
||||
else
|
||||
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
||||
}
|
||||
void cInterfaceWGL::Swap()
|
||||
{
|
||||
SwapBuffers(hDC);
|
||||
}
|
||||
|
||||
void* cInterfaceWGL::GetFuncAddress(const std::string& name)
|
||||
{
|
||||
void* func = (void*)wglGetProcAddress((LPCSTR)name.c_str());
|
||||
if (func == nullptr)
|
||||
func = (void*)GetProcAddress(dllHandle, (LPCSTR)name.c_str());
|
||||
return func;
|
||||
}
|
||||
|
||||
// Draw messages on top of the screen
|
||||
bool cInterfaceWGL::PeekMessages()
|
||||
{
|
||||
// TODO: peekmessage
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
return FALSE;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Create rendering window.
|
||||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||
bool cInterfaceWGL::Create(void *window_handle)
|
||||
{
|
||||
if (window_handle == nullptr)
|
||||
return false;
|
||||
|
||||
HWND window_handle_reified = reinterpret_cast<HWND>(window_handle);
|
||||
RECT window_rect = {0};
|
||||
|
||||
if (!GetClientRect(window_handle_reified, &window_rect))
|
||||
return false;
|
||||
|
||||
// Control window size and picture scaling
|
||||
int twidth = (window_rect.right - window_rect.left);
|
||||
int theight = (window_rect.bottom - window_rect.top);
|
||||
s_backbuffer_width = twidth;
|
||||
s_backbuffer_height = theight;
|
||||
|
||||
m_window_handle = window_handle_reified;
|
||||
|
||||
#ifdef _WIN32
|
||||
dllHandle = LoadLibrary(TEXT("OpenGL32.dll"));
|
||||
#endif
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
|
||||
{
|
||||
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
||||
1, // Version Number
|
||||
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
||||
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
||||
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
||||
PFD_TYPE_RGBA, // Request An RGBA Format
|
||||
32, // Select Our Color Depth
|
||||
0, 0, 0, 0, 0, 0, // Color Bits Ignored
|
||||
0, // 8bit Alpha Buffer
|
||||
0, // Shift Bit Ignored
|
||||
0, // No Accumulation Buffer
|
||||
0, 0, 0, 0, // Accumulation Bits Ignored
|
||||
0, // 0Bit Z-Buffer (Depth Buffer)
|
||||
0, // 0bit Stencil Buffer
|
||||
0, // No Auxiliary Buffer
|
||||
PFD_MAIN_PLANE, // Main Drawing Layer
|
||||
0, // Reserved
|
||||
0, 0, 0 // Layer Masks Ignored
|
||||
};
|
||||
|
||||
int PixelFormat; // Holds The Results After Searching For A Match
|
||||
|
||||
if (!(hDC = GetDC(window_handle_reified)))
|
||||
{
|
||||
PanicAlert("(1) Can't create an OpenGL Device context. Fail.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))
|
||||
{
|
||||
PanicAlert("(2) Can't find a suitable PixelFormat.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(hDC, PixelFormat, &pfd))
|
||||
{
|
||||
PanicAlert("(3) Can't set the PixelFormat.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(hRC = wglCreateContext(hDC)))
|
||||
{
|
||||
PanicAlert("(4) Can't create an OpenGL rendering context.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cInterfaceWGL::MakeCurrent()
|
||||
{
|
||||
bool success = wglMakeCurrent(hDC, hRC) ? true : false;
|
||||
if (success)
|
||||
{
|
||||
// Grab the swap interval function pointer
|
||||
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)GLInterface->GetFuncAddress("wglSwapIntervalEXT");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool cInterfaceWGL::ClearCurrent()
|
||||
{
|
||||
return wglMakeCurrent(hDC, nullptr) ? true : false;
|
||||
}
|
||||
|
||||
// Update window width, size and etc. Called from Render.cpp
|
||||
void cInterfaceWGL::Update()
|
||||
{
|
||||
RECT rcWindow;
|
||||
GetClientRect(m_window_handle, &rcWindow);
|
||||
|
||||
// Get the new window width and height
|
||||
s_backbuffer_width = (rcWindow.right - rcWindow.left);
|
||||
s_backbuffer_height = (rcWindow.bottom - rcWindow.top);
|
||||
}
|
||||
|
||||
// Close backend
|
||||
void cInterfaceWGL::Shutdown()
|
||||
{
|
||||
if (hRC)
|
||||
{
|
||||
if (!wglMakeCurrent(nullptr, nullptr))
|
||||
NOTICE_LOG(VIDEO, "Could not release drawing context.");
|
||||
|
||||
if (!wglDeleteContext(hRC))
|
||||
ERROR_LOG(VIDEO, "Attempt to release rendering context failed.");
|
||||
|
||||
hRC = nullptr;
|
||||
}
|
||||
|
||||
if (hDC && !ReleaseDC(m_window_handle, hDC))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Attempt to release device context failed.");
|
||||
hDC = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||
|
||||
class cInterfaceWGL : public cInterfaceBase
|
||||
{
|
||||
public:
|
||||
void SwapInterval(int Interval);
|
||||
void Swap();
|
||||
void* GetFuncAddress(const std::string& name);
|
||||
bool Create(void *window_handle);
|
||||
bool MakeCurrent();
|
||||
bool ClearCurrent();
|
||||
void Shutdown();
|
||||
|
||||
void Update();
|
||||
bool PeekMessages();
|
||||
|
||||
HWND m_window_handle;
|
||||
};
|
@ -1,75 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Common/Thread.h"
|
||||
#include "Core/Host.h"
|
||||
#include "DolphinWX/GLInterface/X11_Util.h"
|
||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
void cX11Window::Initialize(Display *_dpy)
|
||||
{
|
||||
dpy = _dpy;
|
||||
}
|
||||
|
||||
Window cX11Window::CreateXWindow(Window parent, XVisualInfo *vi)
|
||||
{
|
||||
XSetWindowAttributes attr;
|
||||
|
||||
colormap = XCreateColormap(dpy, parent, vi->visual, AllocNone);
|
||||
|
||||
// Setup window attributes
|
||||
attr.colormap = colormap;
|
||||
|
||||
XWindowAttributes attribs;
|
||||
if (!XGetWindowAttributes(dpy, parent, &attribs))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Window attribute retrieval failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create the window
|
||||
win = XCreateWindow(dpy, parent,
|
||||
0, 0, attribs.width, attribs.height, 0,
|
||||
vi->depth, InputOutput, vi->visual,
|
||||
CWColormap, &attr);
|
||||
XSelectInput(dpy, parent, StructureNotifyMask);
|
||||
XMapWindow(dpy, win);
|
||||
XSync(dpy, True);
|
||||
|
||||
xEventThread = std::thread(&cX11Window::XEventThread, this);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
void cX11Window::DestroyXWindow(void)
|
||||
{
|
||||
XUnmapWindow(dpy, win);
|
||||
win = 0;
|
||||
if (xEventThread.joinable())
|
||||
xEventThread.join();
|
||||
XFreeColormap(dpy, colormap);
|
||||
}
|
||||
|
||||
void cX11Window::XEventThread()
|
||||
{
|
||||
while (win)
|
||||
{
|
||||
XEvent event;
|
||||
for (int num_events = XPending(dpy); num_events > 0; num_events--)
|
||||
{
|
||||
XNextEvent(dpy, &event);
|
||||
switch (event.type)
|
||||
{
|
||||
case ConfigureNotify:
|
||||
XResizeWindow(dpy, win, event.xconfigure.width, event.xconfigure.height);
|
||||
GLInterface->SetBackBufferDimensions(event.xconfigure.width, event.xconfigure.height);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Common::SleepCurrentThread(20);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
class cX11Window
|
||||
{
|
||||
private:
|
||||
void XEventThread();
|
||||
std::thread xEventThread;
|
||||
Colormap colormap;
|
||||
public:
|
||||
void Initialize(Display *dpy);
|
||||
Window CreateXWindow(Window parent, XVisualInfo *vi);
|
||||
void DestroyXWindow();
|
||||
|
||||
Display *dpy;
|
||||
Window win;
|
||||
};
|
@ -129,7 +129,7 @@ void Host_ShowVideoConfig(void*, const std::string&, const std::string&) {}
|
||||
|
||||
#if HAVE_X11
|
||||
#include <X11/keysym.h>
|
||||
#include "DolphinWX/X11Utils.h"
|
||||
#include "VideoBackends/OGL/GLInterface/X11Utils.h"
|
||||
|
||||
class PlatformX11 : public Platform
|
||||
{
|
||||
|
@ -1,291 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <spawn.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "DolphinWX/X11Utils.h"
|
||||
|
||||
extern char **environ;
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
#endif
|
||||
|
||||
namespace X11Utils
|
||||
{
|
||||
|
||||
void ToggleFullscreen(Display *dpy, Window win)
|
||||
{
|
||||
// Init X event structure for _NET_WM_STATE_FULLSCREEN client message
|
||||
XEvent event;
|
||||
event.xclient.type = ClientMessage;
|
||||
event.xclient.message_type = XInternAtom(dpy, "_NET_WM_STATE", False);
|
||||
event.xclient.window = win;
|
||||
event.xclient.format = 32;
|
||||
event.xclient.data.l[0] = _NET_WM_STATE_TOGGLE;
|
||||
event.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
||||
|
||||
// Send the event
|
||||
if (!XSendEvent(dpy, DefaultRootWindow(dpy), False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask, &event))
|
||||
ERROR_LOG(VIDEO, "Failed to switch fullscreen/windowed mode.");
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
Window XWindowFromHandle(void *Handle)
|
||||
{
|
||||
return GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(Handle)));
|
||||
}
|
||||
|
||||
Display *XDisplayFromHandle(void *Handle)
|
||||
{
|
||||
return GDK_WINDOW_XDISPLAY(gtk_widget_get_window(GTK_WIDGET(Handle)));
|
||||
}
|
||||
#endif
|
||||
|
||||
void InhibitScreensaver(Display *dpy, Window win, bool suspend)
|
||||
{
|
||||
char id[11];
|
||||
snprintf(id, sizeof(id), "0x%lx", win);
|
||||
|
||||
// Call xdg-screensaver
|
||||
char *argv[4] = {
|
||||
(char *)"xdg-screensaver",
|
||||
(char *)(suspend ? "suspend" : "resume"),
|
||||
id,
|
||||
nullptr};
|
||||
pid_t pid;
|
||||
if (!posix_spawnp(&pid, "xdg-screensaver", nullptr, nullptr, argv, environ))
|
||||
{
|
||||
int status;
|
||||
while (waitpid (pid, &status, 0) == -1);
|
||||
|
||||
DEBUG_LOG(VIDEO, "Started xdg-screensaver (PID = %d)", (int)pid);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||
XRRConfiguration::XRRConfiguration(Display *_dpy, Window _win)
|
||||
: dpy(_dpy)
|
||||
, win(_win)
|
||||
, screenResources(nullptr), outputInfo(nullptr), crtcInfo(nullptr)
|
||||
, fullMode(0)
|
||||
, fs_fb_width(0), fs_fb_height(0), fs_fb_width_mm(0), fs_fb_height_mm(0)
|
||||
, bValid(true), bIsFullscreen(false)
|
||||
{
|
||||
int XRRMajorVersion, XRRMinorVersion;
|
||||
|
||||
if (!XRRQueryVersion(dpy, &XRRMajorVersion, &XRRMinorVersion) ||
|
||||
(XRRMajorVersion < 1 || (XRRMajorVersion == 1 && XRRMinorVersion < 3)))
|
||||
{
|
||||
WARN_LOG(VIDEO, "XRRExtension not supported.");
|
||||
bValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
screenResources = XRRGetScreenResourcesCurrent(dpy, win);
|
||||
|
||||
screen = DefaultScreen(dpy);
|
||||
fb_width = DisplayWidth(dpy, screen);
|
||||
fb_height = DisplayHeight(dpy, screen);
|
||||
fb_width_mm = DisplayWidthMM(dpy, screen);
|
||||
fb_height_mm = DisplayHeightMM(dpy, screen);
|
||||
|
||||
INFO_LOG(VIDEO, "XRRExtension-Version %d.%d", XRRMajorVersion, XRRMinorVersion);
|
||||
Update();
|
||||
}
|
||||
|
||||
XRRConfiguration::~XRRConfiguration()
|
||||
{
|
||||
if (bValid && bIsFullscreen)
|
||||
ToggleDisplayMode(False);
|
||||
if (screenResources)
|
||||
XRRFreeScreenResources(screenResources);
|
||||
if (outputInfo)
|
||||
XRRFreeOutputInfo(outputInfo);
|
||||
if (crtcInfo)
|
||||
XRRFreeCrtcInfo(crtcInfo);
|
||||
}
|
||||
|
||||
void XRRConfiguration::Update()
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution == "Auto")
|
||||
return;
|
||||
|
||||
if (!bValid)
|
||||
return;
|
||||
|
||||
if (outputInfo)
|
||||
{
|
||||
XRRFreeOutputInfo(outputInfo);
|
||||
outputInfo = nullptr;
|
||||
}
|
||||
if (crtcInfo)
|
||||
{
|
||||
XRRFreeCrtcInfo(crtcInfo);
|
||||
crtcInfo = nullptr;
|
||||
}
|
||||
fullMode = 0;
|
||||
|
||||
// Get the resolution setings for fullscreen mode
|
||||
unsigned int fullWidth, fullHeight;
|
||||
char *output_name = nullptr;
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution.find(':') ==
|
||||
std::string::npos)
|
||||
{
|
||||
fullWidth = fb_width;
|
||||
fullHeight = fb_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf(SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution.c_str(),
|
||||
"%m[^:]: %ux%u", &output_name, &fullWidth, &fullHeight);
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenResources->noutput; i++)
|
||||
{
|
||||
XRROutputInfo *output_info = XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]);
|
||||
if (output_info && output_info->crtc && output_info->connection == RR_Connected)
|
||||
{
|
||||
XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(dpy, screenResources, output_info->crtc);
|
||||
if (crtc_info)
|
||||
{
|
||||
if (!output_name || !strcmp(output_name, output_info->name))
|
||||
{
|
||||
// Use the first output for the default setting.
|
||||
if (!output_name)
|
||||
{
|
||||
output_name = strdup(output_info->name);
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution =
|
||||
StringFromFormat("%s: %ux%u", output_info->name, fullWidth, fullHeight);
|
||||
}
|
||||
outputInfo = output_info;
|
||||
crtcInfo = crtc_info;
|
||||
for (int j = 0; j < output_info->nmode && fullMode == 0; j++)
|
||||
{
|
||||
for (int k = 0; k < screenResources->nmode && fullMode == 0; k++)
|
||||
{
|
||||
if (output_info->modes[j] == screenResources->modes[k].id)
|
||||
{
|
||||
if (fullWidth == screenResources->modes[k].width &&
|
||||
fullHeight == screenResources->modes[k].height)
|
||||
{
|
||||
fullMode = screenResources->modes[k].id;
|
||||
if (crtcInfo->x + (int)screenResources->modes[k].width > fs_fb_width)
|
||||
fs_fb_width = crtcInfo->x + screenResources->modes[k].width;
|
||||
if (crtcInfo->y + (int)screenResources->modes[k].height > fs_fb_height)
|
||||
fs_fb_height = crtcInfo->y + screenResources->modes[k].height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (crtc_info->x + (int)crtc_info->width > fs_fb_width)
|
||||
fs_fb_width = crtc_info->x + crtc_info->width;
|
||||
if (crtc_info->y + (int)crtc_info->height > fs_fb_height)
|
||||
fs_fb_height = crtc_info->y + crtc_info->height;
|
||||
}
|
||||
}
|
||||
if (crtc_info && crtcInfo != crtc_info)
|
||||
XRRFreeCrtcInfo(crtc_info);
|
||||
}
|
||||
if (output_info && outputInfo != output_info)
|
||||
XRRFreeOutputInfo(output_info);
|
||||
}
|
||||
fs_fb_width_mm = fs_fb_width * DisplayHeightMM(dpy, screen) / DisplayHeight(dpy, screen);
|
||||
fs_fb_height_mm = fs_fb_height * DisplayHeightMM(dpy, screen) / DisplayHeight(dpy, screen);
|
||||
|
||||
if (output_name)
|
||||
free(output_name);
|
||||
|
||||
if (outputInfo && crtcInfo && fullMode)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Fullscreen Resolution %dx%d", fullWidth, fullHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Failed to obtain fullscreen size.\n"
|
||||
"Using current desktop resolution for fullscreen.");
|
||||
}
|
||||
}
|
||||
|
||||
void XRRConfiguration::ToggleDisplayMode(bool bFullscreen)
|
||||
{
|
||||
if (!bValid || !screenResources || !outputInfo || !crtcInfo || !fullMode)
|
||||
return;
|
||||
if (bFullscreen == bIsFullscreen)
|
||||
return;
|
||||
|
||||
XGrabServer(dpy);
|
||||
if (bFullscreen)
|
||||
{
|
||||
XRRSetCrtcConfig(dpy, screenResources, outputInfo->crtc, CurrentTime,
|
||||
crtcInfo->x, crtcInfo->y, fullMode, crtcInfo->rotation,
|
||||
crtcInfo->outputs, crtcInfo->noutput);
|
||||
XRRSetScreenSize(dpy, win, fs_fb_width, fs_fb_height, fs_fb_width_mm, fs_fb_height_mm);
|
||||
bIsFullscreen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
XRRSetCrtcConfig(dpy, screenResources, outputInfo->crtc, CurrentTime,
|
||||
crtcInfo->x, crtcInfo->y, crtcInfo->mode, crtcInfo->rotation,
|
||||
crtcInfo->outputs, crtcInfo->noutput);
|
||||
XRRSetScreenSize(dpy, win, fb_width, fb_height, fb_width_mm, fb_height_mm);
|
||||
bIsFullscreen = false;
|
||||
}
|
||||
XUngrabServer(dpy);
|
||||
XSync(dpy, false);
|
||||
}
|
||||
|
||||
void XRRConfiguration::AddResolutions(std::vector<std::string>& resos)
|
||||
{
|
||||
if (!bValid || !screenResources)
|
||||
return;
|
||||
|
||||
//Get all full screen resolutions for the config dialog
|
||||
for (int i = 0; i < screenResources->noutput; i++)
|
||||
{
|
||||
XRROutputInfo *output_info =
|
||||
XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]);
|
||||
|
||||
if (output_info && output_info->crtc && output_info->connection == RR_Connected)
|
||||
{
|
||||
for (int j = 0; j < output_info->nmode; j++)
|
||||
{
|
||||
for (int k = 0; k < screenResources->nmode; k++)
|
||||
{
|
||||
if (output_info->modes[j] == screenResources->modes[k].id)
|
||||
{
|
||||
const std::string strRes =
|
||||
std::string(output_info->name) + ": " +
|
||||
std::string(screenResources->modes[k].name);
|
||||
// Only add unique resolutions
|
||||
if (std::find(resos.begin(), resos.end(), strRes) == resos.end())
|
||||
{
|
||||
resos.push_back(strRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (output_info)
|
||||
XRRFreeOutputInfo(output_info);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
// HACK: Xlib.h (included from gtk/gdk headers and directly) uses #defines on
|
||||
// common names such as "Status", "BadRequest" or "Response", causing SFML
|
||||
// headers to be completely broken.
|
||||
//
|
||||
// We work around that issue by including SFML first before X11 headers. This
|
||||
// is terrible, but such is the life with Xlib.
|
||||
#include <SFML/Network.hpp> // NOLINT
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <wx/arrstr.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
||||
// EWMH state actions, see
|
||||
// http://freedesktop.org/wiki/Specifications/wm-spec?action=show&redirect=Standards%2Fwm-spec
|
||||
#define _NET_WM_STATE_REMOVE 0 // remove/unset property
|
||||
#define _NET_WM_STATE_ADD 1 // add/set property
|
||||
#define _NET_WM_STATE_TOGGLE 2 // toggle property
|
||||
|
||||
namespace X11Utils
|
||||
{
|
||||
|
||||
void ToggleFullscreen(Display *dpy, Window win);
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
Window XWindowFromHandle(void *Handle);
|
||||
Display *XDisplayFromHandle(void *Handle);
|
||||
#endif
|
||||
|
||||
void InhibitScreensaver(Display *dpy, Window win, bool suspend);
|
||||
|
||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||
class XRRConfiguration
|
||||
{
|
||||
public:
|
||||
XRRConfiguration(Display *_dpy, Window _win);
|
||||
~XRRConfiguration();
|
||||
|
||||
void Update();
|
||||
void ToggleDisplayMode(bool bFullscreen);
|
||||
void AddResolutions(std::vector<std::string>& resos);
|
||||
|
||||
private:
|
||||
Display *dpy;
|
||||
Window win;
|
||||
int screen;
|
||||
XRRScreenResources *screenResources;
|
||||
XRROutputInfo *outputInfo;
|
||||
XRRCrtcInfo *crtcInfo;
|
||||
RRMode fullMode;
|
||||
int fb_width, fb_height, fb_width_mm, fb_height_mm;
|
||||
int fs_fb_width, fs_fb_height, fs_fb_width_mm, fs_fb_height_mm;
|
||||
bool bValid;
|
||||
bool bIsFullscreen;
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
Reference in New Issue
Block a user