Merge pull request #764 from magcius/new-nogui-2

Rewrite GLInterface
This commit is contained in:
Lioncash 2014-08-21 14:14:54 -04:00
commit f17dcd2019
47 changed files with 449 additions and 1404 deletions

View File

@ -6,7 +6,6 @@ cmake_minimum_required(VERSION 2.8)
option(ANDROID "Enables a build for Android" OFF)
option(USE_EGL "Enables EGL OpenGL Interface" OFF)
option(TRY_X11 "Enables X11 Support" ON)
option(TRY_WAYLAND "Enables Wayland Support" OFF)
option(USE_UPNP "Enables UPnP port mapping support" ON)
option(DISABLE_WX "Disable wxWidgets (use CLI interface)" OFF)
option(ENABLE_PCH "Use PCH to speed up compilation" ON)
@ -324,7 +323,6 @@ if(ANDROID)
message("Building for Android")
add_definitions(-DANDROID)
set(USE_X11 0)
set(USE_WAYLAND 0)
set(USE_UPNP 0)
set(USE_EGL 1)
endif()
@ -407,26 +405,8 @@ if(NOT ANDROID)
endif(OPENAL_FOUND)
set(USE_X11 0)
set(USE_WAYLAND 0)
if(UNIX AND NOT APPLE)
# Note: The convention is to check TRY_X11 or TRY_WAYLAND where needed.
# This is where we detect platforms and set the variables accordingly.
pkg_check_modules(WAYLAND wayland-egl wayland-client wayland-cursor)
if(TRY_WAYLAND AND WAYLAND_FOUND)
pkg_check_modules(XKBCOMMON xkbcommon)
if(XKBCOMMON_FOUND)
set(USE_WAYLAND 1)
add_definitions(-DHAVE_WAYLAND)
include_directories(${WAYLAND_INCLUDE_DIR})
message("Wayland support enabled")
endif(XKBCOMMON_FOUND)
else()
set(USE_WAYLAND 0)
message("Wayland support disabled")
add_definitions(-DHAVE_WAYLAND=0)
endif(TRY_WAYLAND AND WAYLAND_FOUND)
# Note: We do not need to explicitly check for X11 as it is done in the cmake
# FindOpenGL module on linux.
if(TRY_X11 AND X11_FOUND)
@ -441,19 +421,13 @@ if(NOT ANDROID)
add_definitions(-DHAVE_X11=0)
endif(TRY_X11 AND X11_FOUND)
if (NOT USE_WAYLAND AND NOT USE_X11)
if (NOT USE_X11)
message(FATAL_ERROR "\n"
"No suitable display platform found\n"
"Requires wayland or x11 to run")
"Requires x11 to run")
endif()
endif()
# For now Wayland and EGL are tied to each other.
# The alternative would be an shm path
if(USE_WAYLAND)
set(USE_EGL 1)
endif()
if(USE_X11)
check_lib(XRANDR Xrandr)
if(XRANDR_FOUND)

View File

@ -126,21 +126,6 @@ void DisplayMessage(const std::string& message, int time_in_ms)
}
g_video_backend->Video_AddMessage(message, time_in_ms);
if (_CoreParameter.bRenderToMain &&
SConfig::GetInstance().m_InterfaceStatusbar)
{
Host_UpdateStatusBar(message);
}
else
{
Host_UpdateTitle(message);
}
}
void *GetWindowHandle()
{
return g_pWindowHandle;
}
bool IsRunning()
@ -213,9 +198,6 @@ bool Init()
!!SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.AR"));
}
// g_pWindowHandle is first the m_Panel handle,
// then it is updated to the render window handle,
// within g_video_backend->Initialize()
g_pWindowHandle = Host_GetRenderHandle();
// Start the emu thread
@ -700,10 +682,6 @@ void UpdateTitle()
}
// This is our final "frame counter" string
std::string SMessage = StringFromFormat("%s | %s", SSettings.c_str(), SFPS.c_str());
std::string TMessage = StringFromFormat("%s | %s", scm_rev_str, SMessage.c_str());
// Show message
g_video_backend->UpdateFPSDisplay(SMessage);
// Update the audio timestretcher with the current speed
if (soundStream)
@ -712,16 +690,7 @@ void UpdateTitle()
pMixer->UpdateSpeed((float)Speed / 100);
}
if (_CoreParameter.bRenderToMain &&
SConfig::GetInstance().m_InterfaceStatusbar)
{
Host_UpdateStatusBar(SMessage);
Host_UpdateTitle(scm_rev_str);
}
else
{
Host_UpdateTitle(TMessage);
}
Host_UpdateTitle(SMessage);
}
void Shutdown()

View File

@ -59,9 +59,6 @@ void SaveScreenShot();
void Callback_WiimoteInterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size);
void* GetWindowHandle();
// This displays messages in a user-visible way.
void DisplayMessage(const std::string& message, int time_in_ms);

View File

@ -37,7 +37,6 @@ void Host_SetWiiMoteConnectionState(int _State);
void Host_SysMessage(const char *fmt, ...);
void Host_UpdateDisasmDialog();
void Host_UpdateMainFrame();
void Host_UpdateStatusBar(const std::string& text, int Filed = 0);
void Host_UpdateTitle(const std::string& title);
void Host_ShowVideoConfig(void* parent, const std::string& backend_name,
const std::string& config_name);

View File

@ -279,9 +279,6 @@ bool PPCSymbolDB::SaveMap(const std::string& filename, bool WithCodes) const
mapFile.c_str()).c_str(), "Confirm", wxYES_NO)) return false;
}
if (WithCodes)
Host_UpdateStatusBar("Saving code, please stand by ...");
// Make a file
File::IOFile f(mapFile, "w");
if (!f)
@ -342,8 +339,6 @@ bool PPCSymbolDB::SaveMap(const std::string& filename, bool WithCodes) const
fprintf(f.GetHandle(), "\n");
}
}
// ---------------
Host_UpdateStatusBar(StringFromFormat("Saved %s", mapFile.c_str()).c_str());
return true;
}

View File

@ -4,8 +4,10 @@
#include <unordered_map>
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Common/Thread.h"
#include "DolphinWX/Android/ButtonManager.h"
#include "DolphinWX/GLInterface/GLInterface.h"
namespace ButtonManager
{

View File

@ -10,9 +10,6 @@ if(NOT ANDROID)
if(USE_X11)
set(LIBS ${LIBS} ${XRANDR_LIBRARIES})
endif()
if(USE_WAYLAND)
set(LIBS ${LIBS} ${WAYLAND_LIBRARIES} ${XKBCOMMON_LIBRARIES})
endif()
link_directories(${CMAKE_PREFIX_PATH}/lib)
else()
@ -76,25 +73,23 @@ set(ANDROID_SRCS Android/ButtonManager.cpp
MainAndroid.cpp)
if(USE_EGL)
set(SRCS ${SRCS} GLInterface/Platform.cpp
GLInterface/EGL.cpp)
if(USE_WAYLAND)
set(SRCS ${SRCS} GLInterface/Wayland_Util.cpp)
endif()
if(USE_X11)
set(SRCS ${SRCS} GLInterface/X11_Util.cpp)
endif()
else()
if(WIN32)
set(SRCS ${SRCS} GLInterface/WGL.cpp)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(SRCS ${SRCS} GLInterface/AGL.cpp)
else()
set(SRCS ${SRCS} GLInterface/GLX.cpp
GLInterface/X11_Util.cpp)
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)
set(SRCS ${SRCS} GLInterface/GLX.cpp
GLInterface/X11_Util.cpp)
endif()
set(SRCS ${SRCS} GLInterface/GLInterface.cpp)
set(NOGUI_SRCS MainNoGUI.cpp)

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
@ -100,7 +100,6 @@
<ClCompile Include="WxUtils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="GLInterface\GLInterface.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="AboutDolphin.h" />
<ClInclude Include="ARCodeAddEdit.h" />

View File

@ -282,7 +282,6 @@
<ClInclude Include="WiimoteConfigDiag.h">
<Filter>GUI</Filter>
</ClInclude>
<ClInclude Include="GLInterface\GLInterface.h" />
<ClInclude Include="SoftwareVideoConfigDialog.h">
<Filter>GUI\Video</Filter>
</ClInclude>

View File

@ -2,14 +2,6 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
// CFrame is the main parent window. Inside CFrame there is an m_Panel that is
// the parent for the rendering window (when we render to the main window). In
// Windows the rendering window is created by giving CreateWindow()
// m_Panel->GetHandle() as parent window and creating a new child window to
// m_Panel. The new child window handle that is returned by CreateWindow() can
// be accessed from Core::GetWindowHandle().
#ifdef __APPLE__
#include <Cocoa/Cocoa.h>
#endif
@ -636,6 +628,21 @@ WXLRESULT CFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
}
#endif
void CFrame::UpdateTitle(const std::string &str)
{
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain &&
SConfig::GetInstance().m_InterfaceStatusbar)
{
GetStatusBar()->SetStatusText(str, 0);
m_RenderFrame->SetTitle(scm_rev_str);
}
else
{
std::string titleStr = StringFromFormat("%s | %s", scm_rev_str, str.c_str());
m_RenderFrame->SetTitle(titleStr);
}
}
void CFrame::OnHostMessage(wxCommandEvent& event)
{
switch (event.GetId())
@ -650,8 +657,7 @@ void CFrame::OnHostMessage(wxCommandEvent& event)
break;
case IDM_UPDATETITLE:
if (m_RenderFrame != nullptr)
m_RenderFrame->SetTitle(event.GetString());
SetTitle(event.GetString());
break;
case IDM_WINDOWSIZEREQUEST:

View File

@ -126,6 +126,7 @@ public:
void UpdateWiiMenuChoice(wxMenuItem *WiiMenuItem=nullptr);
void PopulateSavedPerspectives();
static void ConnectWiimote(int wm_idx, bool connect);
void UpdateTitle(const std::string &str);
const CGameListCtrl *GetGameListCtrl() const;

View File

@ -2,18 +2,6 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
/*
1.1 Windows
CFrame is the main parent window. Inside CFrame there is m_Panel which is the
parent for the rendering window (when we render to the main window). In Windows
the rendering window is created by giving CreateWindow() m_Panel->GetHandle()
as parent window and creating a new child window to m_Panel. The new child
window handle that is returned by CreateWindow() can be accessed from
Core::GetWindowHandle().
*/
#include <cstdarg>
#include <cstdio>
#include <mutex>
@ -840,13 +828,6 @@ void CFrame::OnRenderParentResize(wxSizeEvent& event)
SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth = width;
SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight = height;
}
#if defined(HAVE_X11) && HAVE_X11
wxRect client_rect = m_RenderParent->GetClientRect();
XMoveResizeWindow(X11Utils::XDisplayFromHandle(GetHandle()),
(Window) Core::GetWindowHandle(),
client_rect.x, client_rect.y,
client_rect.width, client_rect.height);
#endif
m_LogWindow->Refresh();
m_LogWindow->Update();
}

View File

@ -4,28 +4,29 @@
#include <wx/panel.h>
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/AGL.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/VideoConfig.h"
void cInterfaceAGL::Swap()
{
[GLWin.cocoaCtx flushBuffer];
[cocoaCtx flushBuffer];
}
// Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool cInterfaceAGL::Create(void *&window_handle)
bool cInterfaceAGL::Create(void *window_handle)
{
// FIXME: Get rid of the explicit use of wxPanel here. This shouldn't be necessary.
GLWin.cocoaWin = reinterpret_cast<NSView*>(((wxPanel*)window_handle)->GetHandle());
NSSize size = [GLWin.cocoaWin frame].size;
cocoaWin = reinterpret_cast<NSView*>(((wxPanel*)window_handle)->GetHandle());
NSSize size = [cocoaWin frame].size;
// Enable high-resolution display support.
[GLWin.cocoaWin setWantsBestResolutionOpenGLSurface:YES];
[cocoaWin setWantsBestResolutionOpenGLSurface:YES];
NSWindow *window = [GLWin.cocoaWin window];
NSWindow *window = [cocoaWin window];
float scale = [window backingScaleFactor];
size.width *= scale;
@ -43,21 +44,21 @@ bool cInterfaceAGL::Create(void *&window_handle)
return false;
}
GLWin.cocoaCtx = [[NSOpenGLContext alloc]
cocoaCtx = [[NSOpenGLContext alloc]
initWithFormat: fmt shareContext: nil];
[fmt release];
if (GLWin.cocoaCtx == nil) {
if (cocoaCtx == nil) {
ERROR_LOG(VIDEO, "failed to create context");
return false;
}
if (GLWin.cocoaWin == nil) {
if (cocoaWin == nil) {
ERROR_LOG(VIDEO, "failed to create window");
return false;
}
[window makeFirstResponder:GLWin.cocoaWin];
[GLWin.cocoaCtx setView: GLWin.cocoaWin];
[window makeFirstResponder:cocoaWin];
[cocoaCtx setView: cocoaWin];
[window makeKeyAndOrderFront: nil];
return true;
@ -65,7 +66,7 @@ bool cInterfaceAGL::Create(void *&window_handle)
bool cInterfaceAGL::MakeCurrent()
{
[GLWin.cocoaCtx makeCurrentContext];
[cocoaCtx makeCurrentContext];
return true;
}
@ -79,15 +80,15 @@ bool cInterfaceAGL::ClearCurrent()
// Close backend
void cInterfaceAGL::Shutdown()
{
[GLWin.cocoaCtx clearDrawable];
[GLWin.cocoaCtx release];
GLWin.cocoaCtx = nil;
[cocoaCtx clearDrawable];
[cocoaCtx release];
cocoaCtx = nil;
}
void cInterfaceAGL::Update()
{
NSWindow *window = [GLWin.cocoaWin window];
NSSize size = [GLWin.cocoaWin frame].size;
NSWindow *window = [cocoaWin window];
NSSize size = [cocoaWin frame].size;
float scale = [window backingScaleFactor];
size.width *= scale;
@ -100,11 +101,11 @@ void cInterfaceAGL::Update()
s_backbuffer_width = size.width;
s_backbuffer_height = size.height;
[GLWin.cocoaCtx update];
[cocoaCtx update];
}
void cInterfaceAGL::SwapInterval(int interval)
{
[GLWin.cocoaCtx setValues:(GLint *)&interval forParameter:NSOpenGLCPSwapInterval];
[cocoaCtx setValues:(GLint *)&interval forParameter:NSOpenGLCPSwapInterval];
}

View File

@ -12,9 +12,12 @@
class cInterfaceAGL : public cInterfaceBase
{
private:
NSView *cocoaWin;
NSOpenGLContext *cocoaCtx;
public:
void Swap();
bool Create(void *&window_handle);
bool Create(void *window_handle);
bool MakeCurrent();
bool ClearCurrent();
void Shutdown();

View File

@ -2,22 +2,18 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "Core/Host.h"
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/EGL.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
#include "VideoCommon/RenderBase.h"
// Show the current FPS
void cInterfaceEGL::UpdateFPSDisplay(const std::string& text)
{
Platform.UpdateFPSDisplay(text);
}
void cInterfaceEGL::Swap()
{
Platform.SwapBuffers();
eglSwapBuffers(egl_dpy, egl_surf);
}
void cInterfaceEGL::SwapInterval(int Interval)
{
eglSwapInterval(GLWin.egl_dpy, Interval);
eglSwapInterval(egl_dpy, Interval);
}
void* cInterfaceEGL::GetFuncAddress(const std::string& name)
@ -43,7 +39,7 @@ void cInterfaceEGL::DetectMode()
EGL_NONE };
// Get how many configs there are
if (!eglChooseConfig( GLWin.egl_dpy, attribs, nullptr, 0, &num_configs))
if (!eglChooseConfig( egl_dpy, attribs, nullptr, 0, &num_configs))
{
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
goto err_exit;
@ -52,7 +48,7 @@ void cInterfaceEGL::DetectMode()
config = new EGLConfig[num_configs];
// Get all the configurations
if (!eglChooseConfig(GLWin.egl_dpy, attribs, config, num_configs, &num_configs))
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;
@ -62,7 +58,7 @@ void cInterfaceEGL::DetectMode()
{
EGLint attribVal;
bool ret;
ret = eglGetConfigAttrib(GLWin.egl_dpy, config[i], EGL_RENDERABLE_TYPE, &attribVal);
ret = eglGetConfigAttrib(egl_dpy, config[i], EGL_RENDERABLE_TYPE, &attribVal);
if (ret)
{
if (attribVal & EGL_OPENGL_BIT)
@ -88,25 +84,20 @@ err_exit:
// Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool cInterfaceEGL::Create(void *&window_handle)
bool cInterfaceEGL::Create(void *window_handle)
{
const char *s;
EGLint egl_major, egl_minor;
if (!Platform.SelectDisplay())
return false;
egl_dpy = OpenDisplay();
GLWin.egl_dpy = Platform.EGLGetDisplay();
if (!GLWin.egl_dpy)
if (!egl_dpy)
{
INFO_LOG(VIDEO, "Error: eglGetDisplay() failed\n");
return false;
}
GLWin.platform = Platform.platform;
if (!eglInitialize(GLWin.egl_dpy, &egl_major, &egl_minor))
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor))
{
INFO_LOG(VIDEO, "Error: eglInitialize() failed\n");
return false;
@ -151,7 +142,7 @@ bool cInterfaceEGL::Create(void *&window_handle)
break;
}
if (!eglChooseConfig( GLWin.egl_dpy, attribs, &config, 1, &num_configs))
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs))
{
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
exit(1);
@ -162,62 +153,57 @@ bool cInterfaceEGL::Create(void *&window_handle)
else
eglBindAPI(EGL_OPENGL_ES_API);
if (!Platform.Init(config, window_handle))
return false;
EGLNativeWindowType host_window = (EGLNativeWindowType) window_handle;
EGLNativeWindowType native_window = InitializePlatform(host_window, config);
s = eglQueryString(GLWin.egl_dpy, EGL_VERSION);
s = eglQueryString(egl_dpy, EGL_VERSION);
INFO_LOG(VIDEO, "EGL_VERSION = %s\n", s);
s = eglQueryString(GLWin.egl_dpy, EGL_VENDOR);
s = eglQueryString(egl_dpy, EGL_VENDOR);
INFO_LOG(VIDEO, "EGL_VENDOR = %s\n", s);
s = eglQueryString(GLWin.egl_dpy, EGL_EXTENSIONS);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
INFO_LOG(VIDEO, "EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(GLWin.egl_dpy, EGL_CLIENT_APIS);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
INFO_LOG(VIDEO, "EGL_CLIENT_APIS = %s\n", s);
GLWin.egl_ctx = eglCreateContext(GLWin.egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
if (!GLWin.egl_ctx)
egl_ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
if (!egl_ctx)
{
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
exit(1);
}
GLWin.native_window = Platform.CreateWindow();
GLWin.egl_surf = eglCreateWindowSurface(GLWin.egl_dpy, config, GLWin.native_window, nullptr);
if (!GLWin.egl_surf)
egl_surf = eglCreateWindowSurface(egl_dpy, config, native_window, nullptr);
if (!egl_surf)
{
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
exit(1);
}
Platform.ToggleFullscreen(SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen);
window_handle = (void *)GLWin.native_window;
return true;
}
bool cInterfaceEGL::MakeCurrent()
{
return eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx);
return eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx);
}
// Close backend
void cInterfaceEGL::Shutdown()
{
Platform.DestroyWindow();
if (GLWin.egl_ctx && !eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx))
ShutdownPlatform();
if (egl_ctx && !eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx))
NOTICE_LOG(VIDEO, "Could not release drawing context.");
if (GLWin.egl_ctx)
if (egl_ctx)
{
eglMakeCurrent(GLWin.egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglDestroyContext(GLWin.egl_dpy, GLWin.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(GLWin.egl_dpy, GLWin.egl_surf))
if (!eglDestroySurface(egl_dpy, egl_surf))
NOTICE_LOG(VIDEO, "Could not destroy window surface.");
if (!eglTerminate(GLWin.egl_dpy))
if (!eglTerminate(egl_dpy))
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
GLWin.egl_ctx = nullptr;
egl_ctx = nullptr;
}
}

View File

@ -10,41 +10,23 @@
#include "Core/ConfigManager.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
class cPlatform
{
private:
#if HAVE_X11
cXInterface XInterface;
#endif
#if HAVE_WAYLAND
cWaylandInterface WaylandInterface;
#endif
public:
enum egl_platform platform;
bool SelectDisplay(void);
bool Init(EGLConfig config, void *window_handle);
EGLDisplay EGLGetDisplay(void);
EGLNativeWindowType CreateWindow(void);
void DestroyWindow(void);
void UpdateFPSDisplay(const std::string& text);
void ToggleFullscreen(bool fullscreen);
void SwapBuffers();
};
class cInterfaceEGL : public cInterfaceBase
{
private:
cPlatform Platform;
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:
friend class cPlatform;
void SwapInterval(int Interval);
void Swap();
void SetMode(u32 mode) { s_opengl_mode = mode; }
void UpdateFPSDisplay(const std::string& text);
void* GetFuncAddress(const std::string& name);
bool Create(void *&window_handle);
bool Create(void *window_handle);
bool MakeCurrent();
void Shutdown();
};

View File

@ -0,0 +1,29 @@
// 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()
{
}

View File

@ -0,0 +1,15 @@
// 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;
};

View File

@ -0,0 +1,34 @@
// 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);
return (EGLNativeWindowType) XWindow.CreateXWindow((Window) host_window, vi);
}
void cInterfaceEGLX11::ShutdownPlatform()
{
XWindow.DestroyXWindow();
XCloseDisplay(dpy);
}

View File

@ -0,0 +1,21 @@
// 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;
};

View File

@ -2,21 +2,38 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "DolphinWX/GLInterface/GLInterface.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
GLWindow GLWin;
#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()
{
#if defined(USE_EGL) && USE_EGL
return new cInterfaceEGL;
#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

View File

@ -1,109 +0,0 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#pragma once
#include "Common/Thread.h"
#if USE_EGL
// Currently Wayland/EGL and X11/EGL platforms are supported.
// The platform may be spelected at run time by setting the
// environment variable DOLPHIN_EGL_PLATFORM to "wayland" or "x11".
enum egl_platform {
EGL_PLATFORM_NONE,
EGL_PLATFORM_WAYLAND,
EGL_PLATFORM_X11,
EGL_PLATFORM_ANDROID
};
#if HAVE_X11
#include "DolphinWX/GLInterface/X11_Util.h"
#endif
#if HAVE_WAYLAND
#include "DolphinWX/GLInterface/Wayland_Util.h"
#endif
#include "DolphinWX/GLInterface/EGL.h"
#elif defined(__APPLE__)
#include "DolphinWX/GLInterface/AGL.h"
#elif defined(_WIN32)
#include "DolphinWX/GLInterface/WGL.h"
#elif HAVE_X11
#include "DolphinWX/GLInterface/GLX.h"
#include <GL/glx.h>
#else
#error Platform doesnt have a GLInterface
#endif
#if HAVE_WAYLAND
struct geometry {
int width;
int height;
};
struct xkb {
struct xkb_context *context;
struct xkb_keymap *keymap;
struct xkb_state *state;
xkb_mod_mask_t control_mask;
xkb_mod_mask_t alt_mask;
xkb_mod_mask_t shift_mask;
};
#endif
typedef struct {
#if HAVE_WAYLAND
struct wl_display *wl_display;
struct wl_registry *wl_registry;
struct wl_compositor *wl_compositor;
struct wl_shell *wl_shell;
struct wl_seat *wl_seat;
struct {
struct wl_pointer *wl_pointer;
uint32_t serial;
} pointer;
struct {
struct wl_keyboard *wl_keyboard;
struct xkb xkb;
uint32_t modifiers;
} keyboard;
struct wl_shm *wl_shm;
struct wl_cursor_theme *wl_cursor_theme;
struct wl_cursor *wl_cursor;
struct wl_surface *wl_cursor_surface;
struct geometry geometry, window_size;
struct wl_egl_window *wl_egl_native;
struct wl_surface *wl_surface;
struct wl_shell_surface *wl_shell_surface;
bool fullscreen, running;
#endif
#if USE_EGL
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
enum egl_platform platform;
EGLNativeWindowType native_window;
#elif HAVE_X11
GLXContext ctx;
#endif
#if defined(__APPLE__)
NSView *cocoaWin;
NSOpenGLContext *cocoaCtx;
#elif HAVE_X11
int screen;
Window win;
Window parent;
// dpy used for glx stuff, evdpy for window events etc.
// evdpy is to be used by XEventThread only
Display *dpy, *evdpy;
XVisualInfo *vi;
XSetWindowAttributes attr;
std::thread xEventThread;
#endif
} GLWindow;
extern GLWindow GLWin;

View File

@ -4,7 +4,7 @@
#include <string>
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/GLX.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VideoConfig.h"
@ -12,12 +12,6 @@
typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr;
// Show the current FPS
void cInterfaceGLX::UpdateFPSDisplay(const std::string& text)
{
XStoreName(GLWin.evdpy, GLWin.win, text.c_str());
}
void cInterfaceGLX::SwapInterval(int Interval)
{
if (glXSwapIntervalSGI)
@ -32,12 +26,12 @@ void* cInterfaceGLX::GetFuncAddress(const std::string& name)
void cInterfaceGLX::Swap()
{
glXSwapBuffers(GLWin.dpy, GLWin.win);
glXSwapBuffers(dpy, win);
}
// Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool cInterfaceGLX::Create(void *&window_handle)
bool cInterfaceGLX::Create(void *window_handle)
{
int glxMajorVersion, glxMinorVersion;
@ -64,29 +58,25 @@ bool cInterfaceGLX::Create(void *&window_handle)
GLX_DOUBLEBUFFER,
None };
GLWin.dpy = XOpenDisplay(nullptr);
GLWin.evdpy = XOpenDisplay(nullptr);
GLWin.parent = (Window)window_handle;
GLWin.screen = DefaultScreen(GLWin.dpy);
if (GLWin.parent == 0)
GLWin.parent = RootWindow(GLWin.dpy, GLWin.screen);
dpy = XOpenDisplay(nullptr);
int screen = DefaultScreen(dpy);
glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion);
NOTICE_LOG(VIDEO, "glX-Version %d.%d", glxMajorVersion, glxMinorVersion);
// Get an appropriate visual
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
if (GLWin.vi == nullptr)
vi = glXChooseVisual(dpy, screen, attrListDbl);
if (vi == nullptr)
{
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
if (GLWin.vi != nullptr)
vi = glXChooseVisual(dpy, screen, attrListSgl);
if (vi != nullptr)
{
ERROR_LOG(VIDEO, "Only single buffered visual!");
}
else
{
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDefault);
if (GLWin.vi == nullptr)
vi = glXChooseVisual(dpy, screen, attrListDefault);
if (vi == nullptr)
{
ERROR_LOG(VIDEO, "Could not choose visual (glXChooseVisual)");
return false;
@ -97,21 +87,23 @@ bool cInterfaceGLX::Create(void *&window_handle)
NOTICE_LOG(VIDEO, "Got double buffered visual!");
// Create a GLX context.
GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, nullptr, GL_TRUE);
if (!GLWin.ctx)
ctx = glXCreateContext(dpy, vi, nullptr, GL_TRUE);
if (!ctx)
{
PanicAlert("Unable to create GLX context.");
return false;
}
XWindow.CreateXWindow();
window_handle = (void *)GLWin.win;
XWindow.Initialize(dpy);
Window parent = (Window)window_handle;
win = XWindow.CreateXWindow(parent, vi);
return true;
}
bool cInterfaceGLX::MakeCurrent()
{
bool success = glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
bool success = glXMakeCurrent(dpy, win, ctx);
if (success)
{
// load this function based on the current bound context
@ -122,7 +114,7 @@ bool cInterfaceGLX::MakeCurrent()
bool cInterfaceGLX::ClearCurrent()
{
return glXMakeCurrent(GLWin.dpy, None, nullptr);
return glXMakeCurrent(dpy, None, nullptr);
}
@ -130,12 +122,11 @@ bool cInterfaceGLX::ClearCurrent()
void cInterfaceGLX::Shutdown()
{
XWindow.DestroyXWindow();
if (GLWin.ctx)
if (ctx)
{
glXDestroyContext(GLWin.dpy, GLWin.ctx);
XCloseDisplay(GLWin.dpy);
XCloseDisplay(GLWin.evdpy);
GLWin.ctx = nullptr;
glXDestroyContext(dpy, ctx);
XCloseDisplay(dpy);
ctx = nullptr;
}
}

View File

@ -5,6 +5,7 @@
#pragma once
#include <string>
#include <GL/glx.h>
#include "DolphinWX/GLInterface/X11_Util.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
@ -13,13 +14,16 @@ 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 UpdateFPSDisplay(const std::string& text) override;
void* GetFuncAddress(const std::string& name) override;
bool Create(void *&window_handle) override;
bool Create(void *window_handle);
bool MakeCurrent() override;
bool ClearCurrent() override;
void Shutdown() override;

View File

@ -1,225 +0,0 @@
// Copyright 2014 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <string>
#include "Core/Host.h"
#include "DolphinWX/GLInterface/GLInterface.h"
bool cPlatform::SelectDisplay(void)
{
enum egl_platform selected_platform = EGL_PLATFORM_NONE;
enum egl_platform desired_platform = EGL_PLATFORM_NONE;
char *platform_env = getenv("DOLPHIN_EGL_PLATFORM");
if (platform_env)
platform_env = strdup(platform_env);
if (!platform_env)
printf("Running automatic platform detection\n");
// Try to select the platform set in the environment variable first
#if HAVE_WAYLAND
bool wayland_possible = WaylandInterface.ServerConnect();
if (platform_env && !strcmp(platform_env, "wayland"))
{
desired_platform = EGL_PLATFORM_WAYLAND;
if (wayland_possible)
selected_platform = EGL_PLATFORM_WAYLAND;
else
printf("Wayland display server connection failed\n");
}
#endif
#if HAVE_X11
bool x11_possible = XInterface.ServerConnect();
if (platform_env && !strcmp(platform_env, "x11"))
{
desired_platform = EGL_PLATFORM_X11;
if ((selected_platform != EGL_PLATFORM_WAYLAND) && x11_possible)
selected_platform = EGL_PLATFORM_X11;
else
printf("X11 display server connection failed\n");
}
#endif
// Fall back to automatic detection
if (selected_platform == EGL_PLATFORM_NONE)
{
if (platform_env && (desired_platform == EGL_PLATFORM_NONE)) {
printf("DOLPHIN_EGL_PLATFORM set to unrecognized platform \"%s\".\n"
#if HAVE_WAYLAND && !HAVE_X11
"Note: Valid value is \"wayland\" (built without x11 support)\n",
#endif
#if HAVE_X11 && !HAVE_WAYLAND
"Note: Valid values is \"x11\" (built without wayland support)\n",
#endif
#if HAVE_WAYLAND && HAVE_X11
"Note: Valid values are \"wayland\" and \"x11\"\n",
#endif
#if !HAVE_WAYLAND && !HAVE_X11
"Note: No Valid platform. Must be Android\n",
#endif
platform_env);
free(platform_env);
platform_env = nullptr;
}
#if HAVE_WAYLAND
if (wayland_possible)
{
selected_platform = EGL_PLATFORM_WAYLAND;
platform_env = strdup("wayland");
}
#endif
#if HAVE_X11
if ((selected_platform != EGL_PLATFORM_WAYLAND) && x11_possible)
{
selected_platform = EGL_PLATFORM_X11;
platform_env = strdup("x11");
}
#endif
#ifdef ANDROID
selected_platform = EGL_PLATFORM_ANDROID;
#endif
if (selected_platform == EGL_PLATFORM_NONE)
{
printf("FATAL: Failed to find suitable platform for display connection\n");
goto out;
}
}
printf("Using EGL Native Display Platform: %s\n", platform_env);
out:
cPlatform::platform = selected_platform;
free(platform_env);
#if HAVE_WAYLAND
if (selected_platform != EGL_PLATFORM_WAYLAND) {
if (GLWin.wl_display)
wl_display_disconnect(GLWin.wl_display);
}
#endif
#if HAVE_X11
if (selected_platform != EGL_PLATFORM_X11) {
if (GLWin.dpy)
{
XCloseDisplay(GLWin.dpy);
}
}
#endif
#if ANDROID
selected_platform = EGL_PLATFORM_ANDROID;
#endif
if (selected_platform == EGL_PLATFORM_NONE)
return false;
return true;
}
bool cPlatform::Init(EGLConfig config, void *window_handle)
{
#if HAVE_WAYLAND
if (cPlatform::platform == EGL_PLATFORM_WAYLAND)
if (!WaylandInterface.Initialize(config))
return false;
#endif
#if HAVE_X11
if (cPlatform::platform == EGL_PLATFORM_X11)
if (!XInterface.Initialize(config, window_handle))
return false;
#endif
#ifdef ANDROID
EGLint format;
eglGetConfigAttrib(GLWin.egl_dpy, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry((EGLNativeWindowType)Host_GetRenderHandle(), 0, 0, format);
int none, width, height;
Host_GetRenderWindowSize(none, none, width, height);
GLInterface->SetBackBufferDimensions(width, height);
#endif
return true;
}
EGLDisplay cPlatform::EGLGetDisplay(void)
{
#if HAVE_WAYLAND
if (cPlatform::platform == EGL_PLATFORM_WAYLAND)
return (EGLDisplay) WaylandInterface.EGLGetDisplay();
#endif
#if HAVE_X11
if (cPlatform::platform == EGL_PLATFORM_X11)
return (EGLDisplay) XInterface.EGLGetDisplay();
#endif
#ifdef ANDROID
return eglGetDisplay(EGL_DEFAULT_DISPLAY);
#endif
return nullptr;
}
EGLNativeWindowType cPlatform::CreateWindow(void)
{
#if HAVE_WAYLAND
if (cPlatform::platform == EGL_PLATFORM_WAYLAND)
return (EGLNativeWindowType) WaylandInterface.CreateWindow();
#endif
#if HAVE_X11
if (cPlatform::platform == EGL_PLATFORM_X11)
return (EGLNativeWindowType) XInterface.CreateWindow();
#endif
#ifdef ANDROID
return (EGLNativeWindowType)Host_GetRenderHandle();
#endif
return 0;
}
void cPlatform::DestroyWindow(void)
{
#if HAVE_WAYLAND
if (cPlatform::platform == EGL_PLATFORM_WAYLAND)
WaylandInterface.DestroyWindow();
#endif
#if HAVE_X11
if (cPlatform::platform == EGL_PLATFORM_X11)
XInterface.DestroyWindow();
#endif
}
void cPlatform::UpdateFPSDisplay(const std::string& text)
{
#if HAVE_WAYLAND
if (cPlatform::platform == EGL_PLATFORM_WAYLAND)
WaylandInterface.UpdateFPSDisplay(text);
#endif
#if HAVE_X11
if (cPlatform::platform == EGL_PLATFORM_X11)
XInterface.UpdateFPSDisplay(text);
#endif
}
void
cPlatform::ToggleFullscreen(bool fullscreen)
{
#if HAVE_WAYLAND
if (cPlatform::platform == EGL_PLATFORM_WAYLAND)
WaylandInterface.ToggleFullscreen(fullscreen);
#endif
#if HAVE_X11
// Only wayland uses this function
#endif
}
void
cPlatform::SwapBuffers()
{
#if HAVE_WAYLAND
if (cPlatform::platform == EGL_PLATFORM_WAYLAND)
WaylandInterface.SwapBuffers();
#endif
#if HAVE_X11
if (cPlatform::platform == EGL_PLATFORM_X11)
XInterface.SwapBuffers();
#endif
#if ANDROID
eglSwapBuffers(GLWin.egl_dpy, GLWin.egl_surf);
#endif
}

View File

@ -6,7 +6,7 @@
#include "Core/Host.h"
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/WGL.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VertexShaderManager.h"
@ -55,15 +55,9 @@ bool cInterfaceWGL::PeekMessages()
return TRUE;
}
// Show the current FPS
void cInterfaceWGL::UpdateFPSDisplay(const std::string& text)
{
SetWindowTextA(m_window_handle, text.c_str());
}
// Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool cInterfaceWGL::Create(void *&window_handle)
bool cInterfaceWGL::Create(void *window_handle)
{
if (window_handle == nullptr)
return false;

View File

@ -12,9 +12,8 @@ class cInterfaceWGL : public cInterfaceBase
public:
void SwapInterval(int Interval);
void Swap();
void UpdateFPSDisplay(const std::string& text);
void* GetFuncAddress(const std::string& name);
bool Create(void *&window_handle);
bool Create(void *window_handle);
bool MakeCurrent();
bool ClearCurrent();
void Shutdown();

View File

@ -1,404 +0,0 @@
// Copyright (C) 2013 Scott Moreau <oreaus@gmail.com>
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <linux/input.h>
#include <sys/mman.h>
#include "Core/Core.h"
#include "Core/State.h"
#include "DolphinWX/GLInterface/GLInterface.h"
static void
hide_cursor(void)
{
if (!GLWin.pointer.wl_pointer)
return;
wl_pointer_set_cursor(GLWin.pointer.wl_pointer,
GLWin.pointer.serial, nullptr, 0, 0);
}
static void
handle_ping(void *data, struct wl_shell_surface *wl_shell_surface,
uint32_t serial)
{
wl_shell_surface_pong(wl_shell_surface, serial);
}
static void
handle_configure(void *data, struct wl_shell_surface *wl_shell_surface,
uint32_t edges, int32_t width, int32_t height)
{
if (GLWin.wl_egl_native)
wl_egl_window_resize(GLWin.wl_egl_native, width, height, 0, 0);
GLWin.geometry.width = width;
GLWin.geometry.height = height;
GLInterface->SetBackBufferDimensions(width, height);
if (!GLWin.fullscreen)
GLWin.window_size = GLWin.geometry;
}
static void
handle_popup_done(void *data, struct wl_shell_surface *wl_shell_surface)
{
}
static const struct wl_shell_surface_listener shell_surface_listener = {
handle_ping,
handle_configure,
handle_popup_done
};
static void
pointer_handle_enter(void *data, struct wl_pointer *pointer,
uint32_t serial, struct wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy)
{
GLWin.pointer.serial = serial;
hide_cursor();
}
static void
pointer_handle_leave(void *data, struct wl_pointer *pointer,
uint32_t serial, struct wl_surface *surface)
{
}
static void
pointer_handle_motion(void *data, struct wl_pointer *pointer,
uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
{
}
static void
pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, uint32_t time, uint32_t button,
uint32_t state)
{
}
static void
pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
uint32_t time, uint32_t axis, wl_fixed_t value)
{
}
static const struct wl_pointer_listener pointer_listener = {
pointer_handle_enter,
pointer_handle_leave,
pointer_handle_motion,
pointer_handle_button,
pointer_handle_axis,
};
static void
toggle_fullscreen(bool fullscreen)
{
GLWin.fullscreen = fullscreen;
if (fullscreen) {
wl_shell_surface_set_fullscreen(GLWin.wl_shell_surface,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
0, nullptr);
} else {
wl_shell_surface_set_toplevel(GLWin.wl_shell_surface);
handle_configure(nullptr, GLWin.wl_shell_surface, 0,
GLWin.window_size.width,
GLWin.window_size.height);
}
}
static void
keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
uint32_t format, int fd, uint32_t size)
{
char *map_str;
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
close(fd);
return;
}
map_str = (char *) mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
if (map_str == MAP_FAILED) {
close(fd);
return;
}
GLWin.keyboard.xkb.keymap = xkb_map_new_from_string(GLWin.keyboard.xkb.context,
map_str,
XKB_KEYMAP_FORMAT_TEXT_V1,
(xkb_keymap_compile_flags) 0);
munmap(map_str, size);
close(fd);
if (!GLWin.keyboard.xkb.keymap) {
fprintf(stderr, "failed to compile keymap\n");
return;
}
GLWin.keyboard.xkb.state = xkb_state_new(GLWin.keyboard.xkb.keymap);
if (!GLWin.keyboard.xkb.state) {
fprintf(stderr, "failed to create XKB state\n");
xkb_map_unref(GLWin.keyboard.xkb.keymap);
GLWin.keyboard.xkb.keymap = nullptr;
return;
}
GLWin.keyboard.xkb.control_mask =
1 << xkb_map_mod_get_index(GLWin.keyboard.xkb.keymap, "Control");
GLWin.keyboard.xkb.alt_mask =
1 << xkb_map_mod_get_index(GLWin.keyboard.xkb.keymap, "Mod1");
GLWin.keyboard.xkb.shift_mask =
1 << xkb_map_mod_get_index(GLWin.keyboard.xkb.keymap, "Shift");
}
static void
keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
uint32_t serial, struct wl_surface *surface,
struct wl_array *keys)
{
}
static void
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
uint32_t serial, struct wl_surface *surface)
{
}
static void
keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t time, uint32_t key,
uint32_t state)
{
if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
return;
if (key == KEY_ESC) {
Core::Stop();
GLWin.running = 0;
} else if ((key == KEY_P) ||
((key == KEY_ENTER) && (GLWin.keyboard.modifiers == 0)))
Core::SetState((Core::GetState() == Core::CORE_RUN) ?
Core::CORE_PAUSE : Core::CORE_RUN);
else if (key == KEY_F)
toggle_fullscreen(!GLWin.fullscreen);
else if ((key == KEY_ENTER) && (GLWin.keyboard.modifiers == MOD_ALT_MASK))
toggle_fullscreen(!GLWin.fullscreen);
else if (key >= KEY_F1 && key <= KEY_F8) {
int slot_number = key - KEY_F1 + 1;
if (GLWin.keyboard.modifiers == MOD_SHIFT_MASK)
State::Save(slot_number);
else
State::Load(slot_number);
}
else if (key == KEY_F9)
Core::SaveScreenShot();
else if (key == KEY_F11)
State::LoadLastSaved();
else if (key == KEY_F12) {
if (GLWin.keyboard.modifiers == MOD_SHIFT_MASK)
State::UndoLoadState();
else
State::UndoSaveState();
}
}
static void
keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t mods_depressed,
uint32_t mods_latched, uint32_t mods_locked,
uint32_t group)
{
xkb_mod_mask_t mask;
xkb_state_update_mask(GLWin.keyboard.xkb.state, mods_depressed, mods_latched,
mods_locked, 0, 0, group);
mask = xkb_state_serialize_mods(GLWin.keyboard.xkb.state,
(xkb_state_component)
(XKB_STATE_DEPRESSED |
XKB_STATE_LATCHED));
GLWin.keyboard.modifiers = 0;
if (mask & GLWin.keyboard.xkb.control_mask)
GLWin.keyboard.modifiers |= MOD_CONTROL_MASK;
if (mask & GLWin.keyboard.xkb.alt_mask)
GLWin.keyboard.modifiers |= MOD_ALT_MASK;
if (mask & GLWin.keyboard.xkb.shift_mask)
GLWin.keyboard.modifiers |= MOD_SHIFT_MASK;
}
static const struct wl_keyboard_listener keyboard_listener = {
keyboard_handle_keymap,
keyboard_handle_enter,
keyboard_handle_leave,
keyboard_handle_key,
keyboard_handle_modifiers,
};
static void
seat_handle_capabilities(void *data, struct wl_seat *seat,
uint32_t caps)
{
struct wl_pointer *wl_pointer = nullptr;
struct wl_keyboard *wl_keyboard = nullptr;
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wl_pointer) {
wl_pointer = wl_seat_get_pointer(seat);
wl_pointer_add_listener(wl_pointer, &pointer_listener, 0);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl_pointer) {
wl_pointer_destroy(wl_pointer);
wl_pointer = nullptr;
}
GLWin.pointer.wl_pointer = wl_pointer;
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !wl_keyboard) {
wl_keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, 0);
} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && wl_keyboard) {
wl_keyboard_destroy(wl_keyboard);
wl_keyboard = nullptr;
}
GLWin.keyboard.wl_keyboard = wl_keyboard;
}
static const struct wl_seat_listener seat_listener = {
seat_handle_capabilities,
};
static void
registry_handle_global(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version)
{
if (strcmp(interface, "wl_compositor") == 0) {
GLWin.wl_compositor = (wl_compositor *)
wl_registry_bind(registry, name,
&wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_shell") == 0) {
GLWin.wl_shell = (wl_shell *) wl_registry_bind(registry, name,
&wl_shell_interface, 1);
} else if (strcmp(interface, "wl_seat") == 0) {
GLWin.wl_seat = (wl_seat *) wl_registry_bind(registry, name,
&wl_seat_interface, 1);
wl_seat_add_listener(GLWin.wl_seat, &seat_listener, 0);
} else if (strcmp(interface, "wl_shm") == 0) {
GLWin.wl_shm = (wl_shm *) wl_registry_bind(registry, name,
&wl_shm_interface, 1);
GLWin.wl_cursor_theme = (wl_cursor_theme *) wl_cursor_theme_load(nullptr, 32, GLWin.wl_shm);
GLWin.wl_cursor = (wl_cursor *)
wl_cursor_theme_get_cursor(GLWin.wl_cursor_theme, "left_ptr");
}
}
static void
registry_handle_global_remove(void *data, struct wl_registry *registry,
uint32_t name)
{
}
static const struct wl_registry_listener registry_listener = {
registry_handle_global,
registry_handle_global_remove
};
bool cWaylandInterface::ServerConnect(void)
{
GLWin.wl_display = wl_display_connect(nullptr);
if (!GLWin.wl_display)
return false;
return true;
}
bool cWaylandInterface::Initialize(void *config)
{
if (!GLWin.wl_display) {
printf("Error: couldn't open wayland display\n");
return false;
}
GLWin.pointer.wl_pointer = nullptr;
GLWin.keyboard.wl_keyboard = nullptr;
GLWin.keyboard.xkb.context = xkb_context_new((xkb_context_flags) 0);
if (GLWin.keyboard.xkb.context == nullptr) {
fprintf(stderr, "Failed to create XKB context\n");
return nullptr;
}
GLWin.wl_registry = wl_display_get_registry(GLWin.wl_display);
wl_registry_add_listener(GLWin.wl_registry,
&registry_listener, nullptr);
while (!GLWin.wl_compositor)
wl_display_dispatch(GLWin.wl_display);
GLWin.wl_cursor_surface =
wl_compositor_create_surface(GLWin.wl_compositor);
return true;
}
void *cWaylandInterface::EGLGetDisplay(void)
{
return eglGetDisplay(GLWin.wl_display);
}
void *cWaylandInterface::CreateWindow(void)
{
GLWin.window_size.width = 640;
GLWin.window_size.height = 480;
GLWin.fullscreen = true;
GLWin.wl_surface = wl_compositor_create_surface(GLWin.wl_compositor);
GLWin.wl_shell_surface = wl_shell_get_shell_surface(GLWin.wl_shell,
GLWin.wl_surface);
wl_shell_surface_add_listener(GLWin.wl_shell_surface,
&shell_surface_listener, 0);
GLWin.wl_egl_native = wl_egl_window_create(GLWin.wl_surface,
GLWin.window_size.width,
GLWin.window_size.height);
return GLWin.wl_egl_native;
}
void cWaylandInterface::DestroyWindow(void)
{
wl_egl_window_destroy(GLWin.wl_egl_native);
wl_shell_surface_destroy(GLWin.wl_shell_surface);
wl_surface_destroy(GLWin.wl_surface);
}
void cWaylandInterface::UpdateFPSDisplay(const std::string& text)
{
wl_shell_surface_set_title(GLWin.wl_shell_surface, text.c_str());
}
void cWaylandInterface::ToggleFullscreen(bool fullscreen)
{
toggle_fullscreen(fullscreen);
}
void cWaylandInterface::SwapBuffers()
{
struct wl_region *region;
region = wl_compositor_create_region(GLWin.wl_compositor);
wl_region_add(region, 0, 0,
GLWin.geometry.width,
GLWin.geometry.height);
wl_surface_set_opaque_region(GLWin.wl_surface, region);
wl_region_destroy(region);
eglSwapBuffers(GLWin.egl_dpy, GLWin.egl_surf);
}

View File

@ -1,29 +0,0 @@
// Copyright (C) 2013 Scott Moreau <oreaus@gmail.com>
// Licensed under GPLv2
// Refer to the license.txt file included.
#pragma once
#include <string>
#include <wayland-client.h>
#include <wayland-cursor.h>
#include <wayland-egl.h>
#include <xkbcommon/xkbcommon.h>
#define MOD_SHIFT_MASK 0x01
#define MOD_ALT_MASK 0x02
#define MOD_CONTROL_MASK 0x04
class cWaylandInterface
{
public:
bool ServerConnect(void);
bool Initialize(void *config);
void *EGLGetDisplay(void);
void *CreateWindow(void);
void DestroyWindow(void);
void UpdateFPSDisplay(const std::string& text);
void ToggleFullscreen(bool fullscreen);
void SwapBuffers();
};

View File

@ -2,164 +2,61 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "Common/Thread.h"
#include "Core/Host.h"
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/X11_Util.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
#include "VideoCommon/VideoConfig.h"
#if USE_EGL
bool cXInterface::ServerConnect(void)
void cX11Window::Initialize(Display *_dpy)
{
GLWin.dpy = XOpenDisplay(nullptr);
if (!GLWin.dpy)
return false;
return true;
dpy = _dpy;
}
bool cXInterface::Initialize(void *config, void *window_handle)
Window cX11Window::CreateXWindow(Window parent, XVisualInfo *vi)
{
XVisualInfo visTemplate;
int num_visuals;
EGLint vid;
XSetWindowAttributes attr;
if (!GLWin.dpy) {
printf("Error: couldn't open X display\n");
return false;
}
if (!eglGetConfigAttrib(GLWin.egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
GLWin.vi = XGetVisualInfo(GLWin.dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!GLWin.vi) {
printf("Error: couldn't get X visual\n");
exit(1);
}
GLWin.evdpy = XOpenDisplay(nullptr);
GLWin.parent = (Window) window_handle;
GLWin.screen = DefaultScreen(GLWin.dpy);
if (GLWin.parent == 0)
GLWin.parent = RootWindow(GLWin.dpy, GLWin.screen);
return true;
}
void *cXInterface::EGLGetDisplay(void)
{
#if HAVE_WAYLAND
return eglGetDisplay((wl_display *) GLWin.dpy);
#else
return eglGetDisplay(GLWin.dpy);
#endif
}
void *cXInterface::CreateWindow(void)
{
Atom wmProtocols[1];
colormap = XCreateColormap(dpy, parent, vi->visual, AllocNone);
// Setup window attributes
GLWin.attr.colormap = XCreateColormap(GLWin.evdpy,
GLWin.parent, GLWin.vi->visual, AllocNone);
GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask;
GLWin.attr.background_pixel = BlackPixel(GLWin.evdpy, GLWin.screen);
GLWin.attr.border_pixel = 0;
attr.colormap = colormap;
// Create the window
GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent,
0, 0, 1, 1, 0,
GLWin.vi->depth, InputOutput, GLWin.vi->visual,
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1);
XSetStandardProperties(GLWin.evdpy, GLWin.win, "GPU", "GPU", None, nullptr, 0, nullptr);
XMapRaised(GLWin.evdpy, GLWin.win);
XSync(GLWin.evdpy, True);
win = XCreateWindow(dpy, parent,
0, 0, 1, 1, 0,
vi->depth, InputOutput, vi->visual,
CWColormap, &attr);
XSelectInput(dpy, parent, StructureNotifyMask);
XMapWindow(dpy, win);
XSync(dpy, True);
GLWin.xEventThread = std::thread(&cXInterface::XEventThread, this);
xEventThread = std::thread(&cX11Window::XEventThread, this);
return (void *) GLWin.win;
}
void cXInterface::DestroyWindow(void)
{
XDestroyWindow(GLWin.evdpy, GLWin.win);
GLWin.win = 0;
if (GLWin.xEventThread.joinable())
GLWin.xEventThread.join();
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
}
void cXInterface::UpdateFPSDisplay(const std::string& text)
{
XStoreName(GLWin.evdpy, GLWin.win, text.c_str());
}
void cXInterface::SwapBuffers()
{
eglSwapBuffers(GLWin.egl_dpy, GLWin.egl_surf);
}
void cXInterface::XEventThread()
#else
void cX11Window::CreateXWindow(void)
{
Atom wmProtocols[1];
// Setup window attributes
GLWin.attr.colormap = XCreateColormap(GLWin.evdpy,
GLWin.parent, GLWin.vi->visual, AllocNone);
GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask;
GLWin.attr.background_pixel = BlackPixel(GLWin.evdpy, GLWin.screen);
GLWin.attr.border_pixel = 0;
// Create the window
GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent,
0, 0, 1, 1, 0,
GLWin.vi->depth, InputOutput, GLWin.vi->visual,
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1);
XSetStandardProperties(GLWin.evdpy, GLWin.win, "GPU", "GPU", None, nullptr, 0, nullptr);
XMapRaised(GLWin.evdpy, GLWin.win);
XSync(GLWin.evdpy, True);
GLWin.xEventThread = std::thread(&cX11Window::XEventThread, this);
return win;
}
void cX11Window::DestroyXWindow(void)
{
XUnmapWindow(GLWin.evdpy, GLWin.win);
GLWin.win = 0;
if (GLWin.xEventThread.joinable())
GLWin.xEventThread.join();
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
XUnmapWindow(dpy, win);
if (xEventThread.joinable())
xEventThread.join();
XFreeColormap(dpy, colormap);
}
void cX11Window::XEventThread()
#endif
{
while (GLWin.win)
while (win)
{
XEvent event;
for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--)
for (int num_events = XPending(dpy); num_events > 0; num_events--)
{
XNextEvent(GLWin.evdpy, &event);
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;
case ClientMessage:
if ((unsigned long) event.xclient.data.l[0] ==
XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False))
Host_Message(WM_USER_STOP);
break;
default:
break;
}

View File

@ -5,31 +5,22 @@
#pragma once
#include <string>
#include <thread>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#if USE_EGL
class cXInterface
{
private:
void XEventThread();
public:
bool ServerConnect(void);
bool Initialize(void *config, void *window_handle);
void *EGLGetDisplay(void);
void *CreateWindow(void);
void DestroyWindow(void);
void UpdateFPSDisplay(const std::string& text);
void SwapBuffers();
};
#else
class cX11Window
{
private:
void XEventThread();
std::thread xEventThread;
Colormap colormap;
public:
void CreateXWindow(void);
void Initialize(Display *dpy);
Window CreateXWindow(Window parent, XVisualInfo *vi);
void DestroyXWindow(void);
Display *dpy;
Window win;
};
#endif

View File

@ -607,17 +607,6 @@ void Host_SetStartupDebuggingParameters()
StartUp.bEnableDebugging = main_frame->g_pCodeWindow ? true : false; // RUNNING_DEBUG
}
void Host_UpdateStatusBar(const std::string& text, int Field)
{
wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATESTATUSBAR);
// Set the event string
event.SetString(StrToWxStr(text));
// Update statusbar field
event.SetInt(Field);
// Post message
main_frame->GetEventHandler()->AddPendingEvent(event);
}
void Host_SetWiiMoteConnectionState(int _State)
{
static int currentState = -1;

View File

@ -104,8 +104,6 @@ bool Host_RendererHasFocus()
void Host_ConnectWiimote(int wm_idx, bool connect) {}
void Host_UpdateStatusBar(const std::string& text, int filed){}
void Host_SysMessage(const char *fmt, ...)
{
va_list args;

View File

@ -18,32 +18,27 @@
#include "Core/Core.h"
#include "Core/CoreParameter.h"
#include "Core/Host.h"
#include "Core/State.h"
#include "Core/HW/Wiimote.h"
#include "Core/PowerPC/PowerPC.h"
#include "VideoCommon/VideoBackendBase.h"
#if HAVE_X11
#include <X11/keysym.h>
#include "Core/State.h"
#include "DolphinWX/X11Utils.h"
#endif
#if HAVE_WAYLAND
#include <wayland-client.h>
#endif
#ifdef USE_EGL
#include "DolphinWX/GLInterface/GLInterface.h"
#endif
#ifdef __APPLE__
#import <Cocoa/Cocoa.h>
#endif
static bool rendererHasFocus = true;
static bool running = true;
class Platform
{
public:
virtual void Init() = 0;
virtual void SetTitle(const std::string &title) = 0;
virtual void MainLoop() = 0;
virtual void Shutdown() = 0;
virtual ~Platform() {};
};
static Platform* platform;
void Host_NotifyMapLoaded() {}
void Host_RefreshDSPDebuggerWindow() {}
@ -58,12 +53,16 @@ void Host_Message(int Id)
}
}
void* windowHandle;
void* Host_GetRenderHandle()
{
return nullptr;
return windowHandle;
}
void Host_UpdateTitle(const std::string& title){};
void Host_UpdateTitle(const std::string& title)
{
platform->SetTitle(title);
}
void Host_UpdateDisasmDialog(){}
@ -103,8 +102,6 @@ bool Host_RendererHasFocus()
void Host_ConnectWiimote(int wm_idx, bool connect) {}
void Host_UpdateStatusBar(const std::string& text, int filed){}
void Host_SysMessage(const char *fmt, ...)
{
va_list list;
@ -129,54 +126,84 @@ void Host_SetWiiMoteConnectionState(int _State) {}
void Host_ShowVideoConfig(void*, const std::string&, const std::string&) {}
#if HAVE_X11
static void X11_MainLoop()
#include <X11/keysym.h>
#include "DolphinWX/X11Utils.h"
class PlatformX11 : public Platform
{
bool fullscreen = SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen;
while (!Core::IsRunning())
updateMainFrameEvent.Wait();
Display *dpy = XOpenDisplay(0);
Window win = (Window)Core::GetWindowHandle();
XSelectInput(dpy, win, KeyPressMask | FocusChangeMask);
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bDisableScreenSaver)
X11Utils::InhibitScreensaver(dpy, win, true);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
X11Utils::XRRConfiguration *XRRConfig = new X11Utils::XRRConfiguration(dpy, win);
#endif
Display *dpy;
Window win;
Cursor blankCursor = None;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
{
// make a blank cursor
Pixmap Blank;
XColor DummyColor;
char ZeroData[1] = {0};
Blank = XCreateBitmapFromData (dpy, win, ZeroData, 1, 1);
blankCursor = XCreatePixmapCursor(dpy, Blank, Blank, &DummyColor, &DummyColor, 0, 0);
XFreePixmap (dpy, Blank);
XDefineCursor(dpy, win, blankCursor);
}
if (fullscreen)
{
X11Utils::EWMH_Fullscreen(dpy, _NET_WM_STATE_TOGGLE);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig->ToggleDisplayMode(True);
X11Utils::XRRConfiguration *XRRConfig;
#endif
void Init() override
{
XInitThreads();
dpy = XOpenDisplay(NULL);
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos,
SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos,
SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
0, 0, BlackPixel(dpy, 0));
XSelectInput(dpy, win, KeyPressMask | FocusChangeMask);
Atom wmProtocols[1];
wmProtocols[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(dpy, win, wmProtocols, 1);
XMapRaised(dpy, win);
XFlush(dpy);
windowHandle = (void *) win;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bDisableScreenSaver)
X11Utils::InhibitScreensaver(dpy, win, true);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig = new X11Utils::XRRConfiguration(dpy, win);
#endif
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
{
// make a blank cursor
Pixmap Blank;
XColor DummyColor;
char ZeroData[1] = {0};
Blank = XCreateBitmapFromData (dpy, win, ZeroData, 1, 1);
blankCursor = XCreatePixmapCursor(dpy, Blank, Blank, &DummyColor, &DummyColor, 0, 0);
XFreePixmap (dpy, Blank);
XDefineCursor(dpy, win, blankCursor);
}
}
// The actual loop
while (running)
void SetTitle(const std::string &string) override
{
XEvent event;
KeySym key;
for (int num_events = XPending(dpy); num_events > 0; num_events--)
XStoreName(dpy, win, string.c_str());
}
void MainLoop() override
{
bool fullscreen = SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen;
if (fullscreen)
{
XNextEvent(dpy, &event);
switch (event.type)
X11Utils::ToggleFullscreen(dpy, win);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig->ToggleDisplayMode(True);
#endif
}
// The actual loop
while (running)
{
XEvent event;
KeySym key;
for (int num_events = XPending(dpy); num_events > 0; num_events--)
{
XNextEvent(dpy, &event);
switch (event.type)
{
case KeyPress:
key = XLookupKeysym((XKeyEvent*)&event, 0);
if (key == XK_Escape)
@ -197,7 +224,7 @@ static void X11_MainLoop()
else if ((key == XK_Return) && (event.xkey.state & Mod1Mask))
{
fullscreen = !fullscreen;
X11Utils::EWMH_Fullscreen(dpy, _NET_WM_STATE_TOGGLE);
X11Utils::ToggleFullscreen(dpy, win);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig->ToggleDisplayMode(fullscreen);
#endif
@ -225,7 +252,7 @@ static void X11_MainLoop()
case FocusIn:
rendererHasFocus = true;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
Core::GetState() != Core::CORE_PAUSE)
Core::GetState() != Core::CORE_PAUSE)
XDefineCursor(dpy, win, blankCursor);
break;
case FocusOut:
@ -233,61 +260,51 @@ static void X11_MainLoop()
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XUndefineCursor(dpy, win);
break;
case ClientMessage:
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(dpy, "WM_DELETE_WINDOW", False))
running = false;
break;
}
}
if (!fullscreen)
{
Window winDummy;
unsigned int borderDummy, depthDummy;
XGetGeometry(dpy, win, &winDummy,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
&borderDummy, &depthDummy);
}
usleep(100000);
}
if (!fullscreen)
{
Window winDummy;
unsigned int borderDummy, depthDummy;
XGetGeometry(dpy, win, &winDummy,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
&borderDummy, &depthDummy);
}
usleep(100000);
}
void Shutdown() override
{
#if defined(HAVE_XRANDR) && HAVE_XRANDR
delete XRRConfig;
#endif
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bDisableScreenSaver)
X11Utils::InhibitScreensaver(dpy, win, false);
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XFreeCursor(dpy, blankCursor);
XCloseDisplay(dpy);
Core::Stop();
}
delete XRRConfig;
#endif
#if HAVE_WAYLAND
static void Wayland_MainLoop()
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XFreeCursor(dpy, blankCursor);
XCloseDisplay(dpy);
}
};
#endif
static Platform* GetPlatform()
{
// Wait for display to be initialized
while (!GLWin.wl_display)
usleep(20000);
GLWin.running = 1;
while (GLWin.running)
wl_display_dispatch(GLWin.wl_display);
if (GLWin.wl_display)
wl_display_disconnect(GLWin.wl_display);
}
#if HAVE_X11
return new PlatformX11();
#endif
return nullptr;
}
int main(int argc, char* argv[])
{
#ifdef __APPLE__
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSEvent *event = [[NSEvent alloc] init];
[NSApplication sharedApplication];
[NSApp activateIgnoringOtherApps: YES];
[NSApp finishLaunching];
#endif
int ch, help = 0;
struct option longopts[] = {
{ "exec", no_argument, nullptr, 'e' },
@ -323,6 +340,13 @@ int main(int argc, char* argv[])
return 1;
}
platform = GetPlatform();
if (!platform)
{
fprintf(stderr, "No platform found\n");
return 1;
}
LogManager::Init();
SConfig::Init();
VideoBackend::PopulateList();
@ -330,67 +354,30 @@ int main(int argc, char* argv[])
m_LocalCoreStartupParameter.m_strVideoBackend);
WiimoteReal::LoadSettings();
#if USE_EGL
GLWin.platform = EGL_PLATFORM_NONE;
#endif
#if HAVE_WAYLAND
GLWin.wl_display = nullptr;
#endif
platform->Init();
// No use running the loop when booting fails
if (BootManager::BootCore(argv[optind]))
if (!BootManager::BootCore(argv[optind]))
{
#if USE_EGL
while (GLWin.platform == EGL_PLATFORM_NONE)
usleep(20000);
#endif
#if HAVE_WAYLAND
if (GLWin.platform == EGL_PLATFORM_WAYLAND)
Wayland_MainLoop();
#endif
#if HAVE_X11
#if USE_EGL
if (GLWin.platform == EGL_PLATFORM_X11)
{
#endif
XInitThreads();
X11_MainLoop();
#if USE_EGL
}
#endif
#endif
#ifdef __APPLE__
while (running)
{
event = [NSApp nextEventMatchingMask: NSAnyEventMask
untilDate: [NSDate distantFuture]
inMode: NSDefaultRunLoopMode dequeue: YES];
if ([event type] == NSKeyDown &&
[event modifierFlags] & NSCommandKeyMask &&
[[event characters] UTF8String][0] == 'q')
{
Core::Stop();
break;
}
if ([event type] != NSKeyDown)
[NSApp sendEvent: event];
}
[event release];
[pool release];
#else
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
updateMainFrameEvent.Wait();
#endif
fprintf(stderr, "Could not boot %s\n", argv[optind]);
return 1;
}
while (!Core::IsRunning())
updateMainFrameEvent.Wait();
platform->MainLoop();
Core::Stop();
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
updateMainFrameEvent.Wait();
platform->Shutdown();
Core::Shutdown();
WiimoteReal::Shutdown();
VideoBackend::ClearList();
SConfig::Shutdown();
LogManager::Shutdown();
delete platform;
return 0;
}

View File

@ -24,21 +24,15 @@ extern char **environ;
namespace X11Utils
{
void EWMH_Fullscreen(Display *dpy, int action)
void ToggleFullscreen(Display *dpy, Window win)
{
_assert_(action == _NET_WM_STATE_REMOVE ||
action == _NET_WM_STATE_ADD ||
action == _NET_WM_STATE_TOGGLE);
Window win = (Window)Core::GetWindowHandle();
// 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] = action;
event.xclient.data.l[0] = _NET_WM_STATE_TOGGLE;
event.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
// Send the event

View File

@ -34,7 +34,7 @@
namespace X11Utils
{
void EWMH_Fullscreen(Display *dpy, int action);
void ToggleFullscreen(Display *dpy, Window win);
#if defined(HAVE_WX) && HAVE_WX
Window XWindowFromHandle(void *Handle);
Display *XDisplayFromHandle(void *Handle);

View File

@ -5,10 +5,6 @@
#include "Common/Thread.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#if USE_EGL
#include "DolphinWX/GLInterface/GLInterface.h"
#endif
#ifdef CIFACE_USE_XINPUT
#include "InputCommon/ControllerInterface/XInput/XInput.h"
#endif
@ -57,15 +53,10 @@ void ControllerInterface::Initialize()
ciface::XInput::Init(m_devices);
#endif
#ifdef CIFACE_USE_XLIB
#if USE_EGL
if (GLWin.platform == EGL_PLATFORM_X11)
#endif
{
ciface::Xlib::Init(m_devices, m_hwnd);
ciface::Xlib::Init(m_devices, m_hwnd);
#ifdef CIFACE_USE_X11_XINPUT2
ciface::XInput2::Init(m_devices, m_hwnd);
ciface::XInput2::Init(m_devices, m_hwnd);
#endif
}
#endif
#ifdef CIFACE_USE_OSX
ciface::OSX::Init(m_devices, m_hwnd);

View File

@ -8,7 +8,7 @@ namespace DX11
class VideoBackend : public VideoBackendHardware
{
bool Initialize(void *&) override;
bool Initialize(void *) override;
void Shutdown() override;
std::string GetName() const override;
@ -19,7 +19,6 @@ class VideoBackend : public VideoBackendHardware
void ShowConfig(void* parent) override;
void UpdateFPSDisplay(const std::string&) override;
unsigned int PeekMessages() override;
void* m_window_handle;

View File

@ -51,12 +51,6 @@ unsigned int VideoBackend::PeekMessages()
return TRUE;
}
void VideoBackend::UpdateFPSDisplay(const std::string& text)
{
std::string str = StringFromFormat("%s | D3D | %s", scm_rev_str, text.c_str());
SetWindowTextA((HWND)m_window_handle, str.c_str());
}
std::string VideoBackend::GetName() const
{
return "D3D";
@ -141,7 +135,7 @@ void VideoBackend::ShowConfig(void *hParent)
Host_ShowVideoConfig(hParent, GetDisplayName(), "gfx_dx11");
}
bool VideoBackend::Initialize(void *&window_handle)
bool VideoBackend::Initialize(void *window_handle)
{
if (window_handle == nullptr)
return false;

View File

@ -25,11 +25,10 @@ protected:
u32 s_opengl_mode;
public:
virtual void Swap() {}
virtual void UpdateFPSDisplay(const std::string& text) {}
virtual void SetMode(u32 mode) { s_opengl_mode = GLInterfaceMode::MODE_OPENGL; }
virtual u32 GetMode() { return s_opengl_mode; }
virtual void* GetFuncAddress(const std::string& name) { return nullptr; }
virtual bool Create(void *&window_handle) { return true; }
virtual bool Create(void *window_handle) { return true; }
virtual bool MakeCurrent() { return true; }
virtual bool ClearCurrent() { return true; }
virtual void Shutdown() {}

View File

@ -26,12 +26,6 @@ unsigned int VideoBackend::PeekMessages()
return GLInterface->PeekMessages();
}
// Show the current FPS
void VideoBackend::UpdateFPSDisplay(const std::string& text)
{
return GLInterface->UpdateFPSDisplay(StringFromFormat("%s | %s | %s", scm_rev_str, GetDisplayName().c_str(), text.c_str()));
}
}
void InitInterface()
{

View File

@ -8,7 +8,7 @@ namespace OGL
class VideoBackend : public VideoBackendHardware
{
bool Initialize(void *&) override;
bool Initialize(void *) override;
void Shutdown() override;
std::string GetName() const override;
@ -19,7 +19,6 @@ class VideoBackend : public VideoBackendHardware
void ShowConfig(void* parent) override;
void UpdateFPSDisplay(const std::string&) override;
unsigned int PeekMessages() override;
};

View File

@ -155,7 +155,7 @@ void VideoBackend::ShowConfig(void *_hParent)
Host_ShowVideoConfig(_hParent, GetDisplayName(), "gfx_opengl");
}
bool VideoBackend::Initialize(void *&window_handle)
bool VideoBackend::Initialize(void *window_handle)
{
InitializeShared();
InitBackendInfo();

View File

@ -71,7 +71,7 @@ void VideoSoftware::ShowConfig(void *hParent)
Host_ShowVideoConfig(hParent, GetDisplayName(), "gfx_software");
}
bool VideoSoftware::Initialize(void *&window_handle)
bool VideoSoftware::Initialize(void *window_handle)
{
g_SWVideoConfig.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_software.ini").c_str());
@ -372,10 +372,4 @@ unsigned int VideoSoftware::PeekMessages()
return GLInterface->PeekMessages();
}
// Show the current FPS
void VideoSoftware::UpdateFPSDisplay(const std::string& text)
{
GLInterface->UpdateFPSDisplay(StringFromFormat("%s | Software | %s", scm_rev_str, text.c_str()));
}
}

View File

@ -10,7 +10,7 @@ namespace SW
class VideoSoftware : public VideoBackend
{
bool Initialize(void *&) override;
bool Initialize(void *window_handle) override;
void Shutdown() override;
std::string GetName() const override;
@ -48,7 +48,6 @@ class VideoSoftware : public VideoBackend
void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override;
void UpdateFPSDisplay(const std::string&) override;
unsigned int PeekMessages() override;
void PauseAndLock(bool doLock, bool unpauseOnUnlock=true) override;

View File

@ -14,8 +14,6 @@
#include "VideoCommon/VertexShaderGen.h"
#include "VideoCommon/VideoConfig.h"
//void UpdateFPSDisplay(const char *text);
GFXDebuggerBase *g_pdebugger = nullptr;
volatile bool GFXDebuggerPauseFlag = false; // if true, the GFX thread will be spin locked until it's false again
volatile PauseEvent GFXDebuggerToPauseAtNext = NOT_PAUSE; // Event which will trigger spin locking the GFX thread
@ -57,8 +55,6 @@ void GFXDebuggerCheckAndPause(bool update)
g_pdebugger->OnPause();
while ( GFXDebuggerPauseFlag )
{
g_video_backend->UpdateFPSDisplay("Paused by Video Debugger");
if (update) GFXDebuggerUpdateScreen();
SLEEP(5);
}

View File

@ -68,11 +68,9 @@ public:
virtual void EmuStateChange(EMUSTATE_CHANGE) = 0;
virtual void UpdateFPSDisplay(const std::string&) = 0;
virtual unsigned int PeekMessages() = 0;
virtual bool Initialize(void *&) = 0;
virtual bool Initialize(void *window_handle) = 0;
virtual void Shutdown() = 0;
virtual void RunLoop(bool enable) = 0;