Platform/Unix: Rename X11SharedDisplay to Xlib, and remove Display member variable from all classes.
We now initialize/destroy the display in Xlib::init/shutdown that is called in UnixApplication::init/shutdown and therefore is valid through the whole lifetime. So no need for classes to keep references.
This commit is contained in:
parent
60dd9bacb0
commit
090646b61a
17 changed files with 137 additions and 201 deletions
|
|
@ -64,8 +64,8 @@ if TARGET_OS == "Win32" then
|
||||||
})
|
})
|
||||||
elseif TARGET_OS == "Unix" then
|
elseif TARGET_OS == "Unix" then
|
||||||
platform_spec_module = Module("source/Platform/Unix", {
|
platform_spec_module = Module("source/Platform/Unix", {
|
||||||
|
"Xlib.cpp",
|
||||||
"UnixApplication.cpp",
|
"UnixApplication.cpp",
|
||||||
"X11SharedDisplay.cpp",
|
|
||||||
"X11Display.cpp",
|
"X11Display.cpp",
|
||||||
"GLXContext.cpp",
|
"GLXContext.cpp",
|
||||||
"X11Input.cpp",
|
"X11Input.cpp",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
|
|
||||||
#include "glad_glx.h"
|
#include "glad_glx.h"
|
||||||
#include "X11SharedDisplay.h"
|
#include "Xlib.h"
|
||||||
#include "GLXContext.h"
|
#include "GLXContext.h"
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
@ -60,7 +60,6 @@ static bool ensureExtensionsLoaded(::Display* disp, int screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
GLXContext::GLXContext() :
|
GLXContext::GLXContext() :
|
||||||
m_disp (NULL),
|
|
||||||
m_win (0),
|
m_win (0),
|
||||||
m_ctx (NULL)
|
m_ctx (NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -76,13 +75,6 @@ bool GLXContext::create(const PlatformDisplay* display)
|
||||||
// Destroy any previous context first.
|
// Destroy any previous context first.
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
m_disp = XGetDisplay();
|
|
||||||
if (m_disp == NULL) {
|
|
||||||
destroy();
|
|
||||||
Log::warn("X11: Could not open display");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_win = (::Window) display->getHandle();
|
m_win = (::Window) display->getHandle();
|
||||||
|
|
||||||
if (!createGLContext()) {
|
if (!createGLContext()) {
|
||||||
|
|
@ -95,6 +87,7 @@ bool GLXContext::create(const PlatformDisplay* display)
|
||||||
|
|
||||||
bool GLXContext::createGLContext()
|
bool GLXContext::createGLContext()
|
||||||
{
|
{
|
||||||
|
::Display* disp = Xlib::getDisplay();
|
||||||
::GLXFBConfig *fbc;
|
::GLXFBConfig *fbc;
|
||||||
::XVisualInfo *info;
|
::XVisualInfo *info;
|
||||||
int fbcount;
|
int fbcount;
|
||||||
|
|
@ -117,31 +110,31 @@ bool GLXContext::createGLContext()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure glx extensions are loaded.
|
// Ensure glx extensions are loaded.
|
||||||
if (!ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp))) {
|
if (!ensureExtensionsLoaded(disp, DefaultScreen(disp))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = ::glXChooseVisual(m_disp, DefaultScreen(m_disp), vi_attr);
|
info = ::glXChooseVisual(disp, DefaultScreen(disp), vi_attr);
|
||||||
if (info == NULL) {
|
if (info == NULL) {
|
||||||
Log::warn("GLX: Could not find a valid VisualInfo.");
|
Log::warn("GLX: Could not find a valid VisualInfo.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup GL settings.
|
// Setup GL settings.
|
||||||
fbc = glXChooseFBConfig(m_disp, DefaultScreen(m_disp), (const int*) info->visual, &fbcount);
|
fbc = glXChooseFBConfig(disp, DefaultScreen(disp), (const int*) info->visual, &fbcount);
|
||||||
if (fbc == NULL) {
|
if (fbc == NULL) {
|
||||||
Log::warn("GLX: Could not find FB Config.");
|
Log::warn("GLX: Could not find FB Config.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create context.
|
// Create context.
|
||||||
m_ctx = glXCreateContextAttribsARB(m_disp, fbc[0], NULL, GL_TRUE, ctx_attr);
|
m_ctx = glXCreateContextAttribsARB(disp, fbc[0], NULL, GL_TRUE, ctx_attr);
|
||||||
if (m_ctx == NULL) {
|
if (m_ctx == NULL) {
|
||||||
Log::warn("GLX: Failed to create context.");
|
Log::warn("GLX: Failed to create context.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glXMakeCurrent(m_disp, m_win, m_ctx);
|
glXMakeCurrent(disp, m_win, m_ctx);
|
||||||
|
|
||||||
// Load OpenGL
|
// Load OpenGL
|
||||||
if (!loadGL()) {
|
if (!loadGL()) {
|
||||||
|
|
@ -155,29 +148,24 @@ bool GLXContext::createGLContext()
|
||||||
void GLXContext::destroy()
|
void GLXContext::destroy()
|
||||||
{
|
{
|
||||||
if (m_ctx) {
|
if (m_ctx) {
|
||||||
::glXDestroyContext(m_disp, m_ctx);
|
::glXDestroyContext(Xlib::getDisplay(), m_ctx);
|
||||||
m_ctx = NULL;
|
m_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_disp) {
|
|
||||||
XReleaseDisplay(m_disp);
|
|
||||||
m_disp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_win = None;
|
m_win = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::activate()
|
bool GLXContext::activate()
|
||||||
{
|
{
|
||||||
if (m_win && m_ctx) {
|
if (m_win && m_ctx) {
|
||||||
return ::glXMakeCurrent(m_disp, m_win, m_ctx);
|
return ::glXMakeCurrent(Xlib::getDisplay(), m_win, m_ctx);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::deactivate()
|
bool GLXContext::deactivate()
|
||||||
{
|
{
|
||||||
return ::glXMakeCurrent(m_disp, None, NULL);
|
return ::glXMakeCurrent(Xlib::getDisplay(), None, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::isActive() const
|
bool GLXContext::isActive() const
|
||||||
|
|
@ -187,7 +175,8 @@ bool GLXContext::isActive() const
|
||||||
|
|
||||||
bool GLXContext::setSwapInterval(int interval)
|
bool GLXContext::setSwapInterval(int interval)
|
||||||
{
|
{
|
||||||
ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp));
|
::Display *disp = Xlib::getDisplay();
|
||||||
|
ensureExtensionsLoaded(disp, DefaultScreen(disp));
|
||||||
|
|
||||||
if (GLAD_GLX_MESA_swap_control) {
|
if (GLAD_GLX_MESA_swap_control) {
|
||||||
return glXSwapIntervalMESA(interval);
|
return glXSwapIntervalMESA(interval);
|
||||||
|
|
@ -215,7 +204,7 @@ void GLXContext::setSize(const Vector2u size)
|
||||||
|
|
||||||
void GLXContext::swapBuffers()
|
void GLXContext::swapBuffers()
|
||||||
{
|
{
|
||||||
glXSwapBuffers(m_disp, m_win);
|
glXSwapBuffers(Xlib::getDisplay(), m_win);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,6 @@ private :
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
::Display* m_disp;
|
|
||||||
|
|
||||||
::Window m_win;
|
::Window m_win;
|
||||||
|
|
||||||
::GLXContext m_ctx;
|
::GLXContext m_ctx;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
|
|
||||||
#include "UnixApplication.h"
|
#include "UnixApplication.h"
|
||||||
|
#include "Xlib.h"
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
void UnixApplication::init()
|
void UnixApplication::init()
|
||||||
{
|
{
|
||||||
// TODO
|
Xlib::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnixApplication::shutdown()
|
void UnixApplication::shutdown()
|
||||||
{
|
{
|
||||||
// TODO
|
Xlib::shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformInput& UnixApplication::getInput()
|
PlatformInput& UnixApplication::getInput()
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
|
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
#include <Platform/PlatformMisc.h>
|
#include <Platform/PlatformMisc.h>
|
||||||
#include "X11SharedDisplay.h"
|
#include "Xlib.h"
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -13,7 +12,7 @@ namespace sp {
|
||||||
|
|
||||||
void PlatformMisc::GetDisplayModes(std::vector<DisplayMode>& modes)
|
void PlatformMisc::GetDisplayModes(std::vector<DisplayMode>& modes)
|
||||||
{
|
{
|
||||||
::Display *disp = XGetDisplay();
|
::Display *disp = Xlib::getDisplay();
|
||||||
|
|
||||||
if (disp) {
|
if (disp) {
|
||||||
int scr = DefaultScreen(disp);
|
int scr = DefaultScreen(disp);
|
||||||
|
|
@ -28,7 +27,7 @@ void PlatformMisc::GetDisplayModes(std::vector<DisplayMode>& modes)
|
||||||
XRRScreenSize* sizes = ::XRRConfigSizes(config, &nbSizes);
|
XRRScreenSize* sizes = ::XRRConfigSizes(config, &nbSizes);
|
||||||
if (sizes && nbSizes > 0) {
|
if (sizes && nbSizes > 0) {
|
||||||
int nbDepths = 0;
|
int nbDepths = 0;
|
||||||
int* depths = XListDepths(disp, scr, &nbDepths);
|
int* depths = ::XListDepths(disp, scr, &nbDepths);
|
||||||
if (depths && nbDepths > 0) {
|
if (depths && nbDepths > 0) {
|
||||||
|
|
||||||
for(int i = 0; i < nbDepths; i++) {
|
for(int i = 0; i < nbDepths; i++) {
|
||||||
|
|
@ -59,8 +58,6 @@ void PlatformMisc::GetDisplayModes(std::vector<DisplayMode>& modes)
|
||||||
} else {
|
} else {
|
||||||
Log::error("Failed to use XRandR extension while trying to get display modes.");
|
Log::error("Failed to use XRandR extension while trying to get display modes.");
|
||||||
}
|
}
|
||||||
|
|
||||||
XReleaseDisplay(disp);
|
|
||||||
} else {
|
} else {
|
||||||
Log::error("Failed to connect to the X server while trying to get display modes.");
|
Log::error("Failed to connect to the X server while trying to get display modes.");
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +67,7 @@ DisplayMode PlatformMisc::GetDesktopMode()
|
||||||
{
|
{
|
||||||
DisplayMode mode;
|
DisplayMode mode;
|
||||||
|
|
||||||
::Display *disp = XGetDisplay();
|
::Display *disp = Xlib::getDisplay();
|
||||||
|
|
||||||
if (disp) {
|
if (disp) {
|
||||||
int scr = DefaultScreen(disp);
|
int scr = DefaultScreen(disp);
|
||||||
|
|
@ -103,8 +100,6 @@ DisplayMode PlatformMisc::GetDesktopMode()
|
||||||
} else {
|
} else {
|
||||||
Log::error("Failed to use XRandR extension while trying to get desktop display mode.");
|
Log::error("Failed to use XRandR extension while trying to get desktop display mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
XReleaseDisplay(disp);
|
|
||||||
} else {
|
} else {
|
||||||
Log::error("Failed to connect to the X server while trying to get desktop display mode.");
|
Log::error("Failed to connect to the X server while trying to get desktop display mode.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
#include <Spectre/Graphics/Image.h>
|
#include <Spectre/Graphics/Image.h>
|
||||||
#include "X11WindowEventHandler.h"
|
#include "X11WindowEventHandler.h"
|
||||||
#include "X11SharedDisplay.h"
|
#include "Xlib.h"
|
||||||
#include "GLXContext.h"
|
#include "GLXContext.h"
|
||||||
#include "X11Display.h"
|
#include "X11Display.h"
|
||||||
|
|
||||||
|
|
@ -27,7 +27,6 @@ X11Display* X11Display::getFocused()
|
||||||
X11Display::
|
X11Display::
|
||||||
X11Display() :
|
X11Display() :
|
||||||
m_screen (0),
|
m_screen (0),
|
||||||
m_disp (NULL),
|
|
||||||
m_size (200,200),
|
m_size (200,200),
|
||||||
m_cur_last (0),
|
m_cur_last (0),
|
||||||
m_cur_hidden (0)
|
m_cur_hidden (0)
|
||||||
|
|
@ -41,49 +40,44 @@ bool X11Display::create(DisplayDescription description)
|
||||||
Atom protocols;
|
Atom protocols;
|
||||||
Visual* visual;
|
Visual* visual;
|
||||||
Window root_win;
|
Window root_win;
|
||||||
|
::Display* disp = Xlib::getDisplay();
|
||||||
|
|
||||||
m_disp = XGetDisplay();
|
m_screen = DefaultScreen(disp);
|
||||||
if (m_disp == NULL) {
|
root_win = XRootWindow(disp, m_screen);
|
||||||
Log::warn("X11: Could not open display");
|
visual = DefaultVisual(disp, m_screen);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_screen = DefaultScreen(m_disp);
|
attr.border_pixel = BlackPixel(disp, m_screen);
|
||||||
root_win = XRootWindow(m_disp, m_screen);
|
attr.background_pixel = WhitePixel(disp, m_screen);
|
||||||
visual = DefaultVisual(m_disp, m_screen);
|
|
||||||
|
|
||||||
attr.border_pixel = BlackPixel(m_disp, m_screen);
|
|
||||||
attr.background_pixel = WhitePixel(m_disp, m_screen);
|
|
||||||
//attr.override_redirect = True;
|
//attr.override_redirect = True;
|
||||||
attr.colormap = ::XCreateColormap(m_disp, root_win, visual, AllocNone);
|
attr.colormap = ::XCreateColormap(disp, root_win, visual, AllocNone);
|
||||||
// We want InputFocus,Keyboard,Mouse,Resize,Exposure (repaint) events.
|
// We want InputFocus,Keyboard,Mouse,Resize,Exposure (repaint) events.
|
||||||
attr.event_mask = FocusChangeMask
|
attr.event_mask = FocusChangeMask
|
||||||
| KeyPressMask | KeyReleaseMask
|
| KeyPressMask | KeyReleaseMask
|
||||||
| ButtonPressMask | ButtonReleaseMask | PointerMotionMask
|
| ButtonPressMask | ButtonReleaseMask | PointerMotionMask
|
||||||
| StructureNotifyMask | ExposureMask;
|
| StructureNotifyMask | ExposureMask;
|
||||||
|
|
||||||
m_win = ::XCreateWindow(m_disp, root_win,
|
m_win = ::XCreateWindow(disp, root_win,
|
||||||
0, 0, /* Position */
|
0, 0, /* Position */
|
||||||
m_size.x, m_size.y, 0 /* Border width */, DefaultDepth(m_disp, m_screen),
|
m_size.x, m_size.y, 0 /* Border width */, DefaultDepth(disp, m_screen),
|
||||||
InputOutput, visual,
|
InputOutput, visual,
|
||||||
CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr);
|
CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr);
|
||||||
|
|
||||||
// Register event handler
|
// Register event handler
|
||||||
X11WindowEventHandler::registerHandler(m_disp, m_win, this);
|
X11WindowEventHandler::registerHandler(disp, m_win, this);
|
||||||
|
|
||||||
// X11 does not handle pressing the X button on a window.
|
// X11 does not handle pressing the X button on a window.
|
||||||
// that is the job of the window manager.
|
// that is the job of the window manager.
|
||||||
// Here we can request the WM to send us a delete event so we can handle it ourself.
|
// Here we can request the WM to send us a delete event so we can handle it ourself.
|
||||||
protocols = getAtom("WM_DELETE_WINDOW");
|
protocols = Xlib::getAtom("WM_DELETE_WINDOW");
|
||||||
XSetWMProtocols(m_disp, m_win, &protocols, 1);
|
XSetWMProtocols(disp, m_win, &protocols, 1);
|
||||||
|
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
|
|
||||||
setSize(description.mode.width, description.mode.height);
|
setSize(description.mode.width, description.mode.height);
|
||||||
|
|
||||||
// Clear and take focus
|
// Clear and take focus
|
||||||
XClearWindow(m_disp, m_win);
|
XClearWindow(disp, m_win);
|
||||||
XMapRaised(m_disp, m_win);
|
XMapRaised(disp, m_win);
|
||||||
|
|
||||||
Log::info("X11: Created display");
|
Log::info("X11: Created display");
|
||||||
|
|
||||||
|
|
@ -94,21 +88,16 @@ bool X11Display::create(DisplayDescription description)
|
||||||
|
|
||||||
void X11Display::destroy()
|
void X11Display::destroy()
|
||||||
{
|
{
|
||||||
if (m_disp) {
|
if (m_win) {
|
||||||
|
::Display* disp = Xlib::getDisplay();
|
||||||
if (m_win) {
|
X11WindowEventHandler::unregisterHandler(disp, m_win);
|
||||||
X11WindowEventHandler::unregisterHandler(m_disp, m_win);
|
::XDestroyWindow(disp, m_win);
|
||||||
::XDestroyWindow(m_disp, m_win);
|
|
||||||
}
|
|
||||||
|
|
||||||
XReleaseDisplay(m_disp);
|
|
||||||
m_disp = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X11Display::isValid()
|
bool X11Display::isValid()
|
||||||
{
|
{
|
||||||
return m_disp && m_win;
|
return m_win;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* X11Display::getHandle() const
|
void* X11Display::getHandle() const
|
||||||
|
|
@ -128,7 +117,7 @@ void X11Display::setSize(unsigned int width, unsigned int height)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_size = Vector2u(width, height);
|
m_size = Vector2u(width, height);
|
||||||
::XResizeWindow(m_disp, m_win, m_size.x, m_size.y);
|
::XResizeWindow(Xlib::getDisplay(), m_win, m_size.x, m_size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2u X11Display::getSize() const
|
Vector2u X11Display::getSize() const
|
||||||
|
|
@ -138,7 +127,7 @@ Vector2u X11Display::getSize() const
|
||||||
|
|
||||||
void X11Display::setPosition(unsigned int x, unsigned int y)
|
void X11Display::setPosition(unsigned int x, unsigned int y)
|
||||||
{
|
{
|
||||||
::XMoveWindow(m_disp, m_win, x, y);
|
::XMoveWindow(Xlib::getDisplay(), m_win, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2u X11Display::getPosition() const
|
Vector2u X11Display::getPosition() const
|
||||||
|
|
@ -146,7 +135,7 @@ Vector2u X11Display::getPosition() const
|
||||||
Vector2u pos(0, 0);
|
Vector2u pos(0, 0);
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
|
|
||||||
if (XGetWindowAttributes(m_disp, m_win, &attr)) {
|
if (XGetWindowAttributes(Xlib::getDisplay(), m_win, &attr)) {
|
||||||
pos.x = attr.x;
|
pos.x = attr.x;
|
||||||
pos.y = attr.y;
|
pos.y = attr.y;
|
||||||
}
|
}
|
||||||
|
|
@ -156,37 +145,38 @@ Vector2u X11Display::getPosition() const
|
||||||
void X11Display::setVisible(bool visible)
|
void X11Display::setVisible(bool visible)
|
||||||
{
|
{
|
||||||
if (visible) {
|
if (visible) {
|
||||||
::XMapWindow(m_disp, m_win);
|
::XMapWindow(Xlib::getDisplay(), m_win);
|
||||||
} else {
|
} else {
|
||||||
::XUnmapWindow(m_disp, m_win);
|
::XUnmapWindow(Xlib::getDisplay(), m_win);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Display::minimize()
|
void X11Display::minimize()
|
||||||
{
|
{
|
||||||
::XIconifyWindow(m_disp, m_win, m_screen);
|
::XIconifyWindow(Xlib::getDisplay(), m_win, m_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Display::maximize()
|
void X11Display::maximize()
|
||||||
{
|
{
|
||||||
::XClientMessageEvent ev = {};
|
::XClientMessageEvent ev = {};
|
||||||
|
::Display* disp = Xlib::getDisplay();
|
||||||
|
|
||||||
ev.type = ClientMessage;
|
ev.type = ClientMessage;
|
||||||
ev.window = m_win;
|
ev.window = m_win;
|
||||||
ev.message_type = getAtom("_NET_WM_STATE");
|
ev.message_type = Xlib::getAtom("_NET_WM_STATE");
|
||||||
ev.format = 32;
|
ev.format = 32;
|
||||||
ev.data.l[0] = _NET_WM_STATE_TOGGLE;
|
ev.data.l[0] = _NET_WM_STATE_TOGGLE;
|
||||||
ev.data.l[1] = getAtom("_NET_WM_STATE_MAXIMIZED_HORZ");
|
ev.data.l[1] = Xlib::getAtom("_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||||
ev.data.l[2] = getAtom("_NET_WM_STATE_MAXIMIZED_VERT");
|
ev.data.l[2] = Xlib::getAtom("_NET_WM_STATE_MAXIMIZED_VERT");
|
||||||
ev.data.l[3] = 1;
|
ev.data.l[3] = 1;
|
||||||
|
|
||||||
::XSendEvent(m_disp, DefaultRootWindow(m_disp), False,
|
::XSendEvent(disp, DefaultRootWindow(disp), False,
|
||||||
SubstructureNotifyMask, (XEvent*) &ev);
|
SubstructureNotifyMask, (XEvent*) &ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Display::setCaption(const std::string& caption)
|
void X11Display::setCaption(const std::string& caption)
|
||||||
{
|
{
|
||||||
::XStoreName(m_disp, m_win, caption.c_str());
|
::XStoreName(Xlib::getDisplay(), m_win, caption.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this up to the non-platform layer.
|
// TODO: Move this up to the non-platform layer.
|
||||||
|
|
@ -201,8 +191,9 @@ void X11Display::setIcon(const std::string& icon)
|
||||||
|
|
||||||
void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t *pixels)
|
void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t *pixels)
|
||||||
{
|
{
|
||||||
::Atom net_wm_icon = getAtom("_NET_WM_ICON", False);
|
::Display* disp = Xlib::getDisplay();
|
||||||
::Atom cardinal = getAtom("CARDINAL", False);
|
::Atom net_wm_icon = Xlib::getAtom("_NET_WM_ICON", False);
|
||||||
|
::Atom cardinal = Xlib::getAtom("CARDINAL", False);
|
||||||
std::vector<uint64_t> buffer(2 + width * height);
|
std::vector<uint64_t> buffer(2 + width * height);
|
||||||
uint64_t *ptr = &buffer[0];
|
uint64_t *ptr = &buffer[0];
|
||||||
|
|
||||||
|
|
@ -217,36 +208,37 @@ void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t
|
||||||
| (pixels[i * 4 + 3] << 24);
|
| (pixels[i * 4 + 3] << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
::XChangeProperty(m_disp, m_win,
|
::XChangeProperty(disp, m_win,
|
||||||
net_wm_icon, cardinal, 32,
|
net_wm_icon, cardinal, 32,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
reinterpret_cast<const unsigned char*>(&buffer[0]),
|
reinterpret_cast<const unsigned char*>(&buffer[0]),
|
||||||
2 + width * height);
|
2 + width * height);
|
||||||
|
|
||||||
XFlush(m_disp);
|
XFlush(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Display::createHiddenCursor()
|
void X11Display::createHiddenCursor()
|
||||||
{
|
{
|
||||||
|
::Display* disp = Xlib::getDisplay();
|
||||||
XColor c;
|
XColor c;
|
||||||
Pixmap pix = ::XCreatePixmap(m_disp, m_win, 1, 1, 1);
|
Pixmap pix = ::XCreatePixmap(disp, m_win, 1, 1, 1);
|
||||||
GC gc = ::XCreateGC(m_disp, pix, 0, NULL);
|
GC gc = ::XCreateGC(disp, pix, 0, NULL);
|
||||||
|
|
||||||
// Draw transparent pixel.
|
// Draw transparent pixel.
|
||||||
::XDrawPoint(m_disp, pix, gc, 0, 0);
|
::XDrawPoint(disp, pix, gc, 0, 0);
|
||||||
|
|
||||||
c.red = c.green = c.blue = 0;
|
c.red = c.green = c.blue = 0;
|
||||||
c.flags = DoRed | DoGreen | DoBlue;
|
c.flags = DoRed | DoGreen | DoBlue;
|
||||||
m_cur_hidden = XCreatePixmapCursor(m_disp, pix, pix, &c, &c, 0, 0);
|
m_cur_hidden = XCreatePixmapCursor(disp, pix, pix, &c, &c, 0, 0);
|
||||||
|
|
||||||
// Free GC and pixmap.
|
// Free GC and pixmap.
|
||||||
::XFreePixmap(m_disp, pix);
|
::XFreePixmap(disp, pix);
|
||||||
::XFreeGC(m_disp, gc);
|
::XFreeGC(disp, gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Display::showCursor(bool value)
|
void X11Display::showCursor(bool value)
|
||||||
{
|
{
|
||||||
XDefineCursor(m_disp, m_win, value ? m_cur_last : m_cur_hidden);
|
XDefineCursor(Xlib::getDisplay(), m_win, value ? m_cur_last : m_cur_hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Display::grabCursor(bool value)
|
void X11Display::grabCursor(bool value)
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,6 @@ protected :
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
::Display* m_disp;
|
|
||||||
|
|
||||||
::Window m_win;
|
::Window m_win;
|
||||||
|
|
||||||
int m_screen;
|
int m_screen;
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,24 @@
|
||||||
|
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
|
|
||||||
#include "X11EventQueue.h"
|
#include "X11EventQueue.h"
|
||||||
#include "X11SharedDisplay.h"
|
#include "Xlib.h"
|
||||||
#include "X11Keyboard.h"
|
#include "X11Keyboard.h"
|
||||||
#include "X11Mouse.h"
|
#include "X11Mouse.h"
|
||||||
#include "X11WindowEventHandler.h"
|
#include "X11WindowEventHandler.h"
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
X11EventQueue::X11EventQueue()
|
|
||||||
{
|
|
||||||
m_disp = XGetDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
X11EventQueue::~X11EventQueue()
|
|
||||||
{
|
|
||||||
if (m_disp) {
|
|
||||||
XReleaseDisplay(m_disp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool X11EventQueue::poll(Event& event)
|
bool X11EventQueue::poll(Event& event)
|
||||||
{
|
{
|
||||||
Atom del_win = getAtom("WM_DELETE_WINDOW");
|
::Display* disp = Xlib::getDisplay();
|
||||||
Atom wm_proto = getAtom("WM_PROTOCOLS");
|
Atom del_win = Xlib::getAtom("WM_DELETE_WINDOW");
|
||||||
|
Atom wm_proto = Xlib::getAtom("WM_PROTOCOLS");
|
||||||
|
|
||||||
if (m_disp == NULL) {
|
if (XPending(disp)) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (XPending(m_disp)) {
|
|
||||||
XEvent xevent;
|
XEvent xevent;
|
||||||
|
|
||||||
XNextEvent(m_disp, &xevent);
|
XNextEvent(disp, &xevent);
|
||||||
|
|
||||||
switch(xevent.type) {
|
switch(xevent.type) {
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
|
|
@ -64,7 +50,7 @@ bool X11EventQueue::poll(Event& event)
|
||||||
default:
|
default:
|
||||||
// Pass to window.
|
// Pass to window.
|
||||||
Log::info("X11: Window Event");
|
Log::info("X11: Window Event");
|
||||||
X11WindowEventHandler::process(m_disp, xevent);
|
X11WindowEventHandler::process(disp, xevent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,8 @@ namespace sp {
|
||||||
class X11EventQueue : public PlatformEventQueue
|
class X11EventQueue : public PlatformEventQueue
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
X11EventQueue();
|
|
||||||
virtual ~X11EventQueue();
|
|
||||||
|
|
||||||
virtual bool poll(Event& event);
|
virtual bool poll(Event& event);
|
||||||
|
|
||||||
private :
|
|
||||||
::Display* m_disp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "X11Keyboard.h"
|
#include "X11Keyboard.h"
|
||||||
#include "X11Display.h"
|
#include "X11Display.h"
|
||||||
#include "X11SharedDisplay.h"
|
#include "Xlib.h"
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
|
|
@ -211,14 +211,10 @@ m_win(0)
|
||||||
|
|
||||||
X11Keyboard::~X11Keyboard()
|
X11Keyboard::~X11Keyboard()
|
||||||
{
|
{
|
||||||
if (m_disp) {
|
|
||||||
XReleaseDisplay(m_disp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Keyboard::init()
|
void X11Keyboard::init()
|
||||||
{
|
{
|
||||||
m_disp = XGetDisplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X11Keyboard::isKeyDown(Keyboard::Key key)
|
bool X11Keyboard::isKeyDown(Keyboard::Key key)
|
||||||
|
|
@ -334,7 +330,7 @@ bool X11Keyboard::isKeyDown(Keyboard::Key key)
|
||||||
default : sym = 0; break;
|
default : sym = 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyCode keycode = ::XKeysymToKeycode(m_disp, sym);
|
KeyCode keycode = ::XKeysymToKeycode(Xlib::getDisplay(), sym);
|
||||||
|
|
||||||
if (keycode) {
|
if (keycode) {
|
||||||
return m_key_state[keycode / 8] & (1 << (keycode % 8));
|
return m_key_state[keycode / 8] & (1 << (keycode % 8));
|
||||||
|
|
@ -365,7 +361,7 @@ void X11Keyboard::update(InputModule *input)
|
||||||
if (m_win) {
|
if (m_win) {
|
||||||
|
|
||||||
// Query keyboard state.
|
// Query keyboard state.
|
||||||
::XQueryKeymap(m_disp, m_key_state);
|
::XQueryKeymap(Xlib::getDisplay(), m_key_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,19 @@
|
||||||
|
|
||||||
#include <Spectre/System/Event.h>
|
#include <Spectre/System/Event.h>
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
|
#include "Xlib.h"
|
||||||
#include "X11Display.h"
|
#include "X11Display.h"
|
||||||
#include "X11Mouse.h"
|
#include "X11Mouse.h"
|
||||||
|
|
||||||
#include "X11SharedDisplay.h"
|
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
X11Mouse::X11Mouse() :
|
X11Mouse::X11Mouse() :
|
||||||
m_disp(NULL),
|
|
||||||
m_btn_state(0)
|
m_btn_state(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
X11Mouse::~X11Mouse()
|
|
||||||
{
|
|
||||||
if (m_disp) {
|
|
||||||
XReleaseDisplay(m_disp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void X11Mouse::init()
|
void X11Mouse::init()
|
||||||
{
|
{
|
||||||
m_disp = XGetDisplay();
|
|
||||||
updateFocusedWindow();
|
updateFocusedWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,14 +52,15 @@ bool X11Mouse::isButtonDown(Mouse::Button button) const
|
||||||
|
|
||||||
void X11Mouse::update(InputModule *input)
|
void X11Mouse::update(InputModule *input)
|
||||||
{
|
{
|
||||||
|
::Display* disp = Xlib::getDisplay();
|
||||||
::Window root, child;
|
::Window root, child;
|
||||||
int rx, ry, x = 0, y = 0;
|
int rx, ry, x = 0, y = 0;
|
||||||
|
|
||||||
updateFocusedWindow();
|
updateFocusedWindow();
|
||||||
|
|
||||||
// Query position and button state.
|
// Query position and button state.
|
||||||
XQueryPointer(m_disp,
|
XQueryPointer(disp,
|
||||||
m_win ? m_win : ::XDefaultRootWindow(m_disp),
|
m_win ? m_win : ::XDefaultRootWindow(disp),
|
||||||
&root, &child,
|
&root, &child,
|
||||||
&rx, &ry,
|
&rx, &ry,
|
||||||
&x, &y, &m_btn_state);
|
&x, &y, &m_btn_state);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ class X11Mouse : public Mouse
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
X11Mouse();
|
X11Mouse();
|
||||||
~X11Mouse();
|
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
|
|
@ -32,7 +31,6 @@ protected :
|
||||||
void updateFocusedWindow();
|
void updateFocusedWindow();
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
::Display* m_disp;
|
|
||||||
::Window m_win; // Focused window.
|
::Window m_win; // Focused window.
|
||||||
|
|
||||||
Vector2f m_position;
|
Vector2f m_position;
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include "X11SharedDisplay.h"
|
|
||||||
|
|
||||||
namespace sp {
|
|
||||||
|
|
||||||
// Define a global display (for simplicity, we always connect to local one.)
|
|
||||||
::Display* sharedDisplay = NULL;
|
|
||||||
unsigned int refcount = 0;
|
|
||||||
|
|
||||||
::Display* XGetDisplay() {
|
|
||||||
|
|
||||||
// Create if we dont have any references.
|
|
||||||
if (refcount == 0) {
|
|
||||||
sharedDisplay = XOpenDisplay(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
refcount++;
|
|
||||||
return sharedDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XReleaseDisplay(::Display* disp) {
|
|
||||||
|
|
||||||
assert(disp == sharedDisplay);
|
|
||||||
|
|
||||||
if (refcount < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (--refcount == 0) {
|
|
||||||
XCloseDisplay(sharedDisplay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Atom getAtom(const std::string& name, bool onlyIfExists) {
|
|
||||||
|
|
||||||
return XInternAtom(sharedDisplay, name.c_str(), onlyIfExists);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sp
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
#ifndef SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H
|
|
||||||
#define SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
namespace sp {
|
|
||||||
|
|
||||||
::Display* XGetDisplay();
|
|
||||||
|
|
||||||
void XReleaseDisplay(::Display* disp);
|
|
||||||
|
|
||||||
Atom getAtom(const std::string& name, bool onlyIfExists = false);
|
|
||||||
|
|
||||||
} // namespace sp
|
|
||||||
|
|
||||||
#endif /* SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H */
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
#include "X11Display.h"
|
#include "X11Display.h"
|
||||||
#include "X11SharedDisplay.h"
|
|
||||||
#include "X11WindowEventHandler.h"
|
#include "X11WindowEventHandler.h"
|
||||||
#include <X11/Xresource.h>
|
#include <X11/Xresource.h>
|
||||||
|
|
||||||
|
|
|
||||||
34
source/Platform/Unix/Xlib.cpp
Normal file
34
source/Platform/Unix/Xlib.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include "Xlib.h"
|
||||||
|
|
||||||
|
namespace sp { namespace Xlib {
|
||||||
|
|
||||||
|
namespace _priv {
|
||||||
|
// Define a global display (for simplicity, we always connect to local one.)
|
||||||
|
::Display* display = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
_priv::display = XOpenDisplay(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown()
|
||||||
|
{
|
||||||
|
XCloseDisplay(_priv::display);
|
||||||
|
_priv::display = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Display* getDisplay()
|
||||||
|
{
|
||||||
|
assert(_priv::display != NULL);
|
||||||
|
return _priv::display;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Atom getAtom(const std::string& name, bool onlyIfExists)
|
||||||
|
{
|
||||||
|
return XInternAtom(getDisplay(), name.c_str(), onlyIfExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
} } // namespace sp::Xlib
|
||||||
22
source/Platform/Unix/Xlib.h
Normal file
22
source/Platform/Unix/Xlib.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
#ifndef SPECTRE_PLATFORM_UNIX_XLIB_H
|
||||||
|
#define SPECTRE_PLATFORM_UNIX_XLIB_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
// Wrapper for some Xlib functions.
|
||||||
|
|
||||||
|
namespace sp { namespace Xlib {
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
::Display* getDisplay();
|
||||||
|
|
||||||
|
::Atom getAtom(const std::string& name, bool onlyIfExists = false);
|
||||||
|
|
||||||
|
} } // namespace sp::xlib
|
||||||
|
|
||||||
|
#endif /* SPECTRE_PLATFORM_UNIX_XLIB_H */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue