1
0
Fork 0

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:
Henrik Hautakoski 2020-12-25 17:17:51 +01:00
parent 60dd9bacb0
commit 090646b61a
17 changed files with 137 additions and 201 deletions

View file

@ -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",

View file

@ -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

View file

@ -39,8 +39,6 @@ private :
private : private :
::Display* m_disp;
::Window m_win; ::Window m_win;
::GLXContext m_ctx; ::GLXContext m_ctx;

View file

@ -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()

View file

@ -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.");
} }

View file

@ -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) { if (m_win) {
X11WindowEventHandler::unregisterHandler(m_disp, m_win); ::Display* disp = Xlib::getDisplay();
::XDestroyWindow(m_disp, m_win); X11WindowEventHandler::unregisterHandler(disp, m_win);
} ::XDestroyWindow(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)

View file

@ -60,8 +60,6 @@ protected :
protected : protected :
::Display* m_disp;
::Window m_win; ::Window m_win;
int m_screen; int m_screen;

View file

@ -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);
} }
} }

View file

@ -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

View file

@ -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);
} }
} }

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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 */

View file

@ -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>

View 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

View 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 */